aira-sdk 0.1.3 → 0.2.2
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/README.md +214 -106
- package/dist/client.d.ts +9 -0
- package/dist/client.js +33 -0
- package/dist/extras/index.d.ts +19 -0
- package/dist/extras/index.js +29 -0
- package/dist/extras/langchain.d.ts +33 -0
- package/dist/extras/langchain.js +82 -0
- package/dist/extras/mcp.d.ts +49 -0
- package/dist/extras/mcp.js +101 -0
- package/dist/extras/openai-agents.d.ts +29 -0
- package/dist/extras/openai-agents.js +69 -0
- package/dist/extras/vercel-ai.d.ts +39 -0
- package/dist/extras/vercel-ai.js +89 -0
- package/dist/extras/webhooks.d.ts +34 -0
- package/dist/extras/webhooks.js +59 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +5 -1
- package/dist/offline.d.ts +16 -0
- package/dist/offline.js +27 -0
- package/dist/session.d.ts +20 -0
- package/dist/session.js +24 -0
- package/package.json +57 -2
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LangChain.js integration — auto-notarize tool and chain completions.
|
|
4
|
+
*
|
|
5
|
+
* Requires: @langchain/core (peer dependency)
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { AiraCallbackHandler } from "aira-sdk/extras/langchain";
|
|
9
|
+
* const handler = new AiraCallbackHandler(aira, "my-agent");
|
|
10
|
+
* const chain = someChain.withConfig({ callbacks: [handler] });
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AiraCallbackHandler = void 0;
|
|
14
|
+
const MAX_DETAILS = 5000;
|
|
15
|
+
class AiraCallbackHandler {
|
|
16
|
+
client;
|
|
17
|
+
agentId;
|
|
18
|
+
modelId;
|
|
19
|
+
actionTypes;
|
|
20
|
+
constructor(client, agentId, options) {
|
|
21
|
+
this.client = client;
|
|
22
|
+
this.agentId = agentId;
|
|
23
|
+
this.modelId = options?.modelId;
|
|
24
|
+
this.actionTypes = {
|
|
25
|
+
tool_end: "tool_call",
|
|
26
|
+
chain_end: "chain_completed",
|
|
27
|
+
llm_end: "llm_completion",
|
|
28
|
+
...(options?.actionTypes ?? {}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
notarize(actionType, details) {
|
|
32
|
+
try {
|
|
33
|
+
const params = {
|
|
34
|
+
actionType,
|
|
35
|
+
details: details.slice(0, MAX_DETAILS),
|
|
36
|
+
agentId: this.agentId,
|
|
37
|
+
};
|
|
38
|
+
if (this.modelId)
|
|
39
|
+
params.modelId = this.modelId;
|
|
40
|
+
this.client.notarize(params).catch((e) => {
|
|
41
|
+
console.warn("Aira notarize failed (non-blocking):", e);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
console.warn("Aira notarize failed (non-blocking):", e);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Called when a tool finishes. */
|
|
49
|
+
handleToolEnd(output, name = "unknown") {
|
|
50
|
+
this.notarize(this.actionTypes.tool_end, `Tool '${name}' completed. Output length: ${String(output).length} chars`);
|
|
51
|
+
}
|
|
52
|
+
/** Called when a chain finishes. */
|
|
53
|
+
handleChainEnd(outputs) {
|
|
54
|
+
const keys = typeof outputs === "object" && outputs ? Object.keys(outputs) : [];
|
|
55
|
+
this.notarize(this.actionTypes.chain_end, `Chain completed. Output keys: [${keys.join(", ")}]`);
|
|
56
|
+
}
|
|
57
|
+
/** Called when an LLM finishes. */
|
|
58
|
+
handleLLMEnd(generationCount) {
|
|
59
|
+
this.notarize(this.actionTypes.llm_end, `LLM completed. Generations: ${generationCount}`);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns a LangChain-compatible callbacks object.
|
|
63
|
+
* Use with: chain.invoke(input, { callbacks: [handler.asCallbacks()] })
|
|
64
|
+
*/
|
|
65
|
+
asCallbacks() {
|
|
66
|
+
return {
|
|
67
|
+
handleToolEnd: (output, ...args) => {
|
|
68
|
+
const runId = args[1];
|
|
69
|
+
const name = args[2]?.name ?? "unknown";
|
|
70
|
+
this.handleToolEnd(String(output), name);
|
|
71
|
+
},
|
|
72
|
+
handleChainEnd: (outputs) => {
|
|
73
|
+
this.handleChainEnd((outputs ?? {}));
|
|
74
|
+
},
|
|
75
|
+
handleLLMEnd: (response) => {
|
|
76
|
+
const resp = response;
|
|
77
|
+
this.handleLLMEnd(resp?.generations?.length ?? 0);
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.AiraCallbackHandler = AiraCallbackHandler;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server exposing Aira actions as tools for AI agents.
|
|
3
|
+
*
|
|
4
|
+
* Requires: @modelcontextprotocol/sdk (peer dependency)
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { createServer } from "aira-sdk/extras/mcp";
|
|
8
|
+
* const server = createServer({ apiKey: "aira_live_xxx" });
|
|
9
|
+
*/
|
|
10
|
+
import type { Aira } from "../client";
|
|
11
|
+
/** Tool definition for MCP list_tools response. */
|
|
12
|
+
export interface MCPTool {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
inputSchema: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/** Text content for MCP call_tool response. */
|
|
18
|
+
export interface MCPTextContent {
|
|
19
|
+
type: "text";
|
|
20
|
+
text: string;
|
|
21
|
+
}
|
|
22
|
+
/** MCP tool definitions exposed by the Aira server. */
|
|
23
|
+
export declare function getTools(): MCPTool[];
|
|
24
|
+
/** Handle an MCP tool call and return text content. */
|
|
25
|
+
export declare function handleToolCall(client: Aira, name: string, args: Record<string, unknown>): Promise<MCPTextContent[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Create an MCP-compatible server handler object.
|
|
28
|
+
*
|
|
29
|
+
* This returns plain objects; wire it into @modelcontextprotocol/sdk's Server:
|
|
30
|
+
*
|
|
31
|
+
* import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
32
|
+
* import { createServer } from "aira-sdk/extras/mcp";
|
|
33
|
+
* const { listTools, callTool } = createServer(airaClient);
|
|
34
|
+
* server.setRequestHandler(ListToolsRequestSchema, listTools);
|
|
35
|
+
* server.setRequestHandler(CallToolRequestSchema, callTool);
|
|
36
|
+
*/
|
|
37
|
+
export declare function createServer(client: Aira): {
|
|
38
|
+
listTools: () => Promise<{
|
|
39
|
+
tools: MCPTool[];
|
|
40
|
+
}>;
|
|
41
|
+
callTool: (request: {
|
|
42
|
+
params: {
|
|
43
|
+
name: string;
|
|
44
|
+
arguments?: Record<string, unknown>;
|
|
45
|
+
};
|
|
46
|
+
}) => Promise<{
|
|
47
|
+
content: MCPTextContent[];
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MCP server exposing Aira actions as tools for AI agents.
|
|
4
|
+
*
|
|
5
|
+
* Requires: @modelcontextprotocol/sdk (peer dependency)
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { createServer } from "aira-sdk/extras/mcp";
|
|
9
|
+
* const server = createServer({ apiKey: "aira_live_xxx" });
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.getTools = getTools;
|
|
13
|
+
exports.handleToolCall = handleToolCall;
|
|
14
|
+
exports.createServer = createServer;
|
|
15
|
+
/** MCP tool definitions exposed by the Aira server. */
|
|
16
|
+
function getTools() {
|
|
17
|
+
return [
|
|
18
|
+
{
|
|
19
|
+
name: "notarize_action",
|
|
20
|
+
description: "Notarize an AI agent action with a cryptographic receipt",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
action_type: { type: "string", description: "e.g. email_sent, loan_approved, claim_processed" },
|
|
25
|
+
details: { type: "string", description: "What happened" },
|
|
26
|
+
agent_id: { type: "string", description: "Agent slug" },
|
|
27
|
+
model_id: { type: "string", description: "Model used (optional)" },
|
|
28
|
+
},
|
|
29
|
+
required: ["action_type", "details"],
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "verify_action",
|
|
34
|
+
description: "Verify a notarized action's cryptographic receipt",
|
|
35
|
+
inputSchema: {
|
|
36
|
+
type: "object",
|
|
37
|
+
properties: {
|
|
38
|
+
action_id: { type: "string", description: "Action UUID" },
|
|
39
|
+
},
|
|
40
|
+
required: ["action_id"],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "get_receipt",
|
|
45
|
+
description: "Get the cryptographic receipt for a notarized action",
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
receipt_id: { type: "string", description: "Receipt UUID" },
|
|
50
|
+
},
|
|
51
|
+
required: ["receipt_id"],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
/** Handle an MCP tool call and return text content. */
|
|
57
|
+
async function handleToolCall(client, name, args) {
|
|
58
|
+
try {
|
|
59
|
+
if (name === "notarize_action") {
|
|
60
|
+
const result = await client.notarize({
|
|
61
|
+
actionType: args.action_type,
|
|
62
|
+
details: args.details,
|
|
63
|
+
agentId: args.agent_id,
|
|
64
|
+
modelId: args.model_id,
|
|
65
|
+
});
|
|
66
|
+
return [{ type: "text", text: JSON.stringify(result) }];
|
|
67
|
+
}
|
|
68
|
+
if (name === "verify_action") {
|
|
69
|
+
const result = await client.verifyAction(args.action_id);
|
|
70
|
+
return [{ type: "text", text: JSON.stringify(result) }];
|
|
71
|
+
}
|
|
72
|
+
if (name === "get_receipt") {
|
|
73
|
+
const result = await client.getReceipt(args.receipt_id);
|
|
74
|
+
return [{ type: "text", text: JSON.stringify(result) }];
|
|
75
|
+
}
|
|
76
|
+
return [{ type: "text", text: JSON.stringify({ error: `Unknown tool: ${name}` }) }];
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
return [{ type: "text", text: JSON.stringify({ error: String(e) }) }];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create an MCP-compatible server handler object.
|
|
84
|
+
*
|
|
85
|
+
* This returns plain objects; wire it into @modelcontextprotocol/sdk's Server:
|
|
86
|
+
*
|
|
87
|
+
* import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
88
|
+
* import { createServer } from "aira-sdk/extras/mcp";
|
|
89
|
+
* const { listTools, callTool } = createServer(airaClient);
|
|
90
|
+
* server.setRequestHandler(ListToolsRequestSchema, listTools);
|
|
91
|
+
* server.setRequestHandler(CallToolRequestSchema, callTool);
|
|
92
|
+
*/
|
|
93
|
+
function createServer(client) {
|
|
94
|
+
return {
|
|
95
|
+
listTools: async () => ({ tools: getTools() }),
|
|
96
|
+
callTool: async (request) => {
|
|
97
|
+
const content = await handleToolCall(client, request.params.name, request.params.arguments ?? {});
|
|
98
|
+
return { content };
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Node SDK integration — guardrail that notarizes tool calls.
|
|
3
|
+
*
|
|
4
|
+
* Requires: openai (peer dependency)
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { AiraGuardrail } from "aira-sdk/extras/openai-agents";
|
|
8
|
+
* const guardrail = new AiraGuardrail(aira, "my-agent");
|
|
9
|
+
* guardrail.onToolCall("search", { query: "test" });
|
|
10
|
+
*/
|
|
11
|
+
import type { Aira } from "../client";
|
|
12
|
+
export declare class AiraGuardrail {
|
|
13
|
+
private client;
|
|
14
|
+
private agentId;
|
|
15
|
+
private modelId?;
|
|
16
|
+
constructor(client: Aira, agentId: string, options?: {
|
|
17
|
+
modelId?: string;
|
|
18
|
+
});
|
|
19
|
+
private notarize;
|
|
20
|
+
/** Call after a tool execution to notarize it. */
|
|
21
|
+
onToolCall(toolName: string, args?: Record<string, unknown>): void;
|
|
22
|
+
/** Call after a tool returns to notarize the result. */
|
|
23
|
+
onToolResult(toolName: string, result?: unknown): void;
|
|
24
|
+
/**
|
|
25
|
+
* Wraps a tool function to auto-notarize calls and results.
|
|
26
|
+
* No raw user data is sent — only tool name, arg keys, and output length.
|
|
27
|
+
*/
|
|
28
|
+
wrapTool<T extends (...args: unknown[]) => unknown>(toolFn: T, toolName?: string): T;
|
|
29
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OpenAI Node SDK integration — guardrail that notarizes tool calls.
|
|
4
|
+
*
|
|
5
|
+
* Requires: openai (peer dependency)
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { AiraGuardrail } from "aira-sdk/extras/openai-agents";
|
|
9
|
+
* const guardrail = new AiraGuardrail(aira, "my-agent");
|
|
10
|
+
* guardrail.onToolCall("search", { query: "test" });
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AiraGuardrail = void 0;
|
|
14
|
+
const MAX_DETAILS = 5000;
|
|
15
|
+
class AiraGuardrail {
|
|
16
|
+
client;
|
|
17
|
+
agentId;
|
|
18
|
+
modelId;
|
|
19
|
+
constructor(client, agentId, options) {
|
|
20
|
+
this.client = client;
|
|
21
|
+
this.agentId = agentId;
|
|
22
|
+
this.modelId = options?.modelId;
|
|
23
|
+
}
|
|
24
|
+
notarize(actionType, details) {
|
|
25
|
+
try {
|
|
26
|
+
const params = {
|
|
27
|
+
actionType,
|
|
28
|
+
details: details.slice(0, MAX_DETAILS),
|
|
29
|
+
agentId: this.agentId,
|
|
30
|
+
};
|
|
31
|
+
if (this.modelId)
|
|
32
|
+
params.modelId = this.modelId;
|
|
33
|
+
this.client.notarize(params).catch((e) => {
|
|
34
|
+
console.warn("Aira notarize failed (non-blocking):", e);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.warn("Aira notarize failed (non-blocking):", e);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Call after a tool execution to notarize it. */
|
|
42
|
+
onToolCall(toolName, args) {
|
|
43
|
+
const argKeys = Object.keys(args ?? {});
|
|
44
|
+
this.notarize("tool_call", `Tool '${toolName}' called. Arg keys: [${argKeys.join(", ")}]`);
|
|
45
|
+
}
|
|
46
|
+
/** Call after a tool returns to notarize the result. */
|
|
47
|
+
onToolResult(toolName, result) {
|
|
48
|
+
this.notarize("tool_completed", `Tool '${toolName}' completed. Result length: ${String(result).length} chars`);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wraps a tool function to auto-notarize calls and results.
|
|
52
|
+
* No raw user data is sent — only tool name, arg keys, and output length.
|
|
53
|
+
*/
|
|
54
|
+
wrapTool(toolFn, toolName) {
|
|
55
|
+
const name = toolName ?? toolFn.name ?? "unknown";
|
|
56
|
+
const self = this;
|
|
57
|
+
const wrapped = async function (...args) {
|
|
58
|
+
const kwargs = args.length > 0 && typeof args[0] === "object" && args[0]
|
|
59
|
+
? args[0]
|
|
60
|
+
: undefined;
|
|
61
|
+
self.onToolCall(name, kwargs);
|
|
62
|
+
const result = await toolFn.apply(this, args);
|
|
63
|
+
self.onToolResult(name, result);
|
|
64
|
+
return result;
|
|
65
|
+
};
|
|
66
|
+
return wrapped;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.AiraGuardrail = AiraGuardrail;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel AI SDK integration — middleware that notarizes tool calls and completions.
|
|
3
|
+
*
|
|
4
|
+
* Requires: ai (Vercel AI SDK, peer dependency)
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { AiraVercelMiddleware } from "aira-sdk/extras/vercel-ai";
|
|
8
|
+
* const middleware = new AiraVercelMiddleware(aira, "my-agent");
|
|
9
|
+
* // Use as wrap around tool calls or stream callbacks
|
|
10
|
+
*/
|
|
11
|
+
import type { Aira } from "../client";
|
|
12
|
+
export declare class AiraVercelMiddleware {
|
|
13
|
+
private client;
|
|
14
|
+
private agentId;
|
|
15
|
+
private modelId?;
|
|
16
|
+
constructor(client: Aira, agentId: string, options?: {
|
|
17
|
+
modelId?: string;
|
|
18
|
+
});
|
|
19
|
+
private notarize;
|
|
20
|
+
/** Call after a tool execution to notarize it. */
|
|
21
|
+
onToolCall(toolName: string, argKeys?: string[]): void;
|
|
22
|
+
/** Call after a tool returns to notarize the result. */
|
|
23
|
+
onToolResult(toolName: string, resultLength: number): void;
|
|
24
|
+
/** Call when a text generation step completes. */
|
|
25
|
+
onStepFinish(stepType: string, tokenCount?: number): void;
|
|
26
|
+
/** Call when the full generation completes. */
|
|
27
|
+
onFinish(finishReason: string, totalTokens?: number): void;
|
|
28
|
+
/**
|
|
29
|
+
* Returns a Vercel AI SDK-compatible callbacks object for streamText/generateText.
|
|
30
|
+
*
|
|
31
|
+
* Usage:
|
|
32
|
+
* const result = await streamText({ ...opts, ...middleware.asCallbacks() });
|
|
33
|
+
*/
|
|
34
|
+
asCallbacks(): Record<string, (...args: unknown[]) => void>;
|
|
35
|
+
/**
|
|
36
|
+
* Wraps a tool's execute function to auto-notarize calls and results.
|
|
37
|
+
*/
|
|
38
|
+
wrapTool<T extends (...args: unknown[]) => unknown>(toolFn: T, toolName: string): T;
|
|
39
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Vercel AI SDK integration — middleware that notarizes tool calls and completions.
|
|
4
|
+
*
|
|
5
|
+
* Requires: ai (Vercel AI SDK, peer dependency)
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { AiraVercelMiddleware } from "aira-sdk/extras/vercel-ai";
|
|
9
|
+
* const middleware = new AiraVercelMiddleware(aira, "my-agent");
|
|
10
|
+
* // Use as wrap around tool calls or stream callbacks
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.AiraVercelMiddleware = void 0;
|
|
14
|
+
const MAX_DETAILS = 5000;
|
|
15
|
+
class AiraVercelMiddleware {
|
|
16
|
+
client;
|
|
17
|
+
agentId;
|
|
18
|
+
modelId;
|
|
19
|
+
constructor(client, agentId, options) {
|
|
20
|
+
this.client = client;
|
|
21
|
+
this.agentId = agentId;
|
|
22
|
+
this.modelId = options?.modelId;
|
|
23
|
+
}
|
|
24
|
+
notarize(actionType, details) {
|
|
25
|
+
try {
|
|
26
|
+
const params = {
|
|
27
|
+
actionType,
|
|
28
|
+
details: details.slice(0, MAX_DETAILS),
|
|
29
|
+
agentId: this.agentId,
|
|
30
|
+
};
|
|
31
|
+
if (this.modelId)
|
|
32
|
+
params.modelId = this.modelId;
|
|
33
|
+
this.client.notarize(params).catch((e) => {
|
|
34
|
+
console.warn("Aira notarize failed (non-blocking):", e);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
console.warn("Aira notarize failed (non-blocking):", e);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Call after a tool execution to notarize it. */
|
|
42
|
+
onToolCall(toolName, argKeys = []) {
|
|
43
|
+
this.notarize("tool_call", `Tool '${toolName}' called. Arg keys: [${argKeys.join(", ")}]`);
|
|
44
|
+
}
|
|
45
|
+
/** Call after a tool returns to notarize the result. */
|
|
46
|
+
onToolResult(toolName, resultLength) {
|
|
47
|
+
this.notarize("tool_completed", `Tool '${toolName}' completed. Result length: ${resultLength} chars`);
|
|
48
|
+
}
|
|
49
|
+
/** Call when a text generation step completes. */
|
|
50
|
+
onStepFinish(stepType, tokenCount) {
|
|
51
|
+
this.notarize("step_completed", `Step '${stepType}' completed.${tokenCount != null ? ` Tokens: ${tokenCount}` : ""}`);
|
|
52
|
+
}
|
|
53
|
+
/** Call when the full generation completes. */
|
|
54
|
+
onFinish(finishReason, totalTokens) {
|
|
55
|
+
this.notarize("generation_completed", `Generation completed. Reason: ${finishReason}.${totalTokens != null ? ` Total tokens: ${totalTokens}` : ""}`);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns a Vercel AI SDK-compatible callbacks object for streamText/generateText.
|
|
59
|
+
*
|
|
60
|
+
* Usage:
|
|
61
|
+
* const result = await streamText({ ...opts, ...middleware.asCallbacks() });
|
|
62
|
+
*/
|
|
63
|
+
asCallbacks() {
|
|
64
|
+
return {
|
|
65
|
+
onStepFinish: (step) => {
|
|
66
|
+
const s = step;
|
|
67
|
+
this.onStepFinish(s?.stepType ?? "unknown", s?.usage?.totalTokens);
|
|
68
|
+
},
|
|
69
|
+
onFinish: (result) => {
|
|
70
|
+
const r = result;
|
|
71
|
+
this.onFinish(r?.finishReason ?? "unknown", r?.usage?.totalTokens);
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Wraps a tool's execute function to auto-notarize calls and results.
|
|
77
|
+
*/
|
|
78
|
+
wrapTool(toolFn, toolName) {
|
|
79
|
+
const self = this;
|
|
80
|
+
const wrapped = async function (...args) {
|
|
81
|
+
self.onToolCall(toolName, args.length > 0 && typeof args[0] === "object" && args[0] ? Object.keys(args[0]) : []);
|
|
82
|
+
const result = await toolFn.apply(this, args);
|
|
83
|
+
self.onToolResult(toolName, String(result).length);
|
|
84
|
+
return result;
|
|
85
|
+
};
|
|
86
|
+
return wrapped;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.AiraVercelMiddleware = AiraVercelMiddleware;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook signature verification and event parsing for Aira webhooks.
|
|
3
|
+
*/
|
|
4
|
+
/** Known Aira webhook event types. */
|
|
5
|
+
export declare const WebhookEventType: {
|
|
6
|
+
readonly CASE_COMPLETE: "case.complete";
|
|
7
|
+
readonly CASE_REQUIRES_REVIEW: "case.requires_human_review";
|
|
8
|
+
readonly ACTION_NOTARIZED: "action.notarized";
|
|
9
|
+
readonly ACTION_AUTHORIZED: "action.authorized";
|
|
10
|
+
readonly AGENT_REGISTERED: "agent.registered";
|
|
11
|
+
readonly AGENT_DECOMMISSIONED: "agent.decommissioned";
|
|
12
|
+
readonly EVIDENCE_SEALED: "evidence.sealed";
|
|
13
|
+
readonly ESCROW_DEPOSITED: "escrow.deposited";
|
|
14
|
+
readonly ESCROW_RELEASED: "escrow.released";
|
|
15
|
+
readonly ESCROW_DISPUTED: "escrow.disputed";
|
|
16
|
+
readonly COMPLIANCE_SNAPSHOT: "compliance.snapshot_created";
|
|
17
|
+
};
|
|
18
|
+
export type WebhookEventTypeName = (typeof WebhookEventType)[keyof typeof WebhookEventType];
|
|
19
|
+
/** Parsed webhook event. */
|
|
20
|
+
export interface WebhookEvent {
|
|
21
|
+
eventType: string;
|
|
22
|
+
data: Record<string, unknown>;
|
|
23
|
+
timestamp?: string;
|
|
24
|
+
deliveryId?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Verify webhook signature.
|
|
28
|
+
* Signature format: sha256={hex_digest}
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifySignature(payload: Buffer | string, signature: string, secret: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Parse raw webhook payload into a WebhookEvent.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseEvent(payload: Buffer | string): WebhookEvent;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Webhook signature verification and event parsing for Aira webhooks.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WebhookEventType = void 0;
|
|
7
|
+
exports.verifySignature = verifySignature;
|
|
8
|
+
exports.parseEvent = parseEvent;
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
/** Known Aira webhook event types. */
|
|
11
|
+
exports.WebhookEventType = {
|
|
12
|
+
CASE_COMPLETE: "case.complete",
|
|
13
|
+
CASE_REQUIRES_REVIEW: "case.requires_human_review",
|
|
14
|
+
ACTION_NOTARIZED: "action.notarized",
|
|
15
|
+
ACTION_AUTHORIZED: "action.authorized",
|
|
16
|
+
AGENT_REGISTERED: "agent.registered",
|
|
17
|
+
AGENT_DECOMMISSIONED: "agent.decommissioned",
|
|
18
|
+
EVIDENCE_SEALED: "evidence.sealed",
|
|
19
|
+
ESCROW_DEPOSITED: "escrow.deposited",
|
|
20
|
+
ESCROW_RELEASED: "escrow.released",
|
|
21
|
+
ESCROW_DISPUTED: "escrow.disputed",
|
|
22
|
+
COMPLIANCE_SNAPSHOT: "compliance.snapshot_created",
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Verify webhook signature.
|
|
26
|
+
* Signature format: sha256={hex_digest}
|
|
27
|
+
*/
|
|
28
|
+
function verifySignature(payload, signature, secret) {
|
|
29
|
+
if (!signature.startsWith("sha256="))
|
|
30
|
+
return false;
|
|
31
|
+
const payloadBuf = typeof payload === "string" ? Buffer.from(payload, "utf-8") : payload;
|
|
32
|
+
const expected = (0, crypto_1.createHmac)("sha256", secret).update(payloadBuf).digest("hex");
|
|
33
|
+
const expectedSig = `sha256=${expected}`;
|
|
34
|
+
// Constant-time comparison
|
|
35
|
+
try {
|
|
36
|
+
return (0, crypto_1.timingSafeEqual)(Buffer.from(signature, "utf-8"), Buffer.from(expectedSig, "utf-8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse raw webhook payload into a WebhookEvent.
|
|
44
|
+
*/
|
|
45
|
+
function parseEvent(payload) {
|
|
46
|
+
let data;
|
|
47
|
+
try {
|
|
48
|
+
data = JSON.parse(typeof payload === "string" ? payload : payload.toString("utf-8"));
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
throw new Error(`Invalid webhook payload: ${e}`);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
eventType: data.event ?? "unknown",
|
|
55
|
+
data: data.data ?? data,
|
|
56
|
+
timestamp: data.timestamp,
|
|
57
|
+
deliveryId: data.delivery_id,
|
|
58
|
+
};
|
|
59
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export { Aira } from "./client";
|
|
2
2
|
export type { AiraOptions } from "./client";
|
|
3
|
+
export { AiraSession } from "./session";
|
|
4
|
+
export { OfflineQueue } from "./offline";
|
|
5
|
+
export type { QueuedRequest } from "./offline";
|
|
3
6
|
export { AiraError, type ActionReceipt, type ActionDetail, type AgentDetail, type AgentVersion, type EvidencePackage, type ComplianceSnapshot, type EscrowAccount, type EscrowTransaction, type VerifyResult, type PaginatedList, } from "./types";
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AiraError = exports.Aira = void 0;
|
|
3
|
+
exports.AiraError = exports.OfflineQueue = exports.AiraSession = exports.Aira = void 0;
|
|
4
4
|
var client_1 = require("./client");
|
|
5
5
|
Object.defineProperty(exports, "Aira", { enumerable: true, get: function () { return client_1.Aira; } });
|
|
6
|
+
var session_1 = require("./session");
|
|
7
|
+
Object.defineProperty(exports, "AiraSession", { enumerable: true, get: function () { return session_1.AiraSession; } });
|
|
8
|
+
var offline_1 = require("./offline");
|
|
9
|
+
Object.defineProperty(exports, "OfflineQueue", { enumerable: true, get: function () { return offline_1.OfflineQueue; } });
|
|
6
10
|
var types_1 = require("./types");
|
|
7
11
|
Object.defineProperty(exports, "AiraError", { enumerable: true, get: function () { return types_1.AiraError; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Offline queue for Aira SDK — queues actions locally, syncs later.
|
|
3
|
+
*/
|
|
4
|
+
export interface QueuedRequest {
|
|
5
|
+
id: string;
|
|
6
|
+
method: string;
|
|
7
|
+
path: string;
|
|
8
|
+
body: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare class OfflineQueue {
|
|
11
|
+
private items;
|
|
12
|
+
enqueue(method: string, path: string, body: Record<string, unknown>): string;
|
|
13
|
+
get pendingCount(): number;
|
|
14
|
+
clear(): void;
|
|
15
|
+
drain(): QueuedRequest[];
|
|
16
|
+
}
|
package/dist/offline.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Offline queue for Aira SDK — queues actions locally, syncs later.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.OfflineQueue = void 0;
|
|
7
|
+
const crypto_1 = require("crypto");
|
|
8
|
+
class OfflineQueue {
|
|
9
|
+
items = [];
|
|
10
|
+
enqueue(method, path, body) {
|
|
11
|
+
const id = `offline_${(0, crypto_1.randomUUID)().replace(/-/g, "").slice(0, 12)}`;
|
|
12
|
+
this.items.push({ id, method, path, body });
|
|
13
|
+
return id;
|
|
14
|
+
}
|
|
15
|
+
get pendingCount() {
|
|
16
|
+
return this.items.length;
|
|
17
|
+
}
|
|
18
|
+
clear() {
|
|
19
|
+
this.items = [];
|
|
20
|
+
}
|
|
21
|
+
drain() {
|
|
22
|
+
const drained = [...this.items];
|
|
23
|
+
this.items = [];
|
|
24
|
+
return drained;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.OfflineQueue = OfflineQueue;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AiraSession — scoped session with pre-filled defaults.
|
|
3
|
+
*/
|
|
4
|
+
import type { Aira } from "./client";
|
|
5
|
+
import type { ActionReceipt } from "./types";
|
|
6
|
+
export declare class AiraSession {
|
|
7
|
+
private client;
|
|
8
|
+
private defaults;
|
|
9
|
+
constructor(client: Aira, agentId: string, defaults?: Record<string, unknown>);
|
|
10
|
+
notarize(params: {
|
|
11
|
+
actionType: string;
|
|
12
|
+
details: string;
|
|
13
|
+
modelId?: string;
|
|
14
|
+
modelVersion?: string;
|
|
15
|
+
instructionHash?: string;
|
|
16
|
+
parentActionId?: string;
|
|
17
|
+
storeDetails?: boolean;
|
|
18
|
+
idempotencyKey?: string;
|
|
19
|
+
}): Promise<ActionReceipt>;
|
|
20
|
+
}
|
package/dist/session.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AiraSession — scoped session with pre-filled defaults.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.AiraSession = void 0;
|
|
7
|
+
class AiraSession {
|
|
8
|
+
client;
|
|
9
|
+
defaults;
|
|
10
|
+
constructor(client, agentId, defaults) {
|
|
11
|
+
this.client = client;
|
|
12
|
+
this.defaults = { agentId, ...(defaults ?? {}) };
|
|
13
|
+
}
|
|
14
|
+
async notarize(params) {
|
|
15
|
+
const merged = {
|
|
16
|
+
agentId: this.defaults.agentId,
|
|
17
|
+
...(this.defaults.modelId ? { modelId: this.defaults.modelId } : {}),
|
|
18
|
+
...(this.defaults.agentVersion ? { agentVersion: this.defaults.agentVersion } : {}),
|
|
19
|
+
...params,
|
|
20
|
+
};
|
|
21
|
+
return this.client.notarize(merged);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.AiraSession = AiraSession;
|