@clinebot/core 0.0.33 → 0.0.34

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 (69) hide show
  1. package/dist/auth/client.d.ts +19 -0
  2. package/dist/auth/client.d.ts.map +1 -1
  3. package/dist/auth/cline.d.ts.map +1 -1
  4. package/dist/auth/oca.d.ts.map +1 -1
  5. package/dist/auth/server.d.ts +32 -0
  6. package/dist/auth/server.d.ts.map +1 -1
  7. package/dist/auth/types.d.ts +29 -0
  8. package/dist/auth/types.d.ts.map +1 -1
  9. package/dist/extensions/index.d.ts +2 -1
  10. package/dist/extensions/index.d.ts.map +1 -1
  11. package/dist/extensions/plugin/plugin-config-loader.d.ts +2 -1
  12. package/dist/extensions/plugin/plugin-config-loader.d.ts.map +1 -1
  13. package/dist/extensions/plugin/plugin-load-report.d.ts +19 -0
  14. package/dist/extensions/plugin/plugin-load-report.d.ts.map +1 -0
  15. package/dist/extensions/plugin/plugin-loader.d.ts +6 -0
  16. package/dist/extensions/plugin/plugin-loader.d.ts.map +1 -1
  17. package/dist/extensions/plugin/plugin-sandbox.d.ts +2 -1
  18. package/dist/extensions/plugin/plugin-sandbox.d.ts.map +1 -1
  19. package/dist/extensions/plugin-sandbox-bootstrap.js +148 -148
  20. package/dist/index.d.ts +3 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +207 -207
  23. package/dist/runtime/runtime-builder.d.ts +1 -1
  24. package/dist/runtime/runtime-builder.d.ts.map +1 -1
  25. package/dist/runtime/subprocess-sandbox.d.ts +2 -0
  26. package/dist/runtime/subprocess-sandbox.d.ts.map +1 -1
  27. package/dist/runtime/tool-approval.d.ts.map +1 -1
  28. package/dist/session/default-session-manager.d.ts.map +1 -1
  29. package/dist/session/persistence-service.d.ts.map +1 -1
  30. package/dist/session/session-artifacts.d.ts +2 -0
  31. package/dist/session/session-artifacts.d.ts.map +1 -1
  32. package/dist/session/session-config-builder.d.ts.map +1 -1
  33. package/dist/team/team-tools.d.ts.map +1 -1
  34. package/dist/types/config.d.ts +1 -0
  35. package/dist/types/config.d.ts.map +1 -1
  36. package/package.json +4 -4
  37. package/src/auth/client.test.ts +29 -0
  38. package/src/auth/client.ts +21 -0
  39. package/src/auth/cline.ts +2 -0
  40. package/src/auth/oca.ts +2 -0
  41. package/src/auth/server.test.ts +287 -0
  42. package/src/auth/server.ts +50 -1
  43. package/src/auth/types.ts +29 -0
  44. package/src/extensions/index.ts +6 -0
  45. package/src/extensions/plugin/plugin-config-loader.test.ts +37 -0
  46. package/src/extensions/plugin/plugin-config-loader.ts +18 -10
  47. package/src/extensions/plugin/plugin-load-report.ts +20 -0
  48. package/src/extensions/plugin/plugin-loader.test.ts +45 -0
  49. package/src/extensions/plugin/plugin-loader.ts +57 -3
  50. package/src/extensions/plugin/plugin-sandbox-bootstrap.ts +158 -86
  51. package/src/extensions/plugin/plugin-sandbox.test.ts +70 -0
  52. package/src/extensions/plugin/plugin-sandbox.ts +17 -6
  53. package/src/index.ts +11 -0
  54. package/src/runtime/hook-file-hooks.test.ts +42 -7
  55. package/src/runtime/runtime-builder.test.ts +98 -0
  56. package/src/runtime/runtime-builder.ts +112 -65
  57. package/src/runtime/subprocess-sandbox.ts +26 -23
  58. package/src/runtime/tool-approval.ts +13 -15
  59. package/src/session/default-session-manager.ts +1 -3
  60. package/src/session/persistence-service.test.ts +38 -0
  61. package/src/session/persistence-service.ts +16 -1
  62. package/src/session/session-artifacts.ts +16 -0
  63. package/src/session/session-config-builder.ts +46 -0
  64. package/src/team/team-tools.test.ts +104 -0
  65. package/src/team/team-tools.ts +35 -16
  66. package/src/types/config.ts +1 -0
  67. package/dist/runtime/team-runtime-registry.d.ts +0 -13
  68. package/dist/runtime/team-runtime-registry.d.ts.map +0 -1
  69. package/src/runtime/team-runtime-registry.ts +0 -43
