@agentwares/agentguard-sdk 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +16 -6
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { GuardError, GuardErrorBody, GuardEvent, GuardResult, Policy, PolicyInpu
|
|
|
4
4
|
import { LoadedPolicy, FileKillSwitch } from '@agentwares/agentguard-core/node';
|
|
5
5
|
|
|
6
6
|
interface CreateGuardOptions {
|
|
7
|
-
/** path to `
|
|
7
|
+
/** path to `okgate.yaml` (file-backed state, shared with the CLI) or an inline policy (in-memory) */
|
|
8
8
|
policy: string | PolicyInput | Policy;
|
|
9
9
|
/** run id for calls that do not pass one (default: generated) */
|
|
10
10
|
runId?: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/guard.ts
|
|
2
|
+
import { basename } from "path";
|
|
2
3
|
import {
|
|
3
4
|
Guard,
|
|
4
5
|
GuardError,
|
|
@@ -9,8 +10,8 @@ import {
|
|
|
9
10
|
import {
|
|
10
11
|
FileApprovalStore,
|
|
11
12
|
FileAuditSink,
|
|
12
|
-
FileKillSwitch,
|
|
13
13
|
FileStateStore,
|
|
14
|
+
killSwitchFor,
|
|
14
15
|
loadPolicyFile
|
|
15
16
|
} from "@agentwares/agentguard-core/node";
|
|
16
17
|
function newRunId(now = /* @__PURE__ */ new Date()) {
|
|
@@ -140,10 +141,11 @@ async function createGuard(opts) {
|
|
|
140
141
|
fix: `add it under agents: or use one of ${policy.agents.map((a) => a.name).join(", ") || "(none)"}`
|
|
141
142
|
});
|
|
142
143
|
const useFiles = loaded !== void 0 && !opts.memory;
|
|
143
|
-
const kill = useFiles ?
|
|
144
|
+
const kill = useFiles ? killSwitchFor(loaded) : void 0;
|
|
144
145
|
const guard = new Guard({
|
|
145
146
|
policy,
|
|
146
147
|
env,
|
|
148
|
+
...loaded ? { policyFile: basename(loaded.path) } : {},
|
|
147
149
|
onEvent: opts.onEvent,
|
|
148
150
|
...useFiles ? {
|
|
149
151
|
state: new FileStateStore(loaded.stateDir),
|
|
@@ -251,7 +253,15 @@ function blockedResponse(status, body) {
|
|
|
251
253
|
error: { type: body.code, message: `${body.code}: ${body.cause} \u2014 ${body.fix}` },
|
|
252
254
|
...body
|
|
253
255
|
}),
|
|
254
|
-
{
|
|
256
|
+
{
|
|
257
|
+
status,
|
|
258
|
+
// X-Agentguard is the same header under the name before the rename to okgate
|
|
259
|
+
headers: {
|
|
260
|
+
"Content-Type": "application/json",
|
|
261
|
+
"X-Okgate": String(body.code),
|
|
262
|
+
"X-Agentguard": String(body.code)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
255
265
|
);
|
|
256
266
|
}
|
|
257
267
|
function createGuardedFetch(ag, opts = {}) {
|
|
@@ -276,8 +286,8 @@ function createGuardedFetch(ag, opts = {}) {
|
|
|
276
286
|
if (killed.killed) {
|
|
277
287
|
return blockedResponse(403, {
|
|
278
288
|
code: "KILLED",
|
|
279
|
-
cause: `
|
|
280
|
-
fix: "a human must run `
|
|
289
|
+
cause: `okgate kill switch is on (${killed.reason ?? ""})`,
|
|
290
|
+
fix: "a human must run `okgate resume`",
|
|
281
291
|
retryable: false
|
|
282
292
|
});
|
|
283
293
|
}
|
|
@@ -291,7 +301,7 @@ function createGuardedFetch(ag, opts = {}) {
|
|
|
291
301
|
return blockedResponse(402, {
|
|
292
302
|
code: "CAP_EXCEEDED",
|
|
293
303
|
cause: `spend_usd cap for ${scope} is used up`,
|
|
294
|
-
fix: "stop and report to the user; a human can raise caps in
|
|
304
|
+
fix: "stop and report to the user; a human can raise caps in the policy file (okgate.yaml)",
|
|
295
305
|
retryable: false,
|
|
296
306
|
details: { remaining: check.remaining, runId: runId() }
|
|
297
307
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/guard.ts","../src/fetch.ts","../src/adapters/openai-agents.ts","../src/adapters/langchain.ts","../src/index.ts"],"sourcesContent":["/**\n * `createGuard` — the policy engine for tool calls that bypass MCP. Same YAML, same caps, same\n * audit log as the proxy; file-backed when given a policy path, in-memory when given an object.\n */\nimport {\n Guard,\n GuardError,\n buildReport,\n parsePolicy,\n renderReportMarkdown,\n type AgentScope,\n type ApprovalRecord,\n type AuditEntry,\n type GuardErrorBody,\n type GuardEvent,\n type GuardResult,\n type Policy,\n type PolicyInput,\n type Report,\n type ToolAnnotationsLike,\n} from \"@agentwares/agentguard-core\";\nimport {\n FileApprovalStore,\n FileAuditSink,\n FileKillSwitch,\n FileStateStore,\n loadPolicyFile,\n type LoadedPolicy,\n} from \"@agentwares/agentguard-core/node\";\n\nexport interface CreateGuardOptions {\n /** path to `agentguard.yaml` (file-backed state, shared with the CLI) or an inline policy (in-memory) */\n policy: string | PolicyInput | Policy;\n /** run id for calls that do not pass one (default: generated) */\n runId?: string;\n /** agent scope by name (from `agents:` in the policy) */\n agent?: string;\n onEvent?: (event: GuardEvent) => void | Promise<void>;\n /** in-memory even when `policy` is a path */\n memory?: boolean;\n env?: Record<string, string | undefined>;\n}\n\nexport interface ToolMeta {\n name: string;\n description?: string;\n annotations?: ToolAnnotationsLike;\n /** JSON Schema of the result — used to synthesize dry-run results */\n outputSchema?: Record<string, unknown>;\n /** override the guard's run id for this tool */\n runId?: string;\n}\n\nexport interface WrapOptions extends ToolMeta {\n /** `throw` (default): blocked calls throw `GuardError`; `return`: they return the error body */\n onBlock?: \"throw\" | \"return\";\n}\n\nexport type AnyFn = (...args: never[]) => unknown;\n\nexport function newRunId(now: Date = new Date()): string {\n return `run_${now\n .toISOString()\n .replace(/[-:.TZ]/g, \"\")\n .slice(0, 14)}_${Math.random().toString(36).slice(2, 6)}`;\n}\n\nexport class AgentGuard {\n readonly guard: Guard;\n readonly policy: Policy;\n readonly loaded?: LoadedPolicy;\n readonly kill?: FileKillSwitch;\n runId: string;\n readonly agent: AgentScope | undefined;\n\n constructor(\n guard: Guard,\n opts: { runId: string; agent?: AgentScope; loaded?: LoadedPolicy; kill?: FileKillSwitch },\n ) {\n this.guard = guard;\n this.policy = guard.policy;\n this.runId = opts.runId;\n this.agent = opts.agent;\n this.loaded = opts.loaded;\n this.kill = opts.kill;\n }\n\n /** Start a new run (new per-run caps and loop window). Returns the id. */\n newRun(id: string = newRunId()): string {\n this.runId = id;\n return id;\n }\n\n /** Run one guarded call. `execute` receives the (unchanged) arguments. */\n run(meta: ToolMeta, args: unknown, execute: (args: unknown) => unknown): Promise<GuardResult> {\n return this.guard.run(\n {\n tool: {\n name: meta.name,\n description: meta.description,\n annotations: meta.annotations,\n outputSchema: meta.outputSchema,\n },\n args,\n runId: meta.runId ?? this.runId,\n agent: this.agent,\n },\n execute,\n );\n }\n\n /** Wrap a plain function `(args) => result`. Blocked calls throw `GuardError` (or return the body). */\n wrap<A, R>(\n fn: (args: A) => R | Promise<R>,\n opts: WrapOptions,\n ): (args: A) => Promise<R | GuardErrorBody> {\n return async (args: A) => {\n const result = await this.run(opts, args, (a) => fn(a as A));\n if (result.error && !result.ok) {\n if (opts.onBlock === \"return\") return result.error;\n throw new GuardError({\n code: result.error.code,\n cause: result.error.cause,\n fix: result.error.fix,\n retryable: result.error.retryable,\n details: result.error.details,\n });\n }\n return result.value as R;\n };\n }\n\n /** Wrap a map of named functions at once (`{ crm_get_contact: fn, ... }`). */\n wrapAll<T extends Record<string, AnyFn>>(\n fns: T,\n opts: { annotations?: Record<string, ToolAnnotationsLike>; onBlock?: \"throw\" | \"return\" } = {},\n ): {\n [K in keyof T]: (\n args: Parameters<T[K]>[0],\n ) => Promise<Awaited<ReturnType<T[K]>> | GuardErrorBody>;\n } {\n const out: Record<string, unknown> = {};\n for (const [name, fn] of Object.entries(fns)) {\n out[name] = this.wrap(fn as (args: unknown) => unknown, {\n name,\n annotations: opts.annotations?.[name],\n onBlock: opts.onBlock,\n });\n }\n return out as {\n [K in keyof T]: (\n args: Parameters<T[K]>[0],\n ) => Promise<Awaited<ReturnType<T[K]>> | GuardErrorBody>;\n };\n }\n\n /** Dollars spent outside a tool call (an LLM response, a paid API). Throws `CAP_EXCEEDED` when it does not fit. */\n spend(\n usd: number,\n label: string,\n opts: { details?: unknown; force?: boolean; runId?: string; reason?: string } = {},\n ): Promise<AuditEntry> {\n return this.guard.spend(opts.runId ?? this.runId, usd, {\n label,\n agent: this.agent,\n details: opts.details,\n force: opts.force,\n reason: opts.reason,\n });\n }\n\n async halt(reason = \"killed via SDK\"): Promise<void> {\n await this.guard.halt(reason);\n this.kill?.kill(reason);\n }\n async resume(): Promise<void> {\n await this.guard.resume();\n this.kill?.resume();\n }\n approve(id: string, by = \"sdk\", note?: string): Promise<ApprovalRecord | undefined> {\n return this.guard.decide(id, \"approved\", by, note);\n }\n deny(id: string, by = \"sdk\", note?: string): Promise<ApprovalRecord | undefined> {\n return this.guard.decide(id, \"denied\", by, note);\n }\n pendingApprovals(): Promise<ApprovalRecord[]> {\n return this.guard.approvals.list(\"pending\");\n }\n status(runId: string = this.runId) {\n return this.guard.status(runId, this.agent);\n }\n audit(): Promise<AuditEntry[]> {\n return this.guard.audit.read();\n }\n async report(runId: string | null = this.runId): Promise<Report> {\n return buildReport(await this.audit(), { runId: runId ?? undefined });\n }\n async reportMarkdown(runId: string | null = this.runId): Promise<string> {\n return renderReportMarkdown(await this.report(runId));\n }\n}\n\nexport async function createGuard(opts: CreateGuardOptions): Promise<AgentGuard> {\n const env = opts.env ?? process.env;\n let policy: Policy;\n let loaded: LoadedPolicy | undefined;\n if (typeof opts.policy === \"string\") {\n loaded = loadPolicyFile(opts.policy, { env });\n policy = loaded.policy;\n } else {\n policy =\n \"version\" in opts.policy &&\n typeof (opts.policy as Policy).kill === \"object\" &&\n (opts.policy as Policy).audit\n ? (opts.policy as Policy)\n : parsePolicy(opts.policy, { env });\n }\n const agent = opts.agent ? policy.agents.find((a) => a.name === opts.agent) : undefined;\n if (opts.agent && !agent)\n throw new GuardError({\n code: \"INVALID_POLICY\",\n cause: `no agent \"${opts.agent}\" in the policy`,\n fix: `add it under agents: or use one of ${policy.agents.map((a) => a.name).join(\", \") || \"(none)\"}`,\n });\n const useFiles = loaded !== undefined && !opts.memory;\n const kill = useFiles ? new FileKillSwitch(loaded!.killPath) : undefined;\n const guard = new Guard({\n policy,\n env,\n onEvent: opts.onEvent,\n ...(useFiles\n ? {\n state: new FileStateStore(loaded!.stateDir),\n audit: new FileAuditSink(loaded!.auditPath),\n approvals: new FileApprovalStore(loaded!.stateDir),\n kill,\n }\n : {}),\n });\n return new AgentGuard(guard, { runId: opts.runId ?? newRunId(), agent, loaded, kill });\n}\n","/**\n * Hard spend limits for LLM calls: a `fetch` that recognizes OpenAI, Anthropic and Gemini\n * requests, refuses them once the run/day budget is gone, and charges the actual token cost of\n * every response (streamed or not) to the same counters the tool caps use.\n */\nimport { estimateLlmCost, noListPriceReason, type LlmUsage } from \"@agentwares/agentguard-core\";\nimport type { AgentGuard } from \"./guard.js\";\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nexport interface GuardedFetchOptions {\n /** underlying fetch (default `globalThis.fetch`) */\n fetch?: FetchLike;\n /** run id override (default: the guard's current run) */\n runId?: () => string;\n /** hosts to treat as LLM providers beyond the built-ins (e.g. a proxy) → provider */\n providers?: Record<string, Provider>;\n /** called with every priced call */\n onSpend?: (info: {\n provider: Provider;\n model: string;\n usage: LlmUsage;\n usd: number | undefined;\n }) => void;\n}\n\nexport type Provider = \"openai\" | \"anthropic\" | \"gemini\";\n\nconst HOSTS: Record<string, Provider> = {\n \"api.openai.com\": \"openai\",\n \"api.anthropic.com\": \"anthropic\",\n \"generativelanguage.googleapis.com\": \"gemini\",\n};\n\nexport function detectProvider(\n url: URL,\n extra: Record<string, Provider> = {},\n): Provider | undefined {\n return extra[url.host] ?? HOSTS[url.host];\n}\n\n/** Normalize the usage object of any provider into input/output/cached tokens. */\nexport function normalizeUsage(provider: Provider, raw: unknown): LlmUsage | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const u = raw as Record<string, unknown>;\n const n = (v: unknown): number => (typeof v === \"number\" ? v : 0);\n if (provider === \"openai\") {\n const details = (u.prompt_tokens_details ?? u.input_tokens_details) as\n Record<string, unknown> | undefined;\n if (u.prompt_tokens !== undefined || u.input_tokens !== undefined) {\n return {\n input_tokens: n(u.prompt_tokens ?? u.input_tokens),\n output_tokens: n(u.completion_tokens ?? u.output_tokens),\n cached_input_tokens: n(details?.cached_tokens),\n };\n }\n return undefined;\n }\n if (provider === \"anthropic\") {\n if (u.input_tokens === undefined && u.output_tokens === undefined) return undefined;\n return {\n input_tokens:\n n(u.input_tokens) + n(u.cache_read_input_tokens) + n(u.cache_creation_input_tokens),\n output_tokens: n(u.output_tokens),\n cached_input_tokens: n(u.cache_read_input_tokens),\n };\n }\n if (u.promptTokenCount === undefined && u.candidatesTokenCount === undefined) return undefined;\n return {\n input_tokens: n(u.promptTokenCount),\n output_tokens: n(u.candidatesTokenCount) + n(u.thoughtsTokenCount),\n cached_input_tokens: n(u.cachedContentTokenCount),\n };\n}\n\nfunction modelFrom(\n provider: Provider,\n url: URL,\n body: Record<string, unknown> | undefined,\n responseJson?: Record<string, unknown>,\n): string {\n if (typeof responseJson?.model === \"string\") return responseJson.model;\n if (typeof body?.model === \"string\") return body.model;\n if (provider === \"gemini\") {\n const m = /\\/models\\/([^:/]+)/.exec(url.pathname);\n if (m) return m[1]!;\n }\n return \"unknown\";\n}\n\n/** Extract usage from a non-streamed JSON body. */\nexport function usageFromJson(\n provider: Provider,\n json: Record<string, unknown>,\n): LlmUsage | undefined {\n return normalizeUsage(\n provider,\n json.usage ??\n (json.response as Record<string, unknown> | undefined)?.usage ??\n json.usageMetadata,\n );\n}\n\n/** Extract usage from a complete SSE transcript (all `data:` payloads). */\nexport function usageFromSse(provider: Provider, text: string): LlmUsage | undefined {\n let usage: LlmUsage | undefined;\n let anthropicInput: LlmUsage | undefined;\n for (const line of text.split(\"\\n\")) {\n if (!line.startsWith(\"data:\")) continue;\n const payload = line.slice(5).trim();\n if (!payload || payload === \"[DONE]\") continue;\n let json: Record<string, unknown>;\n try {\n json = JSON.parse(payload) as Record<string, unknown>;\n } catch {\n continue;\n }\n if (provider === \"anthropic\") {\n if (json.type === \"message_start\")\n anthropicInput = normalizeUsage(\n provider,\n (json.message as Record<string, unknown> | undefined)?.usage,\n );\n if (json.type === \"message_delta\") {\n const delta = normalizeUsage(provider, json.usage);\n if (delta)\n usage = {\n ...anthropicInput,\n ...delta,\n input_tokens: (delta.input_tokens || anthropicInput?.input_tokens) ?? 0,\n };\n }\n continue;\n }\n const found = usageFromJson(provider, json);\n if (found) usage = found;\n }\n return usage;\n}\n\nfunction blockedResponse(status: number, body: Record<string, unknown>): Response {\n return new Response(\n JSON.stringify({\n error: { type: body.code, message: `${body.code}: ${body.cause} — ${body.fix}` },\n ...body,\n }),\n { status, headers: { \"Content-Type\": \"application/json\", \"X-Agentguard\": String(body.code) } },\n );\n}\n\n/**\n * Wrap `fetch` for an OpenAI / Anthropic / Gemini SDK client (`new OpenAI({ fetch })`,\n * `new Anthropic({ fetch })`). Non-provider URLs pass straight through.\n */\nexport function createGuardedFetch(ag: AgentGuard, opts: GuardedFetchOptions = {}): FetchLike {\n const base = opts.fetch ?? globalThis.fetch.bind(globalThis);\n const runId = opts.runId ?? (() => ag.runId);\n return async (input, init) => {\n const request = input instanceof Request ? input : undefined;\n const url = new URL(request ? request.url : input instanceof URL ? input.href : String(input));\n const provider = detectProvider(url, opts.providers);\n if (!provider) return base(input, init);\n\n let bodyText: string | undefined;\n if (typeof init?.body === \"string\") bodyText = init.body;\n else if (request && request.method !== \"GET\") bodyText = await request.clone().text();\n let body: Record<string, unknown> | undefined;\n try {\n body = bodyText ? (JSON.parse(bodyText) as Record<string, unknown>) : undefined;\n } catch {\n body = undefined;\n }\n const model = modelFrom(provider, url, body);\n\n const killed = await ag.guard.killState();\n if (killed.killed) {\n return blockedResponse(403, {\n code: \"KILLED\",\n cause: `agentguard kill switch is on (${killed.reason ?? \"\"})`,\n fix: \"a human must run `agentguard resume`\",\n retryable: false,\n });\n }\n const check = await ag.guard.canSpend(runId(), 0, ag.agent);\n const remaining = Math.min(\n check.remaining.spend_usd?.per_run ?? Infinity,\n check.remaining.spend_usd?.per_day ?? Infinity,\n );\n if (remaining <= 0) {\n const scope = (check.remaining.spend_usd?.per_run ?? Infinity) <= 0 ? \"this run\" : \"today\";\n return blockedResponse(402, {\n code: \"CAP_EXCEEDED\",\n cause: `spend_usd cap for ${scope} is used up`,\n fix: \"stop and report to the user; a human can raise caps in agentguard.yaml\",\n retryable: false,\n details: { remaining: check.remaining, runId: runId() },\n });\n }\n\n // OpenAI chat streams only report usage when asked to.\n let forwardedInit = init;\n if (\n provider === \"openai\" &&\n body?.stream === true &&\n url.pathname.endsWith(\"/chat/completions\") &&\n !body.stream_options\n ) {\n body.stream_options = { include_usage: true };\n forwardedInit = { ...init, body: JSON.stringify(body) };\n }\n const response = await base(\n request && forwardedInit === init ? request : url,\n request && forwardedInit === init\n ? undefined\n : {\n ...forwardedInit,\n method: forwardedInit?.method ?? request?.method,\n headers: forwardedInit?.headers ?? request?.headers,\n },\n );\n if (!response.ok || !response.body) return response;\n\n const charge = async (usage: LlmUsage | undefined, resolvedModel: string): Promise<void> => {\n if (!usage) return;\n const usd = estimateLlmCost(ag.policy, resolvedModel, usage);\n opts.onSpend?.({ provider, model: resolvedModel, usage, usd });\n // No list price for this model: record the call at $0 rather than dropping it, so the run\n // shows a model the budget is not covering instead of silently under-counting.\n await ag.spend(usd ?? 0, `llm:${resolvedModel}`, {\n force: true,\n runId: runId(),\n details: { provider, model: resolvedModel, usage },\n reason: usd === undefined ? noListPriceReason(resolvedModel) : undefined,\n });\n };\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"text/event-stream\")) {\n let transcript = \"\";\n const decoder = new TextDecoder();\n const tapped = response.body.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n transcript += decoder.decode(chunk, { stream: true });\n controller.enqueue(chunk);\n },\n async flush() {\n transcript += decoder.decode();\n await charge(usageFromSse(provider, transcript), model);\n },\n }),\n );\n return new Response(tapped, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n const text = await response.text();\n try {\n const json = JSON.parse(text) as Record<string, unknown>;\n await charge(usageFromJson(provider, json), modelFrom(provider, url, body, json));\n } catch {\n // not JSON\n }\n return new Response(text, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n };\n}\n","/**\n * OpenAI Agents SDK (`@openai/agents`) — wrap the object `tool({...})` returns. Duck-typed on\n * `{ name, description?, parameters?, invoke(runContext, input) }` so this package has no\n * dependency on the SDK. Blocked calls return the structured error as the tool's string result\n * (the model reads `fix`), so the run keeps going instead of crashing.\n */\nimport type { AgentGuard, ToolMeta } from \"../guard.js\";\nimport type { ToolAnnotationsLike } from \"@agentwares/agentguard-core\";\n\nexport interface OpenAIAgentsToolLike {\n name: string;\n description?: string;\n parameters?: unknown;\n invoke: (runContext: unknown, input: string, ...rest: unknown[]) => Promise<unknown> | unknown;\n}\n\nexport interface OpenAIAgentsWrapOptions {\n annotations?: ToolAnnotationsLike;\n outputSchema?: Record<string, unknown>;\n /** `return` (default): blocked calls return the error JSON as the tool output; `throw`: throw `GuardError` */\n onBlock?: \"return\" | \"throw\";\n}\n\nfunction parseInput(input: unknown): unknown {\n if (typeof input !== \"string\") return input;\n try {\n return JSON.parse(input);\n } catch {\n return { input };\n }\n}\n\nexport function wrapOpenAIAgentsTool<T extends OpenAIAgentsToolLike>(\n ag: AgentGuard,\n tool: T,\n opts: OpenAIAgentsWrapOptions = {},\n): T {\n const meta: ToolMeta = {\n name: tool.name,\n description: tool.description,\n annotations: opts.annotations,\n outputSchema: opts.outputSchema,\n };\n const original = tool.invoke.bind(tool);\n const invoke = async (\n runContext: unknown,\n input: string,\n ...rest: unknown[]\n ): Promise<unknown> => {\n const result = await ag.run(meta, parseInput(input), () =>\n original(runContext, input, ...rest),\n );\n if (result.error && !result.ok) {\n if (opts.onBlock === \"throw\")\n throw Object.assign(new Error(`${result.error.code}: ${result.error.cause}`), result.error);\n return JSON.stringify(result.error);\n }\n if (result.faked)\n return typeof result.value === \"string\" ? result.value : JSON.stringify(result.value);\n return result.value;\n };\n return { ...tool, invoke } as T;\n}\n\nexport function wrapOpenAIAgentsTools<T extends OpenAIAgentsToolLike>(\n ag: AgentGuard,\n tools: T[],\n opts: OpenAIAgentsWrapOptions & { annotations?: Record<string, ToolAnnotationsLike> } = {},\n): T[] {\n return tools.map((t) =>\n wrapOpenAIAgentsTool(ag, t, { ...opts, annotations: opts.annotations?.[t.name] }),\n );\n}\n","/**\n * LangChain.js — wrap a `StructuredTool` / `DynamicStructuredTool` / anything with\n * `{ name, description?, _call(args, ...) }` or `{ name, invoke(args, ...) }`. The wrapper keeps the\n * tool's prototype (so `instanceof StructuredTool` still holds) and intercepts `_call`, which every\n * public entry point (`invoke`, `call`, `run`) ends up in. Blocked calls return the error JSON.\n */\nimport type { AgentGuard, ToolMeta } from \"../guard.js\";\nimport type { ToolAnnotationsLike } from \"@agentwares/agentguard-core\";\n\nexport interface LangChainToolLike {\n name: string;\n description?: string;\n _call?: (args: unknown, ...rest: unknown[]) => Promise<unknown> | unknown;\n invoke?: (args: unknown, ...rest: unknown[]) => Promise<unknown> | unknown;\n}\n\nexport interface LangChainWrapOptions {\n annotations?: ToolAnnotationsLike;\n outputSchema?: Record<string, unknown>;\n onBlock?: \"return\" | \"throw\";\n}\n\nfunction stringify(value: unknown): unknown {\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nexport function wrapLangChainTool<T extends LangChainToolLike>(\n ag: AgentGuard,\n tool: T,\n opts: LangChainWrapOptions = {},\n): T {\n const meta: ToolMeta = {\n name: tool.name,\n description: tool.description,\n annotations: opts.annotations,\n outputSchema: opts.outputSchema,\n };\n const guardCall = async (\n original: (...a: unknown[]) => unknown,\n args: unknown,\n rest: unknown[],\n ): Promise<unknown> => {\n const result = await ag.run(meta, args, () => original(args, ...rest));\n if (result.error && !result.ok) {\n if (opts.onBlock === \"throw\")\n throw Object.assign(new Error(`${result.error.code}: ${result.error.cause}`), result.error);\n return JSON.stringify(result.error);\n }\n return result.faked ? stringify(result.value) : result.value;\n };\n const wrapped = Object.create(tool) as T;\n if (typeof tool._call === \"function\") {\n const original = tool._call.bind(tool) as (...a: unknown[]) => unknown;\n Object.defineProperty(wrapped, \"_call\", {\n value: (args: unknown, ...rest: unknown[]) => guardCall(original, args, rest),\n writable: true,\n configurable: true,\n });\n } else if (typeof tool.invoke === \"function\") {\n const original = tool.invoke.bind(tool) as (...a: unknown[]) => unknown;\n Object.defineProperty(wrapped, \"invoke\", {\n value: (args: unknown, ...rest: unknown[]) => guardCall(original, args, rest),\n writable: true,\n configurable: true,\n });\n } else {\n throw new Error(`cannot wrap \"${tool.name}\": no _call or invoke`);\n }\n return wrapped;\n}\n\nexport function wrapLangChainTools<T extends LangChainToolLike>(\n ag: AgentGuard,\n tools: T[],\n opts: LangChainWrapOptions & { annotations?: Record<string, ToolAnnotationsLike> } = {},\n): T[] {\n return tools.map((t) =>\n wrapLangChainTool(ag, t, { ...opts, annotations: opts.annotations?.[t.name] }),\n );\n}\n","/**\n * @agentwares/agentguard-sdk — agentguard for tool calls that bypass MCP.\n *\n * const ag = await createGuard({ policy: \"agentguard.yaml\" });\n * const tools = wrapOpenAIAgentsTools(ag, [deleteContact, sendEmail]);\n * const openai = new OpenAI({ fetch: createGuardedFetch(ag) }); // hard spend limit on tokens\n */\nexport {\n AgentGuard,\n createGuard,\n newRunId,\n type AnyFn,\n type CreateGuardOptions,\n type ToolMeta,\n type WrapOptions,\n} from \"./guard.js\";\nexport {\n createGuardedFetch,\n detectProvider,\n normalizeUsage,\n usageFromJson,\n usageFromSse,\n type FetchLike,\n type GuardedFetchOptions,\n type Provider,\n} from \"./fetch.js\";\nexport {\n wrapOpenAIAgentsTool,\n wrapOpenAIAgentsTools,\n type OpenAIAgentsToolLike,\n type OpenAIAgentsWrapOptions,\n} from \"./adapters/openai-agents.js\";\nexport {\n wrapLangChainTool,\n wrapLangChainTools,\n type LangChainToolLike,\n type LangChainWrapOptions,\n} from \"./adapters/langchain.js\";\nexport {\n GuardError,\n type GuardErrorBody,\n type GuardEvent,\n type GuardResult,\n type Policy,\n type PolicyInput,\n type Report,\n} from \"@agentwares/agentguard-core\";\n"],"mappings":"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","names":["GuardError"]}
|
|
1
|
+
{"version":3,"sources":["../src/guard.ts","../src/fetch.ts","../src/adapters/openai-agents.ts","../src/adapters/langchain.ts","../src/index.ts"],"sourcesContent":["/**\n * `createGuard` — the policy engine for tool calls that bypass MCP. Same YAML, same caps, same\n * audit log as the proxy; file-backed when given a policy path, in-memory when given an object.\n */\nimport { basename } from \"node:path\";\nimport {\n Guard,\n GuardError,\n buildReport,\n parsePolicy,\n renderReportMarkdown,\n type AgentScope,\n type ApprovalRecord,\n type AuditEntry,\n type GuardErrorBody,\n type GuardEvent,\n type GuardResult,\n type Policy,\n type PolicyInput,\n type Report,\n type ToolAnnotationsLike,\n} from \"@agentwares/agentguard-core\";\nimport {\n FileApprovalStore,\n FileAuditSink,\n type FileKillSwitch,\n FileStateStore,\n killSwitchFor,\n loadPolicyFile,\n type LoadedPolicy,\n} from \"@agentwares/agentguard-core/node\";\n\nexport interface CreateGuardOptions {\n /** path to `okgate.yaml` (file-backed state, shared with the CLI) or an inline policy (in-memory) */\n policy: string | PolicyInput | Policy;\n /** run id for calls that do not pass one (default: generated) */\n runId?: string;\n /** agent scope by name (from `agents:` in the policy) */\n agent?: string;\n onEvent?: (event: GuardEvent) => void | Promise<void>;\n /** in-memory even when `policy` is a path */\n memory?: boolean;\n env?: Record<string, string | undefined>;\n}\n\nexport interface ToolMeta {\n name: string;\n description?: string;\n annotations?: ToolAnnotationsLike;\n /** JSON Schema of the result — used to synthesize dry-run results */\n outputSchema?: Record<string, unknown>;\n /** override the guard's run id for this tool */\n runId?: string;\n}\n\nexport interface WrapOptions extends ToolMeta {\n /** `throw` (default): blocked calls throw `GuardError`; `return`: they return the error body */\n onBlock?: \"throw\" | \"return\";\n}\n\nexport type AnyFn = (...args: never[]) => unknown;\n\nexport function newRunId(now: Date = new Date()): string {\n return `run_${now\n .toISOString()\n .replace(/[-:.TZ]/g, \"\")\n .slice(0, 14)}_${Math.random().toString(36).slice(2, 6)}`;\n}\n\nexport class AgentGuard {\n readonly guard: Guard;\n readonly policy: Policy;\n readonly loaded?: LoadedPolicy;\n readonly kill?: FileKillSwitch;\n runId: string;\n readonly agent: AgentScope | undefined;\n\n constructor(\n guard: Guard,\n opts: { runId: string; agent?: AgentScope; loaded?: LoadedPolicy; kill?: FileKillSwitch },\n ) {\n this.guard = guard;\n this.policy = guard.policy;\n this.runId = opts.runId;\n this.agent = opts.agent;\n this.loaded = opts.loaded;\n this.kill = opts.kill;\n }\n\n /** Start a new run (new per-run caps and loop window). Returns the id. */\n newRun(id: string = newRunId()): string {\n this.runId = id;\n return id;\n }\n\n /** Run one guarded call. `execute` receives the (unchanged) arguments. */\n run(meta: ToolMeta, args: unknown, execute: (args: unknown) => unknown): Promise<GuardResult> {\n return this.guard.run(\n {\n tool: {\n name: meta.name,\n description: meta.description,\n annotations: meta.annotations,\n outputSchema: meta.outputSchema,\n },\n args,\n runId: meta.runId ?? this.runId,\n agent: this.agent,\n },\n execute,\n );\n }\n\n /** Wrap a plain function `(args) => result`. Blocked calls throw `GuardError` (or return the body). */\n wrap<A, R>(\n fn: (args: A) => R | Promise<R>,\n opts: WrapOptions,\n ): (args: A) => Promise<R | GuardErrorBody> {\n return async (args: A) => {\n const result = await this.run(opts, args, (a) => fn(a as A));\n if (result.error && !result.ok) {\n if (opts.onBlock === \"return\") return result.error;\n throw new GuardError({\n code: result.error.code,\n cause: result.error.cause,\n fix: result.error.fix,\n retryable: result.error.retryable,\n details: result.error.details,\n });\n }\n return result.value as R;\n };\n }\n\n /** Wrap a map of named functions at once (`{ crm_get_contact: fn, ... }`). */\n wrapAll<T extends Record<string, AnyFn>>(\n fns: T,\n opts: { annotations?: Record<string, ToolAnnotationsLike>; onBlock?: \"throw\" | \"return\" } = {},\n ): {\n [K in keyof T]: (\n args: Parameters<T[K]>[0],\n ) => Promise<Awaited<ReturnType<T[K]>> | GuardErrorBody>;\n } {\n const out: Record<string, unknown> = {};\n for (const [name, fn] of Object.entries(fns)) {\n out[name] = this.wrap(fn as (args: unknown) => unknown, {\n name,\n annotations: opts.annotations?.[name],\n onBlock: opts.onBlock,\n });\n }\n return out as {\n [K in keyof T]: (\n args: Parameters<T[K]>[0],\n ) => Promise<Awaited<ReturnType<T[K]>> | GuardErrorBody>;\n };\n }\n\n /** Dollars spent outside a tool call (an LLM response, a paid API). Throws `CAP_EXCEEDED` when it does not fit. */\n spend(\n usd: number,\n label: string,\n opts: { details?: unknown; force?: boolean; runId?: string; reason?: string } = {},\n ): Promise<AuditEntry> {\n return this.guard.spend(opts.runId ?? this.runId, usd, {\n label,\n agent: this.agent,\n details: opts.details,\n force: opts.force,\n reason: opts.reason,\n });\n }\n\n async halt(reason = \"killed via SDK\"): Promise<void> {\n await this.guard.halt(reason);\n this.kill?.kill(reason);\n }\n async resume(): Promise<void> {\n await this.guard.resume();\n this.kill?.resume();\n }\n approve(id: string, by = \"sdk\", note?: string): Promise<ApprovalRecord | undefined> {\n return this.guard.decide(id, \"approved\", by, note);\n }\n deny(id: string, by = \"sdk\", note?: string): Promise<ApprovalRecord | undefined> {\n return this.guard.decide(id, \"denied\", by, note);\n }\n pendingApprovals(): Promise<ApprovalRecord[]> {\n return this.guard.approvals.list(\"pending\");\n }\n status(runId: string = this.runId) {\n return this.guard.status(runId, this.agent);\n }\n audit(): Promise<AuditEntry[]> {\n return this.guard.audit.read();\n }\n async report(runId: string | null = this.runId): Promise<Report> {\n return buildReport(await this.audit(), { runId: runId ?? undefined });\n }\n async reportMarkdown(runId: string | null = this.runId): Promise<string> {\n return renderReportMarkdown(await this.report(runId));\n }\n}\n\nexport async function createGuard(opts: CreateGuardOptions): Promise<AgentGuard> {\n const env = opts.env ?? process.env;\n let policy: Policy;\n let loaded: LoadedPolicy | undefined;\n if (typeof opts.policy === \"string\") {\n loaded = loadPolicyFile(opts.policy, { env });\n policy = loaded.policy;\n } else {\n policy =\n \"version\" in opts.policy &&\n typeof (opts.policy as Policy).kill === \"object\" &&\n (opts.policy as Policy).audit\n ? (opts.policy as Policy)\n : parsePolicy(opts.policy, { env });\n }\n const agent = opts.agent ? policy.agents.find((a) => a.name === opts.agent) : undefined;\n if (opts.agent && !agent)\n throw new GuardError({\n code: \"INVALID_POLICY\",\n cause: `no agent \"${opts.agent}\" in the policy`,\n fix: `add it under agents: or use one of ${policy.agents.map((a) => a.name).join(\", \") || \"(none)\"}`,\n });\n const useFiles = loaded !== undefined && !opts.memory;\n const kill = useFiles ? killSwitchFor(loaded!) : undefined;\n const guard = new Guard({\n policy,\n env,\n ...(loaded ? { policyFile: basename(loaded.path) } : {}),\n onEvent: opts.onEvent,\n ...(useFiles\n ? {\n state: new FileStateStore(loaded!.stateDir),\n audit: new FileAuditSink(loaded!.auditPath),\n approvals: new FileApprovalStore(loaded!.stateDir),\n kill,\n }\n : {}),\n });\n return new AgentGuard(guard, { runId: opts.runId ?? newRunId(), agent, loaded, kill });\n}\n","/**\n * Hard spend limits for LLM calls: a `fetch` that recognizes OpenAI, Anthropic and Gemini\n * requests, refuses them once the run/day budget is gone, and charges the actual token cost of\n * every response (streamed or not) to the same counters the tool caps use.\n */\nimport { estimateLlmCost, noListPriceReason, type LlmUsage } from \"@agentwares/agentguard-core\";\nimport type { AgentGuard } from \"./guard.js\";\n\nexport type FetchLike = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;\n\nexport interface GuardedFetchOptions {\n /** underlying fetch (default `globalThis.fetch`) */\n fetch?: FetchLike;\n /** run id override (default: the guard's current run) */\n runId?: () => string;\n /** hosts to treat as LLM providers beyond the built-ins (e.g. a proxy) → provider */\n providers?: Record<string, Provider>;\n /** called with every priced call */\n onSpend?: (info: {\n provider: Provider;\n model: string;\n usage: LlmUsage;\n usd: number | undefined;\n }) => void;\n}\n\nexport type Provider = \"openai\" | \"anthropic\" | \"gemini\";\n\nconst HOSTS: Record<string, Provider> = {\n \"api.openai.com\": \"openai\",\n \"api.anthropic.com\": \"anthropic\",\n \"generativelanguage.googleapis.com\": \"gemini\",\n};\n\nexport function detectProvider(\n url: URL,\n extra: Record<string, Provider> = {},\n): Provider | undefined {\n return extra[url.host] ?? HOSTS[url.host];\n}\n\n/** Normalize the usage object of any provider into input/output/cached tokens. */\nexport function normalizeUsage(provider: Provider, raw: unknown): LlmUsage | undefined {\n if (!raw || typeof raw !== \"object\") return undefined;\n const u = raw as Record<string, unknown>;\n const n = (v: unknown): number => (typeof v === \"number\" ? v : 0);\n if (provider === \"openai\") {\n const details = (u.prompt_tokens_details ?? u.input_tokens_details) as\n Record<string, unknown> | undefined;\n if (u.prompt_tokens !== undefined || u.input_tokens !== undefined) {\n return {\n input_tokens: n(u.prompt_tokens ?? u.input_tokens),\n output_tokens: n(u.completion_tokens ?? u.output_tokens),\n cached_input_tokens: n(details?.cached_tokens),\n };\n }\n return undefined;\n }\n if (provider === \"anthropic\") {\n if (u.input_tokens === undefined && u.output_tokens === undefined) return undefined;\n return {\n input_tokens:\n n(u.input_tokens) + n(u.cache_read_input_tokens) + n(u.cache_creation_input_tokens),\n output_tokens: n(u.output_tokens),\n cached_input_tokens: n(u.cache_read_input_tokens),\n };\n }\n if (u.promptTokenCount === undefined && u.candidatesTokenCount === undefined) return undefined;\n return {\n input_tokens: n(u.promptTokenCount),\n output_tokens: n(u.candidatesTokenCount) + n(u.thoughtsTokenCount),\n cached_input_tokens: n(u.cachedContentTokenCount),\n };\n}\n\nfunction modelFrom(\n provider: Provider,\n url: URL,\n body: Record<string, unknown> | undefined,\n responseJson?: Record<string, unknown>,\n): string {\n if (typeof responseJson?.model === \"string\") return responseJson.model;\n if (typeof body?.model === \"string\") return body.model;\n if (provider === \"gemini\") {\n const m = /\\/models\\/([^:/]+)/.exec(url.pathname);\n if (m) return m[1]!;\n }\n return \"unknown\";\n}\n\n/** Extract usage from a non-streamed JSON body. */\nexport function usageFromJson(\n provider: Provider,\n json: Record<string, unknown>,\n): LlmUsage | undefined {\n return normalizeUsage(\n provider,\n json.usage ??\n (json.response as Record<string, unknown> | undefined)?.usage ??\n json.usageMetadata,\n );\n}\n\n/** Extract usage from a complete SSE transcript (all `data:` payloads). */\nexport function usageFromSse(provider: Provider, text: string): LlmUsage | undefined {\n let usage: LlmUsage | undefined;\n let anthropicInput: LlmUsage | undefined;\n for (const line of text.split(\"\\n\")) {\n if (!line.startsWith(\"data:\")) continue;\n const payload = line.slice(5).trim();\n if (!payload || payload === \"[DONE]\") continue;\n let json: Record<string, unknown>;\n try {\n json = JSON.parse(payload) as Record<string, unknown>;\n } catch {\n continue;\n }\n if (provider === \"anthropic\") {\n if (json.type === \"message_start\")\n anthropicInput = normalizeUsage(\n provider,\n (json.message as Record<string, unknown> | undefined)?.usage,\n );\n if (json.type === \"message_delta\") {\n const delta = normalizeUsage(provider, json.usage);\n if (delta)\n usage = {\n ...anthropicInput,\n ...delta,\n input_tokens: (delta.input_tokens || anthropicInput?.input_tokens) ?? 0,\n };\n }\n continue;\n }\n const found = usageFromJson(provider, json);\n if (found) usage = found;\n }\n return usage;\n}\n\nfunction blockedResponse(status: number, body: Record<string, unknown>): Response {\n return new Response(\n JSON.stringify({\n error: { type: body.code, message: `${body.code}: ${body.cause} — ${body.fix}` },\n ...body,\n }),\n {\n status,\n // X-Agentguard is the same header under the name before the rename to okgate\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Okgate\": String(body.code),\n \"X-Agentguard\": String(body.code),\n },\n },\n );\n}\n\n/**\n * Wrap `fetch` for an OpenAI / Anthropic / Gemini SDK client (`new OpenAI({ fetch })`,\n * `new Anthropic({ fetch })`). Non-provider URLs pass straight through.\n */\nexport function createGuardedFetch(ag: AgentGuard, opts: GuardedFetchOptions = {}): FetchLike {\n const base = opts.fetch ?? globalThis.fetch.bind(globalThis);\n const runId = opts.runId ?? (() => ag.runId);\n return async (input, init) => {\n const request = input instanceof Request ? input : undefined;\n const url = new URL(request ? request.url : input instanceof URL ? input.href : String(input));\n const provider = detectProvider(url, opts.providers);\n if (!provider) return base(input, init);\n\n let bodyText: string | undefined;\n if (typeof init?.body === \"string\") bodyText = init.body;\n else if (request && request.method !== \"GET\") bodyText = await request.clone().text();\n let body: Record<string, unknown> | undefined;\n try {\n body = bodyText ? (JSON.parse(bodyText) as Record<string, unknown>) : undefined;\n } catch {\n body = undefined;\n }\n const model = modelFrom(provider, url, body);\n\n const killed = await ag.guard.killState();\n if (killed.killed) {\n return blockedResponse(403, {\n code: \"KILLED\",\n cause: `okgate kill switch is on (${killed.reason ?? \"\"})`,\n fix: \"a human must run `okgate resume`\",\n retryable: false,\n });\n }\n const check = await ag.guard.canSpend(runId(), 0, ag.agent);\n const remaining = Math.min(\n check.remaining.spend_usd?.per_run ?? Infinity,\n check.remaining.spend_usd?.per_day ?? Infinity,\n );\n if (remaining <= 0) {\n const scope = (check.remaining.spend_usd?.per_run ?? Infinity) <= 0 ? \"this run\" : \"today\";\n return blockedResponse(402, {\n code: \"CAP_EXCEEDED\",\n cause: `spend_usd cap for ${scope} is used up`,\n fix: \"stop and report to the user; a human can raise caps in the policy file (okgate.yaml)\",\n retryable: false,\n details: { remaining: check.remaining, runId: runId() },\n });\n }\n\n // OpenAI chat streams only report usage when asked to.\n let forwardedInit = init;\n if (\n provider === \"openai\" &&\n body?.stream === true &&\n url.pathname.endsWith(\"/chat/completions\") &&\n !body.stream_options\n ) {\n body.stream_options = { include_usage: true };\n forwardedInit = { ...init, body: JSON.stringify(body) };\n }\n const response = await base(\n request && forwardedInit === init ? request : url,\n request && forwardedInit === init\n ? undefined\n : {\n ...forwardedInit,\n method: forwardedInit?.method ?? request?.method,\n headers: forwardedInit?.headers ?? request?.headers,\n },\n );\n if (!response.ok || !response.body) return response;\n\n const charge = async (usage: LlmUsage | undefined, resolvedModel: string): Promise<void> => {\n if (!usage) return;\n const usd = estimateLlmCost(ag.policy, resolvedModel, usage);\n opts.onSpend?.({ provider, model: resolvedModel, usage, usd });\n // No list price for this model: record the call at $0 rather than dropping it, so the run\n // shows a model the budget is not covering instead of silently under-counting.\n await ag.spend(usd ?? 0, `llm:${resolvedModel}`, {\n force: true,\n runId: runId(),\n details: { provider, model: resolvedModel, usage },\n reason: usd === undefined ? noListPriceReason(resolvedModel) : undefined,\n });\n };\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"text/event-stream\")) {\n let transcript = \"\";\n const decoder = new TextDecoder();\n const tapped = response.body.pipeThrough(\n new TransformStream<Uint8Array, Uint8Array>({\n transform(chunk, controller) {\n transcript += decoder.decode(chunk, { stream: true });\n controller.enqueue(chunk);\n },\n async flush() {\n transcript += decoder.decode();\n await charge(usageFromSse(provider, transcript), model);\n },\n }),\n );\n return new Response(tapped, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n const text = await response.text();\n try {\n const json = JSON.parse(text) as Record<string, unknown>;\n await charge(usageFromJson(provider, json), modelFrom(provider, url, body, json));\n } catch {\n // not JSON\n }\n return new Response(text, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n };\n}\n","/**\n * OpenAI Agents SDK (`@openai/agents`) — wrap the object `tool({...})` returns. Duck-typed on\n * `{ name, description?, parameters?, invoke(runContext, input) }` so this package has no\n * dependency on the SDK. Blocked calls return the structured error as the tool's string result\n * (the model reads `fix`), so the run keeps going instead of crashing.\n */\nimport type { AgentGuard, ToolMeta } from \"../guard.js\";\nimport type { ToolAnnotationsLike } from \"@agentwares/agentguard-core\";\n\nexport interface OpenAIAgentsToolLike {\n name: string;\n description?: string;\n parameters?: unknown;\n invoke: (runContext: unknown, input: string, ...rest: unknown[]) => Promise<unknown> | unknown;\n}\n\nexport interface OpenAIAgentsWrapOptions {\n annotations?: ToolAnnotationsLike;\n outputSchema?: Record<string, unknown>;\n /** `return` (default): blocked calls return the error JSON as the tool output; `throw`: throw `GuardError` */\n onBlock?: \"return\" | \"throw\";\n}\n\nfunction parseInput(input: unknown): unknown {\n if (typeof input !== \"string\") return input;\n try {\n return JSON.parse(input);\n } catch {\n return { input };\n }\n}\n\nexport function wrapOpenAIAgentsTool<T extends OpenAIAgentsToolLike>(\n ag: AgentGuard,\n tool: T,\n opts: OpenAIAgentsWrapOptions = {},\n): T {\n const meta: ToolMeta = {\n name: tool.name,\n description: tool.description,\n annotations: opts.annotations,\n outputSchema: opts.outputSchema,\n };\n const original = tool.invoke.bind(tool);\n const invoke = async (\n runContext: unknown,\n input: string,\n ...rest: unknown[]\n ): Promise<unknown> => {\n const result = await ag.run(meta, parseInput(input), () =>\n original(runContext, input, ...rest),\n );\n if (result.error && !result.ok) {\n if (opts.onBlock === \"throw\")\n throw Object.assign(new Error(`${result.error.code}: ${result.error.cause}`), result.error);\n return JSON.stringify(result.error);\n }\n if (result.faked)\n return typeof result.value === \"string\" ? result.value : JSON.stringify(result.value);\n return result.value;\n };\n return { ...tool, invoke } as T;\n}\n\nexport function wrapOpenAIAgentsTools<T extends OpenAIAgentsToolLike>(\n ag: AgentGuard,\n tools: T[],\n opts: OpenAIAgentsWrapOptions & { annotations?: Record<string, ToolAnnotationsLike> } = {},\n): T[] {\n return tools.map((t) =>\n wrapOpenAIAgentsTool(ag, t, { ...opts, annotations: opts.annotations?.[t.name] }),\n );\n}\n","/**\n * LangChain.js — wrap a `StructuredTool` / `DynamicStructuredTool` / anything with\n * `{ name, description?, _call(args, ...) }` or `{ name, invoke(args, ...) }`. The wrapper keeps the\n * tool's prototype (so `instanceof StructuredTool` still holds) and intercepts `_call`, which every\n * public entry point (`invoke`, `call`, `run`) ends up in. Blocked calls return the error JSON.\n */\nimport type { AgentGuard, ToolMeta } from \"../guard.js\";\nimport type { ToolAnnotationsLike } from \"@agentwares/agentguard-core\";\n\nexport interface LangChainToolLike {\n name: string;\n description?: string;\n _call?: (args: unknown, ...rest: unknown[]) => Promise<unknown> | unknown;\n invoke?: (args: unknown, ...rest: unknown[]) => Promise<unknown> | unknown;\n}\n\nexport interface LangChainWrapOptions {\n annotations?: ToolAnnotationsLike;\n outputSchema?: Record<string, unknown>;\n onBlock?: \"return\" | \"throw\";\n}\n\nfunction stringify(value: unknown): unknown {\n return typeof value === \"string\" ? value : JSON.stringify(value);\n}\n\nexport function wrapLangChainTool<T extends LangChainToolLike>(\n ag: AgentGuard,\n tool: T,\n opts: LangChainWrapOptions = {},\n): T {\n const meta: ToolMeta = {\n name: tool.name,\n description: tool.description,\n annotations: opts.annotations,\n outputSchema: opts.outputSchema,\n };\n const guardCall = async (\n original: (...a: unknown[]) => unknown,\n args: unknown,\n rest: unknown[],\n ): Promise<unknown> => {\n const result = await ag.run(meta, args, () => original(args, ...rest));\n if (result.error && !result.ok) {\n if (opts.onBlock === \"throw\")\n throw Object.assign(new Error(`${result.error.code}: ${result.error.cause}`), result.error);\n return JSON.stringify(result.error);\n }\n return result.faked ? stringify(result.value) : result.value;\n };\n const wrapped = Object.create(tool) as T;\n if (typeof tool._call === \"function\") {\n const original = tool._call.bind(tool) as (...a: unknown[]) => unknown;\n Object.defineProperty(wrapped, \"_call\", {\n value: (args: unknown, ...rest: unknown[]) => guardCall(original, args, rest),\n writable: true,\n configurable: true,\n });\n } else if (typeof tool.invoke === \"function\") {\n const original = tool.invoke.bind(tool) as (...a: unknown[]) => unknown;\n Object.defineProperty(wrapped, \"invoke\", {\n value: (args: unknown, ...rest: unknown[]) => guardCall(original, args, rest),\n writable: true,\n configurable: true,\n });\n } else {\n throw new Error(`cannot wrap \"${tool.name}\": no _call or invoke`);\n }\n return wrapped;\n}\n\nexport function wrapLangChainTools<T extends LangChainToolLike>(\n ag: AgentGuard,\n tools: T[],\n opts: LangChainWrapOptions & { annotations?: Record<string, ToolAnnotationsLike> } = {},\n): T[] {\n return tools.map((t) =>\n wrapLangChainTool(ag, t, { ...opts, annotations: opts.annotations?.[t.name] }),\n );\n}\n","/**\n * @agentwares/agentguard-sdk — okgate for tool calls that bypass MCP.\n *\n * const ag = await createGuard({ policy: \"okgate.yaml\" });\n * const tools = wrapOpenAIAgentsTools(ag, [deleteContact, sendEmail]);\n * const openai = new OpenAI({ fetch: createGuardedFetch(ag) }); // hard spend limit on tokens\n */\nexport {\n AgentGuard,\n createGuard,\n newRunId,\n type AnyFn,\n type CreateGuardOptions,\n type ToolMeta,\n type WrapOptions,\n} from \"./guard.js\";\nexport {\n createGuardedFetch,\n detectProvider,\n normalizeUsage,\n usageFromJson,\n usageFromSse,\n type FetchLike,\n type GuardedFetchOptions,\n type Provider,\n} from \"./fetch.js\";\nexport {\n wrapOpenAIAgentsTool,\n wrapOpenAIAgentsTools,\n type OpenAIAgentsToolLike,\n type OpenAIAgentsWrapOptions,\n} from \"./adapters/openai-agents.js\";\nexport {\n wrapLangChainTool,\n wrapLangChainTools,\n type LangChainToolLike,\n type LangChainWrapOptions,\n} from \"./adapters/langchain.js\";\nexport {\n GuardError,\n type GuardErrorBody,\n type GuardEvent,\n type GuardResult,\n type Policy,\n type PolicyInput,\n type Report,\n} from \"@agentwares/agentguard-core\";\n"],"mappings":"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","names":["GuardError"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentwares/agentguard-sdk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "agentguard for tool calls that bypass MCP: wrap OpenAI Agents SDK, LangChain or plain function tools with the same policy engine (spend caps, approvals, kill switch, dry-run, loop breaker, audit log) and cap LLM spend with a guarded fetch.",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "okgate (formerly agentguard) for tool calls that bypass MCP: wrap OpenAI Agents SDK, LangChain or plain function tools with the same policy engine (spend caps, approvals, kill switch, dry-run, loop breaker, audit log) and cap LLM spend with a guarded fetch.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"directory": "packages/agentguard-sdk"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
28
|
+
"okgate",
|
|
28
29
|
"agentguard",
|
|
29
30
|
"openai-agents",
|
|
30
31
|
"langchain",
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
"test": "vitest run"
|
|
46
47
|
},
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@agentwares/agentguard-core": "^0.1.
|
|
49
|
+
"@agentwares/agentguard-core": "^0.1.6"
|
|
49
50
|
},
|
|
50
51
|
"homepage": "https://github.com/agentwares/agentguard#readme",
|
|
51
52
|
"bugs": {
|