@sponsio/sdk 0.1.0-alpha.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/contracts/capability/credentials.yaml +188 -0
- package/contracts/capability/database.yaml +141 -0
- package/contracts/capability/filesystem-strict.yaml +101 -0
- package/contracts/capability/filesystem.yaml +239 -0
- package/contracts/capability/self-modify.yaml +152 -0
- package/contracts/capability/shell.yaml +246 -0
- package/contracts/capability/subagent.yaml +184 -0
- package/contracts/core/llm_safety.yaml +130 -0
- package/contracts/core/runaway.yaml +43 -0
- package/contracts/core/universal.yaml +34 -0
- package/contracts/incident/claude-code-secret-bypass.yaml +197 -0
- package/contracts/incident/cursor-railway-wipe.yaml +164 -0
- package/contracts/incident/mcp-composition.yaml +418 -0
- package/contracts/incident/openclaw.yaml +500 -0
- package/contracts/incident/subagent-escape.yaml +177 -0
- package/contracts/premium/.gitkeep +7 -0
- package/dist/contract.d.ts +59 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +97 -0
- package/dist/contract.js.map +1 -0
- package/dist/core/config-loader.d.ts +90 -0
- package/dist/core/config-loader.d.ts.map +1 -0
- package/dist/core/config-loader.js +530 -0
- package/dist/core/config-loader.js.map +1 -0
- package/dist/core/evaluator.d.ts +15 -0
- package/dist/core/evaluator.d.ts.map +1 -0
- package/dist/core/evaluator.js +87 -0
- package/dist/core/evaluator.js.map +1 -0
- package/dist/core/formula.d.ts +103 -0
- package/dist/core/formula.d.ts.map +1 -0
- package/dist/core/formula.js +167 -0
- package/dist/core/formula.js.map +1 -0
- package/dist/core/grounding.d.ts +43 -0
- package/dist/core/grounding.d.ts.map +1 -0
- package/dist/core/grounding.js +269 -0
- package/dist/core/grounding.js.map +1 -0
- package/dist/core/nl-parser.d.ts +12 -0
- package/dist/core/nl-parser.d.ts.map +1 -0
- package/dist/core/nl-parser.js +152 -0
- package/dist/core/nl-parser.js.map +1 -0
- package/dist/core/pack-loader.d.ts +15 -0
- package/dist/core/pack-loader.d.ts.map +1 -0
- package/dist/core/pack-loader.js +220 -0
- package/dist/core/pack-loader.js.map +1 -0
- package/dist/core/parser.d.ts +19 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +235 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/pattern-factory.d.ts +38 -0
- package/dist/core/pattern-factory.d.ts.map +1 -0
- package/dist/core/pattern-factory.js +222 -0
- package/dist/core/pattern-factory.js.map +1 -0
- package/dist/core/patterns.d.ts +67 -0
- package/dist/core/patterns.d.ts.map +1 -0
- package/dist/core/patterns.js +585 -0
- package/dist/core/patterns.js.map +1 -0
- package/dist/core/session-log.d.ts +91 -0
- package/dist/core/session-log.d.ts.map +1 -0
- package/dist/core/session-log.js +196 -0
- package/dist/core/session-log.js.map +1 -0
- package/dist/core/spans.d.ts +92 -0
- package/dist/core/spans.d.ts.map +1 -0
- package/dist/core/spans.js +148 -0
- package/dist/core/spans.js.map +1 -0
- package/dist/core/sto.d.ts +120 -0
- package/dist/core/sto.d.ts.map +1 -0
- package/dist/core/sto.js +147 -0
- package/dist/core/sto.js.map +1 -0
- package/dist/index.d.ts +267 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +540 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/claude-agent.d.ts +29 -0
- package/dist/integrations/claude-agent.d.ts.map +1 -0
- package/dist/integrations/claude-agent.js +40 -0
- package/dist/integrations/claude-agent.js.map +1 -0
- package/dist/integrations/google-adk.d.ts +27 -0
- package/dist/integrations/google-adk.d.ts.map +1 -0
- package/dist/integrations/google-adk.js +81 -0
- package/dist/integrations/google-adk.js.map +1 -0
- package/dist/integrations/langchain.d.ts +26 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +74 -0
- package/dist/integrations/langchain.js.map +1 -0
- package/dist/integrations/openai-agents.d.ts +45 -0
- package/dist/integrations/openai-agents.d.ts.map +1 -0
- package/dist/integrations/openai-agents.js +81 -0
- package/dist/integrations/openai-agents.js.map +1 -0
- package/dist/integrations/openai.d.ts +24 -0
- package/dist/integrations/openai.d.ts.map +1 -0
- package/dist/integrations/openai.js +77 -0
- package/dist/integrations/openai.js.map +1 -0
- package/dist/integrations/vercel-ai.d.ts +38 -0
- package/dist/integrations/vercel-ai.d.ts.map +1 -0
- package/dist/integrations/vercel-ai.js +107 -0
- package/dist/integrations/vercel-ai.js.map +1 -0
- package/dist/render/components.d.ts +23 -0
- package/dist/render/components.d.ts.map +1 -0
- package/dist/render/components.js +133 -0
- package/dist/render/components.js.map +1 -0
- package/dist/render/derive.d.ts +23 -0
- package/dist/render/derive.d.ts.map +1 -0
- package/dist/render/derive.js +92 -0
- package/dist/render/derive.js.map +1 -0
- package/dist/render/session-view.d.ts +19 -0
- package/dist/render/session-view.d.ts.map +1 -0
- package/dist/render/session-view.js +236 -0
- package/dist/render/session-view.js.map +1 -0
- package/dist/render/tokens.d.ts +44 -0
- package/dist/render/tokens.d.ts.map +1 -0
- package/dist/render/tokens.js +72 -0
- package/dist/render/tokens.js.map +1 -0
- package/package.json +83 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google ADK integration (``@google/adk``) - native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* ADK TypeScript expresses custom tools as ``FunctionTool`` objects
|
|
5
|
+
* with an ``execute`` callback. This adapter clones those tool objects
|
|
6
|
+
* and intercepts ``execute`` with ``guardBefore`` / ``guardAfter`` so
|
|
7
|
+
* Sponsio contracts run at the same boundary ADK already uses.
|
|
8
|
+
*
|
|
9
|
+
* Usage::
|
|
10
|
+
*
|
|
11
|
+
* import { FunctionTool, LlmAgent } from "@google/adk";
|
|
12
|
+
* import { Sponsio } from "@sponsio/sdk";
|
|
13
|
+
* import { wrapGoogleAdkTools } from "@sponsio/sdk/google-adk";
|
|
14
|
+
*
|
|
15
|
+
* const guard = new Sponsio({ config: "sponsio.yaml", agentId: "support" });
|
|
16
|
+
* const tools = wrapGoogleAdkTools([lookupTool, refundTool], guard);
|
|
17
|
+
* export const rootAgent = new LlmAgent({ name: "support", tools, ... });
|
|
18
|
+
*/
|
|
19
|
+
import type { Sponsio } from "../index.js";
|
|
20
|
+
interface GoogleAdkToolLike {
|
|
21
|
+
name: string;
|
|
22
|
+
execute?: (...args: unknown[]) => unknown;
|
|
23
|
+
}
|
|
24
|
+
export declare function wrapGoogleAdkTools<T extends GoogleAdkToolLike>(tools: T[], guard: Sponsio): T[];
|
|
25
|
+
export declare function wrapGoogleAdkTool<T extends GoogleAdkToolLike>(tool: T, guard: Sponsio): T;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=google-adk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-adk.d.ts","sourceRoot":"","sources":["../../src/integrations/google-adk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;CAC3C;AAID,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,iBAAiB,EAC5D,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,OAAO,GACb,CAAC,EAAE,CAEL;AAED,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,iBAAiB,EAC3D,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,OAAO,GACb,CAAC,CAqCH"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google ADK integration (``@google/adk``) - native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* ADK TypeScript expresses custom tools as ``FunctionTool`` objects
|
|
5
|
+
* with an ``execute`` callback. This adapter clones those tool objects
|
|
6
|
+
* and intercepts ``execute`` with ``guardBefore`` / ``guardAfter`` so
|
|
7
|
+
* Sponsio contracts run at the same boundary ADK already uses.
|
|
8
|
+
*
|
|
9
|
+
* Usage::
|
|
10
|
+
*
|
|
11
|
+
* import { FunctionTool, LlmAgent } from "@google/adk";
|
|
12
|
+
* import { Sponsio } from "@sponsio/sdk";
|
|
13
|
+
* import { wrapGoogleAdkTools } from "@sponsio/sdk/google-adk";
|
|
14
|
+
*
|
|
15
|
+
* const guard = new Sponsio({ config: "sponsio.yaml", agentId: "support" });
|
|
16
|
+
* const tools = wrapGoogleAdkTools([lookupTool, refundTool], guard);
|
|
17
|
+
* export const rootAgent = new LlmAgent({ name: "support", tools, ... });
|
|
18
|
+
*/
|
|
19
|
+
let warnedUnwrappable = false;
|
|
20
|
+
export function wrapGoogleAdkTools(tools, guard) {
|
|
21
|
+
return tools.map((tool) => wrapGoogleAdkTool(tool, guard));
|
|
22
|
+
}
|
|
23
|
+
export function wrapGoogleAdkTool(tool, guard) {
|
|
24
|
+
if (!tool.execute) {
|
|
25
|
+
if (!warnedUnwrappable) {
|
|
26
|
+
warnedUnwrappable = true;
|
|
27
|
+
console.warn(`[sponsio] wrapGoogleAdkTools: tool '${tool.name}' has no ` +
|
|
28
|
+
`.execute callback - returning unchanged`);
|
|
29
|
+
}
|
|
30
|
+
return tool;
|
|
31
|
+
}
|
|
32
|
+
const original = tool.execute.bind(tool);
|
|
33
|
+
const wrapped = async (...args) => {
|
|
34
|
+
const callArgs = toArgsObject(args);
|
|
35
|
+
const check = guard.guardBefore(tool.name, callArgs);
|
|
36
|
+
if (check.blocked) {
|
|
37
|
+
return blockedResult(check.message);
|
|
38
|
+
}
|
|
39
|
+
const output = await original(...args);
|
|
40
|
+
const afterCheck = await guard.guardAfter(tool.name, stringify(output));
|
|
41
|
+
if (afterCheck.blocked) {
|
|
42
|
+
return blockedResult(afterCheck.message);
|
|
43
|
+
}
|
|
44
|
+
return output;
|
|
45
|
+
};
|
|
46
|
+
const next = Object.create(Object.getPrototypeOf(tool));
|
|
47
|
+
Object.assign(next, tool);
|
|
48
|
+
Object.defineProperty(next, "execute", {
|
|
49
|
+
value: wrapped,
|
|
50
|
+
writable: true,
|
|
51
|
+
configurable: true,
|
|
52
|
+
enumerable: true,
|
|
53
|
+
});
|
|
54
|
+
return next;
|
|
55
|
+
}
|
|
56
|
+
function toArgsObject(args) {
|
|
57
|
+
const first = args[0];
|
|
58
|
+
if (typeof first === "object" && first !== null && !Array.isArray(first)) {
|
|
59
|
+
return first;
|
|
60
|
+
}
|
|
61
|
+
if (args.length === 0)
|
|
62
|
+
return {};
|
|
63
|
+
return { args };
|
|
64
|
+
}
|
|
65
|
+
function blockedResult(message) {
|
|
66
|
+
return {
|
|
67
|
+
status: "error",
|
|
68
|
+
error_message: `BLOCKED by contract: ${message}`,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function stringify(value) {
|
|
72
|
+
if (typeof value === "string")
|
|
73
|
+
return value;
|
|
74
|
+
try {
|
|
75
|
+
return JSON.stringify(value);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return String(value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=google-adk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-adk.js","sourceRoot":"","sources":["../../src/integrations/google-adk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain.js / LangGraph.js integration — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* LangChain.js tools expose an ``invoke(input, config?)`` method. This
|
|
5
|
+
* adapter clones tool objects and intercepts ``invoke`` with
|
|
6
|
+
* ``guardBefore`` / ``guardAfter`` so Sponsio contracts run at the same
|
|
7
|
+
* boundary LangChain already uses. The original tools are not mutated,
|
|
8
|
+
* so it's safe to share them between guarded and unguarded code paths.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* import { Sponsio } from "@sponsio/sdk";
|
|
12
|
+
* import { wrapTools } from "@sponsio/sdk/langchain";
|
|
13
|
+
* import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
14
|
+
*
|
|
15
|
+
* const guard = new Sponsio({ contracts: [...] });
|
|
16
|
+
* const toolNode = new ToolNode(wrapTools(tools, guard));
|
|
17
|
+
*/
|
|
18
|
+
import type { Sponsio } from "../index.js";
|
|
19
|
+
interface LangChainToolLike {
|
|
20
|
+
name: string;
|
|
21
|
+
invoke?: (input: unknown, config?: unknown) => unknown;
|
|
22
|
+
}
|
|
23
|
+
export declare function wrapTools<T extends LangChainToolLike>(tools: T[], guard: Sponsio): T[];
|
|
24
|
+
export declare function wrapTool<T extends LangChainToolLike>(tool: T, guard: Sponsio): T;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=langchain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../../src/integrations/langchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;CACxD;AAID,wBAAgB,SAAS,CAAC,CAAC,SAAS,iBAAiB,EACnD,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,OAAO,GACb,CAAC,EAAE,CAEL;AAED,wBAAgB,QAAQ,CAAC,CAAC,SAAS,iBAAiB,EAClD,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,OAAO,GACb,CAAC,CAsCH"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LangChain.js / LangGraph.js integration — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* LangChain.js tools expose an ``invoke(input, config?)`` method. This
|
|
5
|
+
* adapter clones tool objects and intercepts ``invoke`` with
|
|
6
|
+
* ``guardBefore`` / ``guardAfter`` so Sponsio contracts run at the same
|
|
7
|
+
* boundary LangChain already uses. The original tools are not mutated,
|
|
8
|
+
* so it's safe to share them between guarded and unguarded code paths.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* import { Sponsio } from "@sponsio/sdk";
|
|
12
|
+
* import { wrapTools } from "@sponsio/sdk/langchain";
|
|
13
|
+
* import { ToolNode } from "@langchain/langgraph/prebuilt";
|
|
14
|
+
*
|
|
15
|
+
* const guard = new Sponsio({ contracts: [...] });
|
|
16
|
+
* const toolNode = new ToolNode(wrapTools(tools, guard));
|
|
17
|
+
*/
|
|
18
|
+
let warnedUnwrappable = false;
|
|
19
|
+
export function wrapTools(tools, guard) {
|
|
20
|
+
return tools.map((tool) => wrapTool(tool, guard));
|
|
21
|
+
}
|
|
22
|
+
export function wrapTool(tool, guard) {
|
|
23
|
+
if (!tool.invoke) {
|
|
24
|
+
if (!warnedUnwrappable) {
|
|
25
|
+
warnedUnwrappable = true;
|
|
26
|
+
console.warn(`[sponsio] wrapTools: tool '${tool.name}' has no .invoke method ` +
|
|
27
|
+
`- returning unchanged`);
|
|
28
|
+
}
|
|
29
|
+
return tool;
|
|
30
|
+
}
|
|
31
|
+
const original = tool.invoke.bind(tool);
|
|
32
|
+
const toolName = tool.name;
|
|
33
|
+
const wrapped = async (input, config) => {
|
|
34
|
+
const args = toArgsObject(input);
|
|
35
|
+
const check = guard.guardBefore(toolName, args);
|
|
36
|
+
if (check.blocked) {
|
|
37
|
+
return `BLOCKED by Sponsio: ${check.message}`;
|
|
38
|
+
}
|
|
39
|
+
const output = await original(input, config);
|
|
40
|
+
const afterCheck = await guard.guardAfter(toolName, stringify(output));
|
|
41
|
+
if (afterCheck.blocked) {
|
|
42
|
+
return `BLOCKED by Sponsio: ${afterCheck.message}`;
|
|
43
|
+
}
|
|
44
|
+
return output;
|
|
45
|
+
};
|
|
46
|
+
const next = Object.create(Object.getPrototypeOf(tool));
|
|
47
|
+
Object.assign(next, tool);
|
|
48
|
+
Object.defineProperty(next, "invoke", {
|
|
49
|
+
value: wrapped,
|
|
50
|
+
writable: true,
|
|
51
|
+
configurable: true,
|
|
52
|
+
enumerable: true,
|
|
53
|
+
});
|
|
54
|
+
return next;
|
|
55
|
+
}
|
|
56
|
+
function toArgsObject(input) {
|
|
57
|
+
if (typeof input === "string")
|
|
58
|
+
return { input };
|
|
59
|
+
if (typeof input === "object" && input !== null && !Array.isArray(input)) {
|
|
60
|
+
return input;
|
|
61
|
+
}
|
|
62
|
+
return { input };
|
|
63
|
+
}
|
|
64
|
+
function stringify(value) {
|
|
65
|
+
if (typeof value === "string")
|
|
66
|
+
return value;
|
|
67
|
+
try {
|
|
68
|
+
return JSON.stringify(value);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return String(value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=langchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../src/integrations/langchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B,MAAM,UAAU,SAAS,CACvB,KAAU,EACV,KAAc;IAEd,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,IAAO,EACP,KAAc;IAEd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,iBAAiB,GAAG,IAAI,CAAC;YACzB,OAAO,CAAC,IAAI,CACV,8BAA8B,IAAI,CAAC,IAAI,0BAA0B;gBAC/D,uBAAuB,CAC1B,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;IAC3B,MAAM,OAAO,GAAG,KAAK,EAAE,KAAc,EAAE,MAAgB,EAAoB,EAAE;QAC3E,MAAM,IAAI,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,uBAAuB,KAAK,CAAC,OAAO,EAAE,CAAC;QAChD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACvE,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,uBAAuB,UAAU,CAAC,OAAO,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAM,CAAC;IAC7D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE;QACpC,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,IAAI;QAClB,UAAU,EAAE,IAAI;KACjB,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,KAAgC,CAAC;IAC1C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Agents SDK integration (``@openai/agents``) — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* The Agents SDK is the "native TS" counterpart to Python's
|
|
5
|
+
* ``openai-agents``. It expresses tools as objects with an async
|
|
6
|
+
* ``execute`` (or ``invoke``) function; this adapter intercepts that
|
|
7
|
+
* function with ``guardBefore`` / ``guardAfter`` so contracts run at
|
|
8
|
+
* the action boundary — the same shape as our LangChain and Vercel
|
|
9
|
+
* adapters.
|
|
10
|
+
*
|
|
11
|
+
* Usage::
|
|
12
|
+
*
|
|
13
|
+
* import { Agent, run, tool } from "@openai/agents";
|
|
14
|
+
* import { Sponsio } from "@sponsio/sdk";
|
|
15
|
+
* import { wrapAgentsTools } from "@sponsio/sdk/openai-agents";
|
|
16
|
+
*
|
|
17
|
+
* const guard = new Sponsio({ config: "sponsio.yaml", agentId: "support" });
|
|
18
|
+
* const tools = wrapAgentsTools([refundTool, lookupTool, …], guard);
|
|
19
|
+
* const agent = new Agent({ name: "support", tools });
|
|
20
|
+
*
|
|
21
|
+
* ``wrapAgentsTools`` is non-destructive: it returns a new array of
|
|
22
|
+
* wrapped tool objects. The originals are unmodified so the same
|
|
23
|
+
* tool can be reused across agents or tests without leftover state.
|
|
24
|
+
*
|
|
25
|
+
* Blocked calls throw a thrown ``Error`` with the Sponsio violation
|
|
26
|
+
* message — the Agents SDK surfaces this as a tool failure the model
|
|
27
|
+
* can react to. If your runtime prefers a structured tool-result
|
|
28
|
+
* error instead, wrap the call site.
|
|
29
|
+
*/
|
|
30
|
+
import type { Sponsio } from "../index.js";
|
|
31
|
+
/**
|
|
32
|
+
* Structural shape we rely on: a ``name`` and some sort of async
|
|
33
|
+
* executable. We probe for the Agents SDK's current field name
|
|
34
|
+
* (``execute``) and fall back to ``invoke`` for runtimes that follow
|
|
35
|
+
* the LangChain convention. If neither is present the tool is
|
|
36
|
+
* returned unchanged and a one-shot warning is emitted.
|
|
37
|
+
*/
|
|
38
|
+
interface AgentsToolLike {
|
|
39
|
+
name: string;
|
|
40
|
+
execute?: (...args: unknown[]) => unknown;
|
|
41
|
+
invoke?: (...args: unknown[]) => unknown;
|
|
42
|
+
}
|
|
43
|
+
export declare function wrapAgentsTools<T extends AgentsToolLike>(tools: T[], guard: Sponsio): T[];
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=openai-agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-agents.d.ts","sourceRoot":"","sources":["../../src/integrations/openai-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;;GAMG;AACH,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;IAC1C,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;CAC1C;AAID,wBAAgB,eAAe,CAAC,CAAC,SAAS,cAAc,EACtD,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,OAAO,GACb,CAAC,EAAE,CA6CL"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Agents SDK integration (``@openai/agents``) — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* The Agents SDK is the "native TS" counterpart to Python's
|
|
5
|
+
* ``openai-agents``. It expresses tools as objects with an async
|
|
6
|
+
* ``execute`` (or ``invoke``) function; this adapter intercepts that
|
|
7
|
+
* function with ``guardBefore`` / ``guardAfter`` so contracts run at
|
|
8
|
+
* the action boundary — the same shape as our LangChain and Vercel
|
|
9
|
+
* adapters.
|
|
10
|
+
*
|
|
11
|
+
* Usage::
|
|
12
|
+
*
|
|
13
|
+
* import { Agent, run, tool } from "@openai/agents";
|
|
14
|
+
* import { Sponsio } from "@sponsio/sdk";
|
|
15
|
+
* import { wrapAgentsTools } from "@sponsio/sdk/openai-agents";
|
|
16
|
+
*
|
|
17
|
+
* const guard = new Sponsio({ config: "sponsio.yaml", agentId: "support" });
|
|
18
|
+
* const tools = wrapAgentsTools([refundTool, lookupTool, …], guard);
|
|
19
|
+
* const agent = new Agent({ name: "support", tools });
|
|
20
|
+
*
|
|
21
|
+
* ``wrapAgentsTools`` is non-destructive: it returns a new array of
|
|
22
|
+
* wrapped tool objects. The originals are unmodified so the same
|
|
23
|
+
* tool can be reused across agents or tests without leftover state.
|
|
24
|
+
*
|
|
25
|
+
* Blocked calls throw a thrown ``Error`` with the Sponsio violation
|
|
26
|
+
* message — the Agents SDK surfaces this as a tool failure the model
|
|
27
|
+
* can react to. If your runtime prefers a structured tool-result
|
|
28
|
+
* error instead, wrap the call site.
|
|
29
|
+
*/
|
|
30
|
+
let warnedUnwrappable = false;
|
|
31
|
+
export function wrapAgentsTools(tools, guard) {
|
|
32
|
+
return tools.map((tool) => {
|
|
33
|
+
const field = tool.execute
|
|
34
|
+
? "execute"
|
|
35
|
+
: tool.invoke
|
|
36
|
+
? "invoke"
|
|
37
|
+
: null;
|
|
38
|
+
if (!field) {
|
|
39
|
+
if (!warnedUnwrappable) {
|
|
40
|
+
warnedUnwrappable = true;
|
|
41
|
+
console.warn(`[sponsio] wrapAgentsTools: tool '${tool.name}' has neither ` +
|
|
42
|
+
`.execute nor .invoke — returning unchanged`);
|
|
43
|
+
}
|
|
44
|
+
return tool;
|
|
45
|
+
}
|
|
46
|
+
const original = tool[field].bind(tool);
|
|
47
|
+
const wrapped = async (...args) => {
|
|
48
|
+
const input = args[0];
|
|
49
|
+
const argsObj = typeof input === "object" && input !== null
|
|
50
|
+
? input
|
|
51
|
+
: { input };
|
|
52
|
+
const check = guard.guardBefore(tool.name, argsObj);
|
|
53
|
+
if (check.blocked) {
|
|
54
|
+
throw new Error(check.message);
|
|
55
|
+
}
|
|
56
|
+
const output = await original(...args);
|
|
57
|
+
const asStr = typeof output === "string" ? output : safeStringify(output);
|
|
58
|
+
// In enforce mode, sto violations surface here (tone, llm_judge,
|
|
59
|
+
// etc.). Propagate via a thrown Error so the Agents SDK routes it
|
|
60
|
+
// as a tool failure the model can see and react to — matches the
|
|
61
|
+
// pre-check block path above.
|
|
62
|
+
const afterCheck = await guard.guardAfter(tool.name, asStr);
|
|
63
|
+
if (afterCheck.blocked) {
|
|
64
|
+
throw new Error(afterCheck.message);
|
|
65
|
+
}
|
|
66
|
+
return output;
|
|
67
|
+
};
|
|
68
|
+
// Clone so we don't mutate the user's original tool object.
|
|
69
|
+
const next = { ...tool, [field]: wrapped };
|
|
70
|
+
return next;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function safeStringify(v) {
|
|
74
|
+
try {
|
|
75
|
+
return JSON.stringify(v);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
return String(v);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=openai-agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-agents.js","sourceRoot":"","sources":["../../src/integrations/openai-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAiBH,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAE9B,MAAM,UAAU,eAAe,CAC7B,KAAU,EACV,KAAc;IAEd,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,KAAK,GAAgC,IAAI,CAAC,OAAO;YACrD,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,IAAI,CAAC,MAAM;gBACX,CAAC,CAAC,QAAQ;gBACV,CAAC,CAAC,IAAI,CAAC;QACX,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACvB,iBAAiB,GAAG,IAAI,CAAC;gBACzB,OAAO,CAAC,IAAI,CACV,oCAAoC,IAAI,CAAC,IAAI,gBAAgB;oBAC3D,4CAA4C,CAC/C,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,KAAK,EAAE,GAAG,IAAe,EAAoB,EAAE;YAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,OAAO,GACX,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;gBACzC,CAAC,CAAE,KAAiC;gBACpC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;YACvC,MAAM,KAAK,GACT,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC9D,iEAAiE;YACjE,kEAAkE;YAClE,iEAAiE;YACjE,8BAA8B;YAC9B,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC5D,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QACF,4DAA4D;QAC5D,MAAM,IAAI,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAO,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,CAAU;IAC/B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI SDK integration — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { Sponsio } from "@sponsio/sdk"
|
|
6
|
+
* import { wrapOpenAI, patchOpenAI } from "@sponsio/sdk/openai"
|
|
7
|
+
*
|
|
8
|
+
* const guard = new Sponsio({ contracts: [...] })
|
|
9
|
+
* const client = wrapOpenAI(new OpenAI(), guard)
|
|
10
|
+
*
|
|
11
|
+
* ``patchOpenAI`` is an alias matching Python's ``patch_openai``
|
|
12
|
+
* factory (same monkey-patch semantics — no wrapped return value
|
|
13
|
+
* required; the client passed in is mutated in place).
|
|
14
|
+
*/
|
|
15
|
+
import type { Sponsio } from "../index.js";
|
|
16
|
+
export declare function wrapOpenAI(client: unknown, guard: Sponsio): unknown;
|
|
17
|
+
/**
|
|
18
|
+
* Alias for ``wrapOpenAI`` — matches Python's
|
|
19
|
+
* ``from sponsio.openai import patch_openai`` naming. Both mutate
|
|
20
|
+
* the passed client in place and return it; use whichever name
|
|
21
|
+
* reads better alongside the Python snippet you're porting.
|
|
22
|
+
*/
|
|
23
|
+
export declare const patchOpenAI: typeof wrapOpenAI;
|
|
24
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/integrations/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA8EnE;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,mBAAa,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI SDK integration — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { Sponsio } from "@sponsio/sdk"
|
|
6
|
+
* import { wrapOpenAI, patchOpenAI } from "@sponsio/sdk/openai"
|
|
7
|
+
*
|
|
8
|
+
* const guard = new Sponsio({ contracts: [...] })
|
|
9
|
+
* const client = wrapOpenAI(new OpenAI(), guard)
|
|
10
|
+
*
|
|
11
|
+
* ``patchOpenAI`` is an alias matching Python's ``patch_openai``
|
|
12
|
+
* factory (same monkey-patch semantics — no wrapped return value
|
|
13
|
+
* required; the client passed in is mutated in place).
|
|
14
|
+
*/
|
|
15
|
+
export function wrapOpenAI(client, guard) {
|
|
16
|
+
const c = client;
|
|
17
|
+
const original = c.chat.completions.create.bind(c.chat.completions);
|
|
18
|
+
c.chat.completions.create = async function (...args) {
|
|
19
|
+
const response = await original(...args);
|
|
20
|
+
for (const choice of response.choices ?? []) {
|
|
21
|
+
const msg = choice.message;
|
|
22
|
+
if (!msg?.tool_calls)
|
|
23
|
+
continue;
|
|
24
|
+
const kept = [];
|
|
25
|
+
const blocked = [];
|
|
26
|
+
for (const tc of msg.tool_calls) {
|
|
27
|
+
let tcArgs = {};
|
|
28
|
+
let parseFailed = false;
|
|
29
|
+
try {
|
|
30
|
+
tcArgs = JSON.parse(tc.function.arguments || "{}");
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
parseFailed = true;
|
|
34
|
+
}
|
|
35
|
+
// Malformed arguments bypass any arg-based contract
|
|
36
|
+
// (``arg_blacklist``, ``arg_length_limit``, ``scope_limit``,
|
|
37
|
+
// ``dangerous_sql_verbs``, ``arg_value_range``) if we treat
|
|
38
|
+
// them as empty. Feed a sentinel so the guard still sees
|
|
39
|
+
// *something* distinctive, and block-by-default so a
|
|
40
|
+
// malformed payload doesn't silently slip through.
|
|
41
|
+
if (parseFailed) {
|
|
42
|
+
guard.guardBefore(tc.function.name, {
|
|
43
|
+
_sponsio_malformed_args: tc.function.arguments ?? "",
|
|
44
|
+
});
|
|
45
|
+
blocked.push(`[BLOCKED] ${tc.function.name}: malformed JSON arguments — ` +
|
|
46
|
+
`refusing to forward to tool loop (set ` +
|
|
47
|
+
`SPONSIO_OPENAI_STRICT_TOOL_ARGS=0 to downgrade once the ` +
|
|
48
|
+
`parity flag ships in TS)`);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const result = guard.guardBefore(tc.function.name, tcArgs);
|
|
52
|
+
if (result.blocked) {
|
|
53
|
+
blocked.push(`[BLOCKED] ${tc.function.name}: ${result.message}`);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
kept.push(tc);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
msg.tool_calls = kept.length > 0 ? kept : null;
|
|
60
|
+
if (blocked.length > 0 && !msg.tool_calls) {
|
|
61
|
+
// Match Python's ``_filter_blocked_calls``: join with a newline
|
|
62
|
+
// separator but no leading newline before the first message.
|
|
63
|
+
msg.content = (msg.content ?? "") + blocked.join("\n");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return response;
|
|
67
|
+
};
|
|
68
|
+
return client;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Alias for ``wrapOpenAI`` — matches Python's
|
|
72
|
+
* ``from sponsio.openai import patch_openai`` naming. Both mutate
|
|
73
|
+
* the passed client in place and return it; use whichever name
|
|
74
|
+
* reads better alongside the Python snippet you're porting.
|
|
75
|
+
*/
|
|
76
|
+
export const patchOpenAI = wrapOpenAI;
|
|
77
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/integrations/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,MAAM,UAAU,UAAU,CAAC,MAAe,EAAE,KAAc;IACxD,MAAM,CAAC,GAAG,MAeT,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAEpE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,KAAK,WAAW,GAAG,IAAe;QAC5D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC;QAEzC,KAAK,MAAM,MAAM,IAAI,QAAQ,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;YAC3B,IAAI,CAAC,GAAG,EAAE,UAAU;gBAAE,SAAS;YAE/B,MAAM,IAAI,GAA0B,EAAE,CAAC;YACvC,MAAM,OAAO,GAAa,EAAE,CAAC;YAE7B,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;gBAChC,IAAI,MAAM,GAA4B,EAAE,CAAC;gBACzC,IAAI,WAAW,GAAG,KAAK,CAAC;gBACxB,IAAI,CAAC;oBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC;gBACrD,CAAC;gBAAC,MAAM,CAAC;oBACP,WAAW,GAAG,IAAI,CAAC;gBACrB,CAAC;gBAED,oDAAoD;gBACpD,6DAA6D;gBAC7D,4DAA4D;gBAC5D,yDAAyD;gBACzD,qDAAqD;gBACrD,mDAAmD;gBACnD,IAAI,WAAW,EAAE,CAAC;oBAChB,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE;wBAClC,uBAAuB,EAAE,EAAE,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE;qBACrD,CAAC,CAAC;oBACH,OAAO,CAAC,IAAI,CACV,aAAa,EAAE,CAAC,QAAQ,CAAC,IAAI,+BAA+B;wBAC1D,wCAAwC;wBACxC,0DAA0D;wBAC1D,0BAA0B,CAC7B,CAAC;oBACF,SAAS;gBACX,CAAC;gBAED,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC3D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;gBACnE,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC;YAED,GAAG,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAC/C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;gBAC1C,gEAAgE;gBAChE,6DAA6D;gBAC7D,GAAG,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAoB,CAAC;IAErB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel AI SDK integration — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { Sponsio } from "@sponsio/sdk"
|
|
6
|
+
* import { sponsioMiddleware } from "@sponsio/sdk/vercel-ai"
|
|
7
|
+
* import { wrapLanguageModel } from "ai"
|
|
8
|
+
*
|
|
9
|
+
* const guard = new Sponsio({ contracts: [...] })
|
|
10
|
+
* const model = wrapLanguageModel({ model, middleware: sponsioMiddleware(guard) })
|
|
11
|
+
*
|
|
12
|
+
* Behaviour:
|
|
13
|
+
* - guardBefore is called for every tool call the model emits.
|
|
14
|
+
* - Allowed calls pass through untouched.
|
|
15
|
+
* - Blocked calls are *dropped* from ``result.toolCalls`` (so the AI
|
|
16
|
+
* SDK's parseToolCall doesn't reject the response with NoSuchToolError),
|
|
17
|
+
* and a `[Sponsio blocked: <reason>]` line is appended to the
|
|
18
|
+
* model's text output. If every emitted call was blocked, the
|
|
19
|
+
* finishReason is forced to ``stop`` so the agent loop terminates
|
|
20
|
+
* instead of spinning on an empty turn.
|
|
21
|
+
* - The model's args are JSON-stringified at the language-model layer;
|
|
22
|
+
* the middleware parses defensively before handing them to the
|
|
23
|
+
* guard so the contract evaluator sees a real object.
|
|
24
|
+
*/
|
|
25
|
+
import type { Sponsio } from "../index.js";
|
|
26
|
+
export declare function sponsioMiddleware(guard: Sponsio): {
|
|
27
|
+
transformParams: ({ params }: {
|
|
28
|
+
params: any;
|
|
29
|
+
}) => Promise<any>;
|
|
30
|
+
wrapGenerate: ({ doGenerate, }: {
|
|
31
|
+
doGenerate: () => any;
|
|
32
|
+
params: any;
|
|
33
|
+
}) => Promise<any>;
|
|
34
|
+
wrapStream: ({ doStream }: {
|
|
35
|
+
doStream: () => any;
|
|
36
|
+
}) => Promise<any>;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=vercel-ai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-ai.d.ts","sourceRoot":"","sources":["../../src/integrations/vercel-ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAgD3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO;kCAER;QAAE,MAAM,EAAE,GAAG,CAAA;KAAE,KAAG,OAAO,CAAC,GAAG,CAAC;oCAI/D;QACD,UAAU,EAAE,MAAM,GAAG,CAAC;QACtB,MAAM,EAAE,GAAG,CAAC;KACb,KAAG,OAAO,CAAC,GAAG,CAAC;+BAqCiB;QAAE,QAAQ,EAAE,MAAM,GAAG,CAAA;KAAE,KAAG,OAAO,CAAC,GAAG,CAAC;EAQ1E"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel AI SDK integration — native TypeScript.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { Sponsio } from "@sponsio/sdk"
|
|
6
|
+
* import { sponsioMiddleware } from "@sponsio/sdk/vercel-ai"
|
|
7
|
+
* import { wrapLanguageModel } from "ai"
|
|
8
|
+
*
|
|
9
|
+
* const guard = new Sponsio({ contracts: [...] })
|
|
10
|
+
* const model = wrapLanguageModel({ model, middleware: sponsioMiddleware(guard) })
|
|
11
|
+
*
|
|
12
|
+
* Behaviour:
|
|
13
|
+
* - guardBefore is called for every tool call the model emits.
|
|
14
|
+
* - Allowed calls pass through untouched.
|
|
15
|
+
* - Blocked calls are *dropped* from ``result.toolCalls`` (so the AI
|
|
16
|
+
* SDK's parseToolCall doesn't reject the response with NoSuchToolError),
|
|
17
|
+
* and a `[Sponsio blocked: <reason>]` line is appended to the
|
|
18
|
+
* model's text output. If every emitted call was blocked, the
|
|
19
|
+
* finishReason is forced to ``stop`` so the agent loop terminates
|
|
20
|
+
* instead of spinning on an empty turn.
|
|
21
|
+
* - The model's args are JSON-stringified at the language-model layer;
|
|
22
|
+
* the middleware parses defensively before handing them to the
|
|
23
|
+
* guard so the contract evaluator sees a real object.
|
|
24
|
+
*/
|
|
25
|
+
function emitBanner(toolName, reason, agentId) {
|
|
26
|
+
if (process.env.SPONSIO_NO_BANNER)
|
|
27
|
+
return;
|
|
28
|
+
const isTty = !!process.stderr.isTTY;
|
|
29
|
+
const c = (code, text) => (isTty ? `\x1b[${code}m${text}\x1b[0m` : text);
|
|
30
|
+
const sep = "━".repeat(60);
|
|
31
|
+
const lines = [
|
|
32
|
+
"",
|
|
33
|
+
c("2;36", ` ${sep}`),
|
|
34
|
+
` ${c("1;31", "BLOCKED")} ${c("1", `${agentId}.${toolName}`)}`,
|
|
35
|
+
` ${c("2", "rule")} ${reason}`,
|
|
36
|
+
c("2;36", ` ${sep}`),
|
|
37
|
+
"",
|
|
38
|
+
];
|
|
39
|
+
process.stderr.write(lines.join("\n"));
|
|
40
|
+
}
|
|
41
|
+
function parseArgs(raw) {
|
|
42
|
+
if (raw == null)
|
|
43
|
+
return {};
|
|
44
|
+
if (typeof raw === "object" && !Array.isArray(raw))
|
|
45
|
+
return raw;
|
|
46
|
+
if (typeof raw === "string") {
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(raw);
|
|
49
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed)
|
|
50
|
+
? parsed
|
|
51
|
+
: {};
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
export function sponsioMiddleware(guard) {
|
|
60
|
+
return {
|
|
61
|
+
transformParams: async ({ params }) => params,
|
|
62
|
+
wrapGenerate: async ({ doGenerate, }) => {
|
|
63
|
+
const result = await doGenerate();
|
|
64
|
+
const calls = result.toolCalls ?? [];
|
|
65
|
+
if (calls.length === 0)
|
|
66
|
+
return result;
|
|
67
|
+
const surviving = [];
|
|
68
|
+
const blockedReasons = [];
|
|
69
|
+
for (const tc of calls) {
|
|
70
|
+
const check = guard.guardBefore(tc.toolName, parseArgs(tc.args));
|
|
71
|
+
if (check.blocked) {
|
|
72
|
+
// Strip the leading "BLOCKED: agent.tool — det constraint violated: "
|
|
73
|
+
// prefix and any "det constraint violated:" / "violated:" boilerplate
|
|
74
|
+
// so the appended text is concise; full message stays in the session log.
|
|
75
|
+
const msg = check.message ?? `${tc.toolName} blocked by Sponsio`;
|
|
76
|
+
const trimmed = msg
|
|
77
|
+
.replace(/^[A-Z-]*BLOCKED:\s*[^—]+—\s*/, "")
|
|
78
|
+
.replace(/^(?:det\s+constraint\s+)?violated:\s*/i, "");
|
|
79
|
+
const reason = trimmed.split("\n")[0];
|
|
80
|
+
emitBanner(tc.toolName, reason, guard.agentId);
|
|
81
|
+
blockedReasons.push(`${tc.toolName}: ${reason}`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
surviving.push(tc);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (blockedReasons.length === 0)
|
|
88
|
+
return result;
|
|
89
|
+
const blockNote = `[Sponsio blocked: ${blockedReasons.join("; ")}]`;
|
|
90
|
+
const newText = result.text ? `${result.text}\n\n${blockNote}` : blockNote;
|
|
91
|
+
return {
|
|
92
|
+
...result,
|
|
93
|
+
toolCalls: surviving,
|
|
94
|
+
text: newText,
|
|
95
|
+
finishReason: surviving.length === 0 ? "stop" : result.finishReason,
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
wrapStream: async ({ doStream }) => {
|
|
99
|
+
// Stream support is intentionally pass-through for now; the
|
|
100
|
+
// stream parts API is more involved and the demo / OSS hot
|
|
101
|
+
// path uses generateText. We can add full stream filtering in
|
|
102
|
+
// a follow-up without changing the wrapGenerate contract.
|
|
103
|
+
return doStream();
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=vercel-ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vercel-ai.js","sourceRoot":"","sources":["../../src/integrations/vercel-ai.ts"],"names":[],"mappings":"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"}
|