@@ -61,6 +61,22 @@ export class SubprocessSandbox {
61
61
  this.options = options;
62
62
  }
63
63
 
64
+ private get processLabel(): string {
65
+ return this.options.name ?? "sandbox";
66
+ }
67
+
68
+ private clearPendingRequest(id: string): PendingRequest | undefined {
69
+ const pending = this.pending.get(id);
70
+ if (!pending) {
71
+ return undefined;
72
+ }
73
+ this.pending.delete(id);
74
+ if (pending.timeout) {
75
+ clearTimeout(pending.timeout);
76
+ }
77
+ return pending;
78
+ }
79
+
64
80
  start(): void {
65
81
  if (this.process && this.process.exitCode === null) {
66
82
  return;
@@ -96,7 +112,7 @@ export class SubprocessSandbox {
96
112
  child.on("error", (error) => {
97
113
  this.failPending(
98
114
  new Error(
99
- `${this.options.name ?? "sandbox"} process error: ${asError(error).message}`,
115
+ `${this.processLabel} process error: ${asError(error).message}`,
100
116
  ),
101
117
  );
102
118
  });
@@ -119,9 +135,7 @@ export class SubprocessSandbox {
119
135
  this.start();
120
136
  const child = this.process;
121
137
  if (!child || child.exitCode !== null) {
122
- throw new Error(
123
- `${this.options.name ?? "sandbox"} process is not available`,
124
- );
138
+ throw new Error(`${this.processLabel} process is not available`);
125
139
  }
126
140
 
127
141
  const id = `req_${++this.requestCounter}`;
@@ -139,13 +153,13 @@ export class SubprocessSandbox {
139
153
  };
140
154
  if ((options.timeoutMs ?? 0) > 0) {
141
155
  pending.timeout = setTimeout(() => {
142
- this.pending.delete(id);
156
+ this.clearPendingRequest(id);
143
157
  this.shutdown().catch(() => {
144
158
  // Best-effort process shutdown after timeout.
145
159
  });
146
160
  reject(
147
161
  new Error(
148
- `${this.options.name ?? "sandbox"} call timed out after ${options.timeoutMs}ms: ${method}`,
162
+ `${this.processLabel} call timed out after ${options.timeoutMs}ms: ${method}`,
149
163
  ),
150
164
  );
151
165
  }, options.timeoutMs);
@@ -155,17 +169,13 @@ export class SubprocessSandbox {
155
169
  if (!error) {
156
170
  return;
157
171
  }
158
- const entry = this.pending.get(id);
172
+ const entry = this.clearPendingRequest(id);
159
173
  if (!entry) {
160
174
  return;
161
175
  }
162
- this.pending.delete(id);
163
- if (entry.timeout) {
164
- clearTimeout(entry.timeout);
165
- }
166
176
  entry.reject(
167
177
  new Error(
168
- `${this.options.name ?? "sandbox"} failed to send call "${method}": ${asError(error).message}`,
178
+ `${this.processLabel} failed to send call "${method}": ${asError(error).message}`,
169
179
  ),
170
180
  );
171
181
  });
@@ -176,7 +186,7 @@ export class SubprocessSandbox {
176
186
  const child = this.process;
177
187
  this.process = null;
178
188
  if (!child || child.exitCode !== null) {
179
- this.failPending(new Error(`${this.options.name ?? "sandbox"} shutdown`));
189
+ this.failPending(new Error(`${this.processLabel} shutdown`));
180
190
  return;
181
191
  }
182
192
  await new Promise<void>((resolve) => {
@@ -199,7 +209,7 @@ export class SubprocessSandbox {
199
209
  resolve();
200
210
  }
201
211
  });
202
- this.failPending(new Error(`${this.options.name ?? "sandbox"} shutdown`));
212
+ this.failPending(new Error(`${this.processLabel} shutdown`));
203
213
  }
204
214
 
205
215
  private onMessage(
@@ -220,23 +230,16 @@ export class SubprocessSandbox {
220
230
  if (message.type !== "response" || !message.id) {
221
231
  return;
222
232
  }
223
- const pending = this.pending.get(message.id);
233
+ const pending = this.clearPendingRequest(message.id);
224
234
  if (!pending) {
225
235
  return;
226
236
  }
227
- this.pending.delete(message.id);
228
- if (pending.timeout) {
229
- clearTimeout(pending.timeout);
230
- }
231
237
  if (message.ok) {
232
238
  pending.resolve(message.result);
233
239
  return;
234
240
  }
235
241
  pending.reject(
236
- new Error(
237
- message.error?.message ||
238
- `${this.options.name ?? "sandbox"} call failed`,
239
- ),
242
+ new Error(message.error?.message || `${this.processLabel} call failed`),
240
243
  );
241
244
  }
242
245
 
@@ -18,6 +18,14 @@ function delay(ms: number): Promise<void> {
18
18
  return new Promise((resolve) => setTimeout(resolve, ms));
19
19
  }
20
20
 
21
+ async function unlinkIfPresent(path: string): Promise<void> {
22
+ try {
23
+ await unlink(path);
24
+ } catch {
25
+ // Best-effort cleanup.
26
+ }
27
+ }
28
+
21
29
  export async function requestDesktopToolApproval(
22
30
  request: ToolApprovalRequest,
23
31
  options: DesktopToolApprovalOptions = {},
@@ -77,16 +85,10 @@ export async function requestDesktopToolApproval(
77
85
  approved: parsed.approved === true,
78
86
  reason: typeof parsed.reason === "string" ? parsed.reason : undefined,
79
87
  };
80
- try {
81
- await unlink(decisionPath);
82
- } catch {
83
- // Best-effort cleanup.
84
- }
85
- try {
86
- await unlink(requestPath);
87
- } catch {
88
- // Best-effort cleanup.
89
- }
88
+ await Promise.all([
89
+ unlinkIfPresent(decisionPath),
90
+ unlinkIfPresent(requestPath),
91
+ ]);
90
92
  return result;
91
93
  } catch {
92
94
  // Decision not available yet.
@@ -94,11 +96,7 @@ export async function requestDesktopToolApproval(
94
96
  await delay(pollIntervalMs);
95
97
  }
96
98
 
97
- try {
98
- await unlink(requestPath);
99
- } catch {
100
- // Best-effort cleanup.
101
- }
99
+ await unlinkIfPresent(requestPath);
102
100
 
103
101
  return { approved: false, reason: "Tool approval request timed out" };
104
102
  }
@@ -1391,9 +1391,7 @@ export class DefaultSessionManager implements SessionManager {
1391
1391
  });
1392
1392
  } catch (error) {
1393
1393
  if (error instanceof OAuthReauthRequiredError) {
1394
- throw new Error(
1395
- `OAuth session for "${error.providerId}" requires re-authentication. Run "clite auth ${error.providerId}" and retry.`,
1396
- );
1394
+ throw new Error(`${error.providerId} requires re-authentication.`);
1397
1395
  }
1398
1396
  throw error;
1399
1397
  }
@@ -200,4 +200,42 @@ describe("UnifiedSessionPersistenceService", () => {
200
200
  );
201
201
  expect(row?.transcriptPath).toMatch(/\.log$/);
202
202
  });
203
+
204
+ it("deletes the full root session directory even when artifact paths are stale", async () => {
205
+ const sessionsDir = mkdtempSync(join(tmpdir(), "delete-root-session-dir-"));
206
+ tempDirs.push(sessionsDir);
207
+
208
+ const store = new SqliteSessionStore({ sessionsDir });
209
+ stores.push(store);
210
+ const service = new CoreSessionService(store);
211
+ const sessionId = "root-session-delete";
212
+ const artifacts = await service.createRootSessionWithArtifacts({
213
+ sessionId,
214
+ source: SessionSource.CLI,
215
+ pid: process.pid,
216
+ interactive: false,
217
+ provider: "anthropic",
218
+ model: "claude-sonnet-4-6",
219
+ cwd: "/tmp/project",
220
+ workspaceRoot: "/tmp/project",
221
+ enableTools: true,
222
+ enableSpawn: false,
223
+ enableTeams: false,
224
+ prompt: "delete me",
225
+ startedAt: "2026-04-10T19:00:00.000Z",
226
+ });
227
+
228
+ store.run(`UPDATE sessions SET messages_path = NULL WHERE session_id = ?`, [
229
+ sessionId,
230
+ ]);
231
+
232
+ expect(existsSync(artifacts.messagesPath)).toBe(true);
233
+ expect(existsSync(join(sessionsDir, sessionId))).toBe(true);
234
+
235
+ const result = await service.deleteSession(sessionId);
236
+
237
+ expect(result).toEqual({ deleted: true });
238
+ expect(existsSync(artifacts.messagesPath)).toBe(false);
239
+ expect(existsSync(join(sessionsDir, sessionId))).toBe(false);
240
+ });
203
241
  });
