@migor/agentia 0.0.1

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.
Files changed (89) hide show
  1. package/README.md +171 -0
  2. package/dist/container/container.d.ts +40 -0
  3. package/dist/container/container.js +66 -0
  4. package/dist/container/container.js.map +1 -0
  5. package/dist/core/schema.d.ts +14 -0
  6. package/dist/core/schema.js +116 -0
  7. package/dist/core/schema.js.map +1 -0
  8. package/dist/core/tool.d.ts +60 -0
  9. package/dist/core/tool.js +2 -0
  10. package/dist/core/tool.js.map +1 -0
  11. package/dist/core/trace.d.ts +52 -0
  12. package/dist/core/trace.js +6 -0
  13. package/dist/core/trace.js.map +1 -0
  14. package/dist/engine/context.d.ts +47 -0
  15. package/dist/engine/context.js +146 -0
  16. package/dist/engine/context.js.map +1 -0
  17. package/dist/engine/errors.d.ts +3 -0
  18. package/dist/engine/errors.js +22 -0
  19. package/dist/engine/errors.js.map +1 -0
  20. package/dist/engine/loop.d.ts +33 -0
  21. package/dist/engine/loop.js +227 -0
  22. package/dist/engine/loop.js.map +1 -0
  23. package/dist/engine/policy.d.ts +30 -0
  24. package/dist/engine/policy.js +35 -0
  25. package/dist/engine/policy.js.map +1 -0
  26. package/dist/engine/tracer.d.ts +27 -0
  27. package/dist/engine/tracer.js +93 -0
  28. package/dist/engine/tracer.js.map +1 -0
  29. package/dist/engine/types.d.ts +58 -0
  30. package/dist/engine/types.js +2 -0
  31. package/dist/engine/types.js.map +1 -0
  32. package/dist/engine/usage.d.ts +5 -0
  33. package/dist/engine/usage.js +30 -0
  34. package/dist/engine/usage.js.map +1 -0
  35. package/dist/index.d.ts +42 -0
  36. package/dist/index.js +31 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/run/async.d.ts +64 -0
  39. package/dist/run/async.js +135 -0
  40. package/dist/run/async.js.map +1 -0
  41. package/dist/run/context.d.ts +16 -0
  42. package/dist/run/context.js +48 -0
  43. package/dist/run/context.js.map +1 -0
  44. package/dist/run/fsStore.d.ts +29 -0
  45. package/dist/run/fsStore.js +79 -0
  46. package/dist/run/fsStore.js.map +1 -0
  47. package/dist/run/run.d.ts +50 -0
  48. package/dist/run/run.js +98 -0
  49. package/dist/run/run.js.map +1 -0
  50. package/dist/run/scheduler.d.ts +27 -0
  51. package/dist/run/scheduler.js +85 -0
  52. package/dist/run/scheduler.js.map +1 -0
  53. package/dist/run/spec.d.ts +40 -0
  54. package/dist/run/spec.js +25 -0
  55. package/dist/run/spec.js.map +1 -0
  56. package/dist/run/store.d.ts +40 -0
  57. package/dist/run/store.js +28 -0
  58. package/dist/run/store.js.map +1 -0
  59. package/dist/run/systemPrompt.d.ts +25 -0
  60. package/dist/run/systemPrompt.js +41 -0
  61. package/dist/run/systemPrompt.js.map +1 -0
  62. package/dist/run/transport.d.ts +12 -0
  63. package/dist/run/transport.js +16 -0
  64. package/dist/run/transport.js.map +1 -0
  65. package/dist/run/types.d.ts +12 -0
  66. package/dist/run/types.js +2 -0
  67. package/dist/run/types.js.map +1 -0
  68. package/dist/toolkit/asset.d.ts +22 -0
  69. package/dist/toolkit/asset.js +26 -0
  70. package/dist/toolkit/asset.js.map +1 -0
  71. package/dist/toolkit/discover.d.ts +2 -0
  72. package/dist/toolkit/discover.js +61 -0
  73. package/dist/toolkit/discover.js.map +1 -0
  74. package/dist/toolkit/module.d.ts +74 -0
  75. package/dist/toolkit/module.js +114 -0
  76. package/dist/toolkit/module.js.map +1 -0
  77. package/dist/toolkit/prompt.d.ts +32 -0
  78. package/dist/toolkit/prompt.js +70 -0
  79. package/dist/toolkit/prompt.js.map +1 -0
  80. package/dist/toolkit/skill.d.ts +74 -0
  81. package/dist/toolkit/skill.js +125 -0
  82. package/dist/toolkit/skill.js.map +1 -0
  83. package/dist/toolkit/subagent.d.ts +54 -0
  84. package/dist/toolkit/subagent.js +120 -0
  85. package/dist/toolkit/subagent.js.map +1 -0
  86. package/dist/toolkit/tool.d.ts +36 -0
  87. package/dist/toolkit/tool.js +54 -0
  88. package/dist/toolkit/tool.js.map +1 -0
  89. package/package.json +39 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracer.js","sourceRoot":"","sources":["../../src/engine/tracer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type Anthropic from '@anthropic-ai/sdk';
