@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.
- package/README.md +171 -0
- package/dist/container/container.d.ts +40 -0
- package/dist/container/container.js +66 -0
- package/dist/container/container.js.map +1 -0
- package/dist/core/schema.d.ts +14 -0
- package/dist/core/schema.js +116 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/tool.d.ts +60 -0
- package/dist/core/tool.js +2 -0
- package/dist/core/tool.js.map +1 -0
- package/dist/core/trace.d.ts +52 -0
- package/dist/core/trace.js +6 -0
- package/dist/core/trace.js.map +1 -0
- package/dist/engine/context.d.ts +47 -0
- package/dist/engine/context.js +146 -0
- package/dist/engine/context.js.map +1 -0
- package/dist/engine/errors.d.ts +3 -0
- package/dist/engine/errors.js +22 -0
- package/dist/engine/errors.js.map +1 -0
- package/dist/engine/loop.d.ts +33 -0
- package/dist/engine/loop.js +227 -0
- package/dist/engine/loop.js.map +1 -0
- package/dist/engine/policy.d.ts +30 -0
- package/dist/engine/policy.js +35 -0
- package/dist/engine/policy.js.map +1 -0
- package/dist/engine/tracer.d.ts +27 -0
- package/dist/engine/tracer.js +93 -0
- package/dist/engine/tracer.js.map +1 -0
- package/dist/engine/types.d.ts +58 -0
- package/dist/engine/types.js +2 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/engine/usage.d.ts +5 -0
- package/dist/engine/usage.js +30 -0
- package/dist/engine/usage.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/run/async.d.ts +64 -0
- package/dist/run/async.js +135 -0
- package/dist/run/async.js.map +1 -0
- package/dist/run/context.d.ts +16 -0
- package/dist/run/context.js +48 -0
- package/dist/run/context.js.map +1 -0
- package/dist/run/fsStore.d.ts +29 -0
- package/dist/run/fsStore.js +79 -0
- package/dist/run/fsStore.js.map +1 -0
- package/dist/run/run.d.ts +50 -0
- package/dist/run/run.js +98 -0
- package/dist/run/run.js.map +1 -0
- package/dist/run/scheduler.d.ts +27 -0
- package/dist/run/scheduler.js +85 -0
- package/dist/run/scheduler.js.map +1 -0
- package/dist/run/spec.d.ts +40 -0
- package/dist/run/spec.js +25 -0
- package/dist/run/spec.js.map +1 -0
- package/dist/run/store.d.ts +40 -0
- package/dist/run/store.js +28 -0
- package/dist/run/store.js.map +1 -0
- package/dist/run/systemPrompt.d.ts +25 -0
- package/dist/run/systemPrompt.js +41 -0
- package/dist/run/systemPrompt.js.map +1 -0
- package/dist/run/transport.d.ts +12 -0
- package/dist/run/transport.js +16 -0
- package/dist/run/transport.js.map +1 -0
- package/dist/run/types.d.ts +12 -0
- package/dist/run/types.js +2 -0
- package/dist/run/types.js.map +1 -0
- package/dist/toolkit/asset.d.ts +22 -0
- package/dist/toolkit/asset.js +26 -0
- package/dist/toolkit/asset.js.map +1 -0
- package/dist/toolkit/discover.d.ts +2 -0
- package/dist/toolkit/discover.js +61 -0
- package/dist/toolkit/discover.js.map +1 -0
- package/dist/toolkit/module.d.ts +74 -0
- package/dist/toolkit/module.js +114 -0
- package/dist/toolkit/module.js.map +1 -0
- package/dist/toolkit/prompt.d.ts +32 -0
- package/dist/toolkit/prompt.js +70 -0
- package/dist/toolkit/prompt.js.map +1 -0
- package/dist/toolkit/skill.d.ts +74 -0
- package/dist/toolkit/skill.js +125 -0
- package/dist/toolkit/skill.js.map +1 -0
- package/dist/toolkit/subagent.d.ts +54 -0
- package/dist/toolkit/subagent.js +120 -0
- package/dist/toolkit/subagent.js.map +1 -0
- package/dist/toolkit/tool.d.ts +36 -0
- package/dist/toolkit/tool.js +54 -0
- package/dist/toolkit/tool.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import type { AgentTool } from '../core/tool.js';
|
|
3
|
+
import type { SystemParam } from '../engine/types.js';
|
|
4
|
+
import { SystemPrompt } from '../run/systemPrompt.js';
|
|
5
|
+
import type { RunInvocationOptions } from '../run/spec.js';
|
|
6
|
+
import type { AgentRunResult } from '../engine/types.js';
|
|
7
|
+
import { Container } from '../container/container.js';
|
|
8
|
+
import type { Provider, Token } from '../container/container.js';
|
|
9
|
+
import type { ContextPolicy } from '../engine/types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Agentia —— 应用装配(spec §4/§6:主 agent + 可调工具菜单)。
|
|
12
|
+
*
|
|
13
|
+
* createApp 组装:DI 容器注册 providers(手动和/或 discover 目录发现)→
|
|
14
|
+
* 从容器实例自动扫描 @Tool / @SubAgent / @Skill / @Prompt 收集成本 app 的工具菜单
|
|
15
|
+
* → agent.run(messages) 带着菜单走 executeRun。装配期统一静态校验(§7):
|
|
16
|
+
* 菜单查重、tools 引用存在性、toolSources 指向。
|
|
17
|
+
* 主 agent 的 system 可由 SystemPrompt 实例给出(内部 build({cache:true})
|
|
18
|
+
* 打稳定前缀 breakpoint),也接受已拼好的 SystemParam 原样透传。
|
|
19
|
+
*/
|
|
20
|
+
export interface AppOptions {
|
|
21
|
+
/** 应用名;同时作为 run 名写入 trace */
|
|
22
|
+
name?: string;
|
|
23
|
+
/** DI providers:值 / 类 / 工厂;与 discover 可混用(同 token 后者覆盖) */
|
|
24
|
+
providers?: Provider[];
|
|
25
|
+
/**
|
|
26
|
+
* 单元目录发现:units/<name>/ 目录约定(一单元一文件夹,index.ts 入口)。
|
|
27
|
+
* 给目录路径(相对 cwd)即启动期扫描装配;因动态 import,带 discover 的
|
|
28
|
+
* createApp 返回 Promise<AgentApp>。
|
|
29
|
+
*/
|
|
30
|
+
discover?: string;
|
|
31
|
+
/** 主 agent system:SystemPrompt 实例(自动打缓存)或拼好的 SystemParam */
|
|
32
|
+
system: SystemPrompt | SystemParam;
|
|
33
|
+
/** 缺省模型;不给则走 engine 默认(claude-opus-5) */
|
|
34
|
+
model?: string;
|
|
35
|
+
/** 缺省 maxTokens(流式给足避免中途截断) */
|
|
36
|
+
maxTokens?: number;
|
|
37
|
+
/** 缺省循环上限 */
|
|
38
|
+
maxIterations?: number;
|
|
39
|
+
/** 缺省上下文预算策略(compaction / context editing) */
|
|
40
|
+
contextPolicy?: ContextPolicy;
|
|
41
|
+
/** 只扫这些 token 的 provider 上的 @Tool;缺省扫全部 providers */
|
|
42
|
+
toolSources?: Token[];
|
|
43
|
+
}
|
|
44
|
+
/** 单次调用参数 = 通用调用参数 + 单次可覆盖 system(spec.ts 的 RunInvocationOptions 为单源) */
|
|
45
|
+
export interface RunAppOptions extends RunInvocationOptions {
|
|
46
|
+
/** 单次覆盖 system(volatile 段建议每 run 重建以拾取最新值) */
|
|
47
|
+
system?: SystemPrompt | SystemParam;
|
|
48
|
+
}
|
|
49
|
+
export interface AgentRunOutput {
|
|
50
|
+
run: import('../run/run.js').Run;
|
|
51
|
+
result: AgentRunResult;
|
|
52
|
+
}
|
|
53
|
+
export declare class AgentApp {
|
|
54
|
+
readonly name: string;
|
|
55
|
+
private readonly di;
|
|
56
|
+
private readonly system;
|
|
57
|
+
private readonly base;
|
|
58
|
+
private _tools?;
|
|
59
|
+
constructor(opts: AppOptions);
|
|
60
|
+
/** app 已装配好的工具菜单(构建期即从容器解析,静态稳定) */
|
|
61
|
+
get tools(): AgentTool[];
|
|
62
|
+
/** 容器访问点(后续 trace 拦截器/生命周期回调可用) */
|
|
63
|
+
get container(): Container;
|
|
64
|
+
/** 执行一次主 agent run。system 每 run 从 SystemPrompt 重建,保证 volatile 新鲜。 */
|
|
65
|
+
run(messages: Anthropic.MessageParam[], opts?: RunAppOptions): Promise<AgentRunOutput>;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* 装配应用。不带 discover 时同步返回 AgentApp;带 discover(单元目录路径)时
|
|
69
|
+
* 先扫描装配,返回 Promise<AgentApp>(动态 import 决定)。
|
|
70
|
+
*/
|
|
71
|
+
export declare function createApp(opts: AppOptions & {
|
|
72
|
+
discover: string;
|
|
73
|
+
}): Promise<AgentApp>;
|
|
74
|
+
export declare function createApp(opts: AppOptions): AgentApp;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { SystemPrompt } from '../run/systemPrompt.js';
|
|
2
|
+
import { executeRun } from '../run/run.js';
|
|
3
|
+
import { Container } from '../container/container.js';
|
|
4
|
+
import { discoverProviders } from './discover.js';
|
|
5
|
+
import { collectTools } from './tool.js';
|
|
6
|
+
import { collectSubAgents, subagentToTool } from './subagent.js';
|
|
7
|
+
import { collectSkills, skillToTool } from './skill.js';
|
|
8
|
+
import { collectPrompts } from './prompt.js';
|
|
9
|
+
export class AgentApp {
|
|
10
|
+
name;
|
|
11
|
+
di;
|
|
12
|
+
system;
|
|
13
|
+
base;
|
|
14
|
+
_tools;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
this.name = opts.name ?? 'app';
|
|
17
|
+
// 同 token 去重(后注册覆盖先注册,与 Container.register 语义一致)——
|
|
18
|
+
// providers 与 discover 混用/重复给出同一 token 时不会重复收集菜单。
|
|
19
|
+
const providerList = [...new Map((opts.providers ?? []).map((p) => [p.provide, p])).values()];
|
|
20
|
+
this.di = new Container().register(...providerList);
|
|
21
|
+
this.system = opts.system;
|
|
22
|
+
this.base = {
|
|
23
|
+
model: opts.model,
|
|
24
|
+
maxTokens: opts.maxTokens,
|
|
25
|
+
maxIterations: opts.maxIterations,
|
|
26
|
+
contextPolicy: opts.contextPolicy,
|
|
27
|
+
};
|
|
28
|
+
// 先为每个 provider 解析实例并预收集它的 @Tool / @SubAgent / @Skill / @Prompt;
|
|
29
|
+
// 子 agent / skill 的 tools token 在装配期即解析到该 provider 的 @Tool 菜单(静态校验)。
|
|
30
|
+
const plainByToken = new Map();
|
|
31
|
+
const unitsByToken = new Map();
|
|
32
|
+
const skillsByToken = new Map();
|
|
33
|
+
const promptsByToken = new Map();
|
|
34
|
+
for (const p of providerList) {
|
|
35
|
+
const inst = this.di.resolve(p.provide);
|
|
36
|
+
plainByToken.set(p.provide, collectTools(inst));
|
|
37
|
+
unitsByToken.set(p.provide, collectSubAgents(inst));
|
|
38
|
+
skillsByToken.set(p.provide, collectSkills(inst));
|
|
39
|
+
promptsByToken.set(p.provide, collectPrompts(inst));
|
|
40
|
+
}
|
|
41
|
+
// 装配期立即解析 tools 引用(§7 启动期静态校验):引用未注册 provider 在
|
|
42
|
+
// createApp 即抛错,不延迟到模型调用该单元的运行时。
|
|
43
|
+
const resolveRefTools = (owner, refs) => {
|
|
44
|
+
const resolved = (refs ?? []).flatMap((t) => {
|
|
45
|
+
const inner = plainByToken.get(t);
|
|
46
|
+
if (!inner) {
|
|
47
|
+
throw new Error(`${owner} tools 引用未注册 provider: "${t}"`);
|
|
48
|
+
}
|
|
49
|
+
return inner;
|
|
50
|
+
});
|
|
51
|
+
return () => resolved;
|
|
52
|
+
};
|
|
53
|
+
const sources = opts.toolSources ?? providerList.map((p) => p.provide);
|
|
54
|
+
this._tools = sources.flatMap((token) => {
|
|
55
|
+
if (!this.di.has(token)) {
|
|
56
|
+
throw new Error(`toolSources 指向未注册 provider: "${token}"`);
|
|
57
|
+
}
|
|
58
|
+
const plain = plainByToken.get(token) ?? [];
|
|
59
|
+
const subTools = (unitsByToken.get(token) ?? []).map((unit) => subagentToTool(unit, resolveRefTools(`@SubAgent "${unit.name}"`, unit.spec.tools)));
|
|
60
|
+
const skillTools = (skillsByToken.get(token) ?? []).map((unit) => skillToTool(unit, resolveRefTools(`@Skill "${unit.name}"`, unit.spec.tools)));
|
|
61
|
+
const promptTools = promptsByToken.get(token) ?? [];
|
|
62
|
+
return [...plain, ...subTools, ...skillTools, ...promptTools];
|
|
63
|
+
});
|
|
64
|
+
// §7 静态校验(最小落地):菜单统一查重 —— 重名会让模型在歧义菜单里猜,直接报错。
|
|
65
|
+
const dup = new Map();
|
|
66
|
+
for (const t of this._tools)
|
|
67
|
+
dup.set(t.name, (dup.get(t.name) ?? 0) + 1);
|
|
68
|
+
const dupNames = [...dup.entries()].filter(([, n]) => n > 1).map(([n]) => n);
|
|
69
|
+
if (dupNames.length > 0) {
|
|
70
|
+
throw new Error(`菜单单元重名(tool/skill/subagent/prompt 共用命名空间): ${dupNames.join(', ')}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** app 已装配好的工具菜单(构建期即从容器解析,静态稳定) */
|
|
74
|
+
get tools() {
|
|
75
|
+
return this._tools ?? [];
|
|
76
|
+
}
|
|
77
|
+
/** 容器访问点(后续 trace 拦截器/生命周期回调可用) */
|
|
78
|
+
get container() {
|
|
79
|
+
return this.di;
|
|
80
|
+
}
|
|
81
|
+
/** 执行一次主 agent run。system 每 run 从 SystemPrompt 重建,保证 volatile 新鲜。 */
|
|
82
|
+
run(messages, opts = {}) {
|
|
83
|
+
const sys = opts.system ?? this.system;
|
|
84
|
+
const system = sys instanceof SystemPrompt ? sys.build({ cache: true }) : sys;
|
|
85
|
+
const seed = opts.blackboard;
|
|
86
|
+
return executeRun({
|
|
87
|
+
system,
|
|
88
|
+
messages,
|
|
89
|
+
tools: opts.tools ?? this._tools,
|
|
90
|
+
model: opts.model ?? this.base.model,
|
|
91
|
+
maxTokens: opts.maxTokens ?? this.base.maxTokens,
|
|
92
|
+
maxIterations: opts.maxIterations ?? this.base.maxIterations,
|
|
93
|
+
client: opts.client,
|
|
94
|
+
onText: opts.onText,
|
|
95
|
+
runName: this.name,
|
|
96
|
+
idempotencyKey: opts.idempotencyKey,
|
|
97
|
+
contextPolicy: opts.contextPolicy ?? this.base.contextPolicy,
|
|
98
|
+
rethrow: opts.rethrow,
|
|
99
|
+
contextInit: (ctx) => {
|
|
100
|
+
if (seed) {
|
|
101
|
+
for (const key of Object.keys(seed))
|
|
102
|
+
ctx.set(key, seed[key]);
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export function createApp(opts) {
|
|
109
|
+
if (opts.discover) {
|
|
110
|
+
return discoverProviders(opts.discover).then((found) => new AgentApp({ ...opts, providers: [...(opts.providers ?? []), ...found] }));
|
|
111
|
+
}
|
|
112
|
+
return new AgentApp(opts);
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/toolkit/module.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAiD7C,MAAM,OAAO,QAAQ;IACV,IAAI,CAAS;IACL,EAAE,CAAY;IACd,MAAM,CAA6B;IACnC,IAAI,CAKnB;IACM,MAAM,CAAe;IAE7B,YAAY,IAAgB;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;QAC/B,mDAAmD;QACnD,kDAAkD;QAClD,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9F,IAAI,CAAC,EAAE,GAAG,IAAI,SAAS,EAAE,CAAC,QAAQ,CAAC,GAAG,YAAY,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG;YACV,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,aAAa,EAAE,IAAI,CAAC,aAAa;SAClC,CAAC;QAEF,iEAAiE;QACjE,qEAAqE;QACrE,MAAM,YAAY,GAAG,IAAI,GAAG,EAAsB,CAAC;QACnD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;QACtD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;QACpD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAsB,CAAC;QACrD,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAS,CAAC,CAAC,OAAO,CAAC,CAAC;YAChD,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;YAChD,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;YACpD,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;YAClD,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,CAAC;QAED,gDAAgD;QAChD,iCAAiC;QACjC,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,IAA0B,EAAuB,EAAE;YACzF,MAAM,QAAQ,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC1C,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAClC,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,2BAA2B,CAAC,GAAG,CAAC,CAAC;gBAC3D,CAAC;gBACD,OAAO,KAAK,CAAC;YACf,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC;QACxB,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACvE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACtC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,gCAAgC,KAAK,GAAG,CAAC,CAAC;YAC5D,CAAC;YACD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5D,cAAc,CAAC,IAAI,EAAE,eAAe,CAAC,cAAc,IAAI,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CACnF,CAAC;YACF,MAAM,UAAU,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/D,WAAW,CAAC,IAAI,EAAE,eAAe,CAAC,WAAW,IAAI,CAAC,IAAI,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAC7E,CAAC;YACF,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YACpD,OAAO,CAAC,GAAG,KAAK,EAAE,GAAG,QAAQ,EAAE,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,CAAC,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7E,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,8CAA8C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAC3B,CAAC;IAED,mCAAmC;IACnC,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,EAAE,CAAC;IACjB,CAAC;IAED,qEAAqE;IACrE,GAAG,CAAC,QAAkC,EAAE,IAAI,GAAkB,EAAE;QAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;QACvC,MAAM,MAAM,GACV,GAAG,YAAY,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QAEjE,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC;QAC7B,OAAO,UAAU,CAAC;YAChB,MAAM;YACN,QAAQ;YACR,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM;YAChC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK;YACpC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;YAChD,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa;YAC5D,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,IAAI,CAAC,IAAI;YAClB,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa;YAC5D,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE;gBACnB,IAAI,IAAI,EAAE,CAAC;oBACT,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;wBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAQD,MAAM,UAAU,SAAS,CAAC,IAAgB;IACxC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,OAAO,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC1C,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CACvF,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentTool, JsonSchema } from '../core/tool.js';
|
|
2
|
+
/**
|
|
3
|
+
* Agentia —— Prompt 单元(spec §3:纯文本资产 —— 模板/宏/playbook,被选中时注入上下文)。
|
|
4
|
+
*
|
|
5
|
+
* 运行时本质:把 prompt 编译成主 agent 菜单里一个**无副作用拉取型 AgentTool** ——
|
|
6
|
+
* 模型判定“这活儿需要该资产”时调用它,返回文本以 tool_result 进上下文。这是
|
|
7
|
+
* 我们现成唯一的“被选中”机制(unit 本身不跑循环、不调模型)。
|
|
8
|
+
*
|
|
9
|
+
* 声明形态(标准装饰器下字段装饰器拿不到值/类引用,故只支持方法形态,与
|
|
10
|
+
* spec §4 草图的 `static brand = '…'` 用 `static method` 同效表达):
|
|
11
|
+
* - 实例方法:`@Prompt({ description }) asset()` 返回 string —— 每次调用重新执行 → volatile 资产新鲜;
|
|
12
|
+
* - 静态方法:`@Prompt({ description }) static brand()` 返回常量 string —— 纯静态资产。
|
|
13
|
+
* 方法可带一个入参(spec.schema 声明)做模板化。
|
|
14
|
+
*/
|
|
15
|
+
export interface PromptSpec {
|
|
16
|
+
/** 菜单名(缺省取被装饰方法名,建议 snake_case) */
|
|
17
|
+
name?: string;
|
|
18
|
+
/** 何时该拉取该资产的指引(模型据此决定调用) */
|
|
19
|
+
description: string;
|
|
20
|
+
/** 模板化入参 schema;缺省空对象(无参资产) */
|
|
21
|
+
schema?: JsonSchema;
|
|
22
|
+
}
|
|
23
|
+
/** 方法装饰器(实例或 static 均可):登记 prompt spec。返回值 = 资产文本。 */
|
|
24
|
+
export declare function Prompt(spec: PromptSpec): (value: Function, context: {
|
|
25
|
+
kind: string;
|
|
26
|
+
name: string | symbol;
|
|
27
|
+
}) => void;
|
|
28
|
+
/**
|
|
29
|
+
* 收集容器实例(+ 其类上的静态方法)里所有 @Prompt,产出 AgentTool[]。
|
|
30
|
+
* 实例方法沿原型链(含继承);静态方法扫描 instance.constructor 自身属性。
|
|
31
|
+
*/
|
|
32
|
+
export declare function collectPrompts(instance: object): AgentTool[];
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const promptSpecs = new WeakMap();
|
|
2
|
+
const EMPTY_SCHEMA = {
|
|
3
|
+
type: 'object',
|
|
4
|
+
properties: {},
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
};
|
|
7
|
+
/** 方法装饰器(实例或 static 均可):登记 prompt spec。返回值 = 资产文本。 */
|
|
8
|
+
export function Prompt(spec) {
|
|
9
|
+
return function (value, context) {
|
|
10
|
+
if (context.kind !== 'method') {
|
|
11
|
+
throw new Error(`@Prompt 只能修饰方法(static 方法亦可),收到 kind=${String(context.kind)}`);
|
|
12
|
+
}
|
|
13
|
+
promptSpecs.set(value, spec);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 收集容器实例(+ 其类上的静态方法)里所有 @Prompt,产出 AgentTool[]。
|
|
18
|
+
* 实例方法沿原型链(含继承);静态方法扫描 instance.constructor 自身属性。
|
|
19
|
+
*/
|
|
20
|
+
export function collectPrompts(instance) {
|
|
21
|
+
const tools = [];
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
const pushTool = (name, fn, thisArg, spec) => {
|
|
24
|
+
tools.push({
|
|
25
|
+
name: spec.name ?? name,
|
|
26
|
+
description: spec.description,
|
|
27
|
+
inputSchema: spec.schema ?? EMPTY_SCHEMA,
|
|
28
|
+
run: (input) => Reflect.apply(fn, thisArg, [input]),
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
// 实例方法(沿原型链)
|
|
32
|
+
let proto = Object.getPrototypeOf(instance);
|
|
33
|
+
while (proto && proto !== Object.prototype) {
|
|
34
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
35
|
+
if (seen.has(key))
|
|
36
|
+
continue;
|
|
37
|
+
const desc = Object.getOwnPropertyDescriptor(proto, key);
|
|
38
|
+
if (!desc || typeof desc.value !== 'function')
|
|
39
|
+
continue;
|
|
40
|
+
const spec = promptSpecs.get(desc.value);
|
|
41
|
+
if (!spec)
|
|
42
|
+
continue; // 未装饰的 override 不标 seen,父类 spec 继续生效
|
|
43
|
+
seen.add(key);
|
|
44
|
+
if (typeof spec.name !== 'string' && typeof key !== 'string') {
|
|
45
|
+
throw new Error(`@Prompt 需要显式 name(方法名为私有符号 ${String(key)})`);
|
|
46
|
+
}
|
|
47
|
+
pushTool(key, desc.value, instance, spec);
|
|
48
|
+
}
|
|
49
|
+
proto = Object.getPrototypeOf(proto);
|
|
50
|
+
}
|
|
51
|
+
// 静态方法(类自身属性)
|
|
52
|
+
const cls = instance.constructor;
|
|
53
|
+
if (typeof cls === 'function') {
|
|
54
|
+
const ctor = cls;
|
|
55
|
+
for (const key of Object.getOwnPropertyNames(ctor)) {
|
|
56
|
+
if (seen.has(key))
|
|
57
|
+
continue;
|
|
58
|
+
const fn = ctor[key];
|
|
59
|
+
if (typeof fn !== 'function')
|
|
60
|
+
continue;
|
|
61
|
+
const spec = promptSpecs.get(fn);
|
|
62
|
+
if (!spec)
|
|
63
|
+
continue;
|
|
64
|
+
seen.add(key);
|
|
65
|
+
pushTool(key, fn, cls, spec);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return tools;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/toolkit/prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type Anthropic from '@anthropic-ai/sdk';
|
|
2
|
+
import type { AgentTool, JsonSchema } from '../core/tool.js';
|
|
3
|
+
import type { AgentStopReason } from '../engine/types.js';
|
|
4
|
+
import { SystemPrompt } from '../run/systemPrompt.js';
|
|
5
|
+
/**
|
|
6
|
+
* Agentia —— Skill 单元(spec §3:指令 + 脚本,受限子运行,回产物/结论)。
|
|
7
|
+
*
|
|
8
|
+
* 与 @SubAgent 的可感知区别:
|
|
9
|
+
* - 子 agent = **模型自主循环**:你只给 role/任务/工具,走几步、何时停由模型决定;
|
|
10
|
+
* - Skill = **代码控制的流程**:方法体是确定性脚本,把“要不要调模型、调几次、
|
|
11
|
+
* 拿结果怎么算”写死在代码里 —— 模型调用只在你显式 `ctx.llm()` 时发生(受限子运行),
|
|
12
|
+
* 每次都在 skill 自己的 `unit` span 下开 llm.turn 记账,中间结果可继续加工,
|
|
13
|
+
* 方法返回值即产物/结论,以 tool_result 交回主 agent。
|
|
14
|
+
*
|
|
15
|
+
* trace:skill = 主 trace 里一个 `unit` span(attribute `skill`),内部 ctx.llm() 的
|
|
16
|
+
* llm.turn 递归成它的子孙 —— 与 @SubAgent 同款 parentSpanId 传播,不双开 run 根。
|
|
17
|
+
*/
|
|
18
|
+
export interface SkillSpec {
|
|
19
|
+
/** 菜单名(缺省取被装饰方法名,建议 snake_case) */
|
|
20
|
+
name?: string;
|
|
21
|
+
description: string;
|
|
22
|
+
/** 主 agent 填给 skill 的结构化入参 schema;缺省空对象(无入参) */
|
|
23
|
+
schema?: JsonSchema;
|
|
24
|
+
/** ctx.llm() 缺省模型;不给走 engine 缺省(AGENTIA_MODEL / claude-opus-5) */
|
|
25
|
+
model?: string;
|
|
26
|
+
maxTokens?: number;
|
|
27
|
+
maxIterations?: number;
|
|
28
|
+
/** skill 内 ctx.llm() 可调工具:容器 provider token 列表(复用其 @Tool 菜单) */
|
|
29
|
+
tools?: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface SkillLlmOptions {
|
|
32
|
+
/** 二选一:直接给 prompt(包成单条 user),或给完整 messages */
|
|
33
|
+
prompt?: string;
|
|
34
|
+
messages?: Anthropic.MessageParam[];
|
|
35
|
+
/** 本次受限子运行的系统提示;SystemPrompt 实例自动打缓存 breakpoint */
|
|
36
|
+
system?: string | SystemPrompt;
|
|
37
|
+
model?: string;
|
|
38
|
+
maxTokens?: number;
|
|
39
|
+
maxIterations?: number;
|
|
40
|
+
}
|
|
41
|
+
export interface SkillLlmResult {
|
|
42
|
+
/** 子运行最终文本 */
|
|
43
|
+
text: string;
|
|
44
|
+
stopReason: AgentStopReason;
|
|
45
|
+
}
|
|
46
|
+
/** 方法体收到的运行句柄:只暴露“受限模型调用”,其余脚本逻辑由作者代码控制。 */
|
|
47
|
+
export interface SkillContext {
|
|
48
|
+
/** 本次 skill 的缺省模型(spec.model 或 undefined → engine 缺省) */
|
|
49
|
+
readonly model?: string;
|
|
50
|
+
/** 受限子运行:每次调用在 skill unit span 下开一轮独立 agent 循环(无工具则纯文本)。 */
|
|
51
|
+
llm(opts: SkillLlmOptions): Promise<SkillLlmResult>;
|
|
52
|
+
}
|
|
53
|
+
export interface SkillUnit {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string;
|
|
56
|
+
inputSchema: JsonSchema;
|
|
57
|
+
spec: SkillSpec;
|
|
58
|
+
/** 内部:绑定 instance 的方法执行器(装饰时拿到 this,供 skillToTool 调用) */
|
|
59
|
+
invoke: (input: unknown, skillCtx: SkillContext) => unknown | Promise<unknown>;
|
|
60
|
+
}
|
|
61
|
+
/** 方法装饰器:登记 skill spec。被装饰方法体由运行时以 (input, skillCtx) 调用。 */
|
|
62
|
+
export declare function Skill(spec: SkillSpec): (value: Function, context: {
|
|
63
|
+
kind: string;
|
|
64
|
+
name: string | symbol;
|
|
65
|
+
}) => void;
|
|
66
|
+
/** 把容器实例上所有 @Skill 方法收集成 SkillUnit[](沿原型链)。 */
|
|
67
|
+
export declare function collectSkills(instance: object): SkillUnit[];
|
|
68
|
+
/**
|
|
69
|
+
* 把 SkillUnit 变成主 agent 菜单里的 AgentTool。
|
|
70
|
+
* run(input, ctx) 需要 ToolRunContext(engine 调用时必有);手动直调会抛错提示。
|
|
71
|
+
* 开 `unit` span → 构造 SkillContext(llm 闭包挂 unit 下)→ 执行方法体 →
|
|
72
|
+
* 返回值字符串化交回;抛错关 unit error 后重抛(引擎包成 is_error,不中断 run)。
|
|
73
|
+
*/
|
|
74
|
+
export declare function skillToTool(unit: SkillUnit, resolveTools: () => AgentTool[]): AgentTool;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { runAgentScoped } from '../engine/loop.js';
|
|
2
|
+
import { classifyError } from '../engine/errors.js';
|
|
3
|
+
import { SystemPrompt } from '../run/systemPrompt.js';
|
|
4
|
+
/** 方法函数 → spec(与 @Tool 同款 WeakMap 注册表,零反射) */
|
|
5
|
+
const skillSpecs = new WeakMap();
|
|
6
|
+
const EMPTY_SCHEMA = {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {},
|
|
9
|
+
additionalProperties: false,
|
|
10
|
+
};
|
|
11
|
+
/** 方法装饰器:登记 skill spec。被装饰方法体由运行时以 (input, skillCtx) 调用。 */
|
|
12
|
+
export function Skill(spec) {
|
|
13
|
+
return function (value, context) {
|
|
14
|
+
if (context.kind !== 'method') {
|
|
15
|
+
throw new Error(`@Skill 只能修饰类方法,收到 kind=${String(context.kind)}`);
|
|
16
|
+
}
|
|
17
|
+
skillSpecs.set(value, spec);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** 把容器实例上所有 @Skill 方法收集成 SkillUnit[](沿原型链)。 */
|
|
21
|
+
export function collectSkills(instance) {
|
|
22
|
+
const units = [];
|
|
23
|
+
const seen = new Set();
|
|
24
|
+
let proto = Object.getPrototypeOf(instance);
|
|
25
|
+
while (proto && proto !== Object.prototype) {
|
|
26
|
+
for (const key of Object.getOwnPropertyNames(proto)) {
|
|
27
|
+
if (seen.has(key))
|
|
28
|
+
continue;
|
|
29
|
+
const desc = Object.getOwnPropertyDescriptor(proto, key);
|
|
30
|
+
if (!desc || typeof desc.value !== 'function')
|
|
31
|
+
continue;
|
|
32
|
+
const spec = skillSpecs.get(desc.value);
|
|
33
|
+
if (!spec)
|
|
34
|
+
continue; // 未装饰的 override 不标 seen,父类 spec 继续生效
|
|
35
|
+
seen.add(key);
|
|
36
|
+
if (typeof spec.name !== 'string' && typeof key !== 'string') {
|
|
37
|
+
throw new Error(`@Skill 需要显式 name(方法名为私有符号 ${String(key)})`);
|
|
38
|
+
}
|
|
39
|
+
const name = spec.name ?? key;
|
|
40
|
+
units.push({
|
|
41
|
+
name,
|
|
42
|
+
description: spec.description,
|
|
43
|
+
inputSchema: spec.schema ?? EMPTY_SCHEMA,
|
|
44
|
+
spec,
|
|
45
|
+
invoke: (input, skillCtx) => Reflect.apply(desc.value, instance, [input, skillCtx]),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
proto = Object.getPrototypeOf(proto);
|
|
49
|
+
}
|
|
50
|
+
return units;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 把 SkillUnit 变成主 agent 菜单里的 AgentTool。
|
|
54
|
+
* run(input, ctx) 需要 ToolRunContext(engine 调用时必有);手动直调会抛错提示。
|
|
55
|
+
* 开 `unit` span → 构造 SkillContext(llm 闭包挂 unit 下)→ 执行方法体 →
|
|
56
|
+
* 返回值字符串化交回;抛错关 unit error 后重抛(引擎包成 is_error,不中断 run)。
|
|
57
|
+
*/
|
|
58
|
+
export function skillToTool(unit, resolveTools) {
|
|
59
|
+
const { name, spec } = unit;
|
|
60
|
+
return {
|
|
61
|
+
name,
|
|
62
|
+
description: spec.description,
|
|
63
|
+
inputSchema: unit.inputSchema,
|
|
64
|
+
run: async (input, ctx) => {
|
|
65
|
+
if (!ctx) {
|
|
66
|
+
throw new Error(`skill "${name}" 只能在主 agent 运行中被调用(engine 会注入 ToolRunContext)`);
|
|
67
|
+
}
|
|
68
|
+
const recorder = ctx.recorder;
|
|
69
|
+
const unitId = recorder.begin('unit', name, ctx.parentSpanId);
|
|
70
|
+
recorder.setAttribute(unitId, 'skill', name);
|
|
71
|
+
let closed = false;
|
|
72
|
+
const close = (patch) => {
|
|
73
|
+
if (closed)
|
|
74
|
+
return;
|
|
75
|
+
closed = true;
|
|
76
|
+
recorder.end(unitId, patch);
|
|
77
|
+
};
|
|
78
|
+
const skillCtx = {
|
|
79
|
+
model: spec.model,
|
|
80
|
+
llm: async (opts) => {
|
|
81
|
+
const messages = opts.prompt != null
|
|
82
|
+
? [{ role: 'user', content: opts.prompt }]
|
|
83
|
+
: (opts.messages ?? []);
|
|
84
|
+
if (messages.length === 0) {
|
|
85
|
+
throw new Error(`skill "${name}".llm 需要 prompt 或 messages`);
|
|
86
|
+
}
|
|
87
|
+
const system = opts.system instanceof SystemPrompt
|
|
88
|
+
? opts.system.build({ cache: true })
|
|
89
|
+
: opts.system;
|
|
90
|
+
const loop = await runAgentScoped({
|
|
91
|
+
client: ctx.client,
|
|
92
|
+
model: opts.model ?? spec.model,
|
|
93
|
+
maxTokens: opts.maxTokens ?? spec.maxTokens,
|
|
94
|
+
maxIterations: opts.maxIterations ?? spec.maxIterations,
|
|
95
|
+
system,
|
|
96
|
+
messages,
|
|
97
|
+
tools: spec.tools?.length ? resolveTools() : [],
|
|
98
|
+
recorder,
|
|
99
|
+
parentSpanId: unitId,
|
|
100
|
+
});
|
|
101
|
+
if (loop.stopReason !== 'end_turn') {
|
|
102
|
+
const report = `skill "${name}".llm ${loop.stopReason}: ${(loop.finalText || loop.error?.message || '').slice(0, 2000)}`;
|
|
103
|
+
const error = loop.error ?? {
|
|
104
|
+
type: 'agent_error',
|
|
105
|
+
message: report,
|
|
106
|
+
retryable: true,
|
|
107
|
+
};
|
|
108
|
+
throw new Error(report);
|
|
109
|
+
}
|
|
110
|
+
return { text: loop.finalText, stopReason: loop.stopReason };
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
try {
|
|
114
|
+
const out = await unit.invoke(input ?? {}, skillCtx);
|
|
115
|
+
close({ status: 'ok' });
|
|
116
|
+
return out;
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
close({ status: 'error', error: classifyError(e) });
|
|
120
|
+
throw e;
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=skill.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/toolkit/skill.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { AgentTool, JsonSchema } from '../core/tool.js';
|
|
2
|
+
import type { SystemParam } from '../engine/types.js';
|
|
3
|
+
import { SystemPrompt } from '../run/systemPrompt.js';
|
|
4
|
+
/**
|
|
5
|
+
* Agentia —— 子 agent 单元(spec §3/§5:独立 agent 循环 + 裁剪上下文 + 隔离报告)。
|
|
6
|
+
*
|
|
7
|
+
* 语义(spec §5):
|
|
8
|
+
* - 子 agent = **完整独立循环**:自己的 system(role)、自己的工具、自己的 model;
|
|
9
|
+
* - **裁剪上下文**:它只见「role + 主 agent 塞给它的任务」+ 自己声明的工具,
|
|
10
|
+
* 主 agent 的对话历史完全不可见;
|
|
11
|
+
* - **隔离报告**:它的中间往返全部不进主上下文,唯一回流主 agent 的是
|
|
12
|
+
* stop_reason=end_turn 的最终文本 —— 以 tool_result 交回(非 end_turn 则抛错 → is_error)。
|
|
13
|
+
*
|
|
14
|
+
* trace:子 agent 是主 trace 里的一个 `unit` span(挂在发起它的 llm.turn 下),
|
|
15
|
+
* 其内部 llm.turn 递归成它的子孙 —— 见 engine/loop.ts 的 runAgentScoped。
|
|
16
|
+
*/
|
|
17
|
+
export interface SubAgentSpec {
|
|
18
|
+
/** 菜单名(缺省取被装饰方法名,建议 snake_case) */
|
|
19
|
+
name?: string;
|
|
20
|
+
description: string;
|
|
21
|
+
/** 主 agent 填给子 agent 的任务入参 schema */
|
|
22
|
+
schema: JsonSchema;
|
|
23
|
+
/**
|
|
24
|
+
* 子 agent 自己的 system:
|
|
25
|
+
* - string / SystemPrompt 实例 → 追加一行“最终输出即交回主 agent 的报告”提示;
|
|
26
|
+
* - (task) => SystemParam | Promise<SystemParam> → 按任务动态拼,框架不附加(作者全权)。
|
|
27
|
+
* 注意:这是裁剪上下文的源头 —— 只写子 agent 完成该任务所需的角色/约束。
|
|
28
|
+
*/
|
|
29
|
+
system: string | SystemPrompt | ((task: Record<string, unknown>) => SystemParam | Promise<SystemParam>);
|
|
30
|
+
/** 子 agent 可调工具:容器 provider token 列表(复用其 @Tool 菜单);缺省 = 无工具纯文本 */
|
|
31
|
+
tools?: string[];
|
|
32
|
+
model?: string;
|
|
33
|
+
maxTokens?: number;
|
|
34
|
+
maxIterations?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface SubAgentUnit {
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
inputSchema: JsonSchema;
|
|
40
|
+
spec: SubAgentSpec;
|
|
41
|
+
}
|
|
42
|
+
/** 方法装饰器:登记子 agent spec。被装饰方法体不执行 —— 运行时拉起独立循环。 */
|
|
43
|
+
export declare function SubAgent(spec: SubAgentSpec): (value: Function, context: {
|
|
44
|
+
kind: string;
|
|
45
|
+
name: string | symbol;
|
|
46
|
+
}) => void;
|
|
47
|
+
/** 把容器实例上所有 @SubAgent 方法收集成 SubAgentUnit[](沿原型链)。 */
|
|
48
|
+
export declare function collectSubAgents(instance: object): SubAgentUnit[];
|
|
49
|
+
/**
|
|
50
|
+
* 把 SubAgentUnit 变成主 agent 菜单里的 AgentTool。
|
|
51
|
+
* run(input, ctx) 需要 ToolRunContext(engine 调用时必有);手动直调会抛错提示。
|
|
52
|
+
* tools token 列表 → resolveTools() 由装配层给出(该 token 的 @Tool 菜单)。
|
|
53
|
+
*/
|
|
54
|
+
export declare function subagentToTool(unit: SubAgentUnit, resolveTools: () => AgentTool[]): AgentTool;
|