@@ -4,6 +4,7 @@ import {
4
4
  readFileSync,
5
5
  writeFileSync,
6
6
  } from "node:fs";
7
+ import { dirname } from "node:path";
7
8
  import type * as LlmsProviders from "@clinebot/llms";
8
9
  import type { AgentResult } from "@clinebot/shared";
9
10
  import { resolveRootSessionId } from "@clinebot/shared";
@@ -922,7 +923,21 @@ export class UnifiedSessionPersistenceService {
922
923
  unlinkIfExists(row.hookPath);
923
924
  unlinkIfExists(row.messagesPath);
924
925
  unlinkIfExists(this.artifacts.sessionManifestPath(id, false));
925
- this.artifacts.removeSessionDirIfEmpty(id);
926
+ if (row.isSubagent) {
927
+ this.artifacts.removeSessionDirIfEmpty(id);
928
+ } else {
929
+ const candidateDirs = new Set<string>([
930
+ this.artifacts.sessionArtifactsDir(id),
931
+ ]);
932
+ for (const path of [row.transcriptPath, row.hookPath, row.messagesPath]) {
933
+ if (typeof path === "string" && path.trim().length > 0) {
934
+ candidateDirs.add(dirname(path));
935
+ }
936
+ }
937
+ for (const dir of candidateDirs) {
938
+ this.artifacts.removeDir(dir);
939
+ }
940
+ }
926
941
  return { deleted: true };
927
942
  }
