@aigne/agent-runtime 1.12.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +26 -0
- package/README.md +79 -0
- package/dist/agent-runners/ai-runner.cjs +133 -0
- package/dist/agent-runners/ai-runner.d.cts +33 -0
- package/dist/agent-runners/ai-runner.d.cts.map +1 -0
- package/dist/agent-runners/ai-runner.d.mts +33 -0
- package/dist/agent-runners/ai-runner.d.mts.map +1 -0
- package/dist/agent-runners/ai-runner.mjs +134 -0
- package/dist/agent-runners/ai-runner.mjs.map +1 -0
- package/dist/agent-runners/ash-runner.cjs +272 -0
- package/dist/agent-runners/ash-runner.d.cts +30 -0
- package/dist/agent-runners/ash-runner.d.cts.map +1 -0
- package/dist/agent-runners/ash-runner.d.mts +30 -0
- package/dist/agent-runners/ash-runner.d.mts.map +1 -0
- package/dist/agent-runners/ash-runner.mjs +273 -0
- package/dist/agent-runners/ash-runner.mjs.map +1 -0
- package/dist/agent-runners/budget.cjs +71 -0
- package/dist/agent-runners/budget.d.cts +40 -0
- package/dist/agent-runners/budget.d.cts.map +1 -0
- package/dist/agent-runners/budget.d.mts +40 -0
- package/dist/agent-runners/budget.d.mts.map +1 -0
- package/dist/agent-runners/budget.mjs +67 -0
- package/dist/agent-runners/budget.mjs.map +1 -0
- package/dist/agent-runners/code-runner.cjs +61 -0
- package/dist/agent-runners/code-runner.mjs +61 -0
- package/dist/agent-runners/code-runner.mjs.map +1 -0
- package/dist/agent-runners/env-whitelist.cjs +36 -0
- package/dist/agent-runners/env-whitelist.d.cts +5 -0
- package/dist/agent-runners/env-whitelist.d.cts.map +1 -0
- package/dist/agent-runners/env-whitelist.d.mts +5 -0
- package/dist/agent-runners/env-whitelist.d.mts.map +1 -0
- package/dist/agent-runners/env-whitelist.mjs +36 -0
- package/dist/agent-runners/env-whitelist.mjs.map +1 -0
- package/dist/agent-runners/guide-rails.cjs +47 -0
- package/dist/agent-runners/guide-rails.d.cts +16 -0
- package/dist/agent-runners/guide-rails.d.cts.map +1 -0
- package/dist/agent-runners/guide-rails.d.mts +16 -0
- package/dist/agent-runners/guide-rails.d.mts.map +1 -0
- package/dist/agent-runners/guide-rails.mjs +48 -0
- package/dist/agent-runners/guide-rails.mjs.map +1 -0
- package/dist/agent-runners/hook-channel.cjs +55 -0
- package/dist/agent-runners/hook-channel.d.cts +38 -0
- package/dist/agent-runners/hook-channel.d.cts.map +1 -0
- package/dist/agent-runners/hook-channel.d.mts +38 -0
- package/dist/agent-runners/hook-channel.d.mts.map +1 -0
- package/dist/agent-runners/hook-channel.mjs +55 -0
- package/dist/agent-runners/hook-channel.mjs.map +1 -0
- package/dist/agent-runners/hooks.cjs +107 -0
- package/dist/agent-runners/hooks.d.cts +41 -0
- package/dist/agent-runners/hooks.d.cts.map +1 -0
- package/dist/agent-runners/hooks.d.mts +41 -0
- package/dist/agent-runners/hooks.d.mts.map +1 -0
- package/dist/agent-runners/hooks.mjs +107 -0
- package/dist/agent-runners/hooks.mjs.map +1 -0
- package/dist/agent-runners/memory-afs.cjs +342 -0
- package/dist/agent-runners/memory-afs.d.cts +221 -0
- package/dist/agent-runners/memory-afs.d.cts.map +1 -0
- package/dist/agent-runners/memory-afs.d.mts +221 -0
- package/dist/agent-runners/memory-afs.d.mts.map +1 -0
- package/dist/agent-runners/memory-afs.mjs +326 -0
- package/dist/agent-runners/memory-afs.mjs.map +1 -0
- package/dist/agent-runners/memory-archive.cjs +263 -0
- package/dist/agent-runners/memory-archive.d.cts +47 -0
- package/dist/agent-runners/memory-archive.d.cts.map +1 -0
- package/dist/agent-runners/memory-archive.d.mts +47 -0
- package/dist/agent-runners/memory-archive.d.mts.map +1 -0
- package/dist/agent-runners/memory-archive.mjs +257 -0
- package/dist/agent-runners/memory-archive.mjs.map +1 -0
- package/dist/agent-runners/orchestrator-runner.cjs +302 -0
- package/dist/agent-runners/orchestrator-runner.d.cts +23 -0
- package/dist/agent-runners/orchestrator-runner.d.cts.map +1 -0
- package/dist/agent-runners/orchestrator-runner.d.mts +23 -0
- package/dist/agent-runners/orchestrator-runner.d.mts.map +1 -0
- package/dist/agent-runners/orchestrator-runner.mjs +303 -0
- package/dist/agent-runners/orchestrator-runner.mjs.map +1 -0
- package/dist/agent-runners/orchestrator-state.cjs +68 -0
- package/dist/agent-runners/orchestrator-state.d.cts +23 -0
- package/dist/agent-runners/orchestrator-state.d.cts.map +1 -0
- package/dist/agent-runners/orchestrator-state.d.mts +23 -0
- package/dist/agent-runners/orchestrator-state.d.mts.map +1 -0
- package/dist/agent-runners/orchestrator-state.mjs +65 -0
- package/dist/agent-runners/orchestrator-state.mjs.map +1 -0
- package/dist/agent-runners/retry.cjs +30 -0
- package/dist/agent-runners/retry.d.cts +13 -0
- package/dist/agent-runners/retry.d.cts.map +1 -0
- package/dist/agent-runners/retry.d.mts +13 -0
- package/dist/agent-runners/retry.d.mts.map +1 -0
- package/dist/agent-runners/retry.mjs +30 -0
- package/dist/agent-runners/retry.mjs.map +1 -0
- package/dist/agent-runners/scratchpad-afs.cjs +276 -0
- package/dist/agent-runners/scratchpad-afs.d.cts +103 -0
- package/dist/agent-runners/scratchpad-afs.d.cts.map +1 -0
- package/dist/agent-runners/scratchpad-afs.d.mts +103 -0
- package/dist/agent-runners/scratchpad-afs.d.mts.map +1 -0
- package/dist/agent-runners/scratchpad-afs.mjs +271 -0
- package/dist/agent-runners/scratchpad-afs.mjs.map +1 -0
- package/dist/agent-runners/stream-router.cjs +72 -0
- package/dist/agent-runners/stream-router.d.cts +22 -0
- package/dist/agent-runners/stream-router.d.cts.map +1 -0
- package/dist/agent-runners/stream-router.d.mts +22 -0
- package/dist/agent-runners/stream-router.d.mts.map +1 -0
- package/dist/agent-runners/stream-router.mjs +72 -0
- package/dist/agent-runners/stream-router.mjs.map +1 -0
- package/dist/agent-runners/system-prompt.cjs +35 -0
- package/dist/agent-runners/system-prompt.d.cts +17 -0
- package/dist/agent-runners/system-prompt.d.cts.map +1 -0
- package/dist/agent-runners/system-prompt.d.mts +17 -0
- package/dist/agent-runners/system-prompt.d.mts.map +1 -0
- package/dist/agent-runners/system-prompt.mjs +34 -0
- package/dist/agent-runners/system-prompt.mjs.map +1 -0
- package/dist/agent-runners/team-modes/aggregates.cjs +36 -0
- package/dist/agent-runners/team-modes/aggregates.mjs +35 -0
- package/dist/agent-runners/team-modes/aggregates.mjs.map +1 -0
- package/dist/agent-runners/team-modes/iterate.cjs +46 -0
- package/dist/agent-runners/team-modes/iterate.mjs +47 -0
- package/dist/agent-runners/team-modes/iterate.mjs.map +1 -0
- package/dist/agent-runners/team-modes/parallel.cjs +59 -0
- package/dist/agent-runners/team-modes/parallel.mjs +60 -0
- package/dist/agent-runners/team-modes/parallel.mjs.map +1 -0
- package/dist/agent-runners/team-modes/reflection.cjs +155 -0
- package/dist/agent-runners/team-modes/reflection.mjs +156 -0
- package/dist/agent-runners/team-modes/reflection.mjs.map +1 -0
- package/dist/agent-runners/team-modes/sequential.cjs +63 -0
- package/dist/agent-runners/team-modes/sequential.mjs +64 -0
- package/dist/agent-runners/team-modes/sequential.mjs.map +1 -0
- package/dist/agent-runners/team-modes/utils.cjs +39 -0
- package/dist/agent-runners/team-modes/utils.mjs +36 -0
- package/dist/agent-runners/team-modes/utils.mjs.map +1 -0
- package/dist/agent-runners/team-runner.cjs +277 -0
- package/dist/agent-runners/team-runner.d.cts +34 -0
- package/dist/agent-runners/team-runner.d.cts.map +1 -0
- package/dist/agent-runners/team-runner.d.mts +34 -0
- package/dist/agent-runners/team-runner.d.mts.map +1 -0
- package/dist/agent-runners/team-runner.mjs +278 -0
- package/dist/agent-runners/team-runner.mjs.map +1 -0
- package/dist/agent-runners/template-context.cjs +32 -0
- package/dist/agent-runners/template-context.d.cts +43 -0
- package/dist/agent-runners/template-context.d.cts.map +1 -0
- package/dist/agent-runners/template-context.d.mts +43 -0
- package/dist/agent-runners/template-context.d.mts.map +1 -0
- package/dist/agent-runners/template-context.mjs +33 -0
- package/dist/agent-runners/template-context.mjs.map +1 -0
- package/dist/index.cjs +123 -0
- package/dist/index.d.cts +29 -0
- package/dist/index.d.mts +29 -0
- package/dist/index.mjs +29 -0
- package/dist/program/agent-action.cjs +496 -0
- package/dist/program/agent-action.d.cts +42 -0
- package/dist/program/agent-action.d.cts.map +1 -0
- package/dist/program/agent-action.d.mts +42 -0
- package/dist/program/agent-action.d.mts.map +1 -0
- package/dist/program/agent-action.mjs +497 -0
- package/dist/program/agent-action.mjs.map +1 -0
- package/dist/program/agent-messages-tools.cjs +137 -0
- package/dist/program/agent-messages-tools.d.cts +59 -0
- package/dist/program/agent-messages-tools.d.cts.map +1 -0
- package/dist/program/agent-messages-tools.d.mts +59 -0
- package/dist/program/agent-messages-tools.d.mts.map +1 -0
- package/dist/program/agent-messages-tools.mjs +130 -0
- package/dist/program/agent-messages-tools.mjs.map +1 -0
- package/dist/program/agent-runner-registry.cjs +314 -0
- package/dist/program/agent-runner-registry.d.cts +52 -0
- package/dist/program/agent-runner-registry.d.cts.map +1 -0
- package/dist/program/agent-runner-registry.d.mts +52 -0
- package/dist/program/agent-runner-registry.d.mts.map +1 -0
- package/dist/program/agent-runner-registry.mjs +313 -0
- package/dist/program/agent-runner-registry.mjs.map +1 -0
- package/dist/program/agent-subscribe.cjs +72 -0
- package/dist/program/agent-subscribe.d.cts +18 -0
- package/dist/program/agent-subscribe.d.cts.map +1 -0
- package/dist/program/agent-subscribe.d.mts +18 -0
- package/dist/program/agent-subscribe.d.mts.map +1 -0
- package/dist/program/agent-subscribe.mjs +73 -0
- package/dist/program/agent-subscribe.mjs.map +1 -0
- package/dist/program/agent-tools.cjs +135 -0
- package/dist/program/agent-tools.d.cts +35 -0
- package/dist/program/agent-tools.d.cts.map +1 -0
- package/dist/program/agent-tools.d.mts +35 -0
- package/dist/program/agent-tools.d.mts.map +1 -0
- package/dist/program/agent-tools.mjs +136 -0
- package/dist/program/agent-tools.mjs.map +1 -0
- package/dist/program/manifest-nesting.cjs +57 -0
- package/dist/program/manifest-nesting.d.cts +13 -0
- package/dist/program/manifest-nesting.d.cts.map +1 -0
- package/dist/program/manifest-nesting.d.mts +13 -0
- package/dist/program/manifest-nesting.d.mts.map +1 -0
- package/dist/program/manifest-nesting.mjs +57 -0
- package/dist/program/manifest-nesting.mjs.map +1 -0
- package/dist/program/result-contract.cjs +55 -0
- package/dist/program/result-contract.d.cts +23 -0
- package/dist/program/result-contract.d.cts.map +1 -0
- package/dist/program/result-contract.d.mts +23 -0
- package/dist/program/result-contract.d.mts.map +1 -0
- package/dist/program/result-contract.mjs +51 -0
- package/dist/program/result-contract.mjs.map +1 -0
- package/dist/program/runner-error.cjs +71 -0
- package/dist/program/runner-error.d.cts +25 -0
- package/dist/program/runner-error.d.cts.map +1 -0
- package/dist/program/runner-error.d.mts +25 -0
- package/dist/program/runner-error.d.mts.map +1 -0
- package/dist/program/runner-error.mjs +72 -0
- package/dist/program/runner-error.mjs.map +1 -0
- package/dist/program/scoped-afs.cjs +538 -0
- package/dist/program/scoped-afs.d.cts +245 -0
- package/dist/program/scoped-afs.d.cts.map +1 -0
- package/dist/program/scoped-afs.d.mts +245 -0
- package/dist/program/scoped-afs.d.mts.map +1 -0
- package/dist/program/scoped-afs.mjs +531 -0
- package/dist/program/scoped-afs.mjs.map +1 -0
- package/dist/program/session-hierarchy.cjs +1 -0
- package/dist/program/session-hierarchy.d.cts +2 -0
- package/dist/program/session-hierarchy.d.mts +2 -0
- package/dist/program/session-hierarchy.mjs +3 -0
- package/dist/program/tool-discovery/ash-frontmatter.cjs +83 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.cts +21 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.cts.map +1 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.mts +21 -0
- package/dist/program/tool-discovery/ash-frontmatter.d.mts.map +1 -0
- package/dist/program/tool-discovery/ash-frontmatter.mjs +84 -0
- package/dist/program/tool-discovery/ash-frontmatter.mjs.map +1 -0
- package/dist/program/tool-discovery/dot-path-resolver.cjs +60 -0
- package/dist/program/tool-discovery/dot-path-resolver.mjs +61 -0
- package/dist/program/tool-discovery/dot-path-resolver.mjs.map +1 -0
- package/dist/program/tool-discovery/skill-gate.cjs +36 -0
- package/dist/program/tool-discovery/skill-gate.d.cts +10 -0
- package/dist/program/tool-discovery/skill-gate.d.cts.map +1 -0
- package/dist/program/tool-discovery/skill-gate.d.mts +10 -0
- package/dist/program/tool-discovery/skill-gate.d.mts.map +1 -0
- package/dist/program/tool-discovery/skill-gate.mjs +35 -0
- package/dist/program/tool-discovery/skill-gate.mjs.map +1 -0
- package/dist/providers/basic/ash/dist/index.cjs +1809 -0
- package/dist/providers/basic/ash/dist/index.mjs +1807 -0
- package/dist/providers/basic/ash/dist/index.mjs.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
const require_memory_archive = require('./memory-archive.cjs');
|
|
2
|
+
const require_hook_channel = require('./hook-channel.cjs');
|
|
3
|
+
const require_scoped_afs = require('../program/scoped-afs.cjs');
|
|
4
|
+
const require_iterate = require('./team-modes/iterate.cjs');
|
|
5
|
+
const require_parallel = require('./team-modes/parallel.cjs');
|
|
6
|
+
const require_reflection = require('./team-modes/reflection.cjs');
|
|
7
|
+
const require_sequential = require('./team-modes/sequential.cjs');
|
|
8
|
+
const require_agent_runner_registry = require('../program/agent-runner-registry.cjs');
|
|
9
|
+
let ufo = require("ufo");
|
|
10
|
+
let _aigne_afs = require("@aigne/afs");
|
|
11
|
+
|
|
12
|
+
//#region src/agent-runners/team-runner.ts
|
|
13
|
+
async function persistedHookPathSpread(afs, session, events) {
|
|
14
|
+
const path = await require_hook_channel.persistHookEvents(afs, session, events);
|
|
15
|
+
return path ? { hook_events_path: path } : {};
|
|
16
|
+
}
|
|
17
|
+
function createMemberRunner(context, handoffAppendix) {
|
|
18
|
+
const parentSessionId = require_scoped_afs.runnerSession(context.afs, context.session);
|
|
19
|
+
const parentScope = require_scoped_afs.resolveParentAgentScope({
|
|
20
|
+
afs: context.afs,
|
|
21
|
+
manifest: context.manifest,
|
|
22
|
+
session: parentSessionId
|
|
23
|
+
});
|
|
24
|
+
const baseSystemAppend = handoffAppendix ? context.systemAppend ? `${context.systemAppend}\n\n${handoffAppendix}` : handoffAppendix : context.systemAppend;
|
|
25
|
+
const teamInputKey = context.manifest.inputKey ?? "message";
|
|
26
|
+
/**
|
|
27
|
+
* B15 — bridge the task payload to the member's own `input_key`.
|
|
28
|
+
*
|
|
29
|
+
* Team-level input lives under the team's inputKey (e.g. `message`) or
|
|
30
|
+
* arrives pre-keyed from sequential/iterate pipelines. The member may
|
|
31
|
+
* declare a different inputKey (e.g. `topic`, `query`). Without this
|
|
32
|
+
* bridge, aiRunner would read `input[memberInputKey]` → undefined →
|
|
33
|
+
* agent-run throws `requires 'task' parameter as string`.
|
|
34
|
+
*/
|
|
35
|
+
function remapForMember(memberInput, memberInputKey) {
|
|
36
|
+
if (memberInputKey === teamInputKey) return memberInput;
|
|
37
|
+
if (memberInput[memberInputKey] !== void 0) return memberInput;
|
|
38
|
+
const taskValue = memberInput[teamInputKey] ?? memberInput.message ?? memberInput.task ?? memberInput.text;
|
|
39
|
+
if (taskValue === void 0) return memberInput;
|
|
40
|
+
return {
|
|
41
|
+
...memberInput,
|
|
42
|
+
[memberInputKey]: taskValue
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return async (memberPath, input, session) => {
|
|
46
|
+
const agentYmlPath = (0, ufo.joinURL)((0, _aigne_afs.resolveMemberPath)(memberPath), "agent.yml");
|
|
47
|
+
let subManifestRaw;
|
|
48
|
+
try {
|
|
49
|
+
subManifestRaw = (await context.afs.read(agentYmlPath))?.data?.content ?? "";
|
|
50
|
+
} catch (err) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: {
|
|
54
|
+
code: "MEMBER_NOT_FOUND",
|
|
55
|
+
message: `Cannot load member agent.yml at ${agentYmlPath}: ${err instanceof Error ? err.message : String(err)}`,
|
|
56
|
+
member: memberPath
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
let subManifest;
|
|
61
|
+
try {
|
|
62
|
+
subManifest = (0, _aigne_afs.parseAgentManifest)(typeof subManifestRaw === "string" ? subManifestRaw : String(subManifestRaw ?? ""));
|
|
63
|
+
} catch (err) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: {
|
|
67
|
+
code: "MEMBER_MANIFEST_INVALID",
|
|
68
|
+
message: `Invalid agent.yml for member "${memberPath}": ${err instanceof Error ? err.message : String(err)}`,
|
|
69
|
+
member: memberPath
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (context.manifest.memory !== void 0 && subManifest.memory === void 0) subManifest = {
|
|
74
|
+
...subManifest,
|
|
75
|
+
memory: context.manifest.memory
|
|
76
|
+
};
|
|
77
|
+
let subAfs;
|
|
78
|
+
try {
|
|
79
|
+
subAfs = require_scoped_afs.projectForChild(parentScope, {
|
|
80
|
+
memberPath,
|
|
81
|
+
childManifest: subManifest,
|
|
82
|
+
session
|
|
83
|
+
});
|
|
84
|
+
} catch (err) {
|
|
85
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
86
|
+
return {
|
|
87
|
+
success: false,
|
|
88
|
+
error: {
|
|
89
|
+
code: message.split(":")[0] ?? "SCOPE_PROJECTION_ERROR",
|
|
90
|
+
message: `Cannot project scope for member "${memberPath}": ${message}`,
|
|
91
|
+
member: memberPath
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const subContext = {
|
|
96
|
+
afs: subAfs,
|
|
97
|
+
mountPath: "/packages",
|
|
98
|
+
manifest: subManifest,
|
|
99
|
+
session,
|
|
100
|
+
parentSession: parentSessionId,
|
|
101
|
+
chain: context.chain,
|
|
102
|
+
systemAppend: baseSystemAppend
|
|
103
|
+
};
|
|
104
|
+
const memberInput = remapForMember(input, subManifest.inputKey ?? "message");
|
|
105
|
+
let result;
|
|
106
|
+
try {
|
|
107
|
+
result = await require_agent_runner_registry.getRunnerForType(subManifest.type)(memberInput, subContext);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
error: {
|
|
112
|
+
code: "MEMBER_DISPATCH_ERROR",
|
|
113
|
+
message: `Member "${memberPath}" dispatch failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
114
|
+
member: memberPath
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function runTeamAgent(input, context) {
|
|
122
|
+
const { manifest } = context;
|
|
123
|
+
const session = require_scoped_afs.runnerSession(context.afs, context.session);
|
|
124
|
+
const scopedAfs = require_scoped_afs.ensureScopeWithMounts(context.afs, {
|
|
125
|
+
session: session ?? "root",
|
|
126
|
+
manifestTools: require_scoped_afs.normalizeManifestTools(manifest),
|
|
127
|
+
scratchRetention: manifest.scratch ? "session" : "run",
|
|
128
|
+
budget: manifest.budget,
|
|
129
|
+
memory: manifest.memory
|
|
130
|
+
});
|
|
131
|
+
const scopedContext = {
|
|
132
|
+
...context,
|
|
133
|
+
afs: scopedAfs,
|
|
134
|
+
session
|
|
135
|
+
};
|
|
136
|
+
const mode = manifest.mode ?? "parallel";
|
|
137
|
+
const inputKey = manifest.inputKey ?? "message";
|
|
138
|
+
const hookChannel = require_hook_channel.createHookChannel();
|
|
139
|
+
let handoffAppendix;
|
|
140
|
+
if (require_memory_archive.isHandoffReadThroughEnabled(manifest.memory)) {
|
|
141
|
+
const domain = scopedAfs.scope?.memoryDomain;
|
|
142
|
+
if (domain) {
|
|
143
|
+
const formatted = require_memory_archive.formatRecallForPrompt(await require_memory_archive.recallForHandoff({
|
|
144
|
+
afs: scopedAfs,
|
|
145
|
+
domain
|
|
146
|
+
}));
|
|
147
|
+
if (formatted) handoffAppendix = formatted;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const runMember = createMemberRunner(scopedContext, handoffAppendix);
|
|
151
|
+
if (scopedContext.hookDispatcher && manifest.hooks?.onHandoff) hookChannel.subscribe((event) => {
|
|
152
|
+
if (event.name === "on_handoff") scopedContext.hookDispatcher.fireOnHandoff(event.from, event.to, event.iteration);
|
|
153
|
+
});
|
|
154
|
+
if (mode === "reflection") {
|
|
155
|
+
if (!manifest.actor || !manifest.reviewer) return {
|
|
156
|
+
success: false,
|
|
157
|
+
error: {
|
|
158
|
+
code: "REFLECTION_MISSING_ROLES",
|
|
159
|
+
message: "Reflection mode requires both actor and reviewer"
|
|
160
|
+
},
|
|
161
|
+
_meta: {
|
|
162
|
+
mode: "reflection",
|
|
163
|
+
hook_events: []
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const result$1 = await require_reflection.runReflection({
|
|
167
|
+
afs: scopedAfs,
|
|
168
|
+
actorPath: manifest.actor,
|
|
169
|
+
reviewerPath: manifest.reviewer,
|
|
170
|
+
session: session ?? "default",
|
|
171
|
+
inputKey,
|
|
172
|
+
input,
|
|
173
|
+
isApprovedField: manifest.isApproved ?? "approved",
|
|
174
|
+
maxIterations: manifest.maxIterations ?? 5,
|
|
175
|
+
returnLastOnMax: manifest.returnLastOnMax ?? false,
|
|
176
|
+
hookChannel,
|
|
177
|
+
runMember
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
success: result$1.success,
|
|
181
|
+
data: result$1.data,
|
|
182
|
+
error: result$1.error,
|
|
183
|
+
_meta: {
|
|
184
|
+
mode: "reflection",
|
|
185
|
+
iterations: result$1._meta.iterations,
|
|
186
|
+
max_iterations_hit: result$1._meta.max_iterations_hit,
|
|
187
|
+
hook_events: result$1._meta.hook_events,
|
|
188
|
+
...await persistedHookPathSpread(scopedAfs, session, result$1._meta.hook_events)
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const members = manifest.members ?? [];
|
|
193
|
+
if (members.length === 0) return {
|
|
194
|
+
success: false,
|
|
195
|
+
error: {
|
|
196
|
+
code: "TEAM_NO_MEMBERS",
|
|
197
|
+
message: "Team has no members"
|
|
198
|
+
},
|
|
199
|
+
_meta: {
|
|
200
|
+
mode,
|
|
201
|
+
hook_events: []
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const inputValue = input[inputKey];
|
|
205
|
+
if (Array.isArray(inputValue) && mode === "sequential") {
|
|
206
|
+
const result$1 = await require_iterate.runIterate({
|
|
207
|
+
members,
|
|
208
|
+
session: session ?? "default",
|
|
209
|
+
inputKey,
|
|
210
|
+
items: inputValue,
|
|
211
|
+
concurrency: manifest.concurrency,
|
|
212
|
+
runMember
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
success: result$1.success,
|
|
216
|
+
data: result$1.data,
|
|
217
|
+
error: result$1.error,
|
|
218
|
+
_meta: {
|
|
219
|
+
mode: "iterate_on",
|
|
220
|
+
items_count: result$1._meta.items_count,
|
|
221
|
+
max_concurrency: result$1._meta.max_concurrency,
|
|
222
|
+
hook_events: result$1._meta.hook_events,
|
|
223
|
+
...await persistedHookPathSpread(scopedAfs, session, result$1._meta.hook_events)
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
if (mode === "sequential") {
|
|
228
|
+
const result$1 = await require_sequential.runSequential({
|
|
229
|
+
members,
|
|
230
|
+
session: session ?? "default",
|
|
231
|
+
inputKey,
|
|
232
|
+
input,
|
|
233
|
+
hookChannel,
|
|
234
|
+
runMember
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
success: result$1.success,
|
|
238
|
+
data: result$1.data,
|
|
239
|
+
error: result$1.error,
|
|
240
|
+
_meta: {
|
|
241
|
+
mode: "sequential",
|
|
242
|
+
members_run: result$1._meta.members_run,
|
|
243
|
+
completed_steps: result$1._meta.completed_steps,
|
|
244
|
+
hook_events: result$1._meta.hook_events,
|
|
245
|
+
...await persistedHookPathSpread(scopedAfs, session, result$1._meta.hook_events),
|
|
246
|
+
member_run_ids: result$1._meta.member_run_ids,
|
|
247
|
+
rounds: result$1._meta.rounds,
|
|
248
|
+
tokens_used: result$1._meta.tokens_used,
|
|
249
|
+
sub_runs: result$1._meta.sub_runs
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const result = await require_parallel.runParallel({
|
|
254
|
+
members,
|
|
255
|
+
session: session ?? "default",
|
|
256
|
+
input,
|
|
257
|
+
concurrency: manifest.concurrency,
|
|
258
|
+
runMember
|
|
259
|
+
});
|
|
260
|
+
return {
|
|
261
|
+
success: result.success,
|
|
262
|
+
data: result.data,
|
|
263
|
+
_meta: {
|
|
264
|
+
mode: "parallel",
|
|
265
|
+
sub_runs: result._meta.sub_runs,
|
|
266
|
+
max_concurrency: result._meta.max_concurrency,
|
|
267
|
+
hook_events: result._meta.hook_events,
|
|
268
|
+
...await persistedHookPathSpread(scopedAfs, session, result._meta.hook_events),
|
|
269
|
+
member_run_ids: result._meta.member_run_ids,
|
|
270
|
+
rounds: result._meta.rounds,
|
|
271
|
+
tokens_used: result._meta.tokens_used
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//#endregion
|
|
277
|
+
exports.runTeamAgent = runTeamAgent;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HookEvent } from "./hook-channel.cjs";
|
|
2
|
+
import { RunnerContext } from "../program/agent-runner-registry.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/agent-runners/team-runner.d.ts
|
|
5
|
+
interface TeamRunnerResult {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: Record<string, unknown>;
|
|
8
|
+
result?: Record<string, unknown>;
|
|
9
|
+
error?: {
|
|
10
|
+
code: string;
|
|
11
|
+
message: string;
|
|
12
|
+
member?: string;
|
|
13
|
+
index?: number;
|
|
14
|
+
};
|
|
15
|
+
_meta?: {
|
|
16
|
+
mode: string;
|
|
17
|
+
members_run?: number;
|
|
18
|
+
sub_runs?: number;
|
|
19
|
+
completed_steps?: number;
|
|
20
|
+
iterations?: number;
|
|
21
|
+
max_iterations_hit?: boolean;
|
|
22
|
+
max_concurrency?: number;
|
|
23
|
+
items_count?: number;
|
|
24
|
+
hook_events?: HookEvent[];
|
|
25
|
+
hook_events_path?: string;
|
|
26
|
+
member_run_ids?: string[];
|
|
27
|
+
rounds?: number;
|
|
28
|
+
tokens_used?: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
declare function runTeamAgent(input: Record<string, unknown>, context: RunnerContext): Promise<TeamRunnerResult>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { TeamRunnerResult, runTeamAgent };
|
|
34
|
+
//# sourceMappingURL=team-runner.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-runner.d.cts","names":[],"sources":["../../src/agent-runners/team-runner.ts"],"mappings":";;;;UAiCiB,gBAAA;EACf,OAAA;EACA,IAAA,GAAO,MAAA;EACP,MAAA,GAAS,MAAA;EACT,KAAA;IAAU,IAAA;IAAc,OAAA;IAAiB,MAAA;IAAiB,KAAA;EAAA;EAC1D,KAAA;IACE,IAAA;IACA,WAAA;IACA,QAAA;IACA,eAAA;IACA,UAAA;IACA,kBAAA;IACA,eAAA;IACA,WAAA;IACA,WAAA,GAAc,SAAA;IACd,gBAAA;IACA,cAAA;IACA,MAAA;IACA,WAAA;EAAA;AAAA;AAAA,iBAkJkB,YAAA,CACpB,KAAA,EAAO,MAAA,mBACP,OAAA,EAAS,aAAA,GACR,OAAA,CAAQ,gBAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { HookEvent } from "./hook-channel.mjs";
|
|
2
|
+
import { RunnerContext } from "../program/agent-runner-registry.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/agent-runners/team-runner.d.ts
|
|
5
|
+
interface TeamRunnerResult {
|
|
6
|
+
success: boolean;
|
|
7
|
+
data?: Record<string, unknown>;
|
|
8
|
+
result?: Record<string, unknown>;
|
|
9
|
+
error?: {
|
|
10
|
+
code: string;
|
|
11
|
+
message: string;
|
|
12
|
+
member?: string;
|
|
13
|
+
index?: number;
|
|
14
|
+
};
|
|
15
|
+
_meta?: {
|
|
16
|
+
mode: string;
|
|
17
|
+
members_run?: number;
|
|
18
|
+
sub_runs?: number;
|
|
19
|
+
completed_steps?: number;
|
|
20
|
+
iterations?: number;
|
|
21
|
+
max_iterations_hit?: boolean;
|
|
22
|
+
max_concurrency?: number;
|
|
23
|
+
items_count?: number;
|
|
24
|
+
hook_events?: HookEvent[];
|
|
25
|
+
hook_events_path?: string;
|
|
26
|
+
member_run_ids?: string[];
|
|
27
|
+
rounds?: number;
|
|
28
|
+
tokens_used?: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
declare function runTeamAgent(input: Record<string, unknown>, context: RunnerContext): Promise<TeamRunnerResult>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { TeamRunnerResult, runTeamAgent };
|
|
34
|
+
//# sourceMappingURL=team-runner.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-runner.d.mts","names":[],"sources":["../../src/agent-runners/team-runner.ts"],"mappings":";;;;UAiCiB,gBAAA;EACf,OAAA;EACA,IAAA,GAAO,MAAA;EACP,MAAA,GAAS,MAAA;EACT,KAAA;IAAU,IAAA;IAAc,OAAA;IAAiB,MAAA;IAAiB,KAAA;EAAA;EAC1D,KAAA;IACE,IAAA;IACA,WAAA;IACA,QAAA;IACA,eAAA;IACA,UAAA;IACA,kBAAA;IACA,eAAA;IACA,WAAA;IACA,WAAA,GAAc,SAAA;IACd,gBAAA;IACA,cAAA;IACA,MAAA;IACA,WAAA;EAAA;AAAA;AAAA,iBAkJkB,YAAA,CACpB,KAAA,EAAO,MAAA,mBACP,OAAA,EAAS,aAAA,GACR,OAAA,CAAQ,gBAAA"}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { formatRecallForPrompt, isHandoffReadThroughEnabled, recallForHandoff } from "./memory-archive.mjs";
|
|
2
|
+
import { createHookChannel, persistHookEvents } from "./hook-channel.mjs";
|
|
3
|
+
import { ensureScopeWithMounts, normalizeManifestTools, projectForChild, resolveParentAgentScope, runnerSession } from "../program/scoped-afs.mjs";
|
|
4
|
+
import { runIterate } from "./team-modes/iterate.mjs";
|
|
5
|
+
import { runParallel } from "./team-modes/parallel.mjs";
|
|
6
|
+
import { runReflection } from "./team-modes/reflection.mjs";
|
|
7
|
+
import { runSequential } from "./team-modes/sequential.mjs";
|
|
8
|
+
import { getRunnerForType } from "../program/agent-runner-registry.mjs";
|
|
9
|
+
import { joinURL } from "ufo";
|
|
10
|
+
import { parseAgentManifest, resolveMemberPath } from "@aigne/afs";
|
|
11
|
+
|
|
12
|
+
//#region src/agent-runners/team-runner.ts
|
|
13
|
+
async function persistedHookPathSpread(afs, session, events) {
|
|
14
|
+
const path = await persistHookEvents(afs, session, events);
|
|
15
|
+
return path ? { hook_events_path: path } : {};
|
|
16
|
+
}
|
|
17
|
+
function createMemberRunner(context, handoffAppendix) {
|
|
18
|
+
const parentSessionId = runnerSession(context.afs, context.session);
|
|
19
|
+
const parentScope = resolveParentAgentScope({
|
|
20
|
+
afs: context.afs,
|
|
21
|
+
manifest: context.manifest,
|
|
22
|
+
session: parentSessionId
|
|
23
|
+
});
|
|
24
|
+
const baseSystemAppend = handoffAppendix ? context.systemAppend ? `${context.systemAppend}\n\n${handoffAppendix}` : handoffAppendix : context.systemAppend;
|
|
25
|
+
const teamInputKey = context.manifest.inputKey ?? "message";
|
|
26
|
+
/**
|
|
27
|
+
* B15 — bridge the task payload to the member's own `input_key`.
|
|
28
|
+
*
|
|
29
|
+
* Team-level input lives under the team's inputKey (e.g. `message`) or
|
|
30
|
+
* arrives pre-keyed from sequential/iterate pipelines. The member may
|
|
31
|
+
* declare a different inputKey (e.g. `topic`, `query`). Without this
|
|
32
|
+
* bridge, aiRunner would read `input[memberInputKey]` → undefined →
|
|
33
|
+
* agent-run throws `requires 'task' parameter as string`.
|
|
34
|
+
*/
|
|
35
|
+
function remapForMember(memberInput, memberInputKey) {
|
|
36
|
+
if (memberInputKey === teamInputKey) return memberInput;
|
|
37
|
+
if (memberInput[memberInputKey] !== void 0) return memberInput;
|
|
38
|
+
const taskValue = memberInput[teamInputKey] ?? memberInput.message ?? memberInput.task ?? memberInput.text;
|
|
39
|
+
if (taskValue === void 0) return memberInput;
|
|
40
|
+
return {
|
|
41
|
+
...memberInput,
|
|
42
|
+
[memberInputKey]: taskValue
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return async (memberPath, input, session) => {
|
|
46
|
+
const agentYmlPath = joinURL(resolveMemberPath(memberPath), "agent.yml");
|
|
47
|
+
let subManifestRaw;
|
|
48
|
+
try {
|
|
49
|
+
subManifestRaw = (await context.afs.read(agentYmlPath))?.data?.content ?? "";
|
|
50
|
+
} catch (err) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: {
|
|
54
|
+
code: "MEMBER_NOT_FOUND",
|
|
55
|
+
message: `Cannot load member agent.yml at ${agentYmlPath}: ${err instanceof Error ? err.message : String(err)}`,
|
|
56
|
+
member: memberPath
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
let subManifest;
|
|
61
|
+
try {
|
|
62
|
+
subManifest = parseAgentManifest(typeof subManifestRaw === "string" ? subManifestRaw : String(subManifestRaw ?? ""));
|
|
63
|
+
} catch (err) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: {
|
|
67
|
+
code: "MEMBER_MANIFEST_INVALID",
|
|
68
|
+
message: `Invalid agent.yml for member "${memberPath}": ${err instanceof Error ? err.message : String(err)}`,
|
|
69
|
+
member: memberPath
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (context.manifest.memory !== void 0 && subManifest.memory === void 0) subManifest = {
|
|
74
|
+
...subManifest,
|
|
75
|
+
memory: context.manifest.memory
|
|
76
|
+
};
|
|
77
|
+
let subAfs;
|
|
78
|
+
try {
|
|
79
|
+
subAfs = projectForChild(parentScope, {
|
|
80
|
+
memberPath,
|
|
81
|
+
childManifest: subManifest,
|
|
82
|
+
session
|
|
83
|
+
});
|
|
84
|
+
} catch (err) {
|
|
85
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
86
|
+
return {
|
|
87
|
+
success: false,
|
|
88
|
+
error: {
|
|
89
|
+
code: message.split(":")[0] ?? "SCOPE_PROJECTION_ERROR",
|
|
90
|
+
message: `Cannot project scope for member "${memberPath}": ${message}`,
|
|
91
|
+
member: memberPath
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const subContext = {
|
|
96
|
+
afs: subAfs,
|
|
97
|
+
mountPath: "/packages",
|
|
98
|
+
manifest: subManifest,
|
|
99
|
+
session,
|
|
100
|
+
parentSession: parentSessionId,
|
|
101
|
+
chain: context.chain,
|
|
102
|
+
systemAppend: baseSystemAppend
|
|
103
|
+
};
|
|
104
|
+
const memberInput = remapForMember(input, subManifest.inputKey ?? "message");
|
|
105
|
+
let result;
|
|
106
|
+
try {
|
|
107
|
+
result = await getRunnerForType(subManifest.type)(memberInput, subContext);
|
|
108
|
+
} catch (err) {
|
|
109
|
+
return {
|
|
110
|
+
success: false,
|
|
111
|
+
error: {
|
|
112
|
+
code: "MEMBER_DISPATCH_ERROR",
|
|
113
|
+
message: `Member "${memberPath}" dispatch failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
114
|
+
member: memberPath
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
async function runTeamAgent(input, context) {
|
|
122
|
+
const { manifest } = context;
|
|
123
|
+
const session = runnerSession(context.afs, context.session);
|
|
124
|
+
const scopedAfs = ensureScopeWithMounts(context.afs, {
|
|
125
|
+
session: session ?? "root",
|
|
126
|
+
manifestTools: normalizeManifestTools(manifest),
|
|
127
|
+
scratchRetention: manifest.scratch ? "session" : "run",
|
|
128
|
+
budget: manifest.budget,
|
|
129
|
+
memory: manifest.memory
|
|
130
|
+
});
|
|
131
|
+
const scopedContext = {
|
|
132
|
+
...context,
|
|
133
|
+
afs: scopedAfs,
|
|
134
|
+
session
|
|
135
|
+
};
|
|
136
|
+
const mode = manifest.mode ?? "parallel";
|
|
137
|
+
const inputKey = manifest.inputKey ?? "message";
|
|
138
|
+
const hookChannel = createHookChannel();
|
|
139
|
+
let handoffAppendix;
|
|
140
|
+
if (isHandoffReadThroughEnabled(manifest.memory)) {
|
|
141
|
+
const domain = scopedAfs.scope?.memoryDomain;
|
|
142
|
+
if (domain) {
|
|
143
|
+
const formatted = formatRecallForPrompt(await recallForHandoff({
|
|
144
|
+
afs: scopedAfs,
|
|
145
|
+
domain
|
|
146
|
+
}));
|
|
147
|
+
if (formatted) handoffAppendix = formatted;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const runMember = createMemberRunner(scopedContext, handoffAppendix);
|
|
151
|
+
if (scopedContext.hookDispatcher && manifest.hooks?.onHandoff) hookChannel.subscribe((event) => {
|
|
152
|
+
if (event.name === "on_handoff") scopedContext.hookDispatcher.fireOnHandoff(event.from, event.to, event.iteration);
|
|
153
|
+
});
|
|
154
|
+
if (mode === "reflection") {
|
|
155
|
+
if (!manifest.actor || !manifest.reviewer) return {
|
|
156
|
+
success: false,
|
|
157
|
+
error: {
|
|
158
|
+
code: "REFLECTION_MISSING_ROLES",
|
|
159
|
+
message: "Reflection mode requires both actor and reviewer"
|
|
160
|
+
},
|
|
161
|
+
_meta: {
|
|
162
|
+
mode: "reflection",
|
|
163
|
+
hook_events: []
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const result$1 = await runReflection({
|
|
167
|
+
afs: scopedAfs,
|
|
168
|
+
actorPath: manifest.actor,
|
|
169
|
+
reviewerPath: manifest.reviewer,
|
|
170
|
+
session: session ?? "default",
|
|
171
|
+
inputKey,
|
|
172
|
+
input,
|
|
173
|
+
isApprovedField: manifest.isApproved ?? "approved",
|
|
174
|
+
maxIterations: manifest.maxIterations ?? 5,
|
|
175
|
+
returnLastOnMax: manifest.returnLastOnMax ?? false,
|
|
176
|
+
hookChannel,
|
|
177
|
+
runMember
|
|
178
|
+
});
|
|
179
|
+
return {
|
|
180
|
+
success: result$1.success,
|
|
181
|
+
data: result$1.data,
|
|
182
|
+
error: result$1.error,
|
|
183
|
+
_meta: {
|
|
184
|
+
mode: "reflection",
|
|
185
|
+
iterations: result$1._meta.iterations,
|
|
186
|
+
max_iterations_hit: result$1._meta.max_iterations_hit,
|
|
187
|
+
hook_events: result$1._meta.hook_events,
|
|
188
|
+
...await persistedHookPathSpread(scopedAfs, session, result$1._meta.hook_events)
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
const members = manifest.members ?? [];
|
|
193
|
+
if (members.length === 0) return {
|
|
194
|
+
success: false,
|
|
195
|
+
error: {
|
|
196
|
+
code: "TEAM_NO_MEMBERS",
|
|
197
|
+
message: "Team has no members"
|
|
198
|
+
},
|
|
199
|
+
_meta: {
|
|
200
|
+
mode,
|
|
201
|
+
hook_events: []
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const inputValue = input[inputKey];
|
|
205
|
+
if (Array.isArray(inputValue) && mode === "sequential") {
|
|
206
|
+
const result$1 = await runIterate({
|
|
207
|
+
members,
|
|
208
|
+
session: session ?? "default",
|
|
209
|
+
inputKey,
|
|
210
|
+
items: inputValue,
|
|
211
|
+
concurrency: manifest.concurrency,
|
|
212
|
+
runMember
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
success: result$1.success,
|
|
216
|
+
data: result$1.data,
|
|
217
|
+
error: result$1.error,
|
|
218
|
+
_meta: {
|
|
219
|
+
mode: "iterate_on",
|
|
220
|
+
items_count: result$1._meta.items_count,
|
|
221
|
+
max_concurrency: result$1._meta.max_concurrency,
|
|
222
|
+
hook_events: result$1._meta.hook_events,
|
|
223
|
+
...await persistedHookPathSpread(scopedAfs, session, result$1._meta.hook_events)
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
if (mode === "sequential") {
|
|
228
|
+
const result$1 = await runSequential({
|
|
229
|
+
members,
|
|
230
|
+
session: session ?? "default",
|
|
231
|
+
inputKey,
|
|
232
|
+
input,
|
|
233
|
+
hookChannel,
|
|
234
|
+
runMember
|
|
235
|
+
});
|
|
236
|
+
return {
|
|
237
|
+
success: result$1.success,
|
|
238
|
+
data: result$1.data,
|
|
239
|
+
error: result$1.error,
|
|
240
|
+
_meta: {
|
|
241
|
+
mode: "sequential",
|
|
242
|
+
members_run: result$1._meta.members_run,
|
|
243
|
+
completed_steps: result$1._meta.completed_steps,
|
|
244
|
+
hook_events: result$1._meta.hook_events,
|
|
245
|
+
...await persistedHookPathSpread(scopedAfs, session, result$1._meta.hook_events),
|
|
246
|
+
member_run_ids: result$1._meta.member_run_ids,
|
|
247
|
+
rounds: result$1._meta.rounds,
|
|
248
|
+
tokens_used: result$1._meta.tokens_used,
|
|
249
|
+
sub_runs: result$1._meta.sub_runs
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const result = await runParallel({
|
|
254
|
+
members,
|
|
255
|
+
session: session ?? "default",
|
|
256
|
+
input,
|
|
257
|
+
concurrency: manifest.concurrency,
|
|
258
|
+
runMember
|
|
259
|
+
});
|
|
260
|
+
return {
|
|
261
|
+
success: result.success,
|
|
262
|
+
data: result.data,
|
|
263
|
+
_meta: {
|
|
264
|
+
mode: "parallel",
|
|
265
|
+
sub_runs: result._meta.sub_runs,
|
|
266
|
+
max_concurrency: result._meta.max_concurrency,
|
|
267
|
+
hook_events: result._meta.hook_events,
|
|
268
|
+
...await persistedHookPathSpread(scopedAfs, session, result._meta.hook_events),
|
|
269
|
+
member_run_ids: result._meta.member_run_ids,
|
|
270
|
+
rounds: result._meta.rounds,
|
|
271
|
+
tokens_used: result._meta.tokens_used
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
//#endregion
|
|
277
|
+
export { runTeamAgent };
|
|
278
|
+
//# sourceMappingURL=team-runner.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-runner.mjs","names":["result"],"sources":["../../src/agent-runners/team-runner.ts"],"sourcesContent":["import type { AFSExecResult, AFSRoot } from \"@aigne/afs\";\nimport { parseAgentManifest, resolveMemberPath } from \"@aigne/afs\";\nimport { joinURL } from \"ufo\";\nimport { getRunnerForType, type RunnerContext } from \"../program/agent-runner-registry.js\";\nimport {\n type AgentScope,\n ensureScopeWithMounts,\n normalizeManifestTools,\n projectForChild,\n resolveParentAgentScope,\n runnerSession,\n} from \"../program/scoped-afs.js\";\nimport { createHookChannel, type HookEvent, persistHookEvents } from \"./hook-channel.js\";\nimport {\n formatRecallForPrompt,\n isHandoffReadThroughEnabled,\n recallForHandoff,\n} from \"./memory-archive.js\";\nimport { runIterate } from \"./team-modes/iterate.js\";\nimport { runParallel } from \"./team-modes/parallel.js\";\nimport { runReflection } from \"./team-modes/reflection.js\";\nimport { runSequential } from \"./team-modes/sequential.js\";\nimport type { MemberRunFn } from \"./team-modes/types.js\";\n\nasync function persistedHookPathSpread(\n afs: RunnerContext[\"afs\"],\n session: string | undefined,\n events: HookEvent[],\n): Promise<{ hook_events_path?: string }> {\n const path = await persistHookEvents(afs, session, events);\n return path ? { hook_events_path: path } : {};\n}\n\nexport interface TeamRunnerResult {\n success: boolean;\n data?: Record<string, unknown>;\n result?: Record<string, unknown>;\n error?: { code: string; message: string; member?: string; index?: number };\n _meta?: {\n mode: string;\n members_run?: number;\n sub_runs?: number;\n completed_steps?: number;\n iterations?: number;\n max_iterations_hit?: boolean;\n max_concurrency?: number;\n items_count?: number;\n hook_events?: HookEvent[];\n hook_events_path?: string;\n member_run_ids?: string[];\n rounds?: number;\n tokens_used?: number;\n };\n}\n\nfunction createMemberRunner(context: RunnerContext, handoffAppendix?: string): MemberRunFn {\n // Phase 5 — anchor the parent scope on the scope-carried session id so a\n // child dispatched below sees the scope's session as its parentSession,\n // not whatever legacy context field happened to be populated.\n const parentSessionId = runnerSession(context.afs, context.session);\n const parentScope = resolveParentAgentScope({\n afs: context.afs,\n manifest: context.manifest,\n session: parentSessionId,\n });\n\n const baseSystemAppend = handoffAppendix\n ? context.systemAppend\n ? `${context.systemAppend}\\n\\n${handoffAppendix}`\n : handoffAppendix\n : context.systemAppend;\n\n const teamInputKey = context.manifest.inputKey ?? \"message\";\n\n /**\n * B15 — bridge the task payload to the member's own `input_key`.\n *\n * Team-level input lives under the team's inputKey (e.g. `message`) or\n * arrives pre-keyed from sequential/iterate pipelines. The member may\n * declare a different inputKey (e.g. `topic`, `query`). Without this\n * bridge, aiRunner would read `input[memberInputKey]` → undefined →\n * agent-run throws `requires 'task' parameter as string`.\n */\n function remapForMember(\n memberInput: Record<string, unknown>,\n memberInputKey: string,\n ): Record<string, unknown> {\n if (memberInputKey === teamInputKey) return memberInput;\n if (memberInput[memberInputKey] !== undefined) return memberInput;\n\n const taskValue =\n memberInput[teamInputKey] ?? memberInput.message ?? memberInput.task ?? memberInput.text;\n\n if (taskValue === undefined) return memberInput;\n return { ...memberInput, [memberInputKey]: taskValue };\n }\n\n return async (memberPath, input, session) => {\n const runtimeMemberPath = resolveMemberPath(memberPath);\n const agentYmlPath = joinURL(runtimeMemberPath, \"agent.yml\");\n\n let subManifestRaw: unknown;\n try {\n const read = await context.afs.read!(agentYmlPath);\n subManifestRaw = (read as any)?.data?.content ?? \"\";\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n error: {\n code: \"MEMBER_NOT_FOUND\",\n message: `Cannot load member agent.yml at ${agentYmlPath}: ${message}`,\n member: memberPath,\n },\n } as unknown as AFSExecResult;\n }\n\n let subManifest: ReturnType<typeof parseAgentManifest>;\n try {\n subManifest = parseAgentManifest(\n typeof subManifestRaw === \"string\" ? subManifestRaw : String(subManifestRaw ?? \"\"),\n );\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n error: {\n code: \"MEMBER_MANIFEST_INVALID\",\n message: `Invalid agent.yml for member \"${memberPath}\": ${message}`,\n member: memberPath,\n },\n } as unknown as AFSExecResult;\n }\n\n // Inherit team-level `memory:` into members so the child scope mounts\n // `/memory/` and the AI runner's `wrapToolProgress` / handoff\n // read-through gates see an enabled config. Member YAML must not declare\n // `memory:` (scoped-afs invariant); we attach it at runtime so the\n // invariant is preserved on disk while still propagating the team's\n // archive + recall settings to the dispatched member.\n if (context.manifest.memory !== undefined && subManifest.memory === undefined) {\n subManifest = { ...subManifest, memory: context.manifest.memory };\n }\n\n let subAfs: AgentScope;\n try {\n subAfs = projectForChild(parentScope, {\n memberPath,\n childManifest: subManifest,\n session,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n const code = message.split(\":\")[0] ?? \"SCOPE_PROJECTION_ERROR\";\n return {\n success: false,\n error: {\n code,\n message: `Cannot project scope for member \"${memberPath}\": ${message}`,\n member: memberPath,\n },\n } as unknown as AFSExecResult;\n }\n\n const subContext: RunnerContext = {\n afs: subAfs as unknown as AFSRoot,\n mountPath: \"/packages\",\n manifest: subManifest,\n session,\n parentSession: parentSessionId,\n chain: context.chain,\n systemAppend: baseSystemAppend,\n };\n\n const memberInputKey = subManifest.inputKey ?? \"message\";\n const memberInput = remapForMember(input, memberInputKey);\n\n let result: AFSExecResult;\n try {\n const runner = getRunnerForType(subManifest.type);\n result = await runner(memberInput, subContext);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n success: false,\n error: {\n code: \"MEMBER_DISPATCH_ERROR\",\n message: `Member \"${memberPath}\" dispatch failed: ${message}`,\n member: memberPath,\n },\n } as unknown as AFSExecResult;\n }\n\n return result;\n };\n}\n\nexport async function runTeamAgent(\n input: Record<string, unknown>,\n context: RunnerContext,\n): Promise<TeamRunnerResult> {\n const { manifest } = context;\n // Phase 5 — session id comes from scope first, legacy context only as\n // fallback. Everything below reads `session` through this resolved value.\n const session = runnerSession(context.afs, context.session);\n // Bootstrap scope + /scratch/ mount when the caller hasn't already done\n // so. Ensures hook-channel persistence lands in scope-local\n // /scratch/hook-channel.jsonl rather than leaking into the parent's\n // /modules/memory/runs/ tree.\n const scopedAfs = ensureScopeWithMounts(context.afs, {\n session: session ?? \"root\",\n manifestTools: normalizeManifestTools(manifest),\n scratchRetention: manifest.scratch ? \"session\" : \"run\",\n budget: manifest.budget,\n memory: manifest.memory,\n }) as unknown as AFSRoot;\n // Phase 5 — after `ensureScopeWithMounts`, the scoped AFS now carries a\n // scope with `session` set. Downstream consumers (createMemberRunner,\n // persistHookEvents) must see the resolved session through the scope.\n const scopedContext: RunnerContext = { ...context, afs: scopedAfs, session };\n const mode = manifest.mode ?? \"parallel\";\n const inputKey = manifest.inputKey ?? \"message\";\n const hookChannel = createHookChannel();\n\n // G2 — single recall per team dispatch. Every member reuses the same\n // appendix string rather than re-scanning memory N times under parallel\n // fan-out. No-op when the team hasn't opted in or the scope has no\n // resolvable memory domain.\n let handoffAppendix: string | undefined;\n if (isHandoffReadThroughEnabled(manifest.memory)) {\n const domain = (scopedAfs as AgentScope).scope?.memoryDomain;\n if (domain) {\n const recalled = await recallForHandoff({ afs: scopedAfs, domain });\n const formatted = formatRecallForPrompt(recalled);\n if (formatted) handoffAppendix = formatted;\n }\n }\n\n const runMember = createMemberRunner(scopedContext, handoffAppendix);\n\n if (scopedContext.hookDispatcher && manifest.hooks?.onHandoff) {\n hookChannel.subscribe((event) => {\n if (event.name === \"on_handoff\") {\n scopedContext.hookDispatcher!.fireOnHandoff(event.from, event.to, event.iteration);\n }\n });\n }\n\n if (mode === \"reflection\") {\n if (!manifest.actor || !manifest.reviewer) {\n return {\n success: false,\n error: {\n code: \"REFLECTION_MISSING_ROLES\",\n message: \"Reflection mode requires both actor and reviewer\",\n },\n _meta: { mode: \"reflection\", hook_events: [] },\n };\n }\n\n const result = await runReflection({\n afs: scopedAfs,\n actorPath: manifest.actor,\n reviewerPath: manifest.reviewer,\n session: session ?? \"default\",\n inputKey,\n input,\n isApprovedField: manifest.isApproved ?? \"approved\",\n maxIterations: manifest.maxIterations ?? 5,\n returnLastOnMax: manifest.returnLastOnMax ?? false,\n hookChannel,\n runMember,\n });\n\n const teamResult: TeamRunnerResult = {\n success: result.success,\n data: result.data,\n error: result.error,\n _meta: {\n mode: \"reflection\",\n iterations: result._meta.iterations,\n max_iterations_hit: result._meta.max_iterations_hit,\n hook_events: result._meta.hook_events,\n ...(await persistedHookPathSpread(scopedAfs, session, result._meta.hook_events)),\n },\n };\n\n return teamResult;\n }\n\n // Validate members for non-reflection modes\n const members = manifest.members ?? [];\n if (members.length === 0) {\n return {\n success: false,\n error: { code: \"TEAM_NO_MEMBERS\", message: \"Team has no members\" },\n _meta: { mode, hook_events: [] },\n };\n }\n\n // Check if input is an array → iterate_on mode\n const inputValue = input[inputKey];\n if (Array.isArray(inputValue) && mode === \"sequential\") {\n const result = await runIterate({\n members,\n session: session ?? \"default\",\n inputKey,\n items: inputValue,\n concurrency: manifest.concurrency,\n runMember,\n });\n\n return {\n success: result.success,\n data: result.data,\n error: result.error,\n _meta: {\n mode: \"iterate_on\",\n items_count: result._meta.items_count,\n max_concurrency: result._meta.max_concurrency,\n hook_events: result._meta.hook_events,\n ...(await persistedHookPathSpread(scopedAfs, session, result._meta.hook_events)),\n },\n };\n }\n\n if (mode === \"sequential\") {\n const result = await runSequential({\n members,\n session: session ?? \"default\",\n inputKey,\n input,\n hookChannel,\n runMember,\n });\n\n const teamResult: TeamRunnerResult = {\n success: result.success,\n data: result.data,\n error: result.error,\n _meta: {\n mode: \"sequential\",\n members_run: result._meta.members_run,\n completed_steps: result._meta.completed_steps,\n hook_events: result._meta.hook_events,\n ...(await persistedHookPathSpread(scopedAfs, session, result._meta.hook_events)),\n member_run_ids: result._meta.member_run_ids,\n rounds: result._meta.rounds,\n tokens_used: result._meta.tokens_used,\n sub_runs: result._meta.sub_runs,\n },\n };\n\n return teamResult;\n }\n\n // Default: parallel\n const result = await runParallel({\n members,\n session: session ?? \"default\",\n input,\n concurrency: manifest.concurrency,\n runMember,\n });\n\n const teamResult: TeamRunnerResult = {\n success: result.success,\n data: result.data,\n _meta: {\n mode: \"parallel\",\n sub_runs: result._meta.sub_runs,\n max_concurrency: result._meta.max_concurrency,\n hook_events: result._meta.hook_events,\n ...(await persistedHookPathSpread(scopedAfs, session, result._meta.hook_events)),\n member_run_ids: result._meta.member_run_ids,\n rounds: result._meta.rounds,\n tokens_used: result._meta.tokens_used,\n },\n };\n\n return teamResult;\n}\n"],"mappings":"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"}
|