orbitx 0.2.1 → 0.2.4

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 (113) hide show
  1. package/Readme.md +26 -0
  2. package/dist/core/ai-provider.d.ts +31 -1
  3. package/dist/core/ai-provider.d.ts.map +1 -1
  4. package/dist/core/ai-provider.js.map +1 -1
  5. package/dist/core/anthropic-provider.d.ts +1 -0
  6. package/dist/core/anthropic-provider.d.ts.map +1 -1
  7. package/dist/core/anthropic-provider.js +83 -3
  8. package/dist/core/anthropic-provider.js.map +1 -1
  9. package/dist/core/base-agent.d.ts +13 -0
  10. package/dist/core/base-agent.d.ts.map +1 -1
  11. package/dist/core/base-agent.js +77 -109
  12. package/dist/core/base-agent.js.map +1 -1
  13. package/dist/core/deepseek-provider.d.ts +2 -0
  14. package/dist/core/deepseek-provider.d.ts.map +1 -1
  15. package/dist/core/deepseek-provider.js +56 -2
  16. package/dist/core/deepseek-provider.js.map +1 -1
  17. package/dist/core/image-describer.d.ts +7 -1
  18. package/dist/core/image-describer.d.ts.map +1 -1
  19. package/dist/core/image-describer.js +5 -1
  20. package/dist/core/image-describer.js.map +1 -1
  21. package/dist/core/ollama-provider.d.ts +1 -0
  22. package/dist/core/ollama-provider.d.ts.map +1 -1
  23. package/dist/core/ollama-provider.js +45 -1
  24. package/dist/core/ollama-provider.js.map +1 -1
  25. package/dist/core/openai-provider.d.ts +1 -0
  26. package/dist/core/openai-provider.d.ts.map +1 -1
  27. package/dist/core/openai-provider.js +54 -1
  28. package/dist/core/openai-provider.js.map +1 -1
  29. package/dist/core/think-effort.d.ts +21 -0
  30. package/dist/core/think-effort.d.ts.map +1 -0
  31. package/dist/core/think-effort.js +19 -0
  32. package/dist/core/think-effort.js.map +1 -0
  33. package/dist/core/worker-agent.d.ts +43 -0
  34. package/dist/core/worker-agent.d.ts.map +1 -0
  35. package/dist/core/worker-agent.js +40 -0
  36. package/dist/core/worker-agent.js.map +1 -0
  37. package/dist/index.d.ts +8 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +4 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/templates/simple.d.ts +2 -0
  42. package/dist/templates/simple.d.ts.map +1 -1
  43. package/dist/templates/simple.js.map +1 -1
  44. package/dist/tests/index.d.ts +1 -0
  45. package/dist/tests/index.d.ts.map +1 -1
  46. package/dist/tests/index.js +1 -0
  47. package/dist/tests/index.js.map +1 -1
  48. package/dist/tests/tools/agent/agent-tools.test.d.ts +2 -0
  49. package/dist/tests/tools/agent/agent-tools.test.d.ts.map +1 -0
  50. package/dist/tests/tools/agent/agent-tools.test.js +156 -0
  51. package/dist/tests/tools/agent/agent-tools.test.js.map +1 -0
  52. package/dist/tools/agent/hire.d.ts +6 -0
  53. package/dist/tools/agent/hire.d.ts.map +1 -0
  54. package/dist/tools/agent/hire.js +32 -0
  55. package/dist/tools/agent/hire.js.map +1 -0
  56. package/dist/tools/agent/index.d.ts +27 -0
  57. package/dist/tools/agent/index.d.ts.map +1 -0
  58. package/dist/tools/agent/index.js +31 -0
  59. package/dist/tools/agent/index.js.map +1 -0
  60. package/dist/tools/agent/interaction.d.ts +25 -0
  61. package/dist/tools/agent/interaction.d.ts.map +1 -0
  62. package/dist/tools/agent/interaction.js +14 -0
  63. package/dist/tools/agent/interaction.js.map +1 -0
  64. package/dist/tools/agent/list.d.ts +5 -0
  65. package/dist/tools/agent/list.d.ts.map +1 -0
  66. package/dist/tools/agent/list.js +16 -0
  67. package/dist/tools/agent/list.js.map +1 -0
  68. package/dist/tools/agent/prompt.d.ts +6 -0
  69. package/dist/tools/agent/prompt.d.ts.map +1 -0
  70. package/dist/tools/agent/prompt.js +73 -0
  71. package/dist/tools/agent/prompt.js.map +1 -0
  72. package/dist/tools/agent/registry.d.ts +33 -0
  73. package/dist/tools/agent/registry.d.ts.map +1 -0
  74. package/dist/tools/agent/registry.js +68 -0
  75. package/dist/tools/agent/registry.js.map +1 -0
  76. package/dist/tools/agent/report.d.ts +12 -0
  77. package/dist/tools/agent/report.d.ts.map +1 -0
  78. package/dist/tools/agent/report.js +31 -0
  79. package/dist/tools/agent/report.js.map +1 -0
  80. package/dist/tools/fs/edit-file.d.ts.map +1 -1
  81. package/dist/tools/fs/edit-file.js +9 -8
  82. package/dist/tools/fs/edit-file.js.map +1 -1
  83. package/dist/tools/fs/list-dir.d.ts.map +1 -1
  84. package/dist/tools/fs/list-dir.js +0 -1
  85. package/dist/tools/fs/list-dir.js.map +1 -1
  86. package/dist/tools/fs/read-file.js +3 -3
  87. package/dist/tools/fs/read-file.js.map +1 -1
  88. package/dist/tools/fs/utils.d.ts +7 -0
  89. package/dist/tools/fs/utils.d.ts.map +1 -1
  90. package/dist/tools/fs/utils.js +9 -2
  91. package/dist/tools/fs/utils.js.map +1 -1
  92. package/dist/tools/utils/index.d.ts +1 -0
  93. package/dist/tools/utils/index.d.ts.map +1 -1
  94. package/dist/tools/utils/index.js +4 -1
  95. package/dist/tools/utils/index.js.map +1 -1
  96. package/dist/tools/utils/read-image.d.ts +12 -0
  97. package/dist/tools/utils/read-image.d.ts.map +1 -0
  98. package/dist/tools/utils/read-image.js +70 -0
  99. package/dist/tools/utils/read-image.js.map +1 -0
  100. package/docs/agents.md +181 -0
  101. package/docs/api-reference.md +54 -0
  102. package/docs/getting-started.md +78 -0
  103. package/docs/index.md +23 -0
  104. package/docs/mcp-architecture.md +103 -0
  105. package/docs/providers.md +151 -0
  106. package/docs/skills.md +68 -0
  107. package/docs/streaming.md +116 -0
  108. package/docs/tools.md +179 -0
  109. package/package.json +4 -3
  110. package/dist/tests/mcp.test.d.ts +0 -2
  111. package/dist/tests/mcp.test.d.ts.map +0 -1
  112. package/dist/tests/mcp.test.js +0 -3
  113. package/dist/tests/mcp.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tests/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AACrC,OAAO,+BAA+B,CAAC;AACvC,OAAO,mCAAmC,CAAC;AAC3C,OAAO,kCAAkC,CAAC;AAG1C,OAAO,6BAA6B,CAAC;AACrC,OAAO,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tests/index.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,CAAC;AACrC,OAAO,+BAA+B,CAAC;AACvC,OAAO,mCAAmC,CAAC;AAC3C,OAAO,kCAAkC,CAAC;AAG1C,OAAO,6BAA6B,CAAC;AACrC,OAAO,wCAAwC,CAAC;AAChD,OAAO,mCAAmC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-tools.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-tools.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/tools/agent/agent-tools.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,156 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { AIProvider, AgentReportTool, AgentTools, MCPClient, MCPConnection, MCPServer, WorkerAgent, } from "../../../index.js";
