@lssm/lib.ai-agent 0.0.0-canary-20251217063201 → 0.0.0-canary-20251217073102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent-factory.js +102 -1
- package/dist/agent/contract-spec-agent.js +147 -1
- package/dist/agent/index.js +4 -1
- package/dist/approval/index.js +3 -1
- package/dist/approval/workflow.js +159 -1
- package/dist/index.js +21 -1
- package/dist/knowledge/index.js +3 -1
- package/dist/knowledge/injector.js +49 -5
- package/dist/memory/in-memory.js +47 -2
- package/dist/memory/index.js +4 -1
- package/dist/memory/manager.js +79 -1
- package/dist/schema/index.js +4 -1
- package/dist/schema/json-schema-to-zod.js +123 -1
- package/dist/schema/schema-output.js +64 -1
- package/dist/session/index.js +3 -1
- package/dist/session/store.js +78 -1
- package/dist/spec/index.js +4 -1
- package/dist/spec/registry.js +116 -1
- package/dist/spec/spec.js +29 -1
- package/dist/telemetry/adapter.js +102 -1
- package/dist/telemetry/index.js +3 -1
- package/dist/tools/index.js +6 -1
- package/dist/tools/knowledge-tool.js +50 -6
- package/dist/tools/mcp-client.js +57 -1
- package/dist/tools/mcp-server.js +68 -1
- package/dist/tools/tool-adapter.js +79 -1
- package/package.json +7 -6
|
@@ -1 +1,102 @@
|
|
|
1
|
-
import{ContractSpecAgent
|
|
1
|
+
import { ContractSpecAgent } from "./contract-spec-agent.js";
|
|
2
|
+
|
|
3
|
+
//#region src/agent/agent-factory.ts
|
|
4
|
+
/**
|
|
5
|
+
* Factory for creating ContractSpec agents from specs.
|
|
6
|
+
*
|
|
7
|
+
* Provides a centralized way to instantiate agents with
|
|
8
|
+
* consistent configuration.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const factory = createAgentFactory({
|
|
13
|
+
* defaultModel: mistral('mistral-large-latest'),
|
|
14
|
+
* registry: agentRegistry,
|
|
15
|
+
* toolHandlers: globalToolHandlers,
|
|
16
|
+
* sessionStore: mySessionStore,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* const agent = await factory.create('support.bot');
|
|
20
|
+
* const result = await agent.generate({ prompt: 'Help me with...' });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
var AgentFactory = class {
|
|
24
|
+
config;
|
|
25
|
+
cache = /* @__PURE__ */ new Map();
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.config = config;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create an agent by name.
|
|
31
|
+
*
|
|
32
|
+
* @param name - Agent name (e.g., "support.bot")
|
|
33
|
+
* @param version - Optional specific version
|
|
34
|
+
* @param options - Optional creation options
|
|
35
|
+
*/
|
|
36
|
+
async create(name, version, options) {
|
|
37
|
+
const spec = this.config.registry.require(name, version);
|
|
38
|
+
return this.createFromSpec(spec, options);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Create an agent from a spec directly.
|
|
42
|
+
*
|
|
43
|
+
* @param spec - Agent specification
|
|
44
|
+
* @param options - Optional creation options
|
|
45
|
+
*/
|
|
46
|
+
async createFromSpec(spec, options) {
|
|
47
|
+
const mergedHandlers = new Map(this.config.toolHandlers);
|
|
48
|
+
if (options?.toolHandlers) for (const [key, handler] of options.toolHandlers) mergedHandlers.set(key, handler);
|
|
49
|
+
const mergedTools = {
|
|
50
|
+
...this.config.additionalTools,
|
|
51
|
+
...options?.additionalTools
|
|
52
|
+
};
|
|
53
|
+
return ContractSpecAgent.create({
|
|
54
|
+
spec,
|
|
55
|
+
model: options?.model ?? this.config.defaultModel,
|
|
56
|
+
toolHandlers: mergedHandlers,
|
|
57
|
+
knowledgeRetriever: this.config.knowledgeRetriever,
|
|
58
|
+
sessionStore: this.config.sessionStore,
|
|
59
|
+
telemetryCollector: this.config.telemetryCollector,
|
|
60
|
+
additionalTools: mergedTools
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get or create a cached agent instance.
|
|
65
|
+
*
|
|
66
|
+
* Use this when you want to reuse agent instances.
|
|
67
|
+
*
|
|
68
|
+
* @param name - Agent name
|
|
69
|
+
* @param version - Optional specific version
|
|
70
|
+
*/
|
|
71
|
+
async getOrCreate(name, version) {
|
|
72
|
+
const spec = this.config.registry.require(name, version);
|
|
73
|
+
const cacheKey = `${spec.meta.name}.v${spec.meta.version}`;
|
|
74
|
+
let agent = this.cache.get(cacheKey);
|
|
75
|
+
if (!agent) {
|
|
76
|
+
agent = await this.createFromSpec(spec);
|
|
77
|
+
this.cache.set(cacheKey, agent);
|
|
78
|
+
}
|
|
79
|
+
return agent;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Clear the agent cache.
|
|
83
|
+
*/
|
|
84
|
+
clearCache() {
|
|
85
|
+
this.cache.clear();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* List all available agent names.
|
|
89
|
+
*/
|
|
90
|
+
listAvailable() {
|
|
91
|
+
return this.config.registry.listNames();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Create an agent factory.
|
|
96
|
+
*/
|
|
97
|
+
function createAgentFactory(config) {
|
|
98
|
+
return new AgentFactory(config);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
export { AgentFactory, createAgentFactory };
|
|
@@ -1 +1,147 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { agentKey } from "../spec/spec.js";
|
|
2
|
+
import { specToolsToAISDKTools } from "../tools/tool-adapter.js";
|
|
3
|
+
import { createKnowledgeQueryTool } from "../tools/knowledge-tool.js";
|
|
4
|
+
import { injectStaticKnowledge } from "../knowledge/injector.js";
|
|
5
|
+
import { generateSessionId } from "../session/store.js";
|
|
6
|
+
import { trackAgentStep } from "../telemetry/adapter.js";
|
|
7
|
+
import { Experimental_Agent, stepCountIs } from "ai";
|
|
8
|
+
import * as z$1 from "zod";
|
|
9
|
+
|
|
10
|
+
//#region src/agent/contract-spec-agent.ts
|
|
11
|
+
/**
|
|
12
|
+
* Call options schema for AI SDK v6.
|
|
13
|
+
* Maps ContractSpec's tenant/actor system to AI SDK callOptionsSchema.
|
|
14
|
+
*/
|
|
15
|
+
const ContractSpecCallOptionsSchema = z$1.object({
|
|
16
|
+
tenantId: z$1.string().optional(),
|
|
17
|
+
actorId: z$1.string().optional(),
|
|
18
|
+
sessionId: z$1.string().optional(),
|
|
19
|
+
metadata: z$1.record(z$1.string(), z$1.unknown()).optional()
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* ContractSpec Agent implementation using AI SDK v6.
|
|
23
|
+
*
|
|
24
|
+
* Integrates ContractSpec's spec-first governance with AI SDK's
|
|
25
|
+
* ToolLoopAgent, providing:
|
|
26
|
+
* - Spec-defined tools with type-safe handlers
|
|
27
|
+
* - Hybrid knowledge injection (static + dynamic RAG)
|
|
28
|
+
* - Session persistence
|
|
29
|
+
* - Telemetry for evolution
|
|
30
|
+
* - MCP interoperability
|
|
31
|
+
*/
|
|
32
|
+
var ContractSpecAgent = class ContractSpecAgent {
|
|
33
|
+
version = "agent-v1";
|
|
34
|
+
id;
|
|
35
|
+
spec;
|
|
36
|
+
tools;
|
|
37
|
+
inner;
|
|
38
|
+
config;
|
|
39
|
+
instructions;
|
|
40
|
+
constructor(config, instructions, tools) {
|
|
41
|
+
this.config = config;
|
|
42
|
+
this.spec = config.spec;
|
|
43
|
+
this.id = agentKey(config.spec.meta);
|
|
44
|
+
this.tools = tools;
|
|
45
|
+
this.instructions = instructions;
|
|
46
|
+
this.inner = new Experimental_Agent({
|
|
47
|
+
model: config.model,
|
|
48
|
+
instructions,
|
|
49
|
+
tools,
|
|
50
|
+
stopWhen: stepCountIs(config.spec.maxSteps ?? 10),
|
|
51
|
+
callOptionsSchema: ContractSpecCallOptionsSchema,
|
|
52
|
+
onStepFinish: async (step) => {
|
|
53
|
+
await this.handleStepFinish(step);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Create a ContractSpecAgent instance.
|
|
59
|
+
* This is async because knowledge injection may need to fetch static content.
|
|
60
|
+
*/
|
|
61
|
+
static async create(config) {
|
|
62
|
+
const instructions = await injectStaticKnowledge(config.spec.instructions, config.spec.knowledge ?? [], config.knowledgeRetriever);
|
|
63
|
+
const specTools = specToolsToAISDKTools(config.spec.tools, config.toolHandlers, { agentId: agentKey(config.spec.meta) });
|
|
64
|
+
const knowledgeTool = config.knowledgeRetriever ? createKnowledgeQueryTool(config.knowledgeRetriever, config.spec.knowledge ?? []) : null;
|
|
65
|
+
return new ContractSpecAgent(config, instructions, {
|
|
66
|
+
...specTools,
|
|
67
|
+
...knowledgeTool ? { query_knowledge: knowledgeTool } : {},
|
|
68
|
+
...config.additionalTools ?? {}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generate a response (non-streaming).
|
|
73
|
+
*/
|
|
74
|
+
async generate(params) {
|
|
75
|
+
const sessionId = params.options?.sessionId ?? generateSessionId();
|
|
76
|
+
if (this.config.sessionStore) {
|
|
77
|
+
if (!await this.config.sessionStore.get(sessionId)) await this.config.sessionStore.create({
|
|
78
|
+
sessionId,
|
|
79
|
+
agentId: this.id,
|
|
80
|
+
tenantId: params.options?.tenantId,
|
|
81
|
+
actorId: params.options?.actorId,
|
|
82
|
+
status: "running",
|
|
83
|
+
messages: [],
|
|
84
|
+
steps: [],
|
|
85
|
+
metadata: params.options?.metadata
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
const prompt = params.systemOverride ? `${this.instructions}\n\n${params.systemOverride}\n\n${params.prompt}` : params.prompt;
|
|
89
|
+
const result = await this.inner.generate({
|
|
90
|
+
prompt,
|
|
91
|
+
abortSignal: params.signal,
|
|
92
|
+
options: {
|
|
93
|
+
tenantId: params.options?.tenantId,
|
|
94
|
+
actorId: params.options?.actorId,
|
|
95
|
+
sessionId,
|
|
96
|
+
metadata: params.options?.metadata
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
if (this.config.sessionStore) await this.config.sessionStore.update(sessionId, { status: "completed" });
|
|
100
|
+
return {
|
|
101
|
+
text: result.text,
|
|
102
|
+
steps: result.steps,
|
|
103
|
+
toolCalls: result.toolCalls.map((tc) => ({
|
|
104
|
+
type: "tool-call",
|
|
105
|
+
toolCallId: tc.toolCallId,
|
|
106
|
+
toolName: tc.toolName,
|
|
107
|
+
args: "args" in tc ? tc.args : "input" in tc ? tc.input : void 0
|
|
108
|
+
})),
|
|
109
|
+
toolResults: result.toolResults.map((tr) => ({
|
|
110
|
+
type: "tool-result",
|
|
111
|
+
toolCallId: tr.toolCallId,
|
|
112
|
+
toolName: tr.toolName,
|
|
113
|
+
output: tr.output
|
|
114
|
+
})),
|
|
115
|
+
finishReason: result.finishReason,
|
|
116
|
+
usage: result.usage
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Stream a response with real-time updates.
|
|
121
|
+
*/
|
|
122
|
+
async stream(params) {
|
|
123
|
+
const sessionId = params.options?.sessionId ?? generateSessionId();
|
|
124
|
+
const prompt = params.systemOverride ? `${this.instructions}\n\n${params.systemOverride}\n\n${params.prompt}` : params.prompt;
|
|
125
|
+
return this.inner.stream({
|
|
126
|
+
prompt,
|
|
127
|
+
abortSignal: params.signal,
|
|
128
|
+
options: {
|
|
129
|
+
tenantId: params.options?.tenantId,
|
|
130
|
+
actorId: params.options?.actorId,
|
|
131
|
+
sessionId,
|
|
132
|
+
metadata: params.options?.metadata
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Handle step completion for persistence and telemetry.
|
|
138
|
+
*/
|
|
139
|
+
async handleStepFinish(step) {
|
|
140
|
+
const sessionId = step.options?.sessionId;
|
|
141
|
+
if (sessionId && this.config.sessionStore) await this.config.sessionStore.appendStep(sessionId, step);
|
|
142
|
+
if (this.config.telemetryCollector) await trackAgentStep(this.config.telemetryCollector, this.id, step);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
//#endregion
|
|
147
|
+
export { ContractSpecAgent };
|
package/dist/agent/index.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
import{ContractSpecAgent
|
|
1
|
+
import { ContractSpecAgent } from "./contract-spec-agent.js";
|
|
2
|
+
import { AgentFactory, createAgentFactory } from "./agent-factory.js";
|
|
3
|
+
|
|
4
|
+
export { AgentFactory, ContractSpecAgent, createAgentFactory };
|
package/dist/approval/index.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{ApprovalWorkflow
|
|
1
|
+
import { ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow } from "./workflow.js";
|
|
2
|
+
|
|
3
|
+
export { ApprovalWorkflow, InMemoryApprovalStore, createApprovalWorkflow };
|
|
@@ -1 +1,159 @@
|
|
|
1
|
-
import{randomUUID
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1 +1,21 @@
|
|
|
1
|
-
import
|
|
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 };
|
package/dist/knowledge/index.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{createKnowledgeInjector
|
|
1
|
+
import { createKnowledgeInjector, injectStaticKnowledge } from "./injector.js";
|
|
2
|
+
|
|
3
|
+
export { createKnowledgeInjector, injectStaticKnowledge };
|
|
@@ -1,4 +1,38 @@
|
|
|
1
|
-
|
|
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}
|
|
2
36
|
|
|
3
37
|
---
|
|
4
38
|
|
|
@@ -6,8 +40,18 @@ async function e(e,t,n){if(!n)return e;let r=t.filter(e=>e.required);if(r.length
|
|
|
6
40
|
|
|
7
41
|
The following information is provided for your reference. Use it to inform your responses.
|
|
8
42
|
|
|
9
|
-
${
|
|
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
|
+
}
|
|
10
55
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`)}`}function t(t){return{inject:(n,r)=>e(n,r,t),hasSpace:e=>t?.supportsSpace(e)??!1,listSpaces:()=>t?.listSpaces()??[]}}export{t as createKnowledgeInjector,e as injectStaticKnowledge};
|
|
56
|
+
//#endregion
|
|
57
|
+
export { createKnowledgeInjector, injectStaticKnowledge };
|
package/dist/memory/in-memory.js
CHANGED
|
@@ -1,2 +1,47 @@
|
|
|
1
|
-
import{BaseAgentMemoryManager
|
|
2
|
-
|
|
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 };
|
package/dist/memory/index.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
import{BaseAgentMemoryManager
|
|
1
|
+
import { BaseAgentMemoryManager, trackMessageInMemory } from "./manager.js";
|
|
2
|
+
import { InMemoryAgentMemory } from "./in-memory.js";
|
|
3
|
+
|
|
4
|
+
export { BaseAgentMemoryManager, InMemoryAgentMemory, trackMessageInMemory };
|
package/dist/memory/manager.js
CHANGED
|
@@ -1 +1,79 @@
|
|
|
1
|
-
import{randomUUID
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
//#region src/memory/manager.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extract text content from a ModelMessage.
|
|
6
|
+
* Handles both string content and array content parts.
|
|
7
|
+
*/
|
|
8
|
+
function extractMessageContent(message) {
|
|
9
|
+
const content = message.content;
|
|
10
|
+
if (typeof content === "string") return content;
|
|
11
|
+
if (Array.isArray(content)) return content.map((part) => {
|
|
12
|
+
if (typeof part === "string") return part;
|
|
13
|
+
if ("text" in part && typeof part.text === "string") return part.text;
|
|
14
|
+
return "";
|
|
15
|
+
}).filter(Boolean).join("");
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract text content from an AgentMessage.
|
|
20
|
+
*/
|
|
21
|
+
function extractAgentMessageContent(message) {
|
|
22
|
+
const content = message.content;
|
|
23
|
+
if (typeof content === "string") return content;
|
|
24
|
+
if (Array.isArray(content)) return content.map((part) => {
|
|
25
|
+
if (typeof part === "string") return part;
|
|
26
|
+
if ("text" in part && typeof part.text === "string") return part.text;
|
|
27
|
+
return "";
|
|
28
|
+
}).filter(Boolean).join("");
|
|
29
|
+
return "";
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Map ModelMessage role to memory entry type.
|
|
33
|
+
*/
|
|
34
|
+
function roleToEntryType(role) {
|
|
35
|
+
switch (role) {
|
|
36
|
+
case "assistant": return "assistant";
|
|
37
|
+
case "system": return "system";
|
|
38
|
+
case "tool": return "tool";
|
|
39
|
+
case "user":
|
|
40
|
+
default: return "user";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var BaseAgentMemoryManager = class {
|
|
44
|
+
async append(session, entry) {
|
|
45
|
+
const current = await this.load(session.sessionId) ?? this.bootstrapMemory(session);
|
|
46
|
+
const finalEntry = {
|
|
47
|
+
id: randomUUID(),
|
|
48
|
+
createdAt: entry.createdAt ?? /* @__PURE__ */ new Date(),
|
|
49
|
+
...entry
|
|
50
|
+
};
|
|
51
|
+
current.memory.entries.push(finalEntry);
|
|
52
|
+
await this.save(current);
|
|
53
|
+
return current;
|
|
54
|
+
}
|
|
55
|
+
async summarize(_session) {}
|
|
56
|
+
async prune(_session) {}
|
|
57
|
+
bootstrapMemory(session) {
|
|
58
|
+
return {
|
|
59
|
+
session,
|
|
60
|
+
memory: { entries: session.messages.map((message) => ({
|
|
61
|
+
id: randomUUID(),
|
|
62
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
63
|
+
type: roleToEntryType(message.role),
|
|
64
|
+
content: extractMessageContent(message)
|
|
65
|
+
})) }
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
function trackMessageInMemory(manager, session, message) {
|
|
70
|
+
if (!manager) return;
|
|
71
|
+
manager.append(session, {
|
|
72
|
+
type: message.role,
|
|
73
|
+
content: extractAgentMessageContent(message),
|
|
74
|
+
metadata: message.metadata
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
export { BaseAgentMemoryManager, trackMessageInMemory };
|
package/dist/schema/index.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
import{jsonSchemaToZod
|
|
1
|
+
import { jsonSchemaToZod, jsonSchemaToZodSafe } from "./json-schema-to-zod.js";
|
|
2
|
+
import { SchemaOutput, enumToChoiceOutput, jsonSchemaToArrayOutput, jsonSchemaToOutput, textOutput, zodToOutput } from "./schema-output.js";
|
|
3
|
+
|
|
4
|
+
export { SchemaOutput, enumToChoiceOutput, jsonSchemaToArrayOutput, jsonSchemaToOutput, jsonSchemaToZod, jsonSchemaToZodSafe, textOutput, zodToOutput };
|