@n8n/instance-ai 1.18.0 → 1.19.0

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 (80) hide show
  1. package/dist/agent/shared-prompts.d.ts +1 -1
  2. package/dist/agent/shared-prompts.js +1 -1
  3. package/dist/agent/shared-prompts.js.map +1 -1
  4. package/dist/agent/sub-agent-factory.d.ts +1 -1
  5. package/dist/build.tsbuildinfo +1 -1
  6. package/dist/debug/run-debug-buffer.d.ts +8 -7
  7. package/dist/debug/run-debug-buffer.js +7 -6
  8. package/dist/debug/run-debug-buffer.js.map +1 -1
  9. package/dist/runtime/run-state-registry.d.ts +3 -2
  10. package/dist/runtime/run-state-registry.js +5 -2
  11. package/dist/runtime/run-state-registry.js.map +1 -1
  12. package/dist/storage/workflow-loop-storage.d.ts +87 -0
  13. package/dist/stream/map-chunk.d.ts +1 -2
  14. package/dist/stream/map-chunk.js +38 -21
  15. package/dist/stream/map-chunk.js.map +1 -1
  16. package/dist/tools/nodes/node-search-engine.js +7 -0
  17. package/dist/tools/nodes/node-search-engine.js.map +1 -1
  18. package/dist/tools/nodes/node-search-engine.types.d.ts +3 -0
  19. package/dist/tools/nodes/node-search-engine.types.js.map +1 -1
  20. package/dist/tools/orchestration/agent-target-binding.d.ts +18 -2
  21. package/dist/tools/orchestration/agent-target-binding.js +56 -25
  22. package/dist/tools/orchestration/agent-target-binding.js.map +1 -1
  23. package/dist/tools/orchestration/build-agent.tool.js +179 -91
  24. package/dist/tools/orchestration/build-agent.tool.js.map +1 -1
  25. package/dist/tools/orchestration/verification/analyze-result.d.ts +4 -0
  26. package/dist/tools/orchestration/verification/analyze-result.js +1 -0
  27. package/dist/tools/orchestration/verification/analyze-result.js.map +1 -1
  28. package/dist/tools/orchestration/verification/prepare-run.d.ts +2 -1
  29. package/dist/tools/orchestration/verification/prepare-run.js +6 -3
  30. package/dist/tools/orchestration/verification/prepare-run.js.map +1 -1
  31. package/dist/tools/orchestration/verification/scripted-gate-run.d.ts +23 -0
  32. package/dist/tools/orchestration/verification/scripted-gate-run.js +91 -0
  33. package/dist/tools/orchestration/verification/scripted-gate-run.js.map +1 -0
  34. package/dist/tools/orchestration/verify-built-workflow.tool.js +33 -13
  35. package/dist/tools/orchestration/verify-built-workflow.tool.js.map +1 -1
  36. package/dist/tools/workflows/build-workflow.tool.js +20 -7
  37. package/dist/tools/workflows/build-workflow.tool.js.map +1 -1
  38. package/dist/tools/workflows/plan-verification-simulation.d.ts +2 -1
  39. package/dist/tools/workflows/plan-verification-simulation.js +5 -1
  40. package/dist/tools/workflows/plan-verification-simulation.js.map +1 -1
  41. package/dist/tools/workflows/preserve-node-positions.d.ts +3 -0
  42. package/dist/tools/workflows/preserve-node-positions.js +148 -0
  43. package/dist/tools/workflows/preserve-node-positions.js.map +1 -0
  44. package/dist/tools/workflows/resolve-credentials.js +52 -18
  45. package/dist/tools/workflows/resolve-credentials.js.map +1 -1
  46. package/dist/tools/workflows/setup-workflow.service.d.ts +10 -2
  47. package/dist/tools/workflows/setup-workflow.service.js +57 -5
  48. package/dist/tools/workflows/setup-workflow.service.js.map +1 -1
  49. package/dist/tools/workflows/wait-gate-script.d.ts +9 -0
  50. package/dist/tools/workflows/wait-gate-script.js +223 -0
  51. package/dist/tools/workflows/wait-gate-script.js.map +1 -0
  52. package/dist/tools/workflows/workflow-build-telemetry.d.ts +5 -0
  53. package/dist/tools/workflows/workflow-build-telemetry.js +15 -0
  54. package/dist/tools/workflows/workflow-build-telemetry.js.map +1 -1
  55. package/dist/tools/workflows/workflow-source-compiler.js +5 -0
  56. package/dist/tools/workflows/workflow-source-compiler.js.map +1 -1
  57. package/dist/tools/workflows/workflow-validation-warnings.d.ts +4 -1
  58. package/dist/tools/workflows/workflow-validation-warnings.js +3 -16
  59. package/dist/tools/workflows/workflow-validation-warnings.js.map +1 -1
  60. package/dist/tools/workflows.tool.js +3 -1
  61. package/dist/tools/workflows.tool.js.map +1 -1
  62. package/dist/types.d.ts +9 -1
  63. package/dist/types.js.map +1 -1
  64. package/dist/utils/quota-error.d.ts +2 -0
  65. package/dist/utils/quota-error.js +44 -0
  66. package/dist/utils/quota-error.js.map +1 -0
  67. package/dist/workflow-loop/workflow-loop-state.d.ts +109 -0
  68. package/dist/workflow-loop/workflow-loop-state.js +10 -1
  69. package/dist/workflow-loop/workflow-loop-state.js.map +1 -1
  70. package/dist/workspace/builder-templates-service.js +2 -4
  71. package/dist/workspace/builder-templates-service.js.map +1 -1
  72. package/dist/workspace/sandbox-fs.js +2 -2
  73. package/dist/workspace/sandbox-fs.js.map +1 -1
  74. package/dist/workspace/snapshot-manager.js +2 -4
  75. package/dist/workspace/snapshot-manager.js.map +1 -1
  76. package/dist/workspace/workspace-files.js +16 -1
  77. package/dist/workspace/workspace-files.js.map +1 -1
  78. package/knowledge-base/reference/workflow-builder-guardrails.md +9 -20
  79. package/package.json +15 -15
  80. package/skills/workflow-builder/SKILL.md +74 -70
