Pak-LLM Coder SDK
Embed the sovereign agent runtime in your own product. The SDK exposes the same tool registry, terminal firewall and compliance sentinel as the IDE and Mission Control, plus a three-class lifecycle hook system, exit verification gates and ephemeral subagent context trees.
Install
npm install @pak-llm/sdkpip install pakllm-codernpm install @modelcontextprotocol/sdkThe official MCP SDK is an optional peer dependency. When it is absent the adapter falls back to a dependency-free JSON-RPC 2.0 dispatcher with the same tool surface, which keeps air-gapped and browser installs working.
Lifecycle hooks
Inspect
Read-only · non-blocking
Collect telemetry, token usage and security audit events. Exceptions are recorded as traces and never interrupt an agent run.
Decide
Blocking · fail-closed
Authorize prompts, tool calls and patches. The first deny wins; a hook that throws is treated as a deny, never as approval.
Transform
Blocking · rewriting
Sanitize prompts, mask secrets and rewrite patches or model output. Hooks run in ascending order, so masking can follow normalization.
Hooks can be scoped to phases: session, prompt, tool, patch and completion. Every invocation is recorded as a bounded trace (registry.getTraces()) for audit and debugging.
import { Agent, DecideHook, InspectHook, TransformHook } from '@pak-llm/sdk';
const agent = new Agent();
agent.lifecycle
.register(new InspectHook({
id: 'token-audit',
run: event => metrics.count(event.phase, event.action),
}))
.register(new TransformHook({
id: 'mask-secrets',
order: 10,
run: (_event, value) => maskSecrets(String(value)),
}))
.register(new DecideHook({
id: 'deny-prod-writes',
phases: ['tool'],
run: event => ({
allow: !String(event.payload.command ?? '').includes('/prod'),
reason: 'production paths are read-only for agents',
}),
}));
const stream = await agent.chat('refactor the billing module');Exit / stop verification
Completion is not accepted while tests, lint or type checks fail. Verification returns structured traces and a feedback block that the caller should route back into the reasoning loop. A Decide hook scoped to completion can also veto task exit.
const result = await agent.lifecycle.verifyCompletion({
testsPassed: false,
lintPassed: true,
typecheckPassed: true,
failures: ['2 tests failed in billing.spec.ts'],
});
if (!result.passed) {
// Feed the traces back into the reasoning loop instead of stopping.
throw new Error(result.feedback);
}Ephemeral subagents
Deep repository searches can run in a child scope with a fresh context window and a restricted toolset. The child never inherits the parent transcript, and only a compact summary is merged back into the parent context.
const scout = agent.spawnSubagent({
objective: 'Locate every call site of calculateTotals',
tools: ['grep_search', 'file_view'],
tokenBudget: 6000,
});
scout.record('assistant', 'found 12 call sites', 900);
scout.addFinding('calculateTotals is re-exported from src/billing/index.ts');
scout.touchFile('src/billing/index.ts');
// The parent only receives a compact summary, never the child transcript.
console.log(agent.subagentSummaries()[0].summary);Python parity
The Python package mirrors the TypeScript surface: the same hook classes, the same fail-closed decision semantics and the same subagent scoping primitives.
import asyncio
from pakllm_coder import Agent, DecideHook, TransformHook
agent = Agent()
agent.lifecycle.register(
TransformHook("mask-secrets", lambda event, value: value.replace("AKIA", "[REDACTED]"))
)
agent.lifecycle.register(
DecideHook(
"deny-forbidden",
lambda event: {"allow": "forbidden" not in event.payload["prompt"]},
phases=["prompt"],
)
)
stream = asyncio.run(agent.chat("review the billing flow"))MCP adapter
Mount the same tool surface on the official MCP transport or the built-in compatible dispatcher. Tool calls stay inside the SDK's firewall, quota and sentinel layers.
import { createMcpServerAdapter, dispatchMcpJsonRpc } from '@pak-llm/sdk';
const adapter = await createMcpServerAdapter({
name: 'pak-llm',
version: '1.4.0',
tools: [{ name: 'workspace_index', description: 'Index the workspace', inputSchema: {
type: 'object', properties: { depth: { type: 'number' } },
}}],
onCall: (tool, args) => client.workspace.index(Number(args.depth ?? 2)),
});
// adapter.mode is "official" when @modelcontextprotocol/sdk is installed,
// otherwise "compat" with a JSON-RPC 2.0 initialize/tools/list/tools/call dispatcher.
const reply = await dispatchMcpJsonRpc(
{ jsonrpc: '2.0', id: 1, method: 'tools/list' },
adapter,
{ name: 'pak-llm', version: '1.4.0' },
);Compliance mapping
| Clause | Implementation |
|---|---|
| NIST AC-3 / AC-6 | Decide hooks enforce least privilege for prompts, tools and patches with fail-closed defaults. |
| NIST AU-6 / SI-2 | Inspect traces and completion verification produce auditable decision paths; failed tests block task exit. |
| NIST SI-7 | Content-addressed artifacts and hook traces make agent decisions and patches verifiable. |
| OWASP LLM01 / LLM02 | Transform hooks sanitize prompts and model output before use; unsafe HTML is never rendered. |
| OWASP LLM07 / LLM08 | Tool allowlists, subagent scopes and approval gates bound agent authority. |
| CWE-22 / CWE-78 | Path normalization and argv-only execution are enforced below the hook layer, so hooks cannot bypass them. |
| ISO/IEC 25010 / 42001 | Deterministic hook ordering, bounded traces and isolated subagent contexts support reliability and AI governance. |