4
+ /**
5
+ * Returns a fixed, scripted response (or repeats the last one once
6
+ * exhausted) instead of calling a real model — lets the agent-management
7
+ * tools be tested end to end (hire -> prompt -> worker's own tool loop ->
8
+ * report) with no network access.
9
+ */
10
+ class ScriptedProvider extends AIProvider {
11
+ #responses;
12
+ #calls = 0;
13
+ constructor(responses) {
14
+ super();
15
+ this.#responses = responses;
16
+ }
17
+ async chat(_messages, streamCallback, _tools) {
18
+ const response = this.#responses[Math.min(this.#calls, this.#responses.length - 1)];
19
+ this.#calls++;
20
+ if (streamCallback) {
21
+ if (response.content) {
22
+ await streamCallback({ role: "assistant", content: response.content, done: false });
23
+ }
24
+ await streamCallback({
25
+ role: "assistant",
26
+ content: "",
27
+ done: true,
28
+ ...(response.toolCalls?.length ? { toolCalls: response.toolCalls } : {}),
29
+ });
30
+ }
31
+ return response;
32
+ }
33
+ getCapabilities() {
34
+ return { supportsTools: true, supportsImages: false, contextWindow: 200_000, safeUsageRatio: 0.9 };
35
+ }
36
+ }
37
+ function buildWorker(name, description, responses) {
38
+ const connection = new MCPConnection();
39
+ const server = new MCPServer(connection);
40
+ const reportTool = AgentReportTool();
41
+ server.registerTool(reportTool);
42
+ const mcpClient = new MCPClient(`worker-${name}`, connection);
43
+ return new WorkerAgent({
44
+ name,
45
+ description,
46
+ rating: { backend: 8, frontend: 3 },
47
+ instruction: "You are a worker agent.",
48
+ aiProvider: new ScriptedProvider(responses),
49
+ mcpClient,
50
+ allowedTools: [reportTool],
51
+ });
52
+ }
53
+ test("AgentTools: agent-list shows every worker, unhired by default", async () => {
54
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "unused", inputTokens: 0, outputTokens: 0 }]);
55
+ const [listTool] = AgentTools([worker]);
56
+ const result = await listTool.getOptions().execute("env", {});
57
+ assert.strictEqual(result.agents.length, 1);
58
+ assert.strictEqual(result.agents[0].name, "backend-worker");
59
+ assert.strictEqual(result.agents[0].description, "Handles backend tasks.");
60
+ assert.deepStrictEqual(result.agents[0].rating, { backend: 8, frontend: 3 });
61
+ assert.strictEqual(result.agents[0].hired, false);
62
+ });
63
+ test("AgentTools: agent-hire marks a worker hired, reflected in agent-list", async () => {
64
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "unused", inputTokens: 0, outputTokens: 0 }]);
65
+ const [listTool, hireTool] = AgentTools([worker]);
66
+ const hireResult = await hireTool.getOptions().execute("env", { name: "backend-worker" });
67
+ assert.deepStrictEqual(hireResult, { hired: true, name: "backend-worker" });
68
+ const listResult = await listTool.getOptions().execute("env", {});
69
+ assert.strictEqual(listResult.agents[0].hired, true);
70
+ });
71
+ test("AgentTools: agent-hire on an unknown name throws", async () => {
72
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "unused", inputTokens: 0, outputTokens: 0 }]);
73
+ const [, hireTool] = AgentTools([worker]);
74
+ await assert.rejects(() => hireTool.getOptions().execute("env", { name: "nonexistent" }), /no worker agent named "nonexistent"/);
75
+ });
76
+ test("AgentTools: agent-prompt on a worker that isn't hired yet throws", async () => {
77
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "unused", inputTokens: 0, outputTokens: 0 }]);
78
+ const [, , promptTool] = AgentTools([worker]);
79
+ await assert.rejects(() => promptTool.getOptions().execute("env", { name: "backend-worker", prompt: "do it" }), /is not hired yet/);
80
+ });
81
+ test("AgentTools: agent-prompt runs the worker and returns its agent-report text", async () => {
82
+ const reportCall = { id: "call-1", name: "agent-report", inputs: { report: "answer is 42" } };
83
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [
84
+ { content: "", inputTokens: 10, outputTokens: 5, toolCalls: [reportCall] },
85
+ ]);
86
+ const [, hireTool, promptTool] = AgentTools([worker]);
87
+ await hireTool.getOptions().execute("env", { name: "backend-worker" });
88
+ const result = await promptTool.getOptions().execute("env", { name: "backend-worker", prompt: "what is the answer?" });
89
+ assert.strictEqual(result.reported, true);
90
+ assert.strictEqual(result.report, "answer is 42");
91
+ });
92
+ test("AgentTools: agent-prompt falls back to the worker's last assistant text when it never calls agent-report", async () => {
93
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [
94
+ { content: "I looked into it, no tool needed.", inputTokens: 10, outputTokens: 5 },
95
+ ]);
96
+ const [, hireTool, promptTool] = AgentTools([worker]);
97
+ await hireTool.getOptions().execute("env", { name: "backend-worker" });
98
+ const result = await promptTool.getOptions().execute("env", { name: "backend-worker", prompt: "check something" });
99
+ assert.strictEqual(result.reported, false);
100
+ assert.strictEqual(result.report, "I looked into it, no tool needed.");
101
+ });
102
+ test("AgentTools: a second agent-prompt call doesn't resurface a stale report from the first call", async () => {
103
+ const reportCall = { id: "call-1", name: "agent-report", inputs: { report: "first answer" } };
104
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [
105
+ { content: "", inputTokens: 10, outputTokens: 5, toolCalls: [reportCall] },
106
+ { content: "just acknowledging, no report this time", inputTokens: 10, outputTokens: 5 },
107
+ ]);
108
+ const [, hireTool, promptTool] = AgentTools([worker]);
109
+ await hireTool.getOptions().execute("env", { name: "backend-worker" });
110
+ await promptTool.getOptions().execute("env", { name: "backend-worker", prompt: "first task" });
111
+ const second = await promptTool.getOptions().execute("env", { name: "backend-worker", prompt: "second task" });
112
+ assert.strictEqual(second.reported, false);
113
+ assert.strictEqual(second.report, "just acknowledging, no report this time");
114
+ });
115
+ test("AgentTools: duplicate worker names are rejected at construction", async () => {
116
+ const workerA = buildWorker("dup", "A", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
117
+ const workerB = buildWorker("dup", "B", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
118
+ assert.throws(() => AgentTools([workerA, workerB]), /duplicate worker agent name "dup"/);
119
+ });
120
+ test("AgentTools: maxHired is mentioned dynamically in agent-hire's description", async () => {
121
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
122
+ const [, hireTool] = AgentTools([worker], { maxHired: 2 });
123
+ assert.match(hireTool.getOptions().description, /At most 2 worker agents may be hired at once/);
124
+ });
125
+ test("AgentTools: agent-hire has no limit note when maxHired is omitted", async () => {
126
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
127
+ const [, hireTool] = AgentTools([worker]);
128
+ assert.doesNotMatch(hireTool.getOptions().description, /At most/);
129
+ });
130
+ test("AgentTools: hiring beyond maxHired throws, but re-hiring an already-hired worker doesn't count against it", async () => {
131
+ const workerA = buildWorker("worker-a", "A", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
132
+ const workerB = buildWorker("worker-b", "B", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
133
+ const workerC = buildWorker("worker-c", "C", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
134
+ const [listTool, hireTool] = AgentTools([workerA, workerB, workerC], { maxHired: 1 });
135
+ await hireTool.getOptions().execute("env", { name: "worker-a" });
136
+ // re-hiring the same worker is a no-op, must not count twice against the limit
137
+ await hireTool.getOptions().execute("env", { name: "worker-a" });
138
+ await assert.rejects(() => hireTool.getOptions().execute("env", { name: "worker-b" }), /maximum of 1 hired agent\(s\) already reached/);
139
+ const listResult = await listTool.getOptions().execute("env", {});
140
+ assert.strictEqual(listResult.hiredCount, 1);
141
+ assert.strictEqual(listResult.maxHired, 1);
142
+ });
143
+ test("AgentTools: agent-list omits maxHired when no limit was configured", async () => {
144
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
145
+ const [listTool] = AgentTools([worker]);
146
+ const result = await listTool.getOptions().execute("env", {});
147
+ assert.strictEqual(result.hiredCount, 0);
148
+ assert.strictEqual("maxHired" in result, false);
149
+ });
150
+ test("AgentTools: maxHired must be a positive integer when given", async () => {
151
+ const worker = buildWorker("backend-worker", "Handles backend tasks.", [{ content: "x", inputTokens: 0, outputTokens: 0 }]);
152
+ assert.throws(() => AgentTools([worker], { maxHired: 0 }), /maxHired must be a positive integer/);
153
+ assert.throws(() => AgentTools([worker], { maxHired: -1 }), /maxHired must be a positive integer/);
154
+ assert.throws(() => AgentTools([worker], { maxHired: 1.5 }), /maxHired must be a positive integer/);
155
+ });
156
+ //# sourceMappingURL=agent-tools.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-tools.test.js","sourceRoot":"","sources":["../../../../src/tests/tools/agent/agent-tools.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ import { AgentInteraction } from "./interaction.js";
3
+ import type AgentRegistry from "./registry.js";
4
+ export declare const AgentHireTool: (registry: AgentRegistry) => MCPTool<AgentInteraction>;
5
+ export default AgentHireTool;
6
+ //# sourceMappingURL=hire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hire.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/hire.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,aAAa,MAAM,eAAe,CAAC;AAE/C,eAAO,MAAM,aAAa,GAAI,UAAU,aAAa,8BAoCpD,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ import { AgentInteraction } from "./interaction.js";
3
+ export const AgentHireTool = (registry) => {
4
+ const maxHired = registry.getMaxHired();
5
+ const limitNote = maxHired !== undefined
6
+ ? ` At most ${maxHired} worker agent${maxHired === 1 ? "" : "s"} may be hired at once — hiring beyond that will fail until fewer than ${maxHired} are currently hired, so choose which agent(s) to hire carefully.`
7
+ : "";
8
+ return new MCPTool({
9
+ name: "agent-hire",
10
+ description: `hire a worker agent by name (see agent-list), making it active. Required once per agent before agent-prompt will work on it — hiring the same agent again is a harmless no-op.${limitNote}`,
11
+ inputs: [
12
+ {
13
+ name: "name",
14
+ type: "string",
15
+ description: "the worker agent's name, exactly as shown by agent-list",
16
+ required: true,
17
+ },
18
+ ],
19
+ customClass: new AgentInteraction(),
20
+ execute: async (_envID, inputs, _mcp, customClass) => {
21
+ const { name } = inputs;
22
+ if (!name || typeof name !== "string") {
23
+ throw new Error("name must be a non-empty string");
24
+ }
25
+ registry.hire(name);
26
+ customClass?.emitAgentEvent({ type: "hired", name });
27
+ return { hired: true, name };
28
+ },
29
+ });
30
+ };
31
+ export default AgentHireTool;
32
+ //# sourceMappingURL=hire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hire.js","sourceRoot":"","sources":["../../../src/tools/agent/hire.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAuB,EAAE,EAAE;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,SAAS,GAAG,QAAQ,KAAK,SAAS;QACpC,CAAC,CAAC,YAAY,QAAQ,gBAAgB,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,yEAAyE,QAAQ,mEAAmE;QACnN,CAAC,CAAC,EAAE,CAAC;IAET,OAAO,IAAI,OAAO,CAAmB;QACjC,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,iLAAiL,SAAS,EAAE;QACzM,MAAM,EAAE;YACJ;gBACI,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yDAAyD;gBACtE,QAAQ,EAAE,IAAI;aACjB;SACJ;QACD,WAAW,EAAE,IAAI,gBAAgB,EAAE;QACnC,OAAO,EAAE,KAAK,EACV,MAAc,EACd,MAA2B,EAC3B,IAAU,EACV,WAA8B,EAClB,EAAE;YACd,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;YAExB,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACvD,CAAC;YAED,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,WAAW,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YAErD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;KACJ,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ export { AgentListTool } from "./list.js";
2
+ export { AgentHireTool } from "./hire.js";
3
+ export { AgentPromptTool } from "./prompt.js";
4
+ export { AgentReportTool } from "./report.js";
5
+ export { AgentRegistry } from "./registry.js";
6
+ export { AgentInteraction } from "./interaction.js";
7
+ export type { AgentInfo } from "./registry.js";
8
+ export type { AgentEvent } from "./interaction.js";
9
+ import type WorkerAgent from "../../core/worker-agent.js";
10
+ export interface AgentToolsOptions {
11
+ /** Cap on how many workers may be hired at once. Omit for no limit. Surfaced dynamically in agent-hire's own description (and in agent-list's output) so the model knows the constraint without being told out of band. */
12
+ maxHired?: number;
13
+ }
14
+ /**
15
+ * EXPERIMENTAL — see the note on WorkerAgent (src/core/worker-agent.ts).
16
+ *
17
+ * Planner-side tools for a fixed roster of WorkerAgents: list them, hire
18
+ * one, and prompt a hired one. Each call builds its own AgentRegistry, so
19
+ * separate AgentTools(...) calls (e.g. for two different planners in the
20
+ * same process) never share hire state.
21
+ *
22
+ * Not included here: AgentReportTool — that one goes on each *worker's*
23
+ * own tool list instead, not the planner's. Import it separately.
24
+ */
25
+ export declare const AgentTools: (availableAgents: WorkerAgent[], options?: AgentToolsOptions) => (import("../../index.js").MCPTool<undefined> | import("../../index.js").MCPTool<import("./interaction.js").AgentInteraction>)[];
26
+ export default AgentTools;
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,WAAW,MAAM,4BAA4B,CAAC;AAM1D,MAAM,WAAW,iBAAiB;IAC9B,2NAA2N;IAC3N,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,UAAU,GAAI,iBAAiB,WAAW,EAAE,EAAE,UAAS,iBAAsB,oIAOzF,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,31 @@
1
+ export { AgentListTool } from "./list.js";
2
+ export { AgentHireTool } from "./hire.js";
3
+ export { AgentPromptTool } from "./prompt.js";
4
+ export { AgentReportTool } from "./report.js";
5
+ export { AgentRegistry } from "./registry.js";
6
+ export { AgentInteraction } from "./interaction.js";
7
+ import { AgentListTool } from "./list.js";
8
+ import { AgentHireTool } from "./hire.js";
9
+ import { AgentPromptTool } from "./prompt.js";
10
+ import { AgentRegistry } from "./registry.js";
11
+ /**
12
+ * EXPERIMENTAL — see the note on WorkerAgent (src/core/worker-agent.ts).
13
+ *
14
+ * Planner-side tools for a fixed roster of WorkerAgents: list them, hire
15
+ * one, and prompt a hired one. Each call builds its own AgentRegistry, so
16
+ * separate AgentTools(...) calls (e.g. for two different planners in the
17
+ * same process) never share hire state.
18
+ *
19
+ * Not included here: AgentReportTool — that one goes on each *worker's*
20
+ * own tool list instead, not the planner's. Import it separately.
21
+ */
22
+ export const AgentTools = (availableAgents, options = {}) => {
23
+ const registry = new AgentRegistry(availableAgents, options.maxHired);
24
+ return [
25
+ AgentListTool(registry),
26
+ AgentHireTool(registry),
27
+ AgentPromptTool(registry),
28
+ ];
29
+ };
30
+ export default AgentTools;
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/agent/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKpD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAO9C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,eAA8B,EAAE,UAA6B,EAAE,EAAE,EAAE;IAC1F,MAAM,QAAQ,GAAG,IAAI,aAAa,CAAC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtE,OAAO;QACH,aAAa,CAAC,QAAQ,CAAC;QACvB,aAAa,CAAC,QAAQ,CAAC;QACvB,eAAe,CAAC,QAAQ,CAAC;KAC5B,CAAC;AACN,CAAC,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { MCPCustomClass } from "../../core/mcp.js";
2
+ export type AgentEvent = {
3
+ type: "hired";
4
+ name: string;
5
+ } | {
6
+ type: "prompted";
7
+ name: string;
8
+ prompt: string;
9
+ } | {
10
+ type: "reported";
11
+ name: string;
12
+ reported: boolean;
13
+ report: string;
14
+ };
15
+ /**
16
+ * Shared custom interaction class for the agent-management tools. A
17
+ * frontend can listen on getEvents() to show live status (e.g. "Hiring
18
+ * backend-worker...", "backend-worker is working...") while the planner
19
+ * hires and prompts worker agents.
20
+ */
21
+ export declare class AgentInteraction extends MCPCustomClass {
22
+ emitAgentEvent(event: AgentEvent): void;
23
+ }
24
+ export default AgentInteraction;
25
+ //# sourceMappingURL=interaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,UAAU,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5E;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,cAAc;IAChD,cAAc,CAAC,KAAK,EAAE,UAAU;CAGnC;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { MCPCustomClass } from "../../core/mcp.js";
2
+ /**
3
+ * Shared custom interaction class for the agent-management tools. A
4
+ * frontend can listen on getEvents() to show live status (e.g. "Hiring
5
+ * backend-worker...", "backend-worker is working...") while the planner
6
+ * hires and prompts worker agents.
7
+ */
8
+ export class AgentInteraction extends MCPCustomClass {
9
+ emitAgentEvent(event) {
10
+ this.getEvents().emit("agent", event);
11
+ }
12
+ }
13
+ export default AgentInteraction;
14
+ //# sourceMappingURL=interaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction.js","sourceRoot":"","sources":["../../../src/tools/agent/interaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOnD;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IAChD,cAAc,CAAC,KAAiB;QAC5B,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC;CACJ;AAED,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ import type AgentRegistry from "./registry.js";
3
+ export declare const AgentListTool: (registry: AgentRegistry) => MCPTool<undefined>;
4
+ export default AgentListTool;
5
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,aAAa,MAAM,eAAe,CAAC;AAE/C,eAAO,MAAM,aAAa,GAAI,UAAU,aAAa,uBAYnD,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ export const AgentListTool = (registry) => new MCPTool({
3
+ name: "agent-list",
4
+ description: "list every worker agent available to hire, with their name, description/persona, per-task-type rating, and whether they're already hired. Check this before hiring — pick whichever agent's rating best fits the task at hand, and check hiredCount against maxHired if there's a hiring limit.",
5
+ inputs: [],
6
+ execute: async () => {
7
+ const maxHired = registry.getMaxHired();
8
+ return {
9
+ agents: registry.list(),
10
+ hiredCount: registry.getHiredCount(),
11
+ ...(maxHired !== undefined ? { maxHired } : {}),
12
+ };
13
+ },
14
+ });
15
+ export default AgentListTool;
16
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/tools/agent/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAG5C,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAuB,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC;IAClE,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,iSAAiS;IAC9S,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,KAAK,IAAkB,EAAE;QAC9B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;QACxC,OAAO;YACH,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE;YACvB,UAAU,EAAE,QAAQ,CAAC,aAAa,EAAE;YACpC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAC;IACN,CAAC;CACJ,CAAC,CAAC;AAEH,eAAe,aAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ import { AgentInteraction } from "./interaction.js";
3
+ import type AgentRegistry from "./registry.js";
4
+ export declare const AgentPromptTool: (registry: AgentRegistry) => MCPTool<AgentInteraction>;
5
+ export default AgentPromptTool;
6
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAY,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,aAAa,MAAM,eAAe,CAAC;AAE/C,eAAO,MAAM,eAAe,GAAI,UAAU,aAAa,8BAkFrD,CAAC;AAEH,eAAe,eAAe,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ import { AgentInteraction } from "./interaction.js";
3
+ export const AgentPromptTool = (registry) => new MCPTool({
4
+ name: "agent-prompt",
5
+ description: "send a prompt to a hired worker agent and wait for its response. The worker runs its own full turn (its own reasoning, its own tools) and either calls agent-report to hand back a result, or just stops on its own — either way this returns once it's done. You can call this again later on the same agent to continue the conversation (it remembers everything from earlier prompts), or move on and never call it again if its report says the work is finished.",
6
+ inputs: [
7
+ {
8
+ name: "name",
9
+ type: "string",
10
+ description: "the hired worker agent's name, exactly as shown by agent-list",
11
+ required: true,
12
+ },
13
+ {
14
+ name: "prompt",
15
+ type: "string",
16
+ description: "the message to send to the worker agent",
17
+ required: true,
18
+ },
19
+ ],
20
+ customClass: new AgentInteraction(),
21
+ execute: async (_envID, inputs, _mcp, customClass) => {
22
+ const { name, prompt } = inputs;
23
+ if (!name || typeof name !== "string") {
24
+ throw new Error("name must be a non-empty string");
25
+ }
26
+ if (!prompt || typeof prompt !== "string") {
27
+ throw new Error("prompt must be a non-empty string");
28
+ }
29
+ const agent = registry.get(name);
30
+ if (!agent) {
31
+ throw new Error(`no worker agent named "${name}" — check agent-list for available names.`);
32
+ }
33
+ if (!registry.isHired(name)) {
34
+ throw new Error(`worker agent "${name}" is not hired yet — call agent-hire first.`);
35
+ }
36
+ customClass?.emitAgentEvent({ type: "prompted", name, prompt });
37
+ const beforeLength = agent.getCurrentAgentStates().messagesFull.length;
38
+ await agent.run(prompt);
39
+ // Only look at messages this specific call produced — otherwise a
40
+ // worker that answers in plain text (no fresh agent-report) could
41
+ // surface a stale report left over from an earlier prompt.
42
+ const newMessages = agent.getCurrentAgentStates().messagesFull.slice(beforeLength);
43
+ let report;
44
+ let reported = false;
45
+ for (let i = newMessages.length - 1; i >= 0; i--) {
46
+ const msg = newMessages[i];
47
+ if (msg.role === "tool" && msg.toolName === "agent-report") {
48
+ try {
49
+ report = JSON.parse(msg.content || "{}").report;
50
+ }
51
+ catch {
52
+ report = msg.content;
53
+ }
54
+ reported = true;
55
+ break;
56
+ }
57
+ }
58
+ if (!reported) {
59
+ for (let i = newMessages.length - 1; i >= 0; i--) {
60
+ const msg = newMessages[i];
61
+ if (msg.role === "assistant" && msg.content) {
62
+ report = msg.content;
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ report ??= "(worker agent produced no output this turn)";
68
+ customClass?.emitAgentEvent({ type: "reported", name, reported, report });
69
+ return { report, reported };
70
+ },
71
+ });
72
+ export default AgentPromptTool;
73
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/tools/agent/prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type WorkerAgent from "../../core/worker-agent.js";
2
+ import type { WorkerAgentRating } from "../../core/worker-agent.js";
3
+ export interface AgentInfo {
4
+ name: string;
5
+ description: string;
6
+ rating: WorkerAgentRating;
7
+ hired: boolean;
8
+ }
9
+ /**
10
+ * In-memory catalog of WorkerAgents a planner can see/hire/prompt, plus
11
+ * which of them are currently "active" (hired). Scoped to one AgentTools()
12
+ * call — not a process-wide singleton — so multiple independent planners in
13
+ * the same process each get their own roster and hire state.
14
+ *
15
+ * WorkerAgent instances are live objects (their own AI provider, message
16
+ * history, etc.), not serializable data, so — unlike MCPTool state such as
17
+ * TodoTools' lists — this can't live in MCPStorage. The roster itself is
18
+ * fixed at construction (only the developer can safely wire up a worker's
19
+ * provider/instruction/tools); the model can only hire/prompt from what's
20
+ * already here, never create new ones.
21
+ */
22
+ export declare class AgentRegistry {
23
+ #private;
24
+ constructor(agents: WorkerAgent[], maxHired?: number);
25
+ getMaxHired(): number | undefined;
26
+ getHiredCount(): number;
27
+ list(): AgentInfo[];
28
+ hire(name: string): void;
29
+ isHired(name: string): boolean;
30
+ get(name: string): WorkerAgent | undefined;
31
+ }
32
+ export default AgentRegistry;
33
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,WAAW,MAAM,4BAA4B,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAa;;gBAKV,MAAM,EAAE,WAAW,EAAE,EAAE,QAAQ,CAAC,EAAE,MAAM;IAepD,WAAW,IAAI,MAAM,GAAG,SAAS;IAIjC,aAAa,IAAI,MAAM;IAIvB,IAAI,IAAI,SAAS,EAAE;IASnB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAkBxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;CAG7C;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * In-memory catalog of WorkerAgents a planner can see/hire/prompt, plus
3
+ * which of them are currently "active" (hired). Scoped to one AgentTools()
4
+ * call — not a process-wide singleton — so multiple independent planners in
5
+ * the same process each get their own roster and hire state.
6
+ *
7
+ * WorkerAgent instances are live objects (their own AI provider, message
8
+ * history, etc.), not serializable data, so — unlike MCPTool state such as
9
+ * TodoTools' lists — this can't live in MCPStorage. The roster itself is
10
+ * fixed at construction (only the developer can safely wire up a worker's
11
+ * provider/instruction/tools); the model can only hire/prompt from what's
12
+ * already here, never create new ones.
13
+ */
14
+ export class AgentRegistry {
15
+ #agents = new Map();
16
+ #hired = new Set();
17
+ #maxHired;
18
+ constructor(agents, maxHired) {
19
+ if (maxHired !== undefined && (!Number.isInteger(maxHired) || maxHired < 1)) {
20
+ throw new Error(`AgentTools: maxHired must be a positive integer when given, got ${maxHired}.`);
21
+ }
22
+ this.#maxHired = maxHired;
23
+ for (const agent of agents) {
24
+ const name = agent.getName();
25
+ if (this.#agents.has(name)) {
26
+ throw new Error(`AgentTools: duplicate worker agent name "${name}" — names must be unique across the roster.`);
27
+ }
28
+ this.#agents.set(name, agent);
29
+ }
30
+ }
31
+ getMaxHired() {
32
+ return this.#maxHired;
33
+ }
34
+ getHiredCount() {
35
+ return this.#hired.size;
36
+ }
37
+ list() {
38
+ return [...this.#agents.values()].map(agent => ({
39
+ name: agent.getName(),
40
+ description: agent.getDescription(),
41
+ rating: agent.getRating(),
42
+ hired: this.#hired.has(agent.getName()),
43
+ }));
44
+ }
45
+ hire(name) {
46
+ if (!this.#agents.has(name)) {
47
+ throw new Error(`no worker agent named "${name}" — check agent-list for available names.`);
48
+ }
49
+ // Re-hiring an already-hired agent is a no-op — it must never count
50
+ // against the limit a second time.
51
+ if (this.#hired.has(name)) {
52
+ return;
53
+ }
54
+ if (this.#maxHired !== undefined && this.#hired.size >= this.#maxHired) {
55
+ throw new Error(`cannot hire "${name}" — maximum of ${this.#maxHired} hired agent(s) already reached ` +
56
+ `(currently hired: ${[...this.#hired].join(", ") || "none"}).`);
57
+ }
58
+ this.#hired.add(name);
59
+ }
60
+ isHired(name) {
61
+ return this.#hired.has(name);
62
+ }
63
+ get(name) {
64
+ return this.#agents.get(name);
65
+ }
66
+ }
67
+ export default AgentRegistry;
68
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/tools/agent/registry.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,aAAa;IACtB,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzC,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3B,SAAS,CAAU;IAEnB,YAAY,MAAqB,EAAE,QAAiB;QAChD,IAAI,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;YAC1E,MAAM,IAAI,KAAK,CAAC,mEAAmE,QAAQ,GAAG,CAAC,CAAC;QACpG,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,4CAA4C,IAAI,6CAA6C,CAAC,CAAC;YACnH,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;IACL,CAAC;IAED,WAAW;QACP,OAAO,IAAI,CAAC,SAAS,CAAC;IAC1B,CAAC;IAED,aAAa;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI;QACA,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC5C,IAAI,EAAE,KAAK,CAAC,OAAO,EAAE;YACrB,WAAW,EAAE,KAAK,CAAC,cAAc,EAAE;YACnC,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE;YACzB,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;SAC1C,CAAC,CAAC,CAAC;IACR,CAAC;IAED,IAAI,CAAC,IAAY;QACb,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,2CAA2C,CAAC,CAAC;QAC/F,CAAC;QACD,oEAAoE;QACpE,mCAAmC;QACnC,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO;QACX,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACrE,MAAM,IAAI,KAAK,CACX,gBAAgB,IAAI,kBAAkB,IAAI,CAAC,SAAS,kCAAkC;gBACtF,qBAAqB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,IAAI,CACjE,CAAC;QACN,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,CAAC,IAAY;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,GAAG,CAAC,IAAY;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACJ;AAED,eAAe,aAAa,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { MCPTool } from "../../core/mcp.js";
2
+ /**
3
+ * For WorkerAgents, not planners: include this in a worker's own
4
+ * `allowedTools` (and register it on whatever MCPServer that worker uses)
5
+ * so it can hand a result back to whoever hired and prompted it. Calling
6
+ * this always ends the worker's current turn immediately
7
+ * (stopIterationAfterUsingThisTool) — AgentPromptTool picks the reported
8
+ * text back up on the hiring agent's side once agent.run() resolves.
9
+ */
10
+ export declare const AgentReportTool: () => MCPTool<undefined>;
11
+ export default AgentReportTool;
12
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/tools/agent/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,0BAqB1B,CAAC;AAEH,eAAe,eAAe,CAAC"}