2
+ import type { AgentTool } from '../core/tool.js';
3
+ import type { SpanError, Trace } from '../core/trace.js';
4
+ export type AgentStopReason = 'end_turn' | 'max_tokens' | 'refusal' | 'pause_turn' | 'max_iterations' | 'tool_use_no_blocks' | 'error';
5
+ /** 可携带 cache_control 的 system 文本块(见 run/systemPrompt.ts) */
6
+ export interface SystemTextBlock {
7
+ type: 'text';
8
+ text: string;
9
+ cache_control?: {
10
+ type: 'ephemeral';
11
+ };
12
+ }
13
+ /** system 参数:纯文本,或可缓存块数组(稳定段带 breakpoint,volatile 段放其后不带) */
14
+ export type SystemParam = string | SystemTextBlock[];
15
+ /**
16
+ * 上下文预算策略(spec §5/§6 —— compaction / context editing)。
17
+ * 引擎在每个 llm 回合发送前调用 beforeTurn;返回的 messages 即本回合发送内容。
18
+ * 实现见 engine/policy.ts 的 createBudgetPolicy,或自实现(如每次用 /count_tokens)。
19
+ */
20
+ export interface ContextPolicy {
21
+ /** 预算(估算 input tokens);超预算的回合触发降级。供观测/文档用 */
22
+ readonly budgetTokens?: number;
23
+ beforeTurn(messages: Anthropic.MessageParam[], info: {
24
+ iteration: number;
25
+ model: string;
26
+ }): Promise<Anthropic.MessageParam[]>;
27
+ }
28
+ export interface RunAgentOptions {
29
+ /** 顶层 system(SystemPrompt 产物)。稳定内容应放在 tools 之后、第一个 breakpoint 前 */
30
+ system?: SystemParam;
31
+ /** 初始消息;Turn 0 由调用方给 user 起始消息 */
32
+ messages: Anthropic.MessageParam[];
33
+ /** 主 agent 可调工具(v1 裸 JSON schema) */
34
+ tools?: AgentTool[];
35
+ model?: string;
36
+ /** 流式请求的 max_tokens,给足避免中途截断 */
37
+ maxTokens?: number;
38
+ /** 循环安全上限,防止无限 tool 往返 */
39
+ maxIterations?: number;
40
+ /** 注入 client(默认 new Anthropic(),读 env/ant auth) */
41
+ client?: Anthropic;
42
+ /** 注入 recorder(run 层复用;不注入则内部新建,traceId 即 runId) */
43
+ recorder?: import('./tracer.js').TraceRecorder;
44
+ /** 文本增量回调(终端/SSE 用) */
45
+ onText?: (delta: string) => void;
46
+ runName?: string;
47
+ /** 上下文预算策略:每回合发送前可编辑/压缩消息(compaction / context editing) */
48
+ contextPolicy?: ContextPolicy;
49
+ }
50
+ export interface AgentRunResult {
51
+ /** 本次 run 的完整调用树 + usage(traceId == runId) */
52
+ trace: Trace;
53
+ stopReason: AgentStopReason;
54
+ /** 最终文本(结构化输出在后续 Turn 接入) */
55
+ finalText: string;
56
+ iterations: number;
57
+ error?: SpanError;
58
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import type Anthropic from '@anthropic-ai/sdk';
2
+ import type { Usage } from '../core/trace.js';
3
+ export declare function usageFromAnthropic(u: Anthropic.Usage): Usage;
4
+ /** 近似成本估计:缓存写≈1.25×输入,缓存读≈0.1×输入。 */
5
+ export declare function costEstimate(model: string, usage: Usage): number | undefined;
@@ -0,0 +1,30 @@
1
+ /** $/1M tokens(输入/输出)。未知模型不估成本。 */
2
+ const PRICING = {
3
+ 'claude-opus-5': { in: 5, out: 25 },
4
+ 'claude-opus-4-8': { in: 5, out: 25 },
5
+ 'claude-opus-4-7': { in: 5, out: 25 },
6
+ 'claude-sonnet-5': { in: 2, out: 10 },
7
+ 'claude-sonnet-4-6': { in: 3, out: 15 },
8
+ 'claude-haiku-4-5': { in: 1, out: 5 },
9
+ };
10
+ export function usageFromAnthropic(u) {
11
+ return {
12
+ inputTokens: u.input_tokens ?? 0,
13
+ outputTokens: u.output_tokens ?? 0,
14
+ cacheReadTokens: u.cache_read_input_tokens ?? 0,
15
+ cacheCreationTokens: u.cache_creation_input_tokens ?? 0,
16
+ };
17
+ }
18
+ /** 近似成本估计:缓存写≈1.25×输入,缓存读≈0.1×输入。 */
19
+ export function costEstimate(model, usage) {
20
+ const p = PRICING[model];
21
+ if (!p)
22
+ return undefined;
23
+ const { inputTokens, outputTokens, cacheReadTokens, cacheCreationTokens } = usage;
24
+ const cost = (inputTokens / 1e6) * p.in +
25
+ (outputTokens / 1e6) * p.out +
26
+ (cacheReadTokens / 1e6) * p.in * 0.1 +
27
+ (cacheCreationTokens / 1e6) * p.in * 1.25;
28
+ return Math.round(cost * 1e6) / 1e6;
29
+ }
30
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/engine/usage.ts"],"names":[],"mappings":"AAGA,mCAAmC;AACnC,MAAM,OAAO,GAAgD;IAC3D,eAAe,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACnC,iBAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACrC,iBAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACrC,iBAAiB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACrC,mBAAmB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;IACvC,kBAAkB,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;CACtC,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,CAAkB;IACnD,OAAO;QACL,WAAW,EAAE,CAAC,CAAC,YAAY,IAAI,CAAC;QAChC,YAAY,EAAE,CAAC,CAAC,aAAa,IAAI,CAAC;QAClC,eAAe,EAAE,CAAC,CAAC,uBAAuB,IAAI,CAAC;QAC/C,mBAAmB,EAAE,CAAC,CAAC,2BAA2B,IAAI,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,KAAY;IACtD,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IACzB,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAAC;IAClF,MAAM,IAAI,GACR,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;QAC1B,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG;QAC5B,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG;QACpC,CAAC,mBAAmB,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC;IAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACtC,CAAC"}
@@ -0,0 +1,42 @@
1
+ export declare const AGENTIA_VERSION = "0.0.1";
2
+ export type { Trace, Span, SpanEvent, SpanError, SpanId, SpanKind, SpanStatus, TraceId, UnitType, Usage, } from './core/trace.js';
3
+ export type { AgentTool, JsonSchema, RecorderBackend, ToolRunContext } from './core/tool.js';
4
+ export { validateJsonSchema } from './core/schema.js';
5
+ export { runAgent, resolveDefaultModel } from './engine/loop.js';
6
+ export { TraceRecorder } from './engine/tracer.js';
7
+ export { classifyError } from './engine/errors.js';
8
+ export type { AgentRunResult, AgentStopReason, ContextPolicy, RunAgentOptions, SystemParam, SystemTextBlock, } from './engine/types.js';
9
+ export { defaultEstimateTokens, estimateMessages, renderMessages, trimToolPairs, compactMessages, } from './engine/context.js';
10
+ export type { CompactOptions, TrimOptions } from './engine/context.js';
11
+ export { createBudgetPolicy } from './engine/policy.js';
12
+ export type { BudgetPolicyOptions } from './engine/policy.js';
13
+ export { Run, executeRun } from './run/run.js';
14
+ export { RunContext, withRunContext } from './run/context.js';
15
+ export { SystemPrompt } from './run/systemPrompt.js';
16
+ export type { SystemSection } from './run/systemPrompt.js';
17
+ export type { ExecuteRunOptions } from './run/run.js';
18
+ export type { RunMeta, RunStatus } from './run/types.js';
19
+ export { Container } from './container/container.js';
20
+ export type { Provider, ClassProvider, ValueProvider, FactoryProvider, Token, } from './container/container.js';
21
+ export { asset } from './toolkit/asset.js';
22
+ export { discoverProviders } from './toolkit/discover.js';
23
+ export { Tool, collectTools } from './toolkit/tool.js';
24
+ export type { ToolSpec } from './toolkit/tool.js';
25
+ export { SubAgent, collectSubAgents, subagentToTool } from './toolkit/subagent.js';
26
+ export type { SubAgentSpec, SubAgentUnit } from './toolkit/subagent.js';
27
+ export { Skill, collectSkills, skillToTool } from './toolkit/skill.js';
28
+ export type { SkillContext, SkillLlmOptions, SkillLlmResult, SkillSpec, SkillUnit, } from './toolkit/skill.js';
29
+ export { Prompt, collectPrompts } from './toolkit/prompt.js';
30
+ export type { PromptSpec } from './toolkit/prompt.js';
31
+ export { createApp, AgentApp } from './toolkit/module.js';
32
+ export type { AppOptions, RunAppOptions, AgentRunOutput } from './toolkit/module.js';
33
+ export { normalizeMessages } from './run/spec.js';
34
+ export type { RunInput, RunSpec, RunInvocationOptions } from './run/spec.js';
35
+ export { InMemoryTaskStore } from './run/store.js';
36
+ export type { TaskRecord, TaskStore } from './run/store.js';
37
+ export { FileTaskStore } from './run/fsStore.js';
38
+ export { AsyncRunner } from './run/async.js';
39
+ export type { AsyncRunnerOptions, AppCallable } from './run/async.js';
40
+ export { Scheduler } from './run/scheduler.js';
41
+ export type { ScheduleEveryOptions, ScheduleHandle } from './run/scheduler.js';
42
+ export { runSync, createSyncHandler } from './run/transport.js';
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ export const AGENTIA_VERSION = '0.0.1';
2
+ export { validateJsonSchema } from './core/schema.js';
3
+ // engine:Turn 0 内核
4
+ export { runAgent, resolveDefaultModel } from './engine/loop.js';
5
+ export { TraceRecorder } from './engine/tracer.js';
6
+ export { classifyError } from './engine/errors.js';
7
+ // engine:Turn 4 长上下文策略
8
+ export { defaultEstimateTokens, estimateMessages, renderMessages, trimToolPairs, compactMessages, } from './engine/context.js';
9
+ export { createBudgetPolicy } from './engine/policy.js';
10
+ // run:Turn 1 生命周期
11
+ export { Run, executeRun } from './run/run.js';
12
+ export { RunContext, withRunContext } from './run/context.js';
13
+ export { SystemPrompt } from './run/systemPrompt.js';
14
+ // container:Turn 2 显式 DI
15
+ export { Container } from './container/container.js';
16
+ // toolkit:Turn 2 声明式单元 + 应用装配
17
+ export { asset } from './toolkit/asset.js';
18
+ export { discoverProviders } from './toolkit/discover.js';
19
+ export { Tool, collectTools } from './toolkit/tool.js';
20
+ export { SubAgent, collectSubAgents, subagentToTool } from './toolkit/subagent.js';
21
+ export { Skill, collectSkills, skillToTool } from './toolkit/skill.js';
22
+ export { Prompt, collectPrompts } from './toolkit/prompt.js';
23
+ export { createApp, AgentApp } from './toolkit/module.js';
24
+ // run:Turn 5 触发传输 + run 存储
25
+ export { normalizeMessages } from './run/spec.js';
26
+ export { InMemoryTaskStore } from './run/store.js';
27
+ export { FileTaskStore } from './run/fsStore.js';
28
+ export { AsyncRunner } from './run/async.js';
29
+ export { Scheduler } from './run/scheduler.js';
30
+ export { runSync, createSyncHandler } from './run/transport.js';
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,OAAO,CAAC;AAgBvC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,mBAAmB;AACnB,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUnD,uBAAuB;AACvB,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,eAAe,GAChB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,kBAAkB;AAClB,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAKrD,yBAAyB;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AASrD,8BAA8B;AAC9B,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEnF,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAQvE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG1D,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type Anthropic from '@anthropic-ai/sdk';
2
+ import type { AgentRunResult } from '../engine/types.js';
3
+ import type { RunStatus } from './types.js';
4
+ import type { RunInvocationOptions } from './spec.js';
5
+ import type { TaskRecord, TaskStore } from './store.js';
6
+ /**
7
+ * Agentia —— 异步任务宿主(spec §6.3 异步 / §6.5 确定性 / §6.6 换宿主不换语义)。
8
+ *
9
+ * - submit 即回(queued),后台驱动状态机 queued → running → succeeded/failed;
10
+ * - **at-least-once 去重**:同一 idempotencyKey 重复 submit,若上一任务仍在
11
+ * queued/running/succeeded 则直接返回既有记录,不重复执行(失败可重试新任务);
12
+ * - run 记录落 TaskStore(v1 InMemoryTaskStore),trace 随 result 一同保留;
13
+ * DB/队列宿主只需实现 TaskStore。
14
+ */
15
+ export interface AsyncRunnerOptions {
16
+ client?: Anthropic;
17
+ store?: TaskStore;
18
+ /** 同时执行的任务上限;缺省不限。超出部分排队等槽位(状态保持 queued) */
19
+ concurrency?: number;
20
+ }
21
+ /** 应用最小调用面(agent 装配无关,避免 run 层向上依赖 toolkit) */
22
+ export interface AppCallable {
23
+ readonly name: string;
24
+ run(messages: Anthropic.MessageParam[], opts?: RunInvocationOptions): Promise<{
25
+ run: {
26
+ runId: string;
27
+ status: RunStatus;
28
+ };
29
+ result: AgentRunResult;
30
+ }>;
31
+ }
32
+ export declare class AsyncRunner {
33
+ #private;
34
+ private readonly app;
35
+ readonly store: TaskStore;
36
+ private readonly client?;
37
+ private readonly concurrency;
38
+ private running;
39
+ private readonly waitQueue;
40
+ constructor(app: AppCallable, opts?: AsyncRunnerOptions);
41
+ /**
42
+ * 提交一次异步任务。入参可为 string / messages / {prompt|text|messages}。
43
+ * 幂等键存在且上一任务未失败 → 直接返回既有记录(去重);失败的同键可产生新任务。
44
+ */
45
+ submit(input: unknown, opts?: {
46
+ idempotencyKey?: string;
47
+ source?: string;
48
+ options?: RunInvocationOptions;
49
+ }): TaskRecord;
50
+ /** 查任务当前记录 */
51
+ poll(taskId: string): TaskRecord | undefined;
52
+ byIdempotency(key: string): TaskRecord | undefined;
53
+ list(): TaskRecord[];
54
+ /** 等到任务终态;超时抛错。 */
55
+ awaitTask(taskId: string, opts?: {
56
+ timeoutMs?: number;
57
+ intervalMs?: number;
58
+ }): Promise<TaskRecord>;
59
+ /**
60
+ * 宿主重启续跑:把 store 里 queued | running 的记录重新派发执行
61
+ * (running 视为进程中断)。返回重派数量。幂等键去重照常生效。
62
+ */
63
+ resumePending(): number;
64
+ }
@@ -0,0 +1,135 @@
1
+ import { classifyError } from '../engine/errors.js';
2
+ import { normalizeMessages } from './spec.js';
3
+ import { InMemoryTaskStore } from './store.js';
4
+ export class AsyncRunner {
5
+ app;
6
+ store;
7
+ client;
8
+ concurrency;
9
+ running = 0;
10
+ waitQueue = [];
11
+ constructor(app, opts = {}) {
12
+ this.app = app;
13
+ this.app = app;
14
+ this.store = opts.store ?? new InMemoryTaskStore();
15
+ this.client = opts.client;
16
+ this.concurrency = opts.concurrency ?? Number.POSITIVE_INFINITY;
17
+ if (!(this.concurrency > 0)) {
18
+ throw new Error(`concurrency 必须为正数,收到 ${opts.concurrency}`);
19
+ }
20
+ }
21
+ /**
22
+ * 提交一次异步任务。入参可为 string / messages / {prompt|text|messages}。
23
+ * 幂等键存在且上一任务未失败 → 直接返回既有记录(去重);失败的同键可产生新任务。
24
+ */
25
+ submit(input, opts = {}) {
26
+ const messages = normalizeMessages(input);
27
+ if (opts.idempotencyKey) {
28
+ const existing = this.store.byIdempotency(opts.idempotencyKey);
29
+ if (existing && existing.status !== 'failed') {
30
+ return { ...existing }; // at-least-once 去重:不重复执行
31
+ }
32
+ }
33
+ const rec = {
34
+ taskId: InMemoryTaskStore.nextTaskId(),
35
+ status: 'queued',
36
+ idempotencyKey: opts.idempotencyKey,
37
+ spec: { messages, options: opts.options, source: opts.source ?? 'async' },
38
+ createdAt: Date.now(),
39
+ };
40
+ this.store.save(rec);
41
+ void this.#execute(rec.taskId);
42
+ // 返回浅拷贝:记录会被后台状态机原地推进,调用方拿到的是提交时刻的快照
43
+ return { ...rec };
44
+ }
45
+ /** 查任务当前记录 */
46
+ poll(taskId) {
47
+ return this.store.get(taskId);
48
+ }
49
+ byIdempotency(key) {
50
+ return this.store.byIdempotency(key);
51
+ }
52
+ list() {
53
+ return this.store.list();
54
+ }
55
+ /** 等到任务终态;超时抛错。 */
56
+ async awaitTask(taskId, opts = {}) {
57
+ const timeoutMs = opts.timeoutMs ?? 30_000;
58
+ const intervalMs = opts.intervalMs ?? 5;
59
+ const start = Date.now();
60
+ for (;;) {
61
+ const rec = this.store.get(taskId);
62
+ if (!rec)
63
+ throw new Error(`task 不存在: ${taskId}`);
64
+ if (rec.status === 'succeeded' || rec.status === 'failed')
65
+ return rec;
66
+ if (Date.now() - start > timeoutMs) {
67
+ throw new Error(`task ${taskId} 等待超时(${rec.status})`);
68
+ }
69
+ await new Promise((r) => setTimeout(r, intervalMs));
70
+ }
71
+ }
72
+ /**
73
+ * 宿主重启续跑:把 store 里 queued | running 的记录重新派发执行
74
+ * (running 视为进程中断)。返回重派数量。幂等键去重照常生效。
75
+ */
76
+ resumePending() {
77
+ const pending = this.store
78
+ .list()
79
+ .filter((r) => r.status === 'queued' || r.status === 'running');
80
+ for (const rec of pending) {
81
+ rec.status = 'queued'; // 重新入队,由 #execute 统一推进
82
+ void this.#execute(rec.taskId);
83
+ }
84
+ return pending.length;
85
+ }
86
+ async #execute(taskId) {
87
+ const rec = this.store.get(taskId);
88
+ if (!rec)
89
+ return;
90
+ await this.#acquireSlot();
91
+ rec.status = 'running';
92
+ rec.startedAt = Date.now();
93
+ this.store.save(rec);
94
+ try {
95
+ const callOpts = {
96
+ ...(rec.spec.options ?? {}),
97
+ client: rec.spec.options?.client ?? this.client,
98
+ idempotencyKey: rec.idempotencyKey,
99
+ rethrow: false, // 硬失败也以 failed 记录落库
100
+ };
101
+ const out = await this.app.run(rec.spec.messages, callOpts);
102
+ rec.runId = out.run.runId;
103
+ rec.status = out.run.status;
104
+ rec.result = out.result;
105
+ rec.error = out.result.error;
106
+ }
107
+ catch (e) {
108
+ rec.error = classifyError(e);
109
+ rec.status = 'failed';
110
+ }
111
+ finally {
112
+ rec.finishedAt = Date.now();
113
+ this.store.save(rec);
114
+ this.#releaseSlot();
115
+ }
116
+ }
117
+ /** 并发槽位:超限则排队等待(任务记录保持 queued,由 store 可见) */
118
+ #acquireSlot() {
119
+ if (this.running < this.concurrency) {
120
+ this.running++;
121
+ return Promise.resolve();
122
+ }
123
+ return new Promise((resolve) => this.waitQueue.push(resolve));
124
+ }
125
+ #releaseSlot() {
126
+ const next = this.waitQueue.shift();
127
+ if (next) {
128
+ next(); // 槽位直接移交给等待者,running 计数不变
129
+ }
130
+ else {
131
+ this.running--;
132
+ }
133
+ }
134
+ }
135
+ //# sourceMappingURL=async.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.js","sourceRoot":"","sources":["../../src/run/async.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Run } from './run.js';
2
+ /** 在指定 ctx 下执行(executeRun 内部使用);当前上下文对外以 current() 读取 */
3
+ export declare function withRunContext<T>(ctx: RunContext, fn: () => T | Promise<T>): Promise<T>;
4
+ export declare class RunContext {
5
+ readonly run: Run;
6
+ private readonly blackboard;
7
+ constructor(run: Run);
8
+ /** 当前 run 的上下文。不在 run 内调用时返回 undefined。 */
9
+ static current(): RunContext | undefined;
10
+ get runId(): string;
11
+ get<T>(key: string): T | undefined;
12
+ set(key: string, value: unknown): this;
13
+ has(key: string): boolean;
14
+ delete(key: string): boolean;
15
+ keys(): string[];
16
+ }
@@ -0,0 +1,48 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ /**
3
+ * Agentia —— run 作用域上下文(spec §2/§9:blackboard + 上下文传播载体)。
4
+ *
5
+ * 传播机制(Turn 2 接入):executeRun 在建 Run 后、跑 engine 前,把本次
6
+ * RunContext 放进 AsyncLocalStorage;runAgent 内任何异步调用(含工具执行、
7
+ * 后续 subagent/skill 执行体)同处该 async 上下文,因此工具方法体内可直接
8
+ * `RunContext.current()` 拿到当前 run —— 无需把 ctx 作为参数层层下传。
9
+ *
10
+ * blackboard:单次 run 内累积的项目事实/产物,随 run 释放(spec §2)。
11
+ * 当前 span 句柄与单元 span 容器在后续 Turn(unit span + TraceInterceptor)接入。
12
+ */
13
+ const store = new AsyncLocalStorage();
14
+ /** 在指定 ctx 下执行(executeRun 内部使用);当前上下文对外以 current() 读取 */
15
+ export function withRunContext(ctx, fn) {
16
+ return store.run(ctx, fn);
17
+ }
18
+ export class RunContext {
19
+ run;
20
+ blackboard = new Map();
21
+ constructor(run) {
22
+ this.run = run;
23
+ }
24
+ /** 当前 run 的上下文。不在 run 内调用时返回 undefined。 */
25
+ static current() {
26
+ return store.getStore();
27
+ }
28
+ get runId() {
29
+ return this.run.runId;
30
+ }
31
+ get(key) {
32
+ return this.blackboard.get(key);
33
+ }
34
+ set(key, value) {
35
+ this.blackboard.set(key, value);
36
+ return this;
37
+ }
38
+ has(key) {
39
+ return this.blackboard.has(key);
40
+ }
41
+ delete(key) {
42
+ return this.blackboard.delete(key);
43
+ }
44
+ keys() {
45
+ return [...this.blackboard.keys()];
46
+ }
47
+ }
48
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/run/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;;;;;;;GAUG;AACH,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAAc,CAAC;AAElD,yDAAyD;AACzD,MAAM,UAAU,cAAc,CAAI,GAAe,EAAE,EAAwB;IACzE,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAe,CAAC;AAC1C,CAAC;AAED,MAAM,OAAO,UAAU;IAGA,GAAG;IAFP,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;IAEzD,YAAqB,GAAQ;mBAAR,GAAG;IAAQ,CAAC;IAEjC,2CAA2C;IAC3C,MAAM,CAAC,OAAO;QACZ,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC1B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;IACxB,CAAC;IAED,GAAG,CAAI,GAAW;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAkB,CAAC;IACnD,CAAC;IACD,GAAG,CAAC,GAAW,EAAE,KAAc;QAC7B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IACD,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { TaskRecord, TaskStore } from './store.js';
2
+ /**
3
+ * Agentia —— 文件宿主 TaskStore(spec §6.6:异步耐久 = 换宿主不换语义)。
4
+ *
5
+ * InMemoryTaskStore 在进程重启即丢;FileTaskStore 用 JSONL 把任务记录落到磁盘,
6
+ * AsyncRunner/Scheduler/触发层**零改动** —— 证明耐久只是换个 store 实现。
7
+ *
8
+ * 语义:
9
+ * - 一行一条记录快照;save 覆写内存 Map 并 append(boot 重读时 last-wins,无顺序依赖);
10
+ * - 构造即 load:文件不存在则从空开始,写入自动建目录;
11
+ * - 宿主重启后:new FileTaskStore(path) 读回记录 → AsyncRunner.resumePending() 续跑
12
+ * queued/running(running 视为中断)。幂等键去重照常生效(失败可重提)。
13
+ *
14
+ * 前提:**单宿主写者**。append 用同步写保证进程内串行;多进程写同一文件会交错,
15
+ * 跨进程协调(锁/队列)属于部署层职责,不在本实现内。
16
+ */
17
+ export declare class FileTaskStore implements TaskStore {
18
+ private readonly file;
19
+ private readonly byTask;
20
+ private readonly byKey;
21
+ constructor(file: string);
22
+ private load;
23
+ private append;
24
+ save(rec: TaskRecord): void;
25
+ get(taskId: string): TaskRecord | undefined;
26
+ byIdempotency(key: string): TaskRecord | undefined;
27
+ list(): TaskRecord[];
28
+ clear(): void;
29
+ }
@@ -0,0 +1,79 @@
1
+ import { mkdirSync, readFileSync, writeFileSync, rmSync, existsSync } from 'node:fs';
2
+ import { dirname } from 'node:path';
3
+ /**
4
+ * Agentia —— 文件宿主 TaskStore(spec §6.6:异步耐久 = 换宿主不换语义)。
5
+ *
6
+ * InMemoryTaskStore 在进程重启即丢;FileTaskStore 用 JSONL 把任务记录落到磁盘,
7
+ * AsyncRunner/Scheduler/触发层**零改动** —— 证明耐久只是换个 store 实现。
8
+ *
9
+ * 语义:
10
+ * - 一行一条记录快照;save 覆写内存 Map 并 append(boot 重读时 last-wins,无顺序依赖);
11
+ * - 构造即 load:文件不存在则从空开始,写入自动建目录;
12
+ * - 宿主重启后:new FileTaskStore(path) 读回记录 → AsyncRunner.resumePending() 续跑
13
+ * queued/running(running 视为中断)。幂等键去重照常生效(失败可重提)。
14
+ *
15
+ * 前提:**单宿主写者**。append 用同步写保证进程内串行;多进程写同一文件会交错,
16
+ * 跨进程协调(锁/队列)属于部署层职责,不在本实现内。
17
+ */
18
+ export class FileTaskStore {
19
+ file;
20
+ byTask = new Map();
21
+ byKey = new Map(); // idempotencyKey → taskId
22
+ constructor(file) {
23
+ this.file = file;
24
+ this.load();
25
+ }
26
+ load() {
27
+ if (!existsSync(this.file))
28
+ return;
29
+ let raw;
30
+ try {
31
+ raw = readFileSync(this.file, 'utf8');
32
+ }
33
+ catch {
34
+ return; // 读失败按空宿主启动(宿主可另行告警)
35
+ }
36
+ for (const line of raw.split('\n')) {
37
+ if (!line.trim())
38
+ continue;
39
+ try {
40
+ const rec = JSON.parse(line);
41
+ if (!rec || typeof rec.taskId !== 'string')
42
+ continue;
43
+ this.byTask.set(rec.taskId, rec);
44
+ if (rec.idempotencyKey)
45
+ this.byKey.set(rec.idempotencyKey, rec.taskId);
46
+ }
47
+ catch {
48
+ // 单条损坏跳过,不整库崩
49
+ }
50
+ }
51
+ }
52
+ append(rec) {
53
+ mkdirSync(dirname(this.file), { recursive: true });
54
+ writeFileSync(this.file, `${JSON.stringify(rec)}\n`, { flag: 'a' });
55
+ }
56
+ save(rec) {
57
+ this.byTask.set(rec.taskId, rec);
58
+ if (rec.idempotencyKey)
59
+ this.byKey.set(rec.idempotencyKey, rec.taskId);
60
+ this.append(rec);
61
+ }
62
+ get(taskId) {
63
+ return this.byTask.get(taskId);
64
+ }
65
+ byIdempotency(key) {
66
+ const taskId = this.byKey.get(key);
67
+ return taskId ? this.byTask.get(taskId) : undefined;
68
+ }
69
+ list() {
70
+ return [...this.byTask.values()];
71
+ }
72
+ clear() {
73
+ this.byTask.clear();
74
+ this.byKey.clear();
75
+ if (existsSync(this.file))
76
+ rmSync(this.file);
77
+ }
78
+ }
79
+ //# sourceMappingURL=fsStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fsStore.js","sourceRoot":"","sources":["../../src/run/fsStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { AgentRunResult, RunAgentOptions } from '../engine/types.js';
2
+ import { TraceRecorder } from '../engine/tracer.js';
3
+ import type { RunMeta, RunStatus } from './types.js';
4
+ import { RunContext } from './context.js';
5
+ /**
6
+ * Run —— 一次运行的生命周期容器(spec §2/§6.1)。
7
+ * runId == recorder.traceId == traceId(1:1)。
8
+ * recorder 由 engine 的 runAgent 写入(run 根 span 归 engine 开)。
9
+ */
10
+ export declare class Run {
11
+ readonly recorder: TraceRecorder;
12
+ readonly runId: string;
13
+ readonly idempotencyKey?: string;
14
+ readonly createdAt: number;
15
+ private _status;
16
+ startedAt?: number;
17
+ finishedAt?: number;
18
+ private _result?;
19
+ constructor(opts?: {
20
+ idempotencyKey?: string;
21
+ });
22
+ get status(): RunStatus;
23
+ get result(): AgentRunResult | undefined;
24
+ /** meta(供运行记录/持久化使用) */
25
+ toMeta(): RunMeta;
26
+ start(): void;
27
+ finish(result: AgentRunResult): void;
28
+ fail(error: unknown): void;
29
+ }
30
+ export interface ExecuteRunOptions extends RunAgentOptions {
31
+ idempotencyKey?: string;
32
+ /** 在 runAgent 前对本次 RunContext 做预置(blackboard 种子等) */
33
+ contextInit?: (ctx: RunContext) => void;
34
+ /**
35
+ * 硬失败(请求/API 层异常)是否抛出。缺省 true;
36
+ * 异步宿主(AsyncRunner)置 false:失败也以 {run(status=failed), result.error} 返回,
37
+ * 便于把失败 run 落库而非冒泡。
38
+ */
39
+ rethrow?: boolean;
40
+ }
41
+ /**
42
+ * 高层入口:建 Run → start → 注入 recorder 跑 engine → finish。
43
+ * run 层持有 recorder,返回后 run.recorder 里的 trace 即本次完整调用树。
44
+ * RunContext 在整个执行期间经 AsyncLocalStorage 可被 `RunContext.current()` 读到,
45
+ * 工具/单元执行体无需把 ctx 作为参数层层下传。
46
+ */
47
+ export declare function executeRun(options: ExecuteRunOptions): Promise<{
48
+ run: Run;
49
+ result: AgentRunResult;
50
+ }>;