@@ -1,24 +1,40 @@
1
1
  import { z } from 'zod';
2
2
  import { type AgentPreviewSession } from './agent-preview-session-binding';
3
3
  import type { InstanceAiContext } from '../../types';
4
+ export declare const PENDING_AGENT_METADATA_KEY = "instanceAiPendingAgentTarget";
4
5
  declare const agentBuilderTargetSchema: z.ZodObject<{
5
6
  agentId: z.ZodString;
6
7
  projectId: z.ZodString;
7
8
  name: z.ZodOptional<z.ZodString>;
9
+ ref: z.ZodOptional<z.ZodString>;
8
10
  }, "strip", z.ZodTypeAny, {
9
11
  agentId: string;
10
12
  projectId: string;
11
13
  name?: string | undefined;
14
+ ref?: string | undefined;
12
15
  }, {
13
16
  agentId: string;
14
17
  projectId: string;
15
18
  name?: string | undefined;
19
+ ref?: string | undefined;
16
20
  }>;
17
21
  export type AgentBuilderTarget = z.infer<typeof agentBuilderTargetSchema>;
22
+ declare const pendingAgentTargetSchema: z.ZodObject<{
23
+ projectId: z.ZodString;
24
+ agentId: z.ZodString;
25
+ }, "strip", z.ZodTypeAny, {
26
+ projectId: string;
27
+ agentId: string;
28
+ }, {
29
+ projectId: string;
30
+ agentId: string;
31
+ }>;
32
+ export type PendingAgentTarget = z.infer<typeof pendingAgentTargetSchema>;
33
+ export declare function readPendingAgentTarget(context: InstanceAiContext): Promise<PendingAgentTarget | undefined>;
34
+ export declare function normalizeAgentRef(value: string): string;
18
35
  export declare function resolveAgentBuilderTarget(context: InstanceAiContext): Promise<AgentBuilderTarget | undefined>;
19
36
  export declare function saveAgentBuilderTarget(context: InstanceAiContext, target: AgentBuilderTarget, options?: {
20
37
  previewSession?: AgentPreviewSession;
21
38
  }): Promise<void>;
22
- export declare function agentNamesMatch(a: string | undefined, b: string | undefined): boolean;
23
- export declare function findSessionAgentByName(context: InstanceAiContext, name: string): Promise<AgentBuilderTarget | undefined>;
39
+ export declare function getSessionAgentByRef(context: InstanceAiContext, ref: string): Promise<AgentBuilderTarget | undefined>;
24
40
  export {};
@@ -1,24 +1,52 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PENDING_AGENT_METADATA_KEY = void 0;
4
+ exports.readPendingAgentTarget = readPendingAgentTarget;
5
+ exports.normalizeAgentRef = normalizeAgentRef;
3
6
  exports.resolveAgentBuilderTarget = resolveAgentBuilderTarget;
4
7
  exports.saveAgentBuilderTarget = saveAgentBuilderTarget;
5
- exports.agentNamesMatch = agentNamesMatch;
6
- exports.findSessionAgentByName = findSessionAgentByName;
8
+ exports.getSessionAgentByRef = getSessionAgentByRef;
7
9
  const zod_1 = require("zod");
8
10
  const agent_preview_session_binding_1 = require("./agent-preview-session-binding");
9
11
  const thread_patch_1 = require("../../storage/thread-patch");