928
943
  }
@@ -3,6 +3,7 @@ import {
3
3
  mkdirSync,
4
4
  readdirSync,
5
5
  rmdirSync,
6
+ rmSync,
6
7
  unlinkSync,
7
8
  } from "node:fs";
8
9
  import { dirname, join } from "node:path";
@@ -116,6 +117,21 @@ export class SessionArtifacts {
116
117
  }
117
118
  }
118
119
 
120
+ public removeSessionDir(sessionId: string): void {
121
+ this.removeDir(this.sessionArtifactsDir(sessionId));
122
+ }
123
+
124
+ public removeDir(dir: string): void {
125
+ if (!existsSync(dir)) {
126
+ return;
127
+ }
128
+ try {
129
+ rmSync(dir, { recursive: true, force: true });
130
+ } catch {
131
+ // Best-effort cleanup.
132
+ }
133
+ }
134
+
119
135
  public subagentArtifactPaths(
120
136
  sessionId: string,
121
137
  subAgentId: string,
@@ -1,5 +1,9 @@
1
1
  import type { ITelemetryService } from "@clinebot/shared";
2
2
  import { resolveAndLoadAgentPlugins } from "../extensions/plugin/plugin-config-loader";
3
+ import type {
4
+ PluginInitializationFailure,
5
+ PluginInitializationWarning,
6
+ } from "../extensions/plugin/plugin-load-report";
3
7
  import {
4
8
  createHookAuditHooks,
5
9
  createHookConfigFileHooks,
@@ -15,6 +19,43 @@ import {
15
19
  import type { StartSessionInput } from "./session-manager";
16
20
  import { hasRuntimeHooks, mergeAgentExtensions } from "./utils/helpers";
17
21
 
22
+ function formatPluginFailure(failure: PluginInitializationFailure): string {
23
+ const label = failure.pluginName ?? failure.pluginPath;
24
+ return `${label}: ${failure.message}`;
25
+ }
26
+
27
+ function logPluginDiagnostics(
28
+ failures: PluginInitializationFailure[],
29
+ warnings: PluginInitializationWarning[],
30
+ logger: CoreSessionConfig["logger"],
31
+ ): void {
32
+ if (warnings.length > 0) {
33
+ for (const warning of warnings) {
34
+ logger?.log(warning.message, { severity: "warn" });
35
+ }
36
+ }
37
+ if (failures.length === 0) {
38
+ return;
39
+ }
40
+ const preview = failures.slice(0, 3).map(formatPluginFailure).join("; ");
41
+ const suffix = failures.length > 3 ? `; and ${failures.length - 3} more` : "";
42
+ logger?.log(
43
+ `Some plugins failed to initialize. ${preview}${suffix}. Use --verbose for more details.`,
44
+ { severity: "warn" },
45
+ );
46
+ for (const failure of failures) {
47
+ logger?.log(
48
+ `Plugin initialization failed (${failure.phase}) for ${failure.pluginPath}`,
49
+ {
50
+ severity: "warn",
51
+ stack: failure.stack,
52
+ pluginPath: failure.pluginPath,
53
+ pluginName: failure.pluginName,
54
+ },
55
+ );
56
+ }
57
+ }
58
+
18
59
  export function resolveWorkspacePath(config: CoreSessionConfig): string {
19
60
  return config.workspaceRoot ?? config.cwd;
20
61
  }
@@ -61,6 +102,11 @@ export async function buildEffectiveConfig(
61
102
  cwd: input.config.cwd,
62
103
  onEvent: onPluginEvent,
63
104
  });
105
+ logPluginDiagnostics(
106
+ loadedPlugins.failures,
107
+ loadedPlugins.warnings,
108
+ input.config.logger,
109
+ );
64
110
  } catch (error) {
65
111
  const message = error instanceof Error ? error.message : String(error);
66
112
  input.config.logger?.log?.(
@@ -743,6 +743,110 @@ describe("createAgentTeamsTools runtime behavior", () => {
743
743
  expect(awaitAllRuns?.timeoutMs).toBe(60 * 60 * 1000);
744
744
  });
745
745
 
746
+ it("deduplicates concurrent sync team_run_task calls to the same agent", async () => {
747
+ let resolveRoute!: (value: { text: string; iterations: number }) => void;
748
+ const routePromise = new Promise<{ text: string; iterations: number }>(
749
+ (resolve) => {
750
+ resolveRoute = resolve;
751
+ },
752
+ );
753
+ const routeToTeammate = vi.fn(() => routePromise);
754
+ const runtime = {
755
+ routeToTeammate,
756
+ getMemberRole: vi.fn(() => "lead"),
757
+ } as unknown as AgentTeamsRuntime;
758
+
759
+ const tools = createAgentTeamsTools({
760
+ runtime,
761
+ requesterId: "lead",
762
+ teammateConfigProvider: makeTeammateConfigProvider(),
763
+ });
764
+ const runTask = tools.find((tool) => tool.name === "team_run_task");
765
+ expect(runTask).toBeDefined();
766
+ if (!runTask) {
767
+ throw new Error("Expected team_run_task tool to be defined");
768
+ }
769
+
770
+ const ctx = { agentId: "lead", conversationId: "conv-1", iteration: 1 };
771
+ const input = {
772
+ agentId: "educator",
773
+ task: "Explain probability",
774
+ runMode: "sync",
775
+ };
776
+
777
+ // Fire two concurrent sync calls to the same agent
778
+ const call1 = runTask.execute(input, ctx);
779
+ const call2 = runTask.execute(input, ctx);
780
+
781
+ // Second call should throw with duplicate detection error
782
+ await expect(call2).rejects.toThrow(
783
+ 'Duplicate team_run_task call detected for agent "educator"',
784
+ );
785
+
786
+ // Only one routeToTeammate call should have been made
787
+ expect(routeToTeammate).toHaveBeenCalledTimes(1);
788
+
789
+ // Now resolve the first call
790
+ resolveRoute({ text: "Probability explained", iterations: 3 });
791
+ const result1 = (await call1) as { text?: string; iterations?: number };
792
+ expect(result1.text).toBe("Probability explained");
793
+ expect(result1.iterations).toBe(3);
794
+ });
795
+
796
+ it("allows concurrent sync team_run_task calls to different agents", async () => {
797
+ let resolveRoute1!: (value: { text: string; iterations: number }) => void;
798
+ let resolveRoute2!: (value: { text: string; iterations: number }) => void;
799
+ const routeToTeammate = vi.fn((agentId: string) => {
800
+ if (agentId === "educator") {
801
+ return new Promise<{ text: string; iterations: number }>((resolve) => {
802
+ resolveRoute1 = resolve;
803
+ });
804
+ }
805
+ return new Promise<{ text: string; iterations: number }>((resolve) => {
806
+ resolveRoute2 = resolve;
807
+ });
808
+ });
809
+ const runtime = {
810
+ routeToTeammate,
811
+ getMemberRole: vi.fn(() => "lead"),
812
+ } as unknown as AgentTeamsRuntime;
813
+
814
+ const tools = createAgentTeamsTools({
815
+ runtime,
816
+ requesterId: "lead",
817
+ teammateConfigProvider: makeTeammateConfigProvider(),
818
+ });
819
+ const runTask = tools.find((tool) => tool.name === "team_run_task");
820
+ expect(runTask).toBeDefined();
821
+ if (!runTask) {
822
+ throw new Error("Expected team_run_task tool to be defined");
823
+ }
824
+
825
+ const ctx = { agentId: "lead", conversationId: "conv-1", iteration: 1 };
826
+
827
+ // Fire sync calls to two different agents - both should proceed
828
+ const call1 = runTask.execute(
829
+ { agentId: "educator", task: "Explain probability", runMode: "sync" },
830
+ ctx,
831
+ );
832
+ const call2 = runTask.execute(
833
+ { agentId: "assessor", task: "Evaluate answer", runMode: "sync" },
834
+ ctx,
835
+ );
836
+
837
+ // Both should have called routeToTeammate
838
+ expect(routeToTeammate).toHaveBeenCalledTimes(2);
839
+
840
+ // Resolve both
841
+ resolveRoute1({ text: "Explained", iterations: 2 });
842
+ resolveRoute2({ text: "Evaluated", iterations: 1 });
843
+
844
+ const result1 = (await call1) as { text?: string };
845
+ const result2 = (await call2) as { text?: string };
846
+ expect(result1.text).toBe("Explained");
847
+ expect(result2.text).toBe("Evaluated");
848
+ });
849
+
746
850
  it("lists ready-to-claim tasks through team_task list action", async () => {
747
851
  const runtime = new AgentTeamsRuntime({ teamName: "test-team" });
748
852
  const tools = createAgentTeamsTools({
@@ -383,6 +383,11 @@ export function createAgentTeamsTools(
383
383
  }) as Tool,
384
384
  );
385
385
 
386
+ // Track in-flight sync runs per agent for dedup
387
+ // (Claude sometimes emits duplicate tool_use blocks in a single response;
388
+ // we execute the first and return an informative "duplicate ignored" to the rest)
389
+ const pendingSyncRuns = new Set<string>();
390
+
386
391
  tools.push(
387
392
  createTool<
388
393
  TeamRunTaskInput,
@@ -417,22 +422,36 @@ export function createAgentTeamsTools(
417
422
  runId: run.id,
418
423
  };
419
424
  }
420
- const result = await options.runtime.routeToTeammate(
421
- validatedInput.agentId,
422
- validatedInput.task,
423
- {
424
- taskId: validatedInput.taskId || undefined,
425
- fromAgentId: options.requesterId,
426
- continueConversation:
427
- validatedInput.continueConversation || undefined,
428
- },
429
- );
430
- return {
431
- agentId: validatedInput.agentId,
432
- mode: "sync",
433
- text: result.text,
434
- iterations: result.iterations,
435
- };
425
+
426
+ /// Deduplication guard: reject a duplicate sync call for the same agent
427
+ // that was already dispatched in this same parallel tool-call batch.
428
+ if (pendingSyncRuns.has(validatedInput.agentId)) {
429
+ throw new Error(
430
+ `Duplicate team_run_task call detected for agent "${validatedInput.agentId}". ` +
431
+ `Only one call per agent is allowed per turn. Discard this duplicate result.`,
432
+ );
433
+ }
434
+ pendingSyncRuns.add(validatedInput.agentId);
435
+ try {
436
+ const result = await options.runtime.routeToTeammate(
437
+ validatedInput.agentId,
438
+ validatedInput.task,
439
+ {
440
+ taskId: validatedInput.taskId || undefined,
441
+ fromAgentId: options.requesterId,
442
+ continueConversation:
443
+ validatedInput.continueConversation || undefined,
444
+ },
445
+ );
446
+ return {
447
+ agentId: validatedInput.agentId,
448
+ mode: "sync",
449
+ text: result.text,
450
+ iterations: result.iterations,
451
+ };
452
+ } finally {
453
+ pendingSyncRuns.delete(validatedInput.agentId);
454
+ }
436
455
  },
437
456
  }) as Tool,
438
457
  );
@@ -42,6 +42,7 @@ export interface CoreRuntimeFeatures {
42
42
  enableTools: boolean;
43
43
  enableSpawnAgent: boolean;
44
44
  enableAgentTeams: boolean;
45
+ disableMcpSettingsTools?: boolean;
45
46
  yolo?: boolean;
46
47
  }
47
48
 
@@ -1,13 +0,0 @@
1
- import type { AgentTeamsRuntime, DelegatedAgentConfigProvider } from "../team";
2
- export interface TeamRuntimeRegistryEntry {
3
- runtime?: AgentTeamsRuntime;
4
- delegatedAgentConfigProvider: DelegatedAgentConfigProvider;
5
- }
6
- export declare class TeamRuntimeRegistry {
7
- private readonly entries;
8
- get(key: string): TeamRuntimeRegistryEntry | undefined;
9
- getOrCreate(key: string, create: () => TeamRuntimeRegistryEntry): TeamRuntimeRegistryEntry;
10
- update(key: string, updateEntry: (entry: TeamRuntimeRegistryEntry) => void): TeamRuntimeRegistryEntry | undefined;
11
- delete(key: string): void;
12
- }
13
- //# sourceMappingURL=team-runtime-registry.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"team-runtime-registry.d.ts","sourceRoot":"","sources":["../../src/runtime/team-runtime-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAE/E,MAAM,WAAW,wBAAwB;IACxC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAC5B,4BAA4B,EAAE,4BAA4B,CAAC;CAC3D;AAED,qBAAa,mBAAmB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+C;IAEvE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,wBAAwB,GAAG,SAAS;IAItD,WAAW,CACV,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,wBAAwB,GACpC,wBAAwB;IAU3B,MAAM,CACL,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,GACpD,wBAAwB,GAAG,SAAS;IASvC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAGzB"}
@@ -1,43 +0,0 @@
1
- import type { AgentTeamsRuntime, DelegatedAgentConfigProvider } from "../team";
2
-
3
- export interface TeamRuntimeRegistryEntry {
4
- runtime?: AgentTeamsRuntime;
5
- delegatedAgentConfigProvider: DelegatedAgentConfigProvider;
6
- }
7
-
8
- export class TeamRuntimeRegistry {
9
- private readonly entries = new Map<string, TeamRuntimeRegistryEntry>();
10
-
11
- get(key: string): TeamRuntimeRegistryEntry | undefined {
12
- return this.entries.get(key);
13
- }
14
-
15
- getOrCreate(
16
- key: string,
17
- create: () => TeamRuntimeRegistryEntry,
18
- ): TeamRuntimeRegistryEntry {
19
- const existing = this.entries.get(key);
20
- if (existing) {
21
- return existing;
22
- }
23
- const created = create();
24
- this.entries.set(key, created);
25
- return created;
26
- }
27
-
28
- update(
29
- key: string,
30
- updateEntry: (entry: TeamRuntimeRegistryEntry) => void,
31
- ): TeamRuntimeRegistryEntry | undefined {
32
- const entry = this.entries.get(key);
33
- if (!entry) {
34
- return undefined;
35
- }
36
- updateEntry(entry);
37
- return entry;
38
- }
39
-
40
- delete(key: string): void {
41
- this.entries.delete(key);
42
- }
43
- }