@agentwares/agentguard-sdk 0.1.1 → 0.1.3
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/LICENSE +21 -0
- package/README.md +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 agentwares
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @agentwares/agentguard-sdk
|
|
2
2
|
|
|
3
|
-
The [agentguard](
|
|
3
|
+
The [agentguard](https://github.com/agentwares/agentguard/tree/main/apps/agentguard-cli#readme) policy engine for tool calls that never go through MCP — OpenAI Agents SDK, LangChain, or plain functions — plus a guarded `fetch` that puts a **hard dollar limit on LLM token spend** across OpenAI, Anthropic and Gemini. Same `agentguard.yaml`, same caps, kill switch, approvals, dry-run and hash-chained audit log as the proxy; the CLI (`agentguard report`, `kill`, `approve`, `verify`) works on the same files.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
npm i @agentwares/agentguard-sdk
|
package/dist/index.js
CHANGED
|
@@ -156,7 +156,7 @@ async function createGuard(opts) {
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
// src/fetch.ts
|
|
159
|
-
import { estimateLlmCost } from "@agentwares/agentguard-core";
|
|
159
|
+
import { estimateLlmCost, noListPriceReason } from "@agentwares/agentguard-core";
|
|
160
160
|
var HOSTS = {
|
|
161
161
|
"api.openai.com": "openai",
|
|
162
162
|
"api.anthropic.com": "anthropic",
|
|
@@ -318,7 +318,7 @@ function createGuardedFetch(ag, opts = {}) {
|
|
|
318
318
|
force: true,
|
|
319
319
|
runId: runId(),
|
|
320
320
|
details: { provider, model: resolvedModel, usage },
|
|
321
|
-
reason: usd === void 0 ?
|
|
321
|
+
reason: usd === void 0 ? noListPriceReason(resolvedModel) : void 0
|
|
322
322
|
});
|
|
323
323
|
};
|
|
324
324
|
const contentType = response.headers.get("content-type") ?? "";
|
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, 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:\n usd === undefined\n ? `no list price for \"${resolvedModel}\" — not counted against spend_usd; add it under spend.models in agentguard.yaml`\n : 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 {\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentwares/agentguard-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
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.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
|
-
"url": "https://github.com/agentwares/agentguard",
|
|
24
|
+
"url": "git+https://github.com/agentwares/agentguard.git",
|
|
25
25
|
"directory": "packages/agentguard-sdk"
|
|
26
26
|
},
|
|
27
27
|
"keywords": [
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"node": ">=20"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@agentwares/agentguard-core": "^0.1.
|
|
42
|
+
"@agentwares/agentguard-core": "^0.1.3"
|
|
43
43
|
},
|
|
44
|
-
"homepage": "https://github.com/agentwares/agentguard
|
|
44
|
+
"homepage": "https://github.com/agentwares/agentguard#readme",
|
|
45
45
|
"bugs": {
|
|
46
46
|
"url": "https://github.com/agentwares/agentguard/issues"
|
|
47
47
|
},
|