@contractspec/lib.ai-agent 1.44.0
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 +49 -0
- package/dist/agent/agent-factory.d.ts +104 -0
- package/dist/agent/agent-factory.d.ts.map +1 -0
- package/dist/agent/agent-factory.js +103 -0
- package/dist/agent/agent-factory.js.map +1 -0
- package/dist/agent/contract-spec-agent.d.ts +75 -0
- package/dist/agent/contract-spec-agent.d.ts.map +1 -0
- package/dist/agent/contract-spec-agent.js +148 -0
- package/dist/agent/contract-spec-agent.js.map +1 -0
- package/dist/agent/index.d.ts +3 -0
- package/dist/agent/index.js +4 -0
- package/dist/approval/index.d.ts +2 -0
- package/dist/approval/index.js +3 -0
- package/dist/approval/workflow.d.ts +156 -0
- package/dist/approval/workflow.d.ts.map +1 -0
- package/dist/approval/workflow.js +160 -0
- package/dist/approval/workflow.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +21 -0
- package/dist/knowledge/index.d.ts +2 -0
- package/dist/knowledge/index.js +3 -0
- package/dist/knowledge/injector.d.ts +38 -0
- package/dist/knowledge/injector.d.ts.map +1 -0
- package/dist/knowledge/injector.js +58 -0
- package/dist/knowledge/injector.js.map +1 -0
- package/dist/memory/in-memory.d.ts +22 -0
- package/dist/memory/in-memory.d.ts.map +1 -0
- package/dist/memory/in-memory.js +48 -0
- package/dist/memory/in-memory.js.map +1 -0
- package/dist/memory/index.d.ts +3 -0
- package/dist/memory/index.js +4 -0
- package/dist/memory/manager.d.ts +42 -0
- package/dist/memory/manager.d.ts.map +1 -0
- package/dist/memory/manager.js +80 -0
- package/dist/memory/manager.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.js +4 -0
- package/dist/schema/json-schema-to-zod.d.ts +55 -0
- package/dist/schema/json-schema-to-zod.d.ts.map +1 -0
- package/dist/schema/json-schema-to-zod.js +124 -0
- package/dist/schema/json-schema-to-zod.js.map +1 -0
- package/dist/schema/schema-output.d.ts +77 -0
- package/dist/schema/schema-output.d.ts.map +1 -0
- package/dist/schema/schema-output.js +65 -0
- package/dist/schema/schema-output.js.map +1 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +3 -0
- package/dist/session/store.d.ts +74 -0
- package/dist/session/store.d.ts.map +1 -0
- package/dist/session/store.js +79 -0
- package/dist/session/store.js.map +1 -0
- package/dist/spec/index.d.ts +3 -0
- package/dist/spec/index.js +4 -0
- package/dist/spec/registry.d.ts +78 -0
- package/dist/spec/registry.d.ts.map +1 -0
- package/dist/spec/registry.js +117 -0
- package/dist/spec/registry.js.map +1 -0
- package/dist/spec/spec.d.ts +127 -0
- package/dist/spec/spec.d.ts.map +1 -0
- package/dist/spec/spec.js +30 -0
- package/dist/spec/spec.js.map +1 -0
- package/dist/telemetry/adapter.d.ts +73 -0
- package/dist/telemetry/adapter.d.ts.map +1 -0
- package/dist/telemetry/adapter.js +103 -0
- package/dist/telemetry/adapter.js.map +1 -0
- package/dist/telemetry/index.d.ts +2 -0
- package/dist/telemetry/index.js +3 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.js +6 -0
- package/dist/tools/knowledge-tool.d.ts +21 -0
- package/dist/tools/knowledge-tool.d.ts.map +1 -0
- package/dist/tools/knowledge-tool.js +54 -0
- package/dist/tools/knowledge-tool.js.map +1 -0
- package/dist/tools/mcp-client.d.ts +59 -0
- package/dist/tools/mcp-client.d.ts.map +1 -0
- package/dist/tools/mcp-client.js +58 -0
- package/dist/tools/mcp-client.js.map +1 -0
- package/dist/tools/mcp-server.d.ts +46 -0
- package/dist/tools/mcp-server.d.ts.map +1 -0
- package/dist/tools/mcp-server.js +69 -0
- package/dist/tools/mcp-server.js.map +1 -0
- package/dist/tools/tool-adapter.d.ts +50 -0
- package/dist/tools/tool-adapter.d.ts.map +1 -0
- package/dist/tools/tool-adapter.js +80 -0
- package/dist/tools/tool-adapter.js.map +1 -0
- package/dist/types.d.ts +146 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +0 -0
- package/package.json +114 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { ToolCallInfo } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/approval/workflow.d.ts
|
|
4
|
+
type ApprovalStatus = 'pending' | 'approved' | 'rejected';
|
|
5
|
+
/**
|
|
6
|
+
* Approval request for a tool execution.
|
|
7
|
+
*
|
|
8
|
+
* When a tool has `needsApproval: true` in AI SDK v6, the agent
|
|
9
|
+
* will pause and wait for approval before executing the tool.
|
|
10
|
+
*/
|
|
11
|
+
interface ApprovalRequest {
|
|
12
|
+
/** Unique request ID */
|
|
13
|
+
id: string;
|
|
14
|
+
/** Agent session ID */
|
|
15
|
+
sessionId: string;
|
|
16
|
+
/** Agent ID */
|
|
17
|
+
agentId: string;
|
|
18
|
+
/** Tenant ID for scoping */
|
|
19
|
+
tenantId?: string;
|
|
20
|
+
/** Tool name requiring approval */
|
|
21
|
+
toolName: string;
|
|
22
|
+
/** Tool call ID from AI SDK */
|
|
23
|
+
toolCallId: string;
|
|
24
|
+
/** Tool arguments */
|
|
25
|
+
toolArgs: unknown;
|
|
26
|
+
/** Human-readable reason for approval */
|
|
27
|
+
reason: string;
|
|
28
|
+
/** When the approval was requested */
|
|
29
|
+
requestedAt: Date;
|
|
30
|
+
/** Current status */
|
|
31
|
+
status: ApprovalStatus;
|
|
32
|
+
/** Additional context payload */
|
|
33
|
+
payload?: Record<string, unknown>;
|
|
34
|
+
/** Who resolved the approval */
|
|
35
|
+
reviewer?: string;
|
|
36
|
+
/** When the approval was resolved */
|
|
37
|
+
resolvedAt?: Date;
|
|
38
|
+
/** Reviewer notes */
|
|
39
|
+
notes?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Storage interface for approval requests.
|
|
43
|
+
*/
|
|
44
|
+
interface ApprovalStore {
|
|
45
|
+
create(request: ApprovalRequest): Promise<void>;
|
|
46
|
+
get(id: string): Promise<ApprovalRequest | null>;
|
|
47
|
+
getByToolCallId(toolCallId: string): Promise<ApprovalRequest | null>;
|
|
48
|
+
update(id: string, updates: Partial<Omit<ApprovalRequest, 'id' | 'sessionId'>>): Promise<void>;
|
|
49
|
+
list(options?: {
|
|
50
|
+
status?: ApprovalStatus;
|
|
51
|
+
agentId?: string;
|
|
52
|
+
tenantId?: string;
|
|
53
|
+
}): Promise<ApprovalRequest[]>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* In-memory approval store for development and testing.
|
|
57
|
+
*/
|
|
58
|
+
declare class InMemoryApprovalStore implements ApprovalStore {
|
|
59
|
+
private readonly items;
|
|
60
|
+
create(request: ApprovalRequest): Promise<void>;
|
|
61
|
+
get(id: string): Promise<ApprovalRequest | null>;
|
|
62
|
+
getByToolCallId(toolCallId: string): Promise<ApprovalRequest | null>;
|
|
63
|
+
update(id: string, updates: Partial<Omit<ApprovalRequest, 'id' | 'sessionId'>>): Promise<void>;
|
|
64
|
+
list(options?: {
|
|
65
|
+
status?: ApprovalStatus;
|
|
66
|
+
agentId?: string;
|
|
67
|
+
tenantId?: string;
|
|
68
|
+
}): Promise<ApprovalRequest[]>;
|
|
69
|
+
clear(): void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Approval workflow for managing tool execution approvals.
|
|
73
|
+
*
|
|
74
|
+
* Integrates with AI SDK v6's `needsApproval` feature on tools.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const workflow = new ApprovalWorkflow();
|
|
79
|
+
*
|
|
80
|
+
* // When a tool needs approval
|
|
81
|
+
* const request = await workflow.requestApproval({
|
|
82
|
+
* sessionId: 'sess_123',
|
|
83
|
+
* agentId: 'support.bot.v1',
|
|
84
|
+
* toolName: 'delete_account',
|
|
85
|
+
* toolCallId: 'call_abc',
|
|
86
|
+
* toolArgs: { userId: 'user_123' },
|
|
87
|
+
* reason: 'Account deletion requires human approval',
|
|
88
|
+
* });
|
|
89
|
+
*
|
|
90
|
+
* // When approval is granted
|
|
91
|
+
* await workflow.approve(request.id, 'admin@example.com', 'Verified identity');
|
|
92
|
+
*
|
|
93
|
+
* // Or rejected
|
|
94
|
+
* await workflow.reject(request.id, 'admin@example.com', 'Suspicious activity');
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare class ApprovalWorkflow {
|
|
98
|
+
private readonly store;
|
|
99
|
+
constructor(store?: ApprovalStore);
|
|
100
|
+
/**
|
|
101
|
+
* Request approval for a tool execution.
|
|
102
|
+
*/
|
|
103
|
+
requestApproval(params: {
|
|
104
|
+
sessionId: string;
|
|
105
|
+
agentId: string;
|
|
106
|
+
tenantId?: string;
|
|
107
|
+
toolName: string;
|
|
108
|
+
toolCallId: string;
|
|
109
|
+
toolArgs: unknown;
|
|
110
|
+
reason: string;
|
|
111
|
+
payload?: Record<string, unknown>;
|
|
112
|
+
}): Promise<ApprovalRequest>;
|
|
113
|
+
/**
|
|
114
|
+
* Request approval from an AI SDK tool call.
|
|
115
|
+
*/
|
|
116
|
+
requestApprovalFromToolCall(toolCall: ToolCallInfo, context: {
|
|
117
|
+
sessionId: string;
|
|
118
|
+
agentId: string;
|
|
119
|
+
tenantId?: string;
|
|
120
|
+
reason?: string;
|
|
121
|
+
}): Promise<ApprovalRequest>;
|
|
122
|
+
/**
|
|
123
|
+
* Approve a pending request.
|
|
124
|
+
*/
|
|
125
|
+
approve(id: string, reviewer: string, notes?: string): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Reject a pending request.
|
|
128
|
+
*/
|
|
129
|
+
reject(id: string, reviewer: string, notes?: string): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Get approval status for a tool call.
|
|
132
|
+
*/
|
|
133
|
+
getStatus(toolCallId: string): Promise<ApprovalStatus | null>;
|
|
134
|
+
/**
|
|
135
|
+
* Check if a tool call is approved.
|
|
136
|
+
*/
|
|
137
|
+
isApproved(toolCallId: string): Promise<boolean>;
|
|
138
|
+
/**
|
|
139
|
+
* List pending approvals.
|
|
140
|
+
*/
|
|
141
|
+
listPending(options?: {
|
|
142
|
+
agentId?: string;
|
|
143
|
+
tenantId?: string;
|
|
144
|
+
}): Promise<ApprovalRequest[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Get approval request by ID.
|
|
147
|
+
*/
|
|
148
|
+
get(id: string): Promise<ApprovalRequest | null>;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create an approval workflow instance.
|
|
152
|
+
*/
|
|
153
|
+
declare function createApprovalWorkflow(store?: ApprovalStore): ApprovalWorkflow;
|
|
154
|
+
//#endregion
|
|
155
|
+
export { ApprovalRequest, ApprovalStatus, ApprovalStore, ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow };
|
|
156
|
+
//# sourceMappingURL=workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.d.ts","names":[],"sources":["../../src/approval/workflow.ts"],"sourcesContent":[],"mappings":";;;KAGY,cAAA;;AAAZ;AAQA;;;;AA0Be,UA1BE,eAAA,CA0BF;EAAI;EAQF,EAAA,EAAA,MAAA;EACC;EAAkB,SAAA,EAAA,MAAA;EACT;EAAR,OAAA,EAAA,MAAA;EAC4B;EAAR,QAAA,CAAA,EAAA,MAAA;EAGb;EAAL,QAAA,EAAA,MAAA;EAAR;EACR,UAAA,EAAA,MAAA;EAEQ;EAGC,QAAA,EAAA,OAAA;EAAR;EAAO,MAAA,EAAA,MAAA;EAMA;EAGW,WAAA,EArCT,IAqCS;EAAkB;EAIT,MAAA,EAvCvB,cAuCuB;EAAR;EAI4B,OAAA,CAAA,EAzCzC,MAyCyC,CAAA,MAAA,EAAA,OAAA,CAAA;EAAR;EAWnB,QAAA,CAAA,EAAA,MAAA;EAAL;EAAR,UAAA,CAAA,EAhDE,IAgDF;EACR;EAQQ,KAAA,CAAA,EAAA,MAAA;;;;;AAoDA,UArGI,aAAA,CAqGY;EAED,MAAA,CAAA,OAAA,EAtGV,eAsGU,CAAA,EAtGQ,OAsGR,CAAA,IAAA,CAAA;EAcd,GAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EAnHK,OAmHL,CAnHa,eAmHb,GAAA,IAAA,CAAA;EACA,eAAA,CAAA,UAAA,EAAA,MAAA,CAAA,EAnHyB,OAmHzB,CAnHiC,eAmHjC,GAAA,IAAA,CAAA;EAAR,MAAA,CAAA,EAAA,EAAA,MAAA,EAAA,OAAA,EAhHO,OAgHP,CAhHe,IAgHf,CAhHoB,eAgHpB,EAAA,IAAA,GAAA,WAAA,CAAA,CAAA,CAAA,EA/GD,OA+GC,CAAA,IAAA,CAAA;EAuBQ,IAAA,CAAA,OAkCgD,CAlChD,EAAA;IAOD,MAAA,CAAA,EA3IA,cA2IA;IAAR,OAAA,CAAA,EAAA,MAAA;IAe0D,QAAA,CAAA,EAAA,MAAA;EAYD,CAAA,CAAA,EAnKxD,OAmKwD,CAnKhD,eAmKgD,EAAA,CAAA;;;;;AA+BxD,cA5LO,qBAAA,YAAiC,aA4LxC,CAAA;EAO2B,iBAAA,KAAA;EAAR,MAAA,CAAA,OAAA,EAhMD,eAgMC,CAAA,EAhMiB,OAgMjB,CAAA,IAAA,CAAA;EAAO,GAAA,CAAA,EAAA,EAAA,MAAA,CAAA,EA5LP,OA4LO,CA5LC,eA4LD,GAAA,IAAA,CAAA;EAQhB,eAAA,CAAA,UAAsB,EAAA,MAAA,CAAA,EAhMO,OAiMnC,CAjM2C,eAkMlD,GAAA,IAAA,CAAA;8BAvLU,QAAQ,KAAK,wCACrB;;aAQQ;;;MAGP,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAiDD,gBAAA;;sBAEe;;;;;;;;;;;;cAcd;MACR,QAAQ;;;;wCAuBA;;;;;MAOT,QAAQ;;;;yDAekD;;;;wDAYD;;;;iCAYvB,QAAQ;;;;kCAQP;;;;;;;MAWlC,QAAQ;;;;mBAOW,QAAQ;;;;;iBAQjB,sBAAA,SACN,gBACP"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
//#region src/approval/workflow.ts
|
|
4
|
+
/**
|
|
5
|
+
* In-memory approval store for development and testing.
|
|
6
|
+
*/
|
|
7
|
+
var InMemoryApprovalStore = class {
|
|
8
|
+
items = /* @__PURE__ */ new Map();
|
|
9
|
+
async create(request) {
|
|
10
|
+
this.items.set(request.id, request);
|
|
11
|
+
}
|
|
12
|
+
async get(id) {
|
|
13
|
+
return this.items.get(id) ?? null;
|
|
14
|
+
}
|
|
15
|
+
async getByToolCallId(toolCallId) {
|
|
16
|
+
for (const request of this.items.values()) if (request.toolCallId === toolCallId) return request;
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
async update(id, updates) {
|
|
20
|
+
const existing = this.items.get(id);
|
|
21
|
+
if (existing) this.items.set(id, {
|
|
22
|
+
...existing,
|
|
23
|
+
...updates
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
async list(options) {
|
|
27
|
+
let results = [...this.items.values()];
|
|
28
|
+
if (options?.status) results = results.filter((r) => r.status === options.status);
|
|
29
|
+
if (options?.agentId) results = results.filter((r) => r.agentId === options.agentId);
|
|
30
|
+
if (options?.tenantId) results = results.filter((r) => r.tenantId === options.tenantId);
|
|
31
|
+
return results.sort((a, b) => b.requestedAt.getTime() - a.requestedAt.getTime());
|
|
32
|
+
}
|
|
33
|
+
clear() {
|
|
34
|
+
this.items.clear();
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Approval workflow for managing tool execution approvals.
|
|
39
|
+
*
|
|
40
|
+
* Integrates with AI SDK v6's `needsApproval` feature on tools.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```typescript
|
|
44
|
+
* const workflow = new ApprovalWorkflow();
|
|
45
|
+
*
|
|
46
|
+
* // When a tool needs approval
|
|
47
|
+
* const request = await workflow.requestApproval({
|
|
48
|
+
* sessionId: 'sess_123',
|
|
49
|
+
* agentId: 'support.bot.v1',
|
|
50
|
+
* toolName: 'delete_account',
|
|
51
|
+
* toolCallId: 'call_abc',
|
|
52
|
+
* toolArgs: { userId: 'user_123' },
|
|
53
|
+
* reason: 'Account deletion requires human approval',
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* // When approval is granted
|
|
57
|
+
* await workflow.approve(request.id, 'admin@example.com', 'Verified identity');
|
|
58
|
+
*
|
|
59
|
+
* // Or rejected
|
|
60
|
+
* await workflow.reject(request.id, 'admin@example.com', 'Suspicious activity');
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
var ApprovalWorkflow = class {
|
|
64
|
+
constructor(store = new InMemoryApprovalStore()) {
|
|
65
|
+
this.store = store;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Request approval for a tool execution.
|
|
69
|
+
*/
|
|
70
|
+
async requestApproval(params) {
|
|
71
|
+
const request = {
|
|
72
|
+
id: randomUUID(),
|
|
73
|
+
sessionId: params.sessionId,
|
|
74
|
+
agentId: params.agentId,
|
|
75
|
+
tenantId: params.tenantId,
|
|
76
|
+
toolName: params.toolName,
|
|
77
|
+
toolCallId: params.toolCallId,
|
|
78
|
+
toolArgs: params.toolArgs,
|
|
79
|
+
reason: params.reason,
|
|
80
|
+
requestedAt: /* @__PURE__ */ new Date(),
|
|
81
|
+
status: "pending",
|
|
82
|
+
payload: params.payload
|
|
83
|
+
};
|
|
84
|
+
await this.store.create(request);
|
|
85
|
+
return request;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Request approval from an AI SDK tool call.
|
|
89
|
+
*/
|
|
90
|
+
async requestApprovalFromToolCall(toolCall, context) {
|
|
91
|
+
return this.requestApproval({
|
|
92
|
+
sessionId: context.sessionId,
|
|
93
|
+
agentId: context.agentId,
|
|
94
|
+
tenantId: context.tenantId,
|
|
95
|
+
toolName: toolCall.toolName,
|
|
96
|
+
toolCallId: toolCall.toolCallId,
|
|
97
|
+
toolArgs: toolCall.args,
|
|
98
|
+
reason: context.reason ?? `Tool "${toolCall.toolName}" requires approval`
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Approve a pending request.
|
|
103
|
+
*/
|
|
104
|
+
async approve(id, reviewer, notes) {
|
|
105
|
+
await this.store.update(id, {
|
|
106
|
+
status: "approved",
|
|
107
|
+
reviewer,
|
|
108
|
+
resolvedAt: /* @__PURE__ */ new Date(),
|
|
109
|
+
notes
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Reject a pending request.
|
|
114
|
+
*/
|
|
115
|
+
async reject(id, reviewer, notes) {
|
|
116
|
+
await this.store.update(id, {
|
|
117
|
+
status: "rejected",
|
|
118
|
+
reviewer,
|
|
119
|
+
resolvedAt: /* @__PURE__ */ new Date(),
|
|
120
|
+
notes
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get approval status for a tool call.
|
|
125
|
+
*/
|
|
126
|
+
async getStatus(toolCallId) {
|
|
127
|
+
return (await this.store.getByToolCallId(toolCallId))?.status ?? null;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if a tool call is approved.
|
|
131
|
+
*/
|
|
132
|
+
async isApproved(toolCallId) {
|
|
133
|
+
return await this.getStatus(toolCallId) === "approved";
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* List pending approvals.
|
|
137
|
+
*/
|
|
138
|
+
async listPending(options) {
|
|
139
|
+
return this.store.list({
|
|
140
|
+
...options,
|
|
141
|
+
status: "pending"
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Get approval request by ID.
|
|
146
|
+
*/
|
|
147
|
+
async get(id) {
|
|
148
|
+
return this.store.get(id);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Create an approval workflow instance.
|
|
153
|
+
*/
|
|
154
|
+
function createApprovalWorkflow(store) {
|
|
155
|
+
return new ApprovalWorkflow(store);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
export { ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow };
|
|
160
|
+
//# sourceMappingURL=workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workflow.js","names":["store: ApprovalStore","request: ApprovalRequest"],"sources":["../../src/approval/workflow.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type { ToolCallInfo } from '../types';\n\nexport type ApprovalStatus = 'pending' | 'approved' | 'rejected';\n\n/**\n * Approval request for a tool execution.\n *\n * When a tool has `needsApproval: true` in AI SDK v6, the agent\n * will pause and wait for approval before executing the tool.\n */\nexport interface ApprovalRequest {\n /** Unique request ID */\n id: string;\n /** Agent session ID */\n sessionId: string;\n /** Agent ID */\n agentId: string;\n /** Tenant ID for scoping */\n tenantId?: string;\n /** Tool name requiring approval */\n toolName: string;\n /** Tool call ID from AI SDK */\n toolCallId: string;\n /** Tool arguments */\n toolArgs: unknown;\n /** Human-readable reason for approval */\n reason: string;\n /** When the approval was requested */\n requestedAt: Date;\n /** Current status */\n status: ApprovalStatus;\n /** Additional context payload */\n payload?: Record<string, unknown>;\n /** Who resolved the approval */\n reviewer?: string;\n /** When the approval was resolved */\n resolvedAt?: Date;\n /** Reviewer notes */\n notes?: string;\n}\n\n/**\n * Storage interface for approval requests.\n */\nexport interface ApprovalStore {\n create(request: ApprovalRequest): Promise<void>;\n get(id: string): Promise<ApprovalRequest | null>;\n getByToolCallId(toolCallId: string): Promise<ApprovalRequest | null>;\n update(\n id: string,\n updates: Partial<Omit<ApprovalRequest, 'id' | 'sessionId'>>\n ): Promise<void>;\n list(options?: {\n status?: ApprovalStatus;\n agentId?: string;\n tenantId?: string;\n }): Promise<ApprovalRequest[]>;\n}\n\n/**\n * In-memory approval store for development and testing.\n */\nexport class InMemoryApprovalStore implements ApprovalStore {\n private readonly items = new Map<string, ApprovalRequest>();\n\n async create(request: ApprovalRequest): Promise<void> {\n this.items.set(request.id, request);\n }\n\n async get(id: string): Promise<ApprovalRequest | null> {\n return this.items.get(id) ?? null;\n }\n\n async getByToolCallId(toolCallId: string): Promise<ApprovalRequest | null> {\n for (const request of this.items.values()) {\n if (request.toolCallId === toolCallId) {\n return request;\n }\n }\n return null;\n }\n\n async update(\n id: string,\n updates: Partial<Omit<ApprovalRequest, 'id' | 'sessionId'>>\n ): Promise<void> {\n const existing = this.items.get(id);\n if (existing) {\n this.items.set(id, { ...existing, ...updates });\n }\n }\n\n async list(options?: {\n status?: ApprovalStatus;\n agentId?: string;\n tenantId?: string;\n }): Promise<ApprovalRequest[]> {\n let results = [...this.items.values()];\n\n if (options?.status) {\n results = results.filter((r) => r.status === options.status);\n }\n if (options?.agentId) {\n results = results.filter((r) => r.agentId === options.agentId);\n }\n if (options?.tenantId) {\n results = results.filter((r) => r.tenantId === options.tenantId);\n }\n\n return results.sort(\n (a, b) => b.requestedAt.getTime() - a.requestedAt.getTime()\n );\n }\n\n clear(): void {\n this.items.clear();\n }\n}\n\n/**\n * Approval workflow for managing tool execution approvals.\n *\n * Integrates with AI SDK v6's `needsApproval` feature on tools.\n *\n * @example\n * ```typescript\n * const workflow = new ApprovalWorkflow();\n *\n * // When a tool needs approval\n * const request = await workflow.requestApproval({\n * sessionId: 'sess_123',\n * agentId: 'support.bot.v1',\n * toolName: 'delete_account',\n * toolCallId: 'call_abc',\n * toolArgs: { userId: 'user_123' },\n * reason: 'Account deletion requires human approval',\n * });\n *\n * // When approval is granted\n * await workflow.approve(request.id, 'admin@example.com', 'Verified identity');\n *\n * // Or rejected\n * await workflow.reject(request.id, 'admin@example.com', 'Suspicious activity');\n * ```\n */\nexport class ApprovalWorkflow {\n constructor(\n private readonly store: ApprovalStore = new InMemoryApprovalStore()\n ) {}\n\n /**\n * Request approval for a tool execution.\n */\n async requestApproval(params: {\n sessionId: string;\n agentId: string;\n tenantId?: string;\n toolName: string;\n toolCallId: string;\n toolArgs: unknown;\n reason: string;\n payload?: Record<string, unknown>;\n }): Promise<ApprovalRequest> {\n const request: ApprovalRequest = {\n id: randomUUID(),\n sessionId: params.sessionId,\n agentId: params.agentId,\n tenantId: params.tenantId,\n toolName: params.toolName,\n toolCallId: params.toolCallId,\n toolArgs: params.toolArgs,\n reason: params.reason,\n requestedAt: new Date(),\n status: 'pending',\n payload: params.payload,\n };\n\n await this.store.create(request);\n return request;\n }\n\n /**\n * Request approval from an AI SDK tool call.\n */\n async requestApprovalFromToolCall(\n toolCall: ToolCallInfo,\n context: {\n sessionId: string;\n agentId: string;\n tenantId?: string;\n reason?: string;\n }\n ): Promise<ApprovalRequest> {\n return this.requestApproval({\n sessionId: context.sessionId,\n agentId: context.agentId,\n tenantId: context.tenantId,\n toolName: toolCall.toolName,\n toolCallId: toolCall.toolCallId,\n toolArgs: toolCall.args,\n reason: context.reason ?? `Tool \"${toolCall.toolName}\" requires approval`,\n });\n }\n\n /**\n * Approve a pending request.\n */\n async approve(id: string, reviewer: string, notes?: string): Promise<void> {\n await this.store.update(id, {\n status: 'approved',\n reviewer,\n resolvedAt: new Date(),\n notes,\n });\n }\n\n /**\n * Reject a pending request.\n */\n async reject(id: string, reviewer: string, notes?: string): Promise<void> {\n await this.store.update(id, {\n status: 'rejected',\n reviewer,\n resolvedAt: new Date(),\n notes,\n });\n }\n\n /**\n * Get approval status for a tool call.\n */\n async getStatus(toolCallId: string): Promise<ApprovalStatus | null> {\n const request = await this.store.getByToolCallId(toolCallId);\n return request?.status ?? null;\n }\n\n /**\n * Check if a tool call is approved.\n */\n async isApproved(toolCallId: string): Promise<boolean> {\n const status = await this.getStatus(toolCallId);\n return status === 'approved';\n }\n\n /**\n * List pending approvals.\n */\n async listPending(options?: {\n agentId?: string;\n tenantId?: string;\n }): Promise<ApprovalRequest[]> {\n return this.store.list({ ...options, status: 'pending' });\n }\n\n /**\n * Get approval request by ID.\n */\n async get(id: string): Promise<ApprovalRequest | null> {\n return this.store.get(id);\n }\n}\n\n/**\n * Create an approval workflow instance.\n */\nexport function createApprovalWorkflow(\n store?: ApprovalStore\n): ApprovalWorkflow {\n return new ApprovalWorkflow(store);\n}\n"],"mappings":";;;;;;AA+DA,IAAa,wBAAb,MAA4D;CAC1D,AAAiB,wBAAQ,IAAI,KAA8B;CAE3D,MAAM,OAAO,SAAyC;AACpD,OAAK,MAAM,IAAI,QAAQ,IAAI,QAAQ;;CAGrC,MAAM,IAAI,IAA6C;AACrD,SAAO,KAAK,MAAM,IAAI,GAAG,IAAI;;CAG/B,MAAM,gBAAgB,YAAqD;AACzE,OAAK,MAAM,WAAW,KAAK,MAAM,QAAQ,CACvC,KAAI,QAAQ,eAAe,WACzB,QAAO;AAGX,SAAO;;CAGT,MAAM,OACJ,IACA,SACe;EACf,MAAM,WAAW,KAAK,MAAM,IAAI,GAAG;AACnC,MAAI,SACF,MAAK,MAAM,IAAI,IAAI;GAAE,GAAG;GAAU,GAAG;GAAS,CAAC;;CAInD,MAAM,KAAK,SAIoB;EAC7B,IAAI,UAAU,CAAC,GAAG,KAAK,MAAM,QAAQ,CAAC;AAEtC,MAAI,SAAS,OACX,WAAU,QAAQ,QAAQ,MAAM,EAAE,WAAW,QAAQ,OAAO;AAE9D,MAAI,SAAS,QACX,WAAU,QAAQ,QAAQ,MAAM,EAAE,YAAY,QAAQ,QAAQ;AAEhE,MAAI,SAAS,SACX,WAAU,QAAQ,QAAQ,MAAM,EAAE,aAAa,QAAQ,SAAS;AAGlE,SAAO,QAAQ,MACZ,GAAG,MAAM,EAAE,YAAY,SAAS,GAAG,EAAE,YAAY,SAAS,CAC5D;;CAGH,QAAc;AACZ,OAAK,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BtB,IAAa,mBAAb,MAA8B;CAC5B,YACE,AAAiBA,QAAuB,IAAI,uBAAuB,EACnE;EADiB;;;;;CAMnB,MAAM,gBAAgB,QASO;EAC3B,MAAMC,UAA2B;GAC/B,IAAI,YAAY;GAChB,WAAW,OAAO;GAClB,SAAS,OAAO;GAChB,UAAU,OAAO;GACjB,UAAU,OAAO;GACjB,YAAY,OAAO;GACnB,UAAU,OAAO;GACjB,QAAQ,OAAO;GACf,6BAAa,IAAI,MAAM;GACvB,QAAQ;GACR,SAAS,OAAO;GACjB;AAED,QAAM,KAAK,MAAM,OAAO,QAAQ;AAChC,SAAO;;;;;CAMT,MAAM,4BACJ,UACA,SAM0B;AAC1B,SAAO,KAAK,gBAAgB;GAC1B,WAAW,QAAQ;GACnB,SAAS,QAAQ;GACjB,UAAU,QAAQ;GAClB,UAAU,SAAS;GACnB,YAAY,SAAS;GACrB,UAAU,SAAS;GACnB,QAAQ,QAAQ,UAAU,SAAS,SAAS,SAAS;GACtD,CAAC;;;;;CAMJ,MAAM,QAAQ,IAAY,UAAkB,OAA+B;AACzE,QAAM,KAAK,MAAM,OAAO,IAAI;GAC1B,QAAQ;GACR;GACA,4BAAY,IAAI,MAAM;GACtB;GACD,CAAC;;;;;CAMJ,MAAM,OAAO,IAAY,UAAkB,OAA+B;AACxE,QAAM,KAAK,MAAM,OAAO,IAAI;GAC1B,QAAQ;GACR;GACA,4BAAY,IAAI,MAAM;GACtB;GACD,CAAC;;;;;CAMJ,MAAM,UAAU,YAAoD;AAElE,UADgB,MAAM,KAAK,MAAM,gBAAgB,WAAW,GAC5C,UAAU;;;;;CAM5B,MAAM,WAAW,YAAsC;AAErD,SADe,MAAM,KAAK,UAAU,WAAW,KAC7B;;;;;CAMpB,MAAM,YAAY,SAGa;AAC7B,SAAO,KAAK,MAAM,KAAK;GAAE,GAAG;GAAS,QAAQ;GAAW,CAAC;;;;;CAM3D,MAAM,IAAI,IAA6C;AACrD,SAAO,KAAK,MAAM,IAAI,GAAG;;;;;;AAO7B,SAAgB,uBACd,OACkB;AAClB,QAAO,IAAI,iBAAiB,MAAM"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { AgentConfidencePolicy, AgentEscalationPolicy, AgentKnowledgeRef, AgentMemoryConfig, AgentMeta, AgentPolicy, AgentSpec, AgentToolConfig, agentKey, defineAgent } from "./spec/spec.js";
|
|
2
|
+
import { AgentRegistry, createAgentRegistry } from "./spec/registry.js";
|
|
3
|
+
import { AgentCallOptions, AgentEventEmitter, AgentEventName, AgentEventPayload, AgentFinishReason, AgentGenerateParams, AgentGenerateResult, AgentMessage, AgentSessionState, AgentStatus, AgentStepMetrics, AgentStreamParams, ToolCallInfo, ToolExecutionContext, ToolHandler, ToolResultInfo } from "./types.js";
|
|
4
|
+
import { AgentSessionStore, InMemorySessionStore, createInMemorySessionStore, generateSessionId } from "./session/store.js";
|
|
5
|
+
import { InMemoryTelemetryCollector, OperationMetricSample, TelemetryCollector, createInMemoryTelemetryCollector, noopTelemetryCollector, trackAgentStep } from "./telemetry/adapter.js";
|
|
6
|
+
import { ContractSpecAgent, ContractSpecAgentConfig } from "./agent/contract-spec-agent.js";
|
|
7
|
+
import { AgentFactory, AgentFactoryConfig, CreateAgentOptions, createAgentFactory } from "./agent/agent-factory.js";
|
|
8
|
+
import "./agent/index.js";
|
|
9
|
+
import { ApprovalRequest, ApprovalStatus, ApprovalStore, ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow } from "./approval/workflow.js";
|
|
10
|
+
import "./approval/index.js";
|
|
11
|
+
import { buildToolHandlers, createToolHandler, specToolToAISDKTool, specToolsToAISDKTools } from "./tools/tool-adapter.js";
|
|
12
|
+
import { createKnowledgeQueryTool } from "./tools/knowledge-tool.js";
|
|
13
|
+
import { McpClientConfig, McpClientResult, createMcpToolsets, mcpServerToTools } from "./tools/mcp-client.js";
|
|
14
|
+
import { AgentMcpServerConfig, agentToMcpServer, createAgentMcpServer } from "./tools/mcp-server.js";
|
|
15
|
+
import "./tools/index.js";
|
|
16
|
+
import { jsonSchemaToZod, jsonSchemaToZodSafe } from "./schema/json-schema-to-zod.js";
|
|
17
|
+
import { SchemaOutput, enumToChoiceOutput, jsonSchemaToArrayOutput, jsonSchemaToOutput, textOutput, zodToOutput } from "./schema/schema-output.js";
|
|
18
|
+
import "./schema/index.js";
|
|
19
|
+
import { createKnowledgeInjector, injectStaticKnowledge } from "./knowledge/injector.js";
|
|
20
|
+
import "./session/index.js";
|
|
21
|
+
import "./telemetry/index.js";
|
|
22
|
+
import { Experimental_Agent as ToolLoopAgent, LanguageModel, LanguageModelUsage, ModelMessage, StepResult, Tool, ToolSet } from "ai";
|
|
23
|
+
export { AgentCallOptions, AgentConfidencePolicy, AgentEscalationPolicy, AgentEventEmitter, AgentEventName, AgentEventPayload, AgentFactory, AgentFactoryConfig, AgentFinishReason, AgentGenerateParams, AgentGenerateResult, AgentKnowledgeRef, AgentMcpServerConfig, AgentMemoryConfig, AgentMessage, AgentMeta, AgentPolicy, AgentRegistry, AgentSessionState, AgentSessionStore, AgentSpec, AgentStatus, AgentStepMetrics, AgentStreamParams, AgentToolConfig, ApprovalRequest, ApprovalStatus, ApprovalStore, ApprovalWorkflow, ContractSpecAgent, ContractSpecAgentConfig, CreateAgentOptions, InMemoryApprovalStore, InMemorySessionStore, InMemoryTelemetryCollector, type LanguageModel, type LanguageModelUsage, McpClientConfig, McpClientResult, type ModelMessage, OperationMetricSample, SchemaOutput, type StepResult, TelemetryCollector, type Tool, ToolCallInfo, ToolExecutionContext, ToolHandler, ToolLoopAgent, ToolResultInfo, type ToolSet, agentKey, agentToMcpServer, buildToolHandlers, createAgentFactory, createAgentMcpServer, createAgentRegistry, createApprovalWorkflow, createInMemorySessionStore, createInMemoryTelemetryCollector, createKnowledgeInjector, createKnowledgeQueryTool, createMcpToolsets, createToolHandler, defineAgent, enumToChoiceOutput, generateSessionId, injectStaticKnowledge, jsonSchemaToArrayOutput, jsonSchemaToOutput, jsonSchemaToZod, jsonSchemaToZodSafe, mcpServerToTools, noopTelemetryCollector, specToolToAISDKTool, specToolsToAISDKTools, textOutput, trackAgentStep, zodToOutput };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { agentKey, defineAgent } from "./spec/spec.js";
|
|
2
|
+
import { jsonSchemaToZod, jsonSchemaToZodSafe } from "./schema/json-schema-to-zod.js";
|
|
3
|
+
import { buildToolHandlers, createToolHandler, specToolToAISDKTool, specToolsToAISDKTools } from "./tools/tool-adapter.js";
|
|
4
|
+
import { createKnowledgeQueryTool } from "./tools/knowledge-tool.js";
|
|
5
|
+
import { createKnowledgeInjector, injectStaticKnowledge } from "./knowledge/injector.js";
|
|
6
|
+
import { InMemorySessionStore, createInMemorySessionStore, generateSessionId } from "./session/store.js";
|
|
7
|
+
import { InMemoryTelemetryCollector, createInMemoryTelemetryCollector, noopTelemetryCollector, trackAgentStep } from "./telemetry/adapter.js";
|
|
8
|
+
import { ContractSpecAgent } from "./agent/contract-spec-agent.js";
|
|
9
|
+
import { AgentFactory, createAgentFactory } from "./agent/agent-factory.js";
|
|
10
|
+
import "./agent/index.js";
|
|
11
|
+
import { AgentRegistry, createAgentRegistry } from "./spec/registry.js";
|
|
12
|
+
import { createMcpToolsets, mcpServerToTools } from "./tools/mcp-client.js";
|
|
13
|
+
import { agentToMcpServer, createAgentMcpServer } from "./tools/mcp-server.js";
|
|
14
|
+
import "./tools/index.js";
|
|
15
|
+
import { SchemaOutput, enumToChoiceOutput, jsonSchemaToArrayOutput, jsonSchemaToOutput, textOutput, zodToOutput } from "./schema/schema-output.js";
|
|
16
|
+
import "./schema/index.js";
|
|
17
|
+
import { ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow } from "./approval/workflow.js";
|
|
18
|
+
import "./approval/index.js";
|
|
19
|
+
import { Experimental_Agent as ToolLoopAgent } from "ai";
|
|
20
|
+
|
|
21
|
+
export { AgentFactory, AgentRegistry, ApprovalWorkflow, ContractSpecAgent, InMemoryApprovalStore, InMemorySessionStore, InMemoryTelemetryCollector, SchemaOutput, ToolLoopAgent, agentKey, agentToMcpServer, buildToolHandlers, createAgentFactory, createAgentMcpServer, createAgentRegistry, createApprovalWorkflow, createInMemorySessionStore, createInMemoryTelemetryCollector, createKnowledgeInjector, createKnowledgeQueryTool, createMcpToolsets, createToolHandler, defineAgent, enumToChoiceOutput, generateSessionId, injectStaticKnowledge, jsonSchemaToArrayOutput, jsonSchemaToOutput, jsonSchemaToZod, jsonSchemaToZodSafe, mcpServerToTools, noopTelemetryCollector, specToolToAISDKTool, specToolsToAISDKTools, textOutput, trackAgentStep, zodToOutput };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AgentKnowledgeRef } from "../spec/spec.js";
|
|
2
|
+
import { KnowledgeRetriever } from "@contractspec/lib.knowledge/retriever";
|
|
3
|
+
|
|
4
|
+
//#region src/knowledge/injector.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Inject static knowledge into agent instructions.
|
|
8
|
+
*
|
|
9
|
+
* This function handles the "required" knowledge that should be
|
|
10
|
+
* injected into the system prompt at agent initialization time.
|
|
11
|
+
* Optional knowledge is handled by the knowledge query tool.
|
|
12
|
+
*
|
|
13
|
+
* @param instructions - Base agent instructions
|
|
14
|
+
* @param knowledgeRefs - Knowledge references from the agent spec
|
|
15
|
+
* @param retriever - Optional knowledge retriever
|
|
16
|
+
* @returns Instructions with injected knowledge
|
|
17
|
+
*/
|
|
18
|
+
declare function injectStaticKnowledge(instructions: string, knowledgeRefs: AgentKnowledgeRef[], retriever?: KnowledgeRetriever): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a knowledge injector instance for reuse.
|
|
21
|
+
*/
|
|
22
|
+
declare function createKnowledgeInjector(retriever?: KnowledgeRetriever): {
|
|
23
|
+
/**
|
|
24
|
+
* Inject static knowledge into instructions.
|
|
25
|
+
*/
|
|
26
|
+
inject: (instructions: string, knowledgeRefs: AgentKnowledgeRef[]) => Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Check if a knowledge space is available.
|
|
29
|
+
*/
|
|
30
|
+
hasSpace: (spaceKey: string) => boolean;
|
|
31
|
+
/**
|
|
32
|
+
* List available knowledge spaces.
|
|
33
|
+
*/
|
|
34
|
+
listSpaces: () => string[];
|
|
35
|
+
};
|
|
36
|
+
//#endregion
|
|
37
|
+
export { createKnowledgeInjector, injectStaticKnowledge };
|
|
38
|
+
//# sourceMappingURL=injector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injector.d.ts","names":[],"sources":["../../src/knowledge/injector.ts"],"sourcesContent":[],"mappings":";;;;;;;AAeA;;;;;AA+CA;;;;;iBA/CsB,qBAAA,sCAEL,iCACH,qBACX;;;;iBA2Ca,uBAAA,aAAoC;;;;gDAKF,wBAAmB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
//#region src/knowledge/injector.ts
|
|
2
|
+
/**
|
|
3
|
+
* Inject static knowledge into agent instructions.
|
|
4
|
+
*
|
|
5
|
+
* This function handles the "required" knowledge that should be
|
|
6
|
+
* injected into the system prompt at agent initialization time.
|
|
7
|
+
* Optional knowledge is handled by the knowledge query tool.
|
|
8
|
+
*
|
|
9
|
+
* @param instructions - Base agent instructions
|
|
10
|
+
* @param knowledgeRefs - Knowledge references from the agent spec
|
|
11
|
+
* @param retriever - Optional knowledge retriever
|
|
12
|
+
* @returns Instructions with injected knowledge
|
|
13
|
+
*/
|
|
14
|
+
async function injectStaticKnowledge(instructions, knowledgeRefs, retriever) {
|
|
15
|
+
if (!retriever) return instructions;
|
|
16
|
+
const requiredRefs = knowledgeRefs.filter((ref) => ref.required);
|
|
17
|
+
if (requiredRefs.length === 0) return instructions;
|
|
18
|
+
const blocks = [];
|
|
19
|
+
for (const ref of requiredRefs) {
|
|
20
|
+
if (!retriever.supportsSpace(ref.key)) {
|
|
21
|
+
console.warn(`Required knowledge space "${ref.key}" is not available`);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const content = await retriever.getStatic(ref.key);
|
|
26
|
+
if (content) {
|
|
27
|
+
const header = ref.instructions ? `## ${ref.key}\n${ref.instructions}` : `## ${ref.key}`;
|
|
28
|
+
blocks.push(`${header}\n\n${content}`);
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.warn(`Failed to load required knowledge "${ref.key}":`, error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (blocks.length === 0) return instructions;
|
|
35
|
+
return `${instructions}
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
# Reference Knowledge
|
|
40
|
+
|
|
41
|
+
The following information is provided for your reference. Use it to inform your responses.
|
|
42
|
+
|
|
43
|
+
${blocks.join("\n\n---\n\n")}`;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Create a knowledge injector instance for reuse.
|
|
47
|
+
*/
|
|
48
|
+
function createKnowledgeInjector(retriever) {
|
|
49
|
+
return {
|
|
50
|
+
inject: (instructions, knowledgeRefs) => injectStaticKnowledge(instructions, knowledgeRefs, retriever),
|
|
51
|
+
hasSpace: (spaceKey) => retriever?.supportsSpace(spaceKey) ?? false,
|
|
52
|
+
listSpaces: () => retriever?.listSpaces() ?? []
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
export { createKnowledgeInjector, injectStaticKnowledge };
|
|
58
|
+
//# sourceMappingURL=injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injector.js","names":["blocks: string[]"],"sources":["../../src/knowledge/injector.ts"],"sourcesContent":["import type { KnowledgeRetriever } from '@contractspec/lib.knowledge/retriever';\nimport type { AgentKnowledgeRef } from '../spec/spec';\n\n/**\n * Inject static knowledge into agent instructions.\n *\n * This function handles the \"required\" knowledge that should be\n * injected into the system prompt at agent initialization time.\n * Optional knowledge is handled by the knowledge query tool.\n *\n * @param instructions - Base agent instructions\n * @param knowledgeRefs - Knowledge references from the agent spec\n * @param retriever - Optional knowledge retriever\n * @returns Instructions with injected knowledge\n */\nexport async function injectStaticKnowledge(\n instructions: string,\n knowledgeRefs: AgentKnowledgeRef[],\n retriever?: KnowledgeRetriever\n): Promise<string> {\n if (!retriever) return instructions;\n\n const requiredRefs = knowledgeRefs.filter((ref) => ref.required);\n if (requiredRefs.length === 0) return instructions;\n\n const blocks: string[] = [];\n\n for (const ref of requiredRefs) {\n if (!retriever.supportsSpace(ref.key)) {\n console.warn(`Required knowledge space \"${ref.key}\" is not available`);\n continue;\n }\n\n try {\n const content = await retriever.getStatic(ref.key);\n if (content) {\n const header = ref.instructions\n ? `## ${ref.key}\\n${ref.instructions}`\n : `## ${ref.key}`;\n blocks.push(`${header}\\n\\n${content}`);\n }\n } catch (error) {\n console.warn(`Failed to load required knowledge \"${ref.key}\":`, error);\n }\n }\n\n if (blocks.length === 0) return instructions;\n\n return `${instructions}\n\n---\n\n# Reference Knowledge\n\nThe following information is provided for your reference. Use it to inform your responses.\n\n${blocks.join('\\n\\n---\\n\\n')}`;\n}\n\n/**\n * Create a knowledge injector instance for reuse.\n */\nexport function createKnowledgeInjector(retriever?: KnowledgeRetriever) {\n return {\n /**\n * Inject static knowledge into instructions.\n */\n inject: (instructions: string, knowledgeRefs: AgentKnowledgeRef[]) =>\n injectStaticKnowledge(instructions, knowledgeRefs, retriever),\n\n /**\n * Check if a knowledge space is available.\n */\n hasSpace: (spaceKey: string) => retriever?.supportsSpace(spaceKey) ?? false,\n\n /**\n * List available knowledge spaces.\n */\n listSpaces: () => retriever?.listSpaces() ?? [],\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,eAAsB,sBACpB,cACA,eACA,WACiB;AACjB,KAAI,CAAC,UAAW,QAAO;CAEvB,MAAM,eAAe,cAAc,QAAQ,QAAQ,IAAI,SAAS;AAChE,KAAI,aAAa,WAAW,EAAG,QAAO;CAEtC,MAAMA,SAAmB,EAAE;AAE3B,MAAK,MAAM,OAAO,cAAc;AAC9B,MAAI,CAAC,UAAU,cAAc,IAAI,IAAI,EAAE;AACrC,WAAQ,KAAK,6BAA6B,IAAI,IAAI,oBAAoB;AACtE;;AAGF,MAAI;GACF,MAAM,UAAU,MAAM,UAAU,UAAU,IAAI,IAAI;AAClD,OAAI,SAAS;IACX,MAAM,SAAS,IAAI,eACf,MAAM,IAAI,IAAI,IAAI,IAAI,iBACtB,MAAM,IAAI;AACd,WAAO,KAAK,GAAG,OAAO,MAAM,UAAU;;WAEjC,OAAO;AACd,WAAQ,KAAK,sCAAsC,IAAI,IAAI,KAAK,MAAM;;;AAI1E,KAAI,OAAO,WAAW,EAAG,QAAO;AAEhC,QAAO,GAAG,aAAa;;;;;;;;EAQvB,OAAO,KAAK,cAAc;;;;;AAM5B,SAAgB,wBAAwB,WAAgC;AACtE,QAAO;EAIL,SAAS,cAAsB,kBAC7B,sBAAsB,cAAc,eAAe,UAAU;EAK/D,WAAW,aAAqB,WAAW,cAAc,SAAS,IAAI;EAKtE,kBAAkB,WAAW,YAAY,IAAI,EAAE;EAChD"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { AgentSessionState } from "../types.js";
|
|
2
|
+
import { AgentMemorySnapshot, AgentSessionMemory, BaseAgentMemoryManager } from "./manager.js";
|
|
3
|
+
|
|
4
|
+
//#region src/memory/in-memory.d.ts
|
|
5
|
+
interface InMemoryAgentMemoryOptions {
|
|
6
|
+
ttlMinutes?: number;
|
|
7
|
+
maxEntries?: number;
|
|
8
|
+
}
|
|
9
|
+
declare class InMemoryAgentMemory extends BaseAgentMemoryManager {
|
|
10
|
+
private readonly ttlMs;
|
|
11
|
+
private readonly maxEntries;
|
|
12
|
+
private readonly store;
|
|
13
|
+
constructor(options?: InMemoryAgentMemoryOptions);
|
|
14
|
+
load(sessionId: string): Promise<AgentSessionMemory | null>;
|
|
15
|
+
save(snapshot: AgentSessionMemory): Promise<void>;
|
|
16
|
+
summarize(session: AgentSessionState): Promise<AgentMemorySnapshot>;
|
|
17
|
+
private trim;
|
|
18
|
+
private evictExpired;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { InMemoryAgentMemory, InMemoryAgentMemoryOptions };
|
|
22
|
+
//# sourceMappingURL=in-memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.d.ts","names":[],"sources":["../../src/memory/in-memory.ts"],"sourcesContent":[],"mappings":";;;;UAaiB,0BAAA;;EAAA,UAAA,CAAA,EAAA,MAAA;AAKjB;AAKwB,cALX,mBAAA,SAA4B,sBAAA,CAKjB;EAMiB,iBAAA,KAAA;EAAR,iBAAA,UAAA;EASV,iBAAA,KAAA;EAAqB,WAAA,CAAA,OAAA,CAAA,EAfpB,0BAeoB;EAQjB,IAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EAjBM,OAiBN,CAjBc,kBAiBd,GAAA,IAAA,CAAA;EAA4B,IAAA,CAAA,QAAA,EARhC,kBAQgC,CAAA,EARX,OAQW,CAAA,IAAA,CAAA;EAAR,SAAA,CAAA,OAAA,EAApB,iBAAoB,CAAA,EAAA,OAAA,CAAQ,mBAAR,CAAA;EA5BN,QAAA,IAAA;EAAsB,QAAA,YAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { BaseAgentMemoryManager } from "./manager.js";
|
|
2
|
+
|
|
3
|
+
//#region src/memory/in-memory.ts
|
|
4
|
+
var InMemoryAgentMemory = class extends BaseAgentMemoryManager {
|
|
5
|
+
ttlMs;
|
|
6
|
+
maxEntries;
|
|
7
|
+
store = /* @__PURE__ */ new Map();
|
|
8
|
+
constructor(options) {
|
|
9
|
+
super();
|
|
10
|
+
this.ttlMs = (options?.ttlMinutes ?? 60) * 60 * 1e3;
|
|
11
|
+
this.maxEntries = options?.maxEntries ?? 250;
|
|
12
|
+
}
|
|
13
|
+
async load(sessionId) {
|
|
14
|
+
this.evictExpired();
|
|
15
|
+
const stored = this.store.get(sessionId);
|
|
16
|
+
if (!stored) return null;
|
|
17
|
+
stored.data.session.updatedAt = /* @__PURE__ */ new Date();
|
|
18
|
+
stored.expiresAt = Date.now() + this.ttlMs;
|
|
19
|
+
return stored.data;
|
|
20
|
+
}
|
|
21
|
+
async save(snapshot) {
|
|
22
|
+
this.trim(snapshot.memory.entries);
|
|
23
|
+
this.store.set(snapshot.session.sessionId, {
|
|
24
|
+
data: snapshot,
|
|
25
|
+
expiresAt: Date.now() + this.ttlMs
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async summarize(session) {
|
|
29
|
+
const current = await this.load(session.sessionId) ?? this.bootstrapMemory(session);
|
|
30
|
+
const content = current.memory.entries.slice(-10).map((entry) => `- ${entry.type}: ${entry.content}`).join("\n");
|
|
31
|
+
current.memory.summary = content;
|
|
32
|
+
current.memory.lastSummarizedAt = /* @__PURE__ */ new Date();
|
|
33
|
+
await this.save(current);
|
|
34
|
+
return current.memory;
|
|
35
|
+
}
|
|
36
|
+
trim(entries) {
|
|
37
|
+
if (entries.length <= this.maxEntries) return;
|
|
38
|
+
entries.splice(0, entries.length - this.maxEntries);
|
|
39
|
+
}
|
|
40
|
+
evictExpired() {
|
|
41
|
+
const now = Date.now();
|
|
42
|
+
for (const [sessionId, stored] of this.store.entries()) if (stored.expiresAt <= now) this.store.delete(sessionId);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { InMemoryAgentMemory };
|
|
48
|
+
//# sourceMappingURL=in-memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory.js","names":[],"sources":["../../src/memory/in-memory.ts"],"sourcesContent":["import type { AgentSessionState } from '../types';\nimport {\n BaseAgentMemoryManager,\n type AgentMemoryEntry,\n type AgentMemorySnapshot,\n type AgentSessionMemory,\n} from './manager';\n\ninterface StoredSession {\n data: AgentSessionMemory;\n expiresAt: number;\n}\n\nexport interface InMemoryAgentMemoryOptions {\n ttlMinutes?: number;\n maxEntries?: number;\n}\n\nexport class InMemoryAgentMemory extends BaseAgentMemoryManager {\n private readonly ttlMs: number;\n private readonly maxEntries: number;\n private readonly store = new Map<string, StoredSession>();\n\n constructor(options?: InMemoryAgentMemoryOptions) {\n super();\n this.ttlMs = (options?.ttlMinutes ?? 60) * 60 * 1000;\n this.maxEntries = options?.maxEntries ?? 250;\n }\n\n async load(sessionId: string): Promise<AgentSessionMemory | null> {\n this.evictExpired();\n const stored = this.store.get(sessionId);\n if (!stored) return null;\n stored.data.session.updatedAt = new Date();\n stored.expiresAt = Date.now() + this.ttlMs;\n return stored.data;\n }\n\n async save(snapshot: AgentSessionMemory): Promise<void> {\n this.trim(snapshot.memory.entries);\n this.store.set(snapshot.session.sessionId, {\n data: snapshot,\n expiresAt: Date.now() + this.ttlMs,\n });\n }\n\n async summarize(session: AgentSessionState): Promise<AgentMemorySnapshot> {\n const current =\n (await this.load(session.sessionId)) ?? this.bootstrapMemory(session);\n const content = current.memory.entries\n .slice(-10)\n .map((entry) => `- ${entry.type}: ${entry.content}`)\n .join('\\n');\n current.memory.summary = content;\n current.memory.lastSummarizedAt = new Date();\n await this.save(current);\n return current.memory;\n }\n\n private trim(entries: AgentMemoryEntry[]) {\n if (entries.length <= this.maxEntries) return;\n entries.splice(0, entries.length - this.maxEntries);\n }\n\n private evictExpired() {\n const now = Date.now();\n for (const [sessionId, stored] of this.store.entries()) {\n if (stored.expiresAt <= now) {\n this.store.delete(sessionId);\n }\n }\n }\n}\n"],"mappings":";;;AAkBA,IAAa,sBAAb,cAAyC,uBAAuB;CAC9D,AAAiB;CACjB,AAAiB;CACjB,AAAiB,wBAAQ,IAAI,KAA4B;CAEzD,YAAY,SAAsC;AAChD,SAAO;AACP,OAAK,SAAS,SAAS,cAAc,MAAM,KAAK;AAChD,OAAK,aAAa,SAAS,cAAc;;CAG3C,MAAM,KAAK,WAAuD;AAChE,OAAK,cAAc;EACnB,MAAM,SAAS,KAAK,MAAM,IAAI,UAAU;AACxC,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,KAAK,QAAQ,4BAAY,IAAI,MAAM;AAC1C,SAAO,YAAY,KAAK,KAAK,GAAG,KAAK;AACrC,SAAO,OAAO;;CAGhB,MAAM,KAAK,UAA6C;AACtD,OAAK,KAAK,SAAS,OAAO,QAAQ;AAClC,OAAK,MAAM,IAAI,SAAS,QAAQ,WAAW;GACzC,MAAM;GACN,WAAW,KAAK,KAAK,GAAG,KAAK;GAC9B,CAAC;;CAGJ,MAAM,UAAU,SAA0D;EACxE,MAAM,UACH,MAAM,KAAK,KAAK,QAAQ,UAAU,IAAK,KAAK,gBAAgB,QAAQ;EACvE,MAAM,UAAU,QAAQ,OAAO,QAC5B,MAAM,IAAI,CACV,KAAK,UAAU,KAAK,MAAM,KAAK,IAAI,MAAM,UAAU,CACnD,KAAK,KAAK;AACb,UAAQ,OAAO,UAAU;AACzB,UAAQ,OAAO,mCAAmB,IAAI,MAAM;AAC5C,QAAM,KAAK,KAAK,QAAQ;AACxB,SAAO,QAAQ;;CAGjB,AAAQ,KAAK,SAA6B;AACxC,MAAI,QAAQ,UAAU,KAAK,WAAY;AACvC,UAAQ,OAAO,GAAG,QAAQ,SAAS,KAAK,WAAW;;CAGrD,AAAQ,eAAe;EACrB,MAAM,MAAM,KAAK,KAAK;AACtB,OAAK,MAAM,CAAC,WAAW,WAAW,KAAK,MAAM,SAAS,CACpD,KAAI,OAAO,aAAa,IACtB,MAAK,MAAM,OAAO,UAAU"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { AgentMemoryEntry, AgentMemoryManager, AgentMemorySnapshot, AgentSessionMemory, BaseAgentMemoryManager, trackMessageInMemory } from "./manager.js";
|
|
2
|
+
import { InMemoryAgentMemory, InMemoryAgentMemoryOptions } from "./in-memory.js";
|
|
3
|
+
export { AgentMemoryEntry, AgentMemoryManager, AgentMemorySnapshot, AgentSessionMemory, BaseAgentMemoryManager, InMemoryAgentMemory, InMemoryAgentMemoryOptions, trackMessageInMemory };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AgentMessage, AgentSessionState } from "../types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/memory/manager.d.ts
|
|
4
|
+
interface AgentMemoryEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
type: 'user' | 'assistant' | 'tool' | 'system';
|
|
7
|
+
content: string;
|
|
8
|
+
createdAt: Date;
|
|
9
|
+
metadata?: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
interface AgentMemorySnapshot {
|
|
12
|
+
entries: AgentMemoryEntry[];
|
|
13
|
+
summary?: string;
|
|
14
|
+
lastSummarizedAt?: Date;
|
|
15
|
+
}
|
|
16
|
+
interface AgentSessionMemory {
|
|
17
|
+
session: AgentSessionState;
|
|
18
|
+
memory: AgentMemorySnapshot;
|
|
19
|
+
}
|
|
20
|
+
interface AgentMemoryManager {
|
|
21
|
+
load(sessionId: string): Promise<AgentSessionMemory | null>;
|
|
22
|
+
save(snapshot: AgentSessionMemory): Promise<void>;
|
|
23
|
+
append(session: AgentSessionState, entry: Omit<AgentMemoryEntry, 'id' | 'createdAt'> & {
|
|
24
|
+
createdAt?: Date;
|
|
25
|
+
}): Promise<AgentSessionMemory>;
|
|
26
|
+
summarize(session: AgentSessionState): Promise<AgentMemorySnapshot | undefined>;
|
|
27
|
+
prune(session: AgentSessionState): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
declare abstract class BaseAgentMemoryManager implements AgentMemoryManager {
|
|
30
|
+
abstract load(sessionId: string): Promise<AgentSessionMemory | null>;
|
|
31
|
+
abstract save(snapshot: AgentSessionMemory): Promise<void>;
|
|
32
|
+
append(session: AgentSessionState, entry: Omit<AgentMemoryEntry, 'id' | 'createdAt'> & {
|
|
33
|
+
createdAt?: Date;
|
|
34
|
+
}): Promise<AgentSessionMemory>;
|
|
35
|
+
summarize(_session: AgentSessionState): Promise<AgentMemorySnapshot | undefined>;
|
|
36
|
+
prune(_session: AgentSessionState): Promise<void>;
|
|
37
|
+
protected bootstrapMemory(session: AgentSessionState): AgentSessionMemory;
|
|
38
|
+
}
|
|
39
|
+
declare function trackMessageInMemory(manager: AgentMemoryManager | undefined, session: AgentSessionState, message: AgentMessage): void;
|
|
40
|
+
//#endregion
|
|
41
|
+
export { AgentMemoryEntry, AgentMemoryManager, AgentMemorySnapshot, AgentSessionMemory, BaseAgentMemoryManager, trackMessageInMemory };
|
|
42
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","names":[],"sources":["../../src/memory/manager.ts"],"sourcesContent":[],"mappings":";;;UAIiB,gBAAA;;EAAA,IAAA,EAAA,MAAA,GAAA,WAAgB,GAAA,MAIpB,GACA,QAAM;EAGF,OAAA,EAAA,MAAA;EAMA,SAAA,EAVJ,IAUI;EAKA,QAAA,CAAA,EAdJ,MAcI,CAAA,MAAkB,EAAA,MAAA,CAAA;;AACR,UAZV,mBAAA,CAYU;EACV,OAAA,EAZN,gBAYM,EAAA;EAAqB,OAAA,CAAA,EAAA,MAAA;EAEzB,gBAAA,CAAA,EAZQ,IAYR;;AACF,UAVM,kBAAA,CAUN;EAA2D,OAAA,EAT3D,iBAS2D;EACzD,MAAA,EATH,mBASG;;AAEA,UARI,kBAAA,CAQJ;EACA,IAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EARc,OAQd,CARsB,kBAQtB,GAAA,IAAA,CAAA;EAAR,IAAA,CAAA,QAAA,EAPY,kBAOZ,CAAA,EAPiC,OAOjC,CAAA,IAAA,CAAA;EACY,MAAA,CAAA,OAAA,EANJ,iBAMI,EAAA,KAAA,EALN,IAKM,CALD,gBAKC,EAAA,IAAA,GAAA,WAAA,CAAA,GAAA;IAAoB,SAAA,CAAA,EALiC,IAKjC;EAAO,CAAA,CAAA,EAJvC,OAIuC,CAJ/B,kBAI+B,CAAA;EAyEtB,SAAA,CAAA,OAAA,EA3ET,iBA2EgC,CAAA,EA1ExC,OA0EwC,CA1EhC,mBA0EgC,GAAA,SAAA,CAAA;EACD,KAAA,CAAA,OAAA,EA1E3B,iBA0E2B,CAAA,EA1EP,OA0EO,CAAA,IAAA,CAAA;;AAClB,uBAFJ,sBAAA,YAAkC,kBAE9B,CAAA;EAAqB,SAAA,IAAA,CAAA,SAAA,EAAA,MAAA,CAAA,EADX,OACW,CADH,kBACG,GAAA,IAAA,CAAA;EAGlC,SAAA,IAAA,CAAA,QAAA,EAHa,kBAGb,CAAA,EAHkC,OAGlC,CAAA,IAAA,CAAA;EACG,MAAA,CAAA,OAAA,EADH,iBACG,EAAA,KAAA,EAAL,IAAK,CAAA,gBAAA,EAAA,IAAA,GAAA,WAAA,CAAA,GAAA;IAAL,SAAA,CAAA,EAA2D,IAA3D;EAA2D,CAAA,CAAA,EACjE,OADiE,CACzD,kBADyD,CAAA;EACzD,SAAA,CAAA,QAAA,EAcC,iBAdD,CAAA,EAeR,OAfQ,CAeA,mBAfA,GAAA,SAAA,CAAA;EAAR,KAAA,CAAA,QAAA,EAmBmB,iBAnBnB,CAAA,EAmBuC,OAnBvC,CAAA,IAAA,CAAA;EAcS,UAAA,eAAA,CAAA,OAAA,EASuB,iBATvB,CAAA,EAS2C,kBAT3C;;AACT,iBAuBW,oBAAA,CAvBX,OAAA,EAwBM,kBAxBN,GAAA,SAAA,EAAA,OAAA,EAyBM,iBAzBN,EAAA,OAAA,EA0BM,YA1BN,CAAA,EAAA,IAAA"}
|