10
12
  const METADATA_KEY = 'instanceAiAgentBuilderTarget';
11
13
  const REGISTRY_METADATA_KEY = 'instanceAiAgentBuilderTargets';
14
+ exports.PENDING_AGENT_METADATA_KEY = 'instanceAiPendingAgentTarget';
12
15
  const agentBuilderTargetSchema = zod_1.z.object({
13
16
  agentId: zod_1.z.string(),
14
17
  projectId: zod_1.z.string(),
15
18
  name: zod_1.z.string().optional(),
19
+ ref: zod_1.z.string().optional(),
16
20
  });
17
- const agentBuilderTargetRegistrySchema = zod_1.z.array(agentBuilderTargetSchema);
21
+ const agentBuilderTargetRegistrySchema = zod_1.z.record(zod_1.z.string(), agentBuilderTargetSchema);
22
+ const pendingAgentTargetSchema = zod_1.z.object({ projectId: zod_1.z.string(), agentId: zod_1.z.string() });
23
+ async function readPendingAgentTarget(context) {
24
+ if (!context.threadMemory || !context.threadId)
25
+ return undefined;
26
+ try {
27
+ const thread = await (0, thread_patch_1.getThread)(context.threadMemory, context.threadId);
28
+ const parsed = pendingAgentTargetSchema.safeParse(thread?.metadata?.[exports.PENDING_AGENT_METADATA_KEY]);
29
+ return parsed.success ? parsed.data : undefined;
30
+ }
31
+ catch {
32
+ return undefined;
33
+ }
34
+ }
35
+ function normalizeAgentRef(value) {
36
+ return value
37
+ .trim()
38
+ .toLowerCase()
39
+ .replace(/[^\p{L}\p{N}]+/gu, '-')
40
+ .replace(/^-+|-+$/g, '');
41
+ }
18
42
  function parseTarget(raw) {
19
43
  const parsed = agentBuilderTargetSchema.safeParse(raw);
20
44
  return parsed.success ? parsed.data : undefined;
21
45
  }
46
+ function parseRegistry(raw) {
47
+ const parsed = agentBuilderTargetRegistrySchema.safeParse(raw);
48
+ return parsed.success ? parsed.data : {};
49
+ }
22
50
  async function readThreadTarget(context) {
23
51
  if (!context.threadMemory || !context.threadId)
24
52
  return undefined;
@@ -43,17 +71,30 @@ async function saveAgentBuilderTarget(context, target, options) {
43
71
  await (0, thread_patch_1.patchThread)(context.threadMemory, {
44
72
  threadId: context.threadId,
45
73
  update: ({ metadata = {} }) => {
46
- const parsed = agentBuilderTargetRegistrySchema.safeParse(metadata[REGISTRY_METADATA_KEY]);
47
- const existingRegistry = parsed.success ? parsed.data : [];
48
- const previous = existingRegistry.find((entry) => entry.agentId === target.agentId);
49
- const entry = target.name === undefined && previous?.name !== undefined
50
- ? { ...target, name: previous.name }
51
- : target;
52
- const registry = existingRegistry.filter((e) => e.agentId !== target.agentId);
53
- registry.push(entry);
74
+ const { [exports.PENDING_AGENT_METADATA_KEY]: _pendingAgent, ...carriedMetadata } = metadata;
75
+ const existingRegistry = parseRegistry(metadata[REGISTRY_METADATA_KEY]);
76
+ const previousByAgentId = Object.values(existingRegistry).find((entry) => entry.agentId === target.agentId);
77
+ const entry = {
78
+ ...target,
79
+ ...(target.name === undefined && previousByAgentId?.name !== undefined
80
+ ? { name: previousByAgentId.name }
81
+ : {}),
82
+ ...(target.ref === undefined && previousByAgentId?.ref !== undefined
83
+ ? { ref: previousByAgentId.ref }
84
+ : {}),
85
+ };
86
+ const registry = { ...existingRegistry };
87
+ if (entry.ref) {
88
+ const normalized = normalizeAgentRef(entry.ref);
89
+ for (const [key, existing] of Object.entries(registry)) {
90
+ if (existing.agentId === entry.agentId)
91
+ delete registry[key];
92
+ }
93
+ registry[normalized] = { ...entry, ref: normalized };
94
+ }
54
95
  return {
55
96
  metadata: {
56
- ...metadata,
97
+ ...carriedMetadata,
57
98
  [METADATA_KEY]: entry,
58
99
  [REGISTRY_METADATA_KEY]: registry,
59
100
  ...(options?.previewSession
@@ -64,21 +105,11 @@ async function saveAgentBuilderTarget(context, target, options) {
64
105
  },
65
106
  });
66
107
  }
67
- function agentNamesMatch(a, b) {
68
- if (a === undefined || b === undefined)
69
- return false;
70
- return a.trim().toLowerCase() === b.trim().toLowerCase();
71
- }
72
- async function findSessionAgentByName(context, name) {
108
+ async function getSessionAgentByRef(context, ref) {
73
109
  if (!context.threadMemory || !context.threadId)
74
110
  return undefined;
75
111
  const thread = await (0, thread_patch_1.getThread)(context.threadMemory, context.threadId);
76
- const parsed = agentBuilderTargetRegistrySchema.safeParse(thread?.metadata?.[REGISTRY_METADATA_KEY]);
77
- const registry = parsed.success ? parsed.data : [];
78
- for (let i = registry.length - 1; i >= 0; i--) {
79
- if (agentNamesMatch(registry[i].name, name))
80
- return registry[i];
81
- }
82
- return undefined;
112
+ const registry = parseRegistry(thread?.metadata?.[REGISTRY_METADATA_KEY]);
113
+ return registry[normalizeAgentRef(ref)];
83
114
  }
84
115
  //# sourceMappingURL=agent-target-binding.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-target-binding.js","sourceRoot":"","sources":["../../../src/tools/orchestration/agent-target-binding.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-target-binding.js","sourceRoot":"","sources":["../../../src/tools/orchestration/agent-target-binding.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ const tool_ids_1 = require("../tool-ids");
13
13
  const tracing_utils_1 = require("./tracing-utils");
14
14
  const BUILDER_SUB_AGENT_ROLE = 'agent-builder';
15
15
  const BUILDER_SUB_AGENT_KIND = 'agent-builder';
16
+ const BUILDER_RUN_CANCELLED_MESSAGE = 'The agent builder run was cancelled.';
16
17
  function getErrorCode(error) {
17
18
  if (!(0, is_record_1.isRecord)(error))
18
19
  return undefined;
@@ -32,17 +33,6 @@ function didUpdateConfig(workSummary) {
32
33
  const mutationToolNames = new Set(api_types_1.CONFIG_MUTATION_TOOL_NAMES);
33
34
  return workSummary.toolCalls.some((call) => call.succeeded && mutationToolNames.has(call.toolName));
34
35
  }
35
- function trackConfigMutations(context, agentId, workSummary) {
36
- const mutationToolNames = new Set(api_types_1.CONFIG_MUTATION_TOOL_NAMES);
37
- for (const call of workSummary.toolCalls) {
38
- if (!call.succeeded || !mutationToolNames.has(call.toolName))
39
- continue;
40
- context.trackTelemetry?.('Builder modified agent', {
41
- thread_id: context.threadId,
42
- agent_id: agentId,
43
- });
44
- }
45
- }
46
36
  function formatWorkflowContextEnvelope(workflowContext) {
47
37
  const lines = workflowContext.map((workflow) => `- ${workflow.name} (id: ${workflow.id})${workflow.description ? `: ${workflow.description}` : ''}`);
48
38
  return [
@@ -73,6 +63,7 @@ function builderSessionFor(context, agentId) {
73
63
  ...(context.tracing?.onMemoryTaskEvent
74
64
  ? { memoryTaskObserver: context.tracing.onMemoryTaskEvent }
75
65
  : {}),
66
+ abortSignal: context.abortSignal,
76
67
  };
77
68
  }
78
69
  function builderAgentIdFor(agentId) {
@@ -85,31 +76,35 @@ const buildAgentInputSchema = zod_1.z.object({
85
76
  .describe('The instruction or user message to forward to the agent builder. The builder cannot ' +
86
77
  'see this chat — include every requirement, decision, and user answer already ' +
87
78
  'gathered in this conversation, not just the latest message.'),
88
- name: zod_1.z
79
+ agentRef: zod_1.z
89
80
  .string()
90
81
  .optional()
91
- .describe('Agent name. A name matching an agent already built in this conversation switches back ' +
92
- 'to that agent; a new name creates a new agent and makes it the active target. Omit on ' +
93
- 'follow-up calls for the current agent. Combine with `createNew: true` to force creating ' +
94
- 'a fresh agent when the name matches one built earlier this conversation.'),
95
- createNew: zod_1.z
96
- .boolean()
82
+ .describe('Short stable key you choose once for an agent in this conversation and repeat on ' +
83
+ 'every later call for that same agent (like a workflow source filePath). Prefer a ' +
84
+ 'slug of the display name. A repeated key continues that agent; a fresh key creates ' +
85
+ 'a new one only when no agent is bound yet, or alongside `createNew`. Omit on ' +
86
+ 'follow-ups for the current agent when neither switching nor creating — the active ' +
87
+ 'target is used. When omitted on a create/switch call, the key is derived from `name`.'),
88
+ name: zod_1.z
89
+ .string()
97
90
  .optional()
98
- .describe('Set true when the user asks to create a brand-new agent. Bypasses the same-name ' +
99
- 'switch-back: with createNew, `name` always creates a fresh agent even if that name ' +
100
- 'matches one built earlier in this conversation. Requires `name`; never combine with ' +
101
- '`agentId`. Omit for edits, follow-ups, and switch-backs.'),
91
+ .describe('Display name for a new agent (required when creating). Also used as the addressing ' +
92
+ 'key when `agentRef` is omitted. Omit on follow-up calls for the current agent.'),
102
93
  agentId: zod_1.z
103
94
  .string()
104
95
  .optional()
105
- .describe('Existing agent id to edit — use the `agentId` returned by earlier build-agent ' +
106
- 'results. Pass to start editing that agent or to switch the active build target; ' +
107
- 'omit on follow-up calls. Only pass this when the user explicitly wants to change ' +
108
- 'that specific existing agent. NEVER pass it for a request to build/create a NEW ' +
109
- 'agent even if an agent with the same or a similar name already exists in the ' +
110
- 'project (duplicate names are allowed). Agents the request merely references — as ' +
111
- 'sub-agents, delegation targets, or examples — are not the build target: mention ' +
112
- 'them in `message` instead.'),
96
+ .describe('Existing agent id to adopt — use when editing an agent that was not built in this ' +
97
+ 'conversation (e.g. from the project list). Once adopted, omit on retries and prefer ' +
98
+ '`agentRef`. NEVER pass for a request to build a NEW agent. Agents the request merely ' +
99
+ 'references as sub-agents, delegation targets, or examples are not the build ' +
100
+ 'target: mention them in `message` instead.'),
101
+ createNew: zod_1.z
102
+ .boolean()
103
+ .optional()
104
+ .describe('Set to true ONLY when the user explicitly wants an ADDITIONAL agent alongside the one ' +
105
+ 'this conversation is already building. Leave unset otherwise: while a target is ' +
106
+ 'bound, a fresh `agentRef`/`name` continues that agent instead of creating a second ' +
107
+ 'one, so naming the agent for the first time cannot strand it behind a duplicate.'),
113
108
  workflowContext: zod_1.z
114
109
  .array(zod_1.z.object({ id: zod_1.z.string(), name: zod_1.z.string(), description: zod_1.z.string().optional() }))
115
110
  .optional()
@@ -123,7 +118,11 @@ const buildAgentOutputSchema = zod_1.z.object({
123
118
  agentId: zod_1.z
124
119
  .string()
125
120
  .optional()
126
- .describe('Id of the agent this turn targeted. Record it and pass it as `agentId` when switching back to this agent later.'),
121
+ .describe('Id of the agent this turn targeted. Prefer `agentRef` for follow-ups in this conversation; use `agentId` when the ref is unknown.'),
122
+ agentRef: zod_1.z
123
+ .string()
124
+ .optional()
125
+ .describe('Addressing key for this agent in this conversation. Pass it back as `agentRef` on later calls for the same agent.'),
127
126
  agentName: zod_1.z.string().optional().describe('Display name of the targeted agent, when known.'),
128
127
  answers: zod_1.z
129
128
  .array(api_types_1.questionAnswerSchema)
@@ -135,7 +134,12 @@ const builderCheckpointRefSchema = zod_1.z.object({
135
134
  toolCallId: zod_1.z.string(),
136
135
  configUpdated: zod_1.z.boolean(),
137
136
  target: zod_1.z
138
- .object({ agentId: zod_1.z.string(), projectId: zod_1.z.string(), name: zod_1.z.string().optional() })
137
+ .object({
138
+ agentId: zod_1.z.string(),
139
+ projectId: zod_1.z.string(),
140
+ name: zod_1.z.string().optional(),
141
+ ref: zod_1.z.string().optional(),
142
+ })
139
143
  .optional(),
140
144
  });
141
145
  const builderSuspendPayloadSchema = zod_1.z.union([
@@ -183,6 +187,14 @@ function publishAgentBuilderFailure(context, builderAgentId, error) {
183
187
  });
184
188
  return message;
185
189
  }
190
+ function publishAgentBuilderCancelled(context, builderAgentId) {
191
+ context.eventBus.publish(context.threadId, {
192
+ type: 'agent-completed',
193
+ runId: context.runId,
194
+ agentId: builderAgentId,
195
+ payload: { role: BUILDER_SUB_AGENT_ROLE, result: '', status: 'cancelled' },
196
+ });
197
+ }
186
198
  async function finishTurn(context, builderAgentId, result, carriedConfigUpdated) {
187
199
  if (result.status === 'completed') {
188
200
  const text = await result.text;
@@ -206,7 +218,11 @@ async function finishTurn(context, builderAgentId, result, carriedConfigUpdated)
206
218
  return { ok: false, error, configUpdated };
207
219
  }
208
220
  function targetIdentity(target) {
209
- return { agentId: target.agentId, ...(target.name ? { agentName: target.name } : {}) };
221
+ return {
222
+ agentId: target.agentId,
223
+ ...(target.ref ? { agentRef: target.ref } : {}),
224
+ ...(target.name ? { agentName: target.name } : {}),
225
+ };
210
226
  }
211
227
  async function runBuilderConsumeLoop(params) {
212
228
  const { context, delegate, ctx, target, builderAgentId, turn, carriedConfigUpdated, onSettled, traceInputs, dedupeBase, } = params;
@@ -244,7 +260,13 @@ async function runBuilderConsumeLoop(params) {
244
260
  throw error;
245
261
  }
246
262
  await onSettled?.();
247
- trackConfigMutations(context, target.agentId, result.workSummary);
263
+ if (result.status === 'cancelled') {
264
+ const cancelled = (0, agents_1.createAbortError)(BUILDER_RUN_CANCELLED_MESSAGE);
265
+ publishAgentBuilderCancelled(context, builderAgentId);
266
+ await (0, tracing_utils_1.failTraceRun)(context, traceRun, cancelled);
267
+ await context.claimSubAgentUsage?.(dedupeBase, result.usage?.usage ?? [], result.status);
268
+ throw cancelled;
269
+ }
248
270
  try {
249
271
  const freshName = await delegate.resolveAgentName(target.agentId);
250
272
  if (freshName && freshName !== target.name) {
@@ -313,6 +335,7 @@ async function runBuilderConsumeLoop(params) {
313
335
  agentId: target.agentId,
314
336
  projectId: target.projectId,
315
337
  ...(target.name ? { name: target.name } : {}),
338
+ ...(target.ref ? { ref: target.ref } : {}),
316
339
  },
317
340
  },
318
341
  });
@@ -386,75 +409,138 @@ async function handleResume(context, domainContext, delegate, ctx) {
386
409
  dedupeBase: `${context.runId}:${ctx.toolCallId ?? builderAgentId}:${ref.toolCallId}`,
387
410
  });
388
411
  }
389
- const NO_TARGET_INPUT_ERROR = 'Pass name to create a new agent or agentId to edit an existing one.';
390
- const CREATE_NEW_INPUT_ERROR = 'createNew requires `name` and cannot be combined with `agentId` pass `name` only to create a new agent.';
412
+ const NO_TARGET_INPUT_ERROR = 'Pass `name` (and optionally `agentRef`) to create a new agent, `agentId` to adopt an existing one, or omit both to continue the current agent.';
413
+ const UNKNOWN_REF_ERROR = 'Unknown `agentRef`. Pass `name` to create a new agent under that key, or `agentId` to adopt an existing agent.';
391
414
  const AGENT_ID_NEEDS_PROJECT_ERROR = 'Cannot bind to agentId without an active project context. Start this conversation from within a project.';
392
- function buildAgentTargetNameMismatchError(agentId, realName, passedName) {
393
- return (`Agent ${agentId} is named "${realName}", but name "${passedName}" was passed. ` +
394
- `To create a new agent named "${passedName}", pass \`name\` only (no \`agentId\`). ` +
395
- `To edit "${realName}", pass \`agentId\` only and put any rename instruction in \`message\`.`);
396
- }
397
- function rejectAgentTargetNameMismatch(agentId, realName, passedName) {
398
- if (!passedName || !realName || (0, agent_target_binding_1.agentNamesMatch)(passedName, realName)) {
415
+ async function resolveAgentNameSafely(delegate, agentId) {
416
+ try {
417
+ return await delegate.resolveAgentName(agentId);
418
+ }
419
+ catch {
399
420
  return undefined;
400
421
  }
401
- return { ok: false, error: buildAgentTargetNameMismatchError(agentId, realName, passedName) };
422
+ }
423
+ async function pendingAgentIdFor(context) {
424
+ const pending = await (0, agent_target_binding_1.readPendingAgentTarget)(context);
425
+ return pending && pending.projectId === context.projectId ? pending.agentId : undefined;
426
+ }
427
+ function agentRefConflictError(ref, boundAgentId, passedAgentId) {
428
+ return (`\`agentRef\` "${ref}" is already bound to agent ${boundAgentId} in this conversation, ` +
429
+ `but \`agentId\` ${passedAgentId} was passed. Continue the bound agent (omit \`agentId\`, ` +
430
+ 'or pass its id), or pick a different `agentRef` for a new agent.');
402
431
  }
403
432
  async function resolveTargetForCall(domainContext, delegate, input, boundTarget) {
404
- if (input.createNew && (input.agentId || !input.name)) {
405
- return { ok: false, error: CREATE_NEW_INPUT_ERROR };
433
+ const keySource = input.agentRef ?? input.name;
434
+ const key = keySource ? (0, agent_target_binding_1.normalizeAgentRef)(keySource) : undefined;
435
+ if (key) {
436
+ const sessionAgent = await (0, agent_target_binding_1.getSessionAgentByRef)(domainContext, key);
437
+ if (sessionAgent) {
438
+ if (input.agentId && input.agentId !== sessionAgent.agentId) {
439
+ return {
440
+ ok: false,
441
+ error: agentRefConflictError(key, sessionAgent.agentId, input.agentId),
442
+ };
443
+ }
444
+ const target = {
445
+ ...sessionAgent,
446
+ ref: key,
447
+ ...(input.name ? { name: input.name } : {}),
448
+ };
449
+ if (boundTarget && boundTarget.agentId === target.agentId) {
450
+ return {
451
+ ok: true,
452
+ target: { ...boundTarget, ...target },
453
+ bindAfterTurn: false,
454
+ mode: 'edit',
455
+ };
456
+ }
457
+ return { ok: true, target, bindAfterTurn: true, mode: 'edit' };
458
+ }
459
+ const boundKey = boundTarget?.ref
460
+ ? (0, agent_target_binding_1.normalizeAgentRef)(boundTarget.ref)
461
+ : boundTarget?.name
462
+ ? (0, agent_target_binding_1.normalizeAgentRef)(boundTarget.name)
463
+ : undefined;
464
+ if (boundTarget && boundKey === key) {
465
+ if (input.agentId && input.agentId !== boundTarget.agentId) {
466
+ return {
467
+ ok: false,
468
+ error: agentRefConflictError(key, boundTarget.agentId, input.agentId),
469
+ };
470
+ }
471
+ return {
472
+ ok: true,
473
+ target: { ...boundTarget, ref: key, ...(input.name ? { name: input.name } : {}) },
474
+ bindAfterTurn: false,
475
+ mode: 'edit',
476
+ };
477
+ }
478
+ if (input.agentId) {
479
+ if (boundTarget && input.agentId === boundTarget.agentId) {
480
+ return {
481
+ ok: true,
482
+ target: { ...boundTarget, ref: key, ...(input.name ? { name: input.name } : {}) },
483
+ bindAfterTurn: false,
484
+ mode: 'edit',
485
+ };
486
+ }
487
+ if (!domainContext.projectId) {
488
+ return { ok: false, error: AGENT_ID_NEEDS_PROJECT_ERROR };
489
+ }
490
+ const name = input.name ?? (await resolveAgentNameSafely(delegate, input.agentId));
491
+ return {
492
+ ok: true,
493
+ target: {
494
+ agentId: input.agentId,
495
+ projectId: domainContext.projectId,
496
+ ref: key,
497
+ ...(name ? { name } : {}),
498
+ },
499
+ bindAfterTurn: true,
500
+ mode: 'edit',
501
+ };
502
+ }
503
+ if (input.name) {
504
+ if (boundTarget && !input.createNew) {
505
+ return {
506
+ ok: true,
507
+ target: { ...boundTarget, ref: key },
508
+ bindAfterTurn: true,
509
+ mode: 'continued',
510
+ };
511
+ }
512
+ const created = await delegate.createAgent(input.name, await pendingAgentIdFor(domainContext));
513
+ const target = {
514
+ agentId: created.agentId,
515
+ projectId: created.projectId,
516
+ name: input.name,
517
+ ref: key,
518
+ };
519
+ domainContext.agentBuilderTarget = target;
520
+ await (0, agent_target_binding_1.saveAgentBuilderTarget)(domainContext, target);
521
+ return { ok: true, target, bindAfterTurn: false, mode: 'create' };
522
+ }
523
+ return { ok: false, error: UNKNOWN_REF_ERROR };
406
524
  }
407
525
  if (input.agentId) {
408
526
  if (boundTarget && input.agentId === boundTarget.agentId) {
409
- const mismatch = rejectAgentTargetNameMismatch(input.agentId, boundTarget.name, input.name);
410
- if (mismatch)
411
- return mismatch;
412
527
  return { ok: true, target: boundTarget, bindAfterTurn: false, mode: 'edit' };
413
528
  }
414
529
  if (!domainContext.projectId) {
415
530
  return { ok: false, error: AGENT_ID_NEEDS_PROJECT_ERROR };
416
531
  }
417
- let name;
418
- try {
419
- name = await delegate.resolveAgentName(input.agentId);
420
- }
421
- catch {
422
- name = undefined;
423
- }
424
- const mismatch = rejectAgentTargetNameMismatch(input.agentId, name, input.name);
425
- if (mismatch)
426
- return mismatch;
532
+ const name = await resolveAgentNameSafely(delegate, input.agentId);
427
533
  return {
428
534
  ok: true,
429
535
  target: {
430
536
  agentId: input.agentId,
431
537
  projectId: domainContext.projectId,
432
- ...(name ? { name } : {}),
538
+ ...(name ? { name, ref: (0, agent_target_binding_1.normalizeAgentRef)(name) } : {}),
433
539
  },
434
540
  bindAfterTurn: true,
435
541
  mode: 'edit',
436
542
  };
437
543
  }
438
- if (input.name) {
439
- if (!input.createNew) {
440
- if (boundTarget && (0, agent_target_binding_1.agentNamesMatch)(input.name, boundTarget.name)) {
441
- return { ok: true, target: boundTarget, bindAfterTurn: false, mode: 'edit' };
442
- }
443
- const sessionAgent = await (0, agent_target_binding_1.findSessionAgentByName)(domainContext, input.name);
444
- if (sessionAgent) {
445
- return { ok: true, target: sessionAgent, bindAfterTurn: true, mode: 'edit' };
446
- }
447
- }
448
- const created = await delegate.createAgent(input.name);
449
- const target = {
450
- agentId: created.agentId,
451
- projectId: created.projectId,
452
- name: input.name,
453
- };
454
- domainContext.agentBuilderTarget = target;
455
- await (0, agent_target_binding_1.saveAgentBuilderTarget)(domainContext, target);
456
- return { ok: true, target, bindAfterTurn: false, mode: 'create' };
457
- }
458
544
  if (boundTarget) {
459
545
  return { ok: true, target: boundTarget, bindAfterTurn: false, mode: 'edit' };
460
546
  }
@@ -470,28 +556,30 @@ function createBuildAgentTool(context) {
470
556
  'tools. If a workflow build seems to need a utility tool the workspace does not ' +
471
557
  'provide, ask the user or use a placeholder; do not route around that by calling ' +
472
558
  '`build-agent`. ' +
473
- 'Pass `name` to start a new agent or `agentId` to edit an existing one; calls ' +
474
- 'without either keep editing the current agent. Create vs. edit follows user ' +
475
- 'intent, not name collisions: a request to build a NEW agent always passes `name` ' +
476
- 'plus `createNew: true` never `agentId` even when a same-named agent already exists in the ' +
477
- 'project. To build ANOTHER agent in the same ' +
478
- 'conversation, pass its `name` or `agentId` a name matching an agent already built ' +
479
- 'in this conversation switches back to it (unless `createNew: true` is passed); an unmatched name creates a new agent and ' +
480
- 'switches the active target. The builder can also publish or unpublish the target ' +
559
+ 'Address agents in this conversation with `agentRef` (a short stable key you choose, ' +
560
+ 'like a workflow `filePath`). Pass `name` with a fresh key to create the first agent; ' +
561
+ 'repeat the same key to continue. Calls with neither key nor `agentId` keep editing ' +
562
+ 'the current agent, and so does a fresh key once an agent is bound naming an agent ' +
563
+ 'never silently creates a second one. To build ANOTHER agent in the same ' +
564
+ 'conversation, pass `createNew: true` with a different `agentRef` and `name`. To edit ' +
565
+ 'an agent that was not built here, pass `agentId` (optionally with `agentRef`) once ' +
566
+ 'to adopt it. The builder can also publish or unpublish the target ' +
481
567
  'agent when the user asks to publish, activate, make it live/usable, or unpublish — ' +
482
568
  'forward that intent in `message`; never tell the user to open the agent editor and ' +
483
569
  'click Publish. When the builder needs user input (a choice, a ' +
484
570
  'credential, or a chat channel), it surfaces automatically as an interactive card in ' +
485
571
  'this chat — do not relay those questions yourself; this tool call resumes with the ' +
486
572
  'user’s answer and returns the builder’s reply. Returns the builder’s reply, the ' +
487
- 'target `agentId`, and whether it updated the agent config. Record the returned ' +
488
- '`agentId` and prefer passing it as `agentId` when switching back to that agent' +
489
- 'the `name` path is a fallback for when the id is unknown.')
573
+ 'target `agentRef`/`agentId`, and whether it updated the agent config. Prefer the ' +
574
+ 'returned `agentRef` on later calls for that agent.')
490
575
  .input(buildAgentInputSchema)
491
576
  .output(buildAgentOutputSchema)
492
577
  .suspend(buildAgentSuspendSchema)
493
578
  .resume(buildAgentResumeSchema)
494
579
  .handler(async (input, ctx) => {
580
+ if (context.abortSignal.aborted) {
581
+ throw (0, agents_1.createAbortError)(BUILDER_RUN_CANCELLED_MESSAGE);
582
+ }
495
583
  const domainContext = context.domainContext;
496
584
  const delegate = domainContext?.builderDelegate;
497
585
  if (!domainContext || !delegate) {