@migor/agentia 0.0.2 → 0.2.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/README.md +62 -6
- package/dist/core/json.d.ts +2 -0
- package/dist/core/json.js +12 -0
- package/dist/core/json.js.map +1 -0
- package/dist/core/schema.d.ts +2 -1
- package/dist/core/schema.js +11 -9
- package/dist/core/schema.js.map +1 -1
- package/dist/core/tool.d.ts +19 -1
- package/dist/engine/loop.d.ts +11 -3
- package/dist/engine/loop.js +69 -15
- package/dist/engine/loop.js.map +1 -1
- package/dist/engine/replay.d.ts +31 -0
- package/dist/engine/replay.js +107 -0
- package/dist/engine/replay.js.map +1 -0
- package/dist/engine/types.d.ts +18 -4
- package/dist/index.d.ts +18 -2
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/dist/run/async.d.ts +12 -17
- package/dist/run/async.js +66 -16
- package/dist/run/async.js.map +1 -1
- package/dist/run/http.d.ts +47 -0
- package/dist/run/http.js +119 -0
- package/dist/run/http.js.map +1 -0
- package/dist/run/memory.d.ts +18 -0
- package/dist/run/memory.js +18 -0
- package/dist/run/memory.js.map +1 -0
- package/dist/run/openai.d.ts +24 -0
- package/dist/run/openai.js +181 -0
- package/dist/run/openai.js.map +1 -0
- package/dist/run/otlp.d.ts +26 -0
- package/dist/run/otlp.js +105 -0
- package/dist/run/otlp.js.map +1 -0
- package/dist/run/redisStore.d.ts +54 -0
- package/dist/run/redisStore.js +72 -0
- package/dist/run/redisStore.js.map +1 -0
- package/dist/run/run.d.ts +10 -0
- package/dist/run/run.js +31 -0
- package/dist/run/run.js.map +1 -1
- package/dist/run/spec.d.ts +2 -1
- package/dist/run/spec.js.map +1 -1
- package/dist/run/sqliteStore.d.ts +24 -0
- package/dist/run/sqliteStore.js +60 -0
- package/dist/run/sqliteStore.js.map +1 -0
- package/dist/run/store.d.ts +12 -5
- package/dist/run/store.js.map +1 -1
- package/dist/toolkit/collect.d.ts +23 -0
- package/dist/toolkit/collect.js +45 -0
- package/dist/toolkit/collect.js.map +1 -0
- package/dist/toolkit/discover.js +7 -1
- package/dist/toolkit/discover.js.map +1 -1
- package/dist/toolkit/middleware.d.ts +27 -0
- package/dist/toolkit/middleware.js +15 -0
- package/dist/toolkit/middleware.js.map +1 -0
- package/dist/toolkit/module.d.ts +18 -0
- package/dist/toolkit/module.js +34 -1
- package/dist/toolkit/module.js.map +1 -1
- package/dist/toolkit/prompt.js +6 -20
- package/dist/toolkit/prompt.js.map +1 -1
- package/dist/toolkit/skill.js +8 -29
- package/dist/toolkit/skill.js.map +1 -1
- package/dist/toolkit/subagent.d.ts +6 -0
- package/dist/toolkit/subagent.js +16 -28
- package/dist/toolkit/subagent.js.map +1 -1
- package/dist/toolkit/tool.js +3 -25
- package/dist/toolkit/tool.js.map +1 -1
- package/dist/toolkit/zod.d.ts +26 -0
- package/dist/toolkit/zod.js +45 -0
- package/dist/toolkit/zod.js.map +1 -0
- package/package.json +27 -17
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
export function createOpenAIClient(opts = {}) {
|
|
2
|
+
const baseURL = (opts.baseURL ?? 'https://api.openai.com').replace(/\/+$/, '');
|
|
3
|
+
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
4
|
+
const apiKey = opts.apiKey ?? process.env.OPENAI_API_KEY;
|
|
5
|
+
return {
|
|
6
|
+
messages: {
|
|
7
|
+
stream(params) {
|
|
8
|
+
const textCallbacks = [];
|
|
9
|
+
return {
|
|
10
|
+
on(event, cb) {
|
|
11
|
+
if (event === 'text')
|
|
12
|
+
textCallbacks.push(cb);
|
|
13
|
+
},
|
|
14
|
+
async finalMessage() {
|
|
15
|
+
const res = await fetchImpl(`${baseURL}/v1/chat/completions`, {
|
|
16
|
+
method: 'POST',
|
|
17
|
+
headers: {
|
|
18
|
+
'content-type': 'application/json',
|
|
19
|
+
...(apiKey ? { authorization: `Bearer ${apiKey}` } : {}),
|
|
20
|
+
},
|
|
21
|
+
body: JSON.stringify(toOpenAIRequest(params)),
|
|
22
|
+
});
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
const body = await res.text();
|
|
25
|
+
throw new Error(`OpenAI 请求失败 ${res.status}: ${body.slice(0, 200)}`);
|
|
26
|
+
}
|
|
27
|
+
const data = (await res.json());
|
|
28
|
+
const message = toAnthropicMessage(data, params.model);
|
|
29
|
+
// 非流式模拟:完整文本一次性发给 text 回调
|
|
30
|
+
const fullText = message.content
|
|
31
|
+
.filter((b) => b.type === 'text')
|
|
32
|
+
.map((b) => b.text)
|
|
33
|
+
.join('');
|
|
34
|
+
if (fullText)
|
|
35
|
+
for (const cb of textCallbacks)
|
|
36
|
+
cb(fullText);
|
|
37
|
+
return message;
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** Anthropic 请求形态 → OpenAI chat.completions 请求 */
|
|
45
|
+
function toOpenAIRequest(params) {
|
|
46
|
+
const messages = [];
|
|
47
|
+
if (params.system) {
|
|
48
|
+
messages.push({
|
|
49
|
+
role: 'system',
|
|
50
|
+
content: typeof params.system === 'string'
|
|
51
|
+
? params.system
|
|
52
|
+
: params.system.map((b) => b.text).join('\n'),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
for (const m of params.messages) {
|
|
56
|
+
if (typeof m.content === 'string') {
|
|
57
|
+
messages.push({ role: m.role, content: m.content });
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (m.role === 'user') {
|
|
61
|
+
// tool_result blocks:每个 block 一条 role=tool 消息;其余合成一条 user
|
|
62
|
+
const blocks = m.content;
|
|
63
|
+
const toolResults = blocks.filter((b) => b.type === 'tool_result');
|
|
64
|
+
const rest = blocks.filter((b) => b.type !== 'tool_result');
|
|
65
|
+
for (const tr of toolResults) {
|
|
66
|
+
messages.push({
|
|
67
|
+
role: 'tool',
|
|
68
|
+
tool_call_id: tr.tool_use_id,
|
|
69
|
+
content: tr.content === undefined
|
|
70
|
+
? ''
|
|
71
|
+
: typeof tr.content === 'string'
|
|
72
|
+
? tr.content
|
|
73
|
+
: JSON.stringify(tr.content),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
if (rest.length > 0)
|
|
77
|
+
messages.push({ role: 'user', content: renderBlocks(rest) });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// assistant:文本部分进 content(无则 null),tool_use → tool_calls
|
|
81
|
+
const blocks = m.content;
|
|
82
|
+
const text = blocks
|
|
83
|
+
.filter((b) => b.type === 'text')
|
|
84
|
+
.map((b) => b.text)
|
|
85
|
+
.join('\n');
|
|
86
|
+
const toolUses = blocks.filter((b) => b.type === 'tool_use');
|
|
87
|
+
messages.push({
|
|
88
|
+
role: 'assistant',
|
|
89
|
+
content: text || null,
|
|
90
|
+
...(toolUses.length > 0
|
|
91
|
+
? {
|
|
92
|
+
tool_calls: toolUses.map((tu) => ({
|
|
93
|
+
id: tu.id,
|
|
94
|
+
type: 'function',
|
|
95
|
+
function: { name: tu.name, arguments: JSON.stringify(tu.input) },
|
|
96
|
+
})),
|
|
97
|
+
}
|
|
98
|
+
: {}),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
model: params.model,
|
|
104
|
+
max_tokens: params.max_tokens,
|
|
105
|
+
messages,
|
|
106
|
+
...(params.tools && params.tools.length > 0
|
|
107
|
+
? {
|
|
108
|
+
tools: params.tools.map((t) => ({
|
|
109
|
+
type: 'function',
|
|
110
|
+
function: {
|
|
111
|
+
name: t.name,
|
|
112
|
+
...(t.description ? { description: t.description } : {}),
|
|
113
|
+
parameters: t.input_schema,
|
|
114
|
+
},
|
|
115
|
+
})),
|
|
116
|
+
}
|
|
117
|
+
: {}),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/** user 消息中非 tool_result 的 blocks 合成一段文本(text 取文本,其余 JSON 兜底) */
|
|
121
|
+
function renderBlocks(blocks) {
|
|
122
|
+
return blocks
|
|
123
|
+
.map((b) => (b.type === 'text' ? b.text : JSON.stringify(b)))
|
|
124
|
+
.join('\n');
|
|
125
|
+
}
|
|
126
|
+
/** OpenAI chat.completions 响应 → Anthropic.Message */
|
|
127
|
+
function toAnthropicMessage(data, model) {
|
|
128
|
+
const choice = data.choices?.[0];
|
|
129
|
+
const msg = choice?.message ?? {};
|
|
130
|
+
const content = [];
|
|
131
|
+
if (typeof msg.content === 'string' && msg.content) {
|
|
132
|
+
content.push({ type: 'text', text: msg.content });
|
|
133
|
+
}
|
|
134
|
+
for (const tc of msg.tool_calls ?? []) {
|
|
135
|
+
let input;
|
|
136
|
+
try {
|
|
137
|
+
input = JSON.parse(tc.function.arguments);
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
// arguments 非法 JSON:原样字符串兜底,交给下游 schema 校验报 is_error
|
|
141
|
+
input = tc.function.arguments;
|
|
142
|
+
}
|
|
143
|
+
content.push({
|
|
144
|
+
type: 'tool_use',
|
|
145
|
+
id: tc.id,
|
|
146
|
+
name: tc.function.name,
|
|
147
|
+
input,
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
id: data.id ?? 'chatcmpl-unknown',
|
|
152
|
+
type: 'message',
|
|
153
|
+
role: 'assistant',
|
|
154
|
+
model: data.model ?? model,
|
|
155
|
+
content,
|
|
156
|
+
stop_reason: mapStopReason(choice?.finish_reason),
|
|
157
|
+
stop_sequence: null,
|
|
158
|
+
usage: {
|
|
159
|
+
input_tokens: data.usage?.prompt_tokens ?? 0,
|
|
160
|
+
output_tokens: data.usage?.completion_tokens ?? 0,
|
|
161
|
+
// OpenAI 形态无 cache 计量:恒 0
|
|
162
|
+
cache_creation_input_tokens: 0,
|
|
163
|
+
cache_read_input_tokens: 0,
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/** finish_reason → Anthropic stop_reason(content_filter→refusal 为近似映射) */
|
|
168
|
+
function mapStopReason(finish) {
|
|
169
|
+
switch (finish) {
|
|
170
|
+
case 'tool_calls':
|
|
171
|
+
return 'tool_use';
|
|
172
|
+
case 'length':
|
|
173
|
+
return 'max_tokens';
|
|
174
|
+
case 'content_filter':
|
|
175
|
+
return 'refusal';
|
|
176
|
+
case 'stop':
|
|
177
|
+
default:
|
|
178
|
+
return 'end_turn';
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/run/openai.ts"],"names":[],"mappings":"AA0BA,MAAM,UAAU,kBAAkB,CAAC,IAAI,GAAwB,EAAE;IAC/D,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,wBAAwB,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAEzD,OAAO;QACL,QAAQ,EAAE;YACR,MAAM,CAAC,MAAM;gBACX,MAAM,aAAa,GAAmC,EAAE,CAAC;gBACzD,OAAO;oBACL,EAAE,CAAC,KAAa,EAAE,EAA2B;wBAC3C,IAAI,KAAK,KAAK,MAAM;4BAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC/C,CAAC;oBACD,KAAK,CAAC,YAAY;wBAChB,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,OAAO,sBAAsB,EAAE;4BAC5D,MAAM,EAAE,MAAM;4BACd,OAAO,EAAE;gCACP,cAAc,EAAE,kBAAkB;gCAClC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;6BACzD;4BACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;yBAC9C,CAAC,CAAC;wBACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;4BACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;4BAC9B,MAAM,IAAI,KAAK,CAAC,eAAe,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;wBACtE,CAAC;wBACD,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAuB,CAAC;wBACtD,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;wBACvD,0BAA0B;wBAC1B,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO;6BAC7B,MAAM,CAAC,CAAC,CAAC,EAA4B,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;6BAC1D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;6BAClB,IAAI,CAAC,EAAE,CAAC,CAAC;wBACZ,IAAI,QAAQ;4BAAE,KAAK,MAAM,EAAE,IAAI,aAAa;gCAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;wBAC3D,OAAO,OAAO,CAAC;oBACjB,CAAC;iBACF,CAAC;YACJ,CAAC;SACF;KACF,CAAC;AACJ,CAAC;AAgDD,kDAAkD;AAClD,SAAS,eAAe,CAAC,MAAoB;IAC3C,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,QAAQ;YACd,OAAO,EACL,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ;gBAC/B,CAAC,CAAC,MAAM,CAAC,MAAM;gBACf,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;SAClD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACtB,0DAA0D;YAC1D,MAAM,MAAM,GAAG,CAAC,CAAC,OAAwC,CAAC;YAC1D,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAC/B,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CACrE,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;YAC5D,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;gBAC7B,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,MAAM;oBACZ,YAAY,EAAE,EAAE,CAAC,WAAW;oBAC5B,OAAO,EACL,EAAE,CAAC,OAAO,KAAK,SAAS;wBACtB,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,KAAK,QAAQ;4BAC9B,CAAC,CAAC,EAAE,CAAC,OAAO;4BACZ,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,OAAO,CAAC;iBACnC,CAAC,CAAC;YACL,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;gBAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;aAAM,CAAC;YACN,yDAAyD;YACzD,MAAM,MAAM,GAAG,CAAC,CAAC,OAAwC,CAAC;YAC1D,MAAM,IAAI,GAAG,MAAM;iBAChB,MAAM,CAAC,CAAC,CAAC,EAAiC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,CAAC,IAAI,CAAC,CAAC;YACd,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAC5B,CAAC,CAAC,EAAoC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAC/D,CAAC;YACF,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,IAAI,IAAI,IAAI;gBACrB,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;oBACrB,CAAC,CAAC;wBACE,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;4BAChC,EAAE,EAAE,EAAE,CAAC,EAAE;4BACT,IAAI,EAAE,UAAmB;4BACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE;yBACjE,CAAC,CAAC;qBACJ;oBACH,CAAC,CAAC,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ;QACR,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YACzC,CAAC,CAAC;gBACE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC9B,IAAI,EAAE,UAAmB;oBACzB,QAAQ,EAAE;wBACR,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;wBACxD,UAAU,EAAE,CAAC,CAAC,YAAY;qBAC3B;iBACF,CAAC,CAAC;aACJ;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC;AAED,iEAAiE;AACjE,SAAS,YAAY,CAAC,MAAqC;IACzD,OAAO,MAAM;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAE,CAA8B,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;SAC1F,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,qDAAqD;AACrD,SAAS,kBAAkB,CAAC,IAAwB,EAAE,KAAa;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;IAElC,MAAM,OAAO,GAA6B,EAAE,CAAC;IAC7C,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAyB,CAAC,CAAC;IAC3E,CAAC;IACD,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,UAAU,IAAI,EAAE,EAAE,CAAC;QACtC,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YACH,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;YACrD,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QAChC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,UAAU;YAChB,EAAE,EAAE,EAAE,CAAC,EAAE;YACT,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI;YACtB,KAAK;SACoB,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,kBAAkB;QACjC,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;QAC1B,OAAO;QACP,WAAW,EAAE,aAAa,CAAC,MAAM,EAAE,aAAa,CAAC;QACjD,aAAa,EAAE,IAAI;QACnB,KAAK,EAAE;YACL,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;YAC5C,aAAa,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;YACjD,0BAA0B;YAC1B,2BAA2B,EAAE,CAAC;YAC9B,uBAAuB,EAAE,CAAC;SAC3B;KACmB,CAAC;AACzB,CAAC;AAED,0EAA0E;AAC1E,SAAS,aAAa,CAAC,MAAiC;IACtD,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,YAAY;YACf,OAAO,UAAU,CAAC;QACpB,KAAK,QAAQ;YACX,OAAO,YAAY,CAAC;QACtB,KAAK,gBAAgB;YACnB,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM,CAAC;QACZ;YACE,OAAO,UAAU,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Trace } from '../core/trace.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— OTLP trace 导出(spec §9.3 生产方向,roadmap R3)。
|
|
4
|
+
*
|
|
5
|
+
* 把一次 run 的 Trace 映射为 OTLP/JSON(resourceSpans → scopeSpans → spans),
|
|
6
|
+
* 用全局 fetch POST 到 `${endpoint}/v1/traces`,零外部依赖:
|
|
7
|
+
* - traceId/spanId/parentSpanId:内部用 UUID,OTLP 要求 hex —— 去掉 '-' 即 32 位 hex;
|
|
8
|
+
* - kind 固定 SPAN_KIND_INTERNAL(1);时间 ms × 1e6 转 string 纳秒;
|
|
9
|
+
* - status:ok → STATUS_CODE_OK,error → STATUS_CODE_ERROR(附 error.message);
|
|
10
|
+
* - attributes 展平 span.attributes + usage(usage.* 前缀);
|
|
11
|
+
* - events → OTLP events(body 的原始类型字段进 attributes,其余 JSON 化)。
|
|
12
|
+
*
|
|
13
|
+
* 非 2xx 抛错(含状态码与响应前 200 字符)。导出失败不影响 run 本身 —— 调用方自行取舍。
|
|
14
|
+
*/
|
|
15
|
+
export interface OtlpExporterOptions {
|
|
16
|
+
/** collector 基地址,例如 http://localhost:4318(尾部斜杠会被去掉) */
|
|
17
|
+
endpoint: string;
|
|
18
|
+
/** 额外请求头(鉴权等) */
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
/** resource 的 service.name,缺省 'agentia' */
|
|
21
|
+
serviceName?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface OtlpExporter {
|
|
24
|
+
export(trace: Trace): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export declare function createOtlpExporter(opts: OtlpExporterOptions): OtlpExporter;
|
package/dist/run/otlp.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
function toValue(v) {
|
|
2
|
+
if (typeof v === 'string')
|
|
3
|
+
return { stringValue: v };
|
|
4
|
+
if (typeof v === 'boolean')
|
|
5
|
+
return { boolValue: v };
|
|
6
|
+
// OTLP int64 走 string;小数用 double
|
|
7
|
+
return Number.isInteger(v) ? { intValue: String(v) } : { doubleValue: v };
|
|
8
|
+
}
|
|
9
|
+
/** 内部 UUID → OTLP hex(去掉 '-' 即 32 位小写 hex) */
|
|
10
|
+
function hexId(id) {
|
|
11
|
+
return id.replaceAll('-', '');
|
|
12
|
+
}
|
|
13
|
+
/** ms → string 纳秒 */
|
|
14
|
+
function nanos(ms) {
|
|
15
|
+
return String(Math.round(ms * 1e6));
|
|
16
|
+
}
|
|
17
|
+
function spanAttributes(span) {
|
|
18
|
+
const attrs = Object.entries(span.attributes).map(([key, v]) => ({
|
|
19
|
+
key,
|
|
20
|
+
value: toValue(v),
|
|
21
|
+
}));
|
|
22
|
+
if (span.usage) {
|
|
23
|
+
const u = span.usage;
|
|
24
|
+
attrs.push({ key: 'usage.inputTokens', value: toValue(u.inputTokens) }, { key: 'usage.outputTokens', value: toValue(u.outputTokens) }, { key: 'usage.cacheReadTokens', value: toValue(u.cacheReadTokens) }, { key: 'usage.cacheCreationTokens', value: toValue(u.cacheCreationTokens) });
|
|
25
|
+
if (u.costEstimate !== undefined) {
|
|
26
|
+
attrs.push({ key: 'usage.costEstimate', value: toValue(u.costEstimate) });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return attrs;
|
|
30
|
+
}
|
|
31
|
+
function eventAttributes(body) {
|
|
32
|
+
if (body === undefined)
|
|
33
|
+
return [];
|
|
34
|
+
if (body && typeof body === 'object' && !Array.isArray(body)) {
|
|
35
|
+
return Object.entries(body).map(([key, v]) => ({
|
|
36
|
+
key,
|
|
37
|
+
value: typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean'
|
|
38
|
+
? toValue(v)
|
|
39
|
+
: { stringValue: JSON.stringify(v) },
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
return [{ key: 'body', value: { stringValue: JSON.stringify(body) } }];
|
|
43
|
+
}
|
|
44
|
+
function mapEvent(e) {
|
|
45
|
+
return {
|
|
46
|
+
timeUnixNano: nanos(e.time),
|
|
47
|
+
name: e.name,
|
|
48
|
+
attributes: eventAttributes(e.body),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function mapSpan(span) {
|
|
52
|
+
return {
|
|
53
|
+
traceId: hexId(span.traceId),
|
|
54
|
+
spanId: hexId(span.spanId),
|
|
55
|
+
...(span.parentSpanId ? { parentSpanId: hexId(span.parentSpanId) } : {}),
|
|
56
|
+
name: span.name,
|
|
57
|
+
kind: 1, // SPAN_KIND_INTERNAL
|
|
58
|
+
startTimeUnixNano: nanos(span.startedAt),
|
|
59
|
+
...(span.endedAt !== undefined ? { endTimeUnixNano: nanos(span.endedAt) } : {}),
|
|
60
|
+
attributes: spanAttributes(span),
|
|
61
|
+
events: span.events.map(mapEvent),
|
|
62
|
+
status: span.status === 'error'
|
|
63
|
+
? {
|
|
64
|
+
code: 'STATUS_CODE_ERROR',
|
|
65
|
+
...(span.error ? { message: span.error.message } : {}),
|
|
66
|
+
}
|
|
67
|
+
: { code: 'STATUS_CODE_OK' },
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function createOtlpExporter(opts) {
|
|
71
|
+
const endpoint = opts.endpoint.replace(/\/+$/, '');
|
|
72
|
+
const serviceName = opts.serviceName ?? 'agentia';
|
|
73
|
+
return {
|
|
74
|
+
async export(trace) {
|
|
75
|
+
const payload = {
|
|
76
|
+
resourceSpans: [
|
|
77
|
+
{
|
|
78
|
+
resource: {
|
|
79
|
+
attributes: [{ key: 'service.name', value: { stringValue: serviceName } }],
|
|
80
|
+
},
|
|
81
|
+
scopeSpans: [
|
|
82
|
+
{
|
|
83
|
+
scope: { name: 'agentia' },
|
|
84
|
+
spans: trace.spans.map(mapSpan),
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
const res = await fetch(`${endpoint}/v1/traces`, {
|
|
91
|
+
method: 'POST',
|
|
92
|
+
headers: {
|
|
93
|
+
'content-type': 'application/json',
|
|
94
|
+
...opts.headers,
|
|
95
|
+
},
|
|
96
|
+
body: JSON.stringify(payload),
|
|
97
|
+
});
|
|
98
|
+
if (!res.ok) {
|
|
99
|
+
const text = (await res.text()).slice(0, 200);
|
|
100
|
+
throw new Error(`OTLP 导出失败: HTTP ${res.status} ${text}`);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=otlp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otlp.js","sourceRoot":"","sources":["../../src/run/otlp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { TaskRecord, TaskStore } from './store.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— Redis 宿主 TaskStore(spec §6.6:异步耐久 = 换宿主不换语义,roadmap R6)。
|
|
4
|
+
*
|
|
5
|
+
* duck-typed 客户端:框架不 import 任何 redis 包,用户传 ioredis / node-redis /
|
|
6
|
+
* 任何满足 RedisLike 结构面的客户端(含测试 fake)。TaskStore 方法已放宽为
|
|
7
|
+
* MaybePromise(见 store.ts),本实现全部异步。
|
|
8
|
+
*
|
|
9
|
+
* 存储模型(prefix 缺省 'agentia:'):
|
|
10
|
+
* - `${prefix}task:<taskId>` → 整行记录 JSON(save = SET 覆写,last-wins);
|
|
11
|
+
* - `${prefix}idem:<idempotencyKey>` → taskId(同键重提覆写,byIdempotency last-wins)。
|
|
12
|
+
*
|
|
13
|
+
* 语义对照 FileTaskStore / SqliteTaskStore:save 覆写、byIdempotency 取最近、
|
|
14
|
+
* clear 清空本前缀全部 key。差异在 list 序:Redis 本身无序,按 createdAt
|
|
15
|
+
* (同刻按 taskId)排序 —— 「写入顺序」语义的确定性近似(FileTaskStore 保插入位、
|
|
16
|
+
* SqliteTaskStore 覆写后移到末尾,三者本就不逐字一致,排序给出稳定契约)。
|
|
17
|
+
*
|
|
18
|
+
* 前提:**单宿主写者**。save 是两次 SET(记录 + 幂等索引),未走 MULTI 事务;
|
|
19
|
+
* 多写者并发下同键写可能交错,跨进程协调属部署层职责(与 FileTaskStore 一致)。
|
|
20
|
+
*/
|
|
21
|
+
export interface RedisLike {
|
|
22
|
+
get(key: string): Promise<string | null>;
|
|
23
|
+
set(key: string, value: string): Promise<unknown>;
|
|
24
|
+
/** 单键删除(ioredis / node-redis 的公共最小面;批量清理由多次单删组成) */
|
|
25
|
+
del(key: string): Promise<unknown>;
|
|
26
|
+
/** 模式枚举(node-redis / ioredis 均有);与 scanIterator 至少提供其一 */
|
|
27
|
+
keys?(pattern: string): Promise<string[]>;
|
|
28
|
+
/**
|
|
29
|
+
* 增量枚举(node-redis v4+ 形态,生产友好不阻塞);yield 单键或一批键均可。
|
|
30
|
+
* 提供时优先于 keys 使用。
|
|
31
|
+
*/
|
|
32
|
+
scanIterator?(opts?: {
|
|
33
|
+
MATCH?: string;
|
|
34
|
+
COUNT?: number;
|
|
35
|
+
}): AsyncIterable<string | string[]>;
|
|
36
|
+
}
|
|
37
|
+
export interface RedisTaskStoreOptions {
|
|
38
|
+
/** key 前缀,缺省 'agentia:' */
|
|
39
|
+
prefix?: string;
|
|
40
|
+
}
|
|
41
|
+
export declare class RedisTaskStore implements TaskStore {
|
|
42
|
+
private readonly client;
|
|
43
|
+
private readonly prefix;
|
|
44
|
+
constructor(client: RedisLike, opts?: RedisTaskStoreOptions);
|
|
45
|
+
private taskKey;
|
|
46
|
+
private idemKey;
|
|
47
|
+
save(rec: TaskRecord): Promise<void>;
|
|
48
|
+
get(taskId: string): Promise<TaskRecord | undefined>;
|
|
49
|
+
byIdempotency(key: string): Promise<TaskRecord | undefined>;
|
|
50
|
+
list(): Promise<TaskRecord[]>;
|
|
51
|
+
clear(): Promise<void>;
|
|
52
|
+
/** 按键枚举:优先 scanIterator,缺则退回 keys(pattern) */
|
|
53
|
+
private enumerate;
|
|
54
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export class RedisTaskStore {
|
|
2
|
+
client;
|
|
3
|
+
prefix;
|
|
4
|
+
constructor(client, opts = {}) {
|
|
5
|
+
this.client = client;
|
|
6
|
+
if (!client.scanIterator && !client.keys) {
|
|
7
|
+
throw new Error('RedisTaskStore 需要 client 提供 scanIterator 或 keys 之一(list/clear 依赖按键枚举)');
|
|
8
|
+
}
|
|
9
|
+
this.prefix = opts.prefix ?? 'agentia:';
|
|
10
|
+
}
|
|
11
|
+
taskKey(taskId) {
|
|
12
|
+
return `${this.prefix}task:${taskId}`;
|
|
13
|
+
}
|
|
14
|
+
idemKey(key) {
|
|
15
|
+
return `${this.prefix}idem:${key}`;
|
|
16
|
+
}
|
|
17
|
+
async save(rec) {
|
|
18
|
+
await this.client.set(this.taskKey(rec.taskId), JSON.stringify(rec));
|
|
19
|
+
if (rec.idempotencyKey)
|
|
20
|
+
await this.client.set(this.idemKey(rec.idempotencyKey), rec.taskId);
|
|
21
|
+
}
|
|
22
|
+
async get(taskId) {
|
|
23
|
+
return parseRecord(await this.client.get(this.taskKey(taskId)));
|
|
24
|
+
}
|
|
25
|
+
async byIdempotency(key) {
|
|
26
|
+
const taskId = await this.client.get(this.idemKey(key));
|
|
27
|
+
return taskId ? this.get(taskId) : undefined;
|
|
28
|
+
}
|
|
29
|
+
async list() {
|
|
30
|
+
const keys = await this.enumerate(`${this.prefix}task:*`);
|
|
31
|
+
const recs = [];
|
|
32
|
+
for (const k of keys) {
|
|
33
|
+
const rec = parseRecord(await this.client.get(k));
|
|
34
|
+
if (rec)
|
|
35
|
+
recs.push(rec);
|
|
36
|
+
}
|
|
37
|
+
recs.sort((a, b) => a.createdAt - b.createdAt || (a.taskId < b.taskId ? -1 : a.taskId > b.taskId ? 1 : 0));
|
|
38
|
+
return recs;
|
|
39
|
+
}
|
|
40
|
+
async clear() {
|
|
41
|
+
const keys = await this.enumerate(`${this.prefix}*`);
|
|
42
|
+
for (const k of keys)
|
|
43
|
+
await this.client.del(k);
|
|
44
|
+
}
|
|
45
|
+
/** 按键枚举:优先 scanIterator,缺则退回 keys(pattern) */
|
|
46
|
+
async enumerate(pattern) {
|
|
47
|
+
if (this.client.scanIterator) {
|
|
48
|
+
const out = [];
|
|
49
|
+
for await (const batch of this.client.scanIterator({ MATCH: pattern, COUNT: 100 })) {
|
|
50
|
+
if (Array.isArray(batch))
|
|
51
|
+
out.push(...batch);
|
|
52
|
+
else
|
|
53
|
+
out.push(batch);
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
return this.client.keys(pattern);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** 解析整行 JSON;单条损坏按缺失处理,不整库崩(与 FileTaskStore 对齐) */
|
|
61
|
+
function parseRecord(raw) {
|
|
62
|
+
if (!raw)
|
|
63
|
+
return undefined;
|
|
64
|
+
try {
|
|
65
|
+
const rec = JSON.parse(raw);
|
|
66
|
+
return rec && typeof rec.taskId === 'string' ? rec : undefined;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=redisStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redisStore.js","sourceRoot":"","sources":["../../src/run/redisStore.ts"],"names":[],"mappings":"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"}
|
package/dist/run/run.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { AgentRunResult, RunAgentOptions } from '../engine/types.js';
|
|
|
2
2
|
import { TraceRecorder } from '../engine/tracer.js';
|
|
3
3
|
import type { RunMeta, RunStatus } from './types.js';
|
|
4
4
|
import { RunContext } from './context.js';
|
|
5
|
+
import type { MemoryStore } from './memory.js';
|
|
5
6
|
/**
|
|
6
7
|
* Run —— 一次运行的生命周期容器(spec §2/§6.1)。
|
|
7
8
|
* runId == recorder.traceId == traceId(1:1)。
|
|
@@ -31,6 +32,15 @@ export interface ExecuteRunOptions extends RunAgentOptions {
|
|
|
31
32
|
idempotencyKey?: string;
|
|
32
33
|
/** 在 runAgent 前对本次 RunContext 做预置(blackboard 种子等) */
|
|
33
34
|
contextInit?: (ctx: RunContext) => void;
|
|
35
|
+
/**
|
|
36
|
+
* 跨 run 记忆(R4):run 开始把 store.load(keys) 水合进 blackboard
|
|
37
|
+
* (在 contextInit 之后执行,且用户种子优先 —— 不覆盖已有同名 key);
|
|
38
|
+
* run 结束(finish/fail 两条路径)把这些 key 的当前值 save 回 store。
|
|
39
|
+
*/
|
|
40
|
+
memory?: {
|
|
41
|
+
store: MemoryStore;
|
|
42
|
+
keys: string[];
|
|
43
|
+
};
|
|
34
44
|
/**
|
|
35
45
|
* 硬失败(请求/API 层异常)是否抛出。缺省 true;
|
|
36
46
|
* 异步宿主(AsyncRunner)置 false:失败也以 {run(status=failed), result.error} 返回,
|
package/dist/run/run.js
CHANGED
|
@@ -80,19 +80,50 @@ export async function executeRun(options) {
|
|
|
80
80
|
const run = new Run({ idempotencyKey: options.idempotencyKey });
|
|
81
81
|
run.start();
|
|
82
82
|
const ctx = new RunContext(run);
|
|
83
|
+
const memory = options.memory;
|
|
83
84
|
return withRunContext(ctx, async () => {
|
|
84
85
|
try {
|
|
85
86
|
options.contextInit?.(ctx);
|
|
87
|
+
if (memory)
|
|
88
|
+
await hydrateMemory(memory, ctx);
|
|
86
89
|
const result = await runAgent({ ...options, recorder: run.recorder });
|
|
87
90
|
run.finish(result);
|
|
91
|
+
if (memory)
|
|
92
|
+
await flushMemory(memory, ctx);
|
|
88
93
|
return { run, result };
|
|
89
94
|
}
|
|
90
95
|
catch (e) {
|
|
91
96
|
run.fail(e);
|
|
97
|
+
if (memory) {
|
|
98
|
+
// 失败路径也回写;save 自身出错不掩盖原始错误
|
|
99
|
+
try {
|
|
100
|
+
await flushMemory(memory, ctx);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* ignore */
|
|
104
|
+
}
|
|
105
|
+
}
|
|
92
106
|
if (options.rethrow === false)
|
|
93
107
|
return { run, result: run.result };
|
|
94
108
|
throw e;
|
|
95
109
|
}
|
|
96
110
|
});
|
|
97
111
|
}
|
|
112
|
+
/** 水合:store 值注入 blackboard;contextInit 已写的同名 key 不覆盖(用户种子优先) */
|
|
113
|
+
async function hydrateMemory(memory, ctx) {
|
|
114
|
+
const loaded = await memory.store.load(memory.keys);
|
|
115
|
+
for (const key of memory.keys) {
|
|
116
|
+
if (key in loaded && !ctx.has(key))
|
|
117
|
+
ctx.set(key, loaded[key]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/** 回写:blackboard 里这些 key 的当前值存回 store */
|
|
121
|
+
async function flushMemory(memory, ctx) {
|
|
122
|
+
const entries = {};
|
|
123
|
+
for (const key of memory.keys) {
|
|
124
|
+
if (ctx.has(key))
|
|
125
|
+
entries[key] = ctx.get(key);
|
|
126
|
+
}
|
|
127
|
+
await memory.store.save(entries);
|
|
128
|
+
}
|
|
98
129
|
//# sourceMappingURL=run.js.map
|
package/dist/run/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run/run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run/run.ts"],"names":[],"mappings":"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"}
|
package/dist/run/spec.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import type { ModelClient } from '../core/tool.js';
|
|
2
3
|
import type { AgentTool } from '../core/tool.js';
|
|
3
4
|
import type { ContextPolicy } from '../engine/types.js';
|
|
4
5
|
/**
|
|
@@ -11,7 +12,7 @@ export interface RunInvocationOptions {
|
|
|
11
12
|
model?: string;
|
|
12
13
|
maxTokens?: number;
|
|
13
14
|
maxIterations?: number;
|
|
14
|
-
client?:
|
|
15
|
+
client?: ModelClient;
|
|
15
16
|
onText?: (delta: string) => void;
|
|
16
17
|
/** 预置进本次 RunContext.blackboard */
|
|
17
18
|
blackboard?: Record<string, unknown>;
|
package/dist/run/spec.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/run/spec.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/run/spec.ts"],"names":[],"mappings":"AA2CA,wCAAwC;AACxC,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QAC5D,OAAO,KAAiC,CAAC;IAC3C,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,KAAiE,CAAC;QAC5E,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;YACjE,OAAO,CAAC,CAAC,QAAoC,CAAC;QAChD,CAAC;QACD,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3F,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { TaskRecord, TaskStore } from './store.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— SQLite 宿主 TaskStore(spec §6.6:异步耐久 = 换宿主不换语义,roadmap R3)。
|
|
4
|
+
*
|
|
5
|
+
* 基于 Node 内置 node:sqlite(DatabaseSync),零外部依赖。语义与 FileTaskStore 逐字对齐:
|
|
6
|
+
* - save = INSERT OR REPLACE(整行记录 JSON 存 json 列,last-wins);
|
|
7
|
+
* - byIdempotency 取该键最近一次 save 的记录(按 rowid 倒序,失败重提产生的新任务胜出);
|
|
8
|
+
* - list 按写入顺序返回;clear 清空整表;
|
|
9
|
+
* - 构造即就绪(建表 + 索引,无异步),重启续跑同样交给 AsyncRunner.resumePending()。
|
|
10
|
+
*
|
|
11
|
+
* 对比 FileTaskStore 的**单写者前提**:多进程安全由 SQLite WAL/事务天然保证 ——
|
|
12
|
+
* 多个宿主进程可同时打开同一库文件,写事务由 SQLite 串行化,无需部署层加锁。
|
|
13
|
+
*/
|
|
14
|
+
export declare class SqliteTaskStore implements TaskStore {
|
|
15
|
+
private readonly db;
|
|
16
|
+
constructor(path: string);
|
|
17
|
+
save(rec: TaskRecord): void;
|
|
18
|
+
get(taskId: string): TaskRecord | undefined;
|
|
19
|
+
byIdempotency(key: string): TaskRecord | undefined;
|
|
20
|
+
list(): TaskRecord[];
|
|
21
|
+
clear(): void;
|
|
22
|
+
/** 关闭底层连接(测试/进程收尾用;TaskStore 接口之外的能力) */
|
|
23
|
+
close(): void;
|
|
24
|
+
}
|