@standardagents/builder 0.11.7 → 0.11.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2917,8 +2917,22 @@ ${errorLines.join("\n")}`);
2917
2917
  }
2918
2918
  const agentType = agentDef.type;
2919
2919
  if (agentType === "ai_human") {
2920
+ let args2 = {};
2921
+ try {
2922
+ args2 = JSON.parse(call.function.arguments);
2923
+ } catch {
2924
+ }
2925
+ const parentToolConfigs = state.prompt._tools || [];
2926
+ const toolConfig = parentToolConfigs.find(
2927
+ (t) => typeof t === "string" ? t === agentName : t.name === agentName
2928
+ );
2920
2929
  state.pendingHandoff = {
2921
- agentId: agentName
2930
+ agentId: agentName,
2931
+ args: args2,
2932
+ toolConfig: typeof toolConfig === "object" ? {
2933
+ initUserMessageProperty: toolConfig.initUserMessageProperty,
2934
+ initAttachmentsProperty: toolConfig.initAttachmentsProperty
2935
+ } : void 0
2922
2936
  };
2923
2937
  const text2 = "Handoff complete";
2924
2938
  return {
@@ -3060,10 +3074,11 @@ ${attachmentPaths}`;
3060
3074
  };
3061
3075
  message = await FlowEngine2.runBeforeCreateMessageHook(state, message);
3062
3076
  message.created_at = Date.now() * TIMESTAMP_MULTIPLIER;
3077
+ const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
3063
3078
  await state.storage.sql.exec(
3064
3079
  `
3065
- INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments)
3066
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)
3080
+ INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, prompt)
3081
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)
3067
3082
  `,
3068
3083
  message.id,
3069
3084
  message.role,
@@ -3074,7 +3089,8 @@ ${attachmentPaths}`;
3074
3089
  message.tool_status,
3075
3090
  message.parent_id,
3076
3091
  message.depth,
3077
- message.attachments
3092
+ message.attachments,
3093
+ currentPrompt
3078
3094
  );
3079
3095
  await FlowEngine2.runAfterCreateMessageHook(state, message);
3080
3096
  const parentLogId = state.currentLogId || null;
@@ -4722,13 +4738,15 @@ var init_FlowEngine = __esm({
4722
4738
  status: "completed"
4723
4739
  };
4724
4740
  interruptionMessage = await this.runBeforeCreateMessageHook(state, interruptionMessage);
4741
+ const currentPromptName = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
4725
4742
  await state.storage.sql.exec(
4726
- `INSERT INTO messages (id, role, content, created_at, status) VALUES (?, ?, ?, ?, ?)`,
4743
+ `INSERT INTO messages (id, role, content, created_at, status, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
4727
4744
  interruptionMessage.id,
4728
4745
  interruptionMessage.role,
4729
4746
  interruptionMessage.content,
4730
4747
  interruptionMessage.created_at,
4731
- interruptionMessage.status
4748
+ interruptionMessage.status,
4749
+ currentPromptName
4732
4750
  );
4733
4751
  await this.runAfterCreateMessageHook(state, interruptionMessage);
4734
4752
  if (state.emitMessage) {
@@ -5014,8 +5032,8 @@ var init_FlowEngine = __esm({
5014
5032
  );
5015
5033
  return !hasExistingResult;
5016
5034
  });
5017
- if (toolsToExecute && toolsToExecute.length > 0) {
5018
- await ToolExecutor.executeSequence(state, toolsToExecute);
5035
+ if (toolsToExecute && toolsToExecute.length > 0 || state.sequence.queue.length > 0) {
5036
+ await ToolExecutor.executeSequence(state, toolsToExecute || []);
5019
5037
  }
5020
5038
  if (await state.thread.instance.shouldStop() || state.abortController?.signal.aborted) {
5021
5039
  throw new Error("aborted");
@@ -5113,10 +5131,72 @@ var init_FlowEngine = __esm({
5113
5131
  state.agentConfig = agentConfig;
5114
5132
  state.prompts.sideA = sideAPrompt;
5115
5133
  state.prompts.sideB = sideBPrompt;
5116
- state.extraMessages = [];
5134
+ const args = state.pendingHandoff?.args || {};
5135
+ const toolConfig = state.pendingHandoff?.toolConfig;
5136
+ const initUserMessageProperty = toolConfig?.initUserMessageProperty;
5137
+ const initAttachmentsProperty = toolConfig?.initAttachmentsProperty;
5138
+ state.context = { ...state.context, ...args };
5139
+ let userMessageContent;
5140
+ let userMessageAttachments;
5141
+ if (initUserMessageProperty && args[initUserMessageProperty] !== void 0) {
5142
+ const propertyValue = args[initUserMessageProperty];
5143
+ userMessageContent = typeof propertyValue === "string" ? propertyValue : JSON.stringify(propertyValue);
5144
+ }
5145
+ if (initAttachmentsProperty && args[initAttachmentsProperty] !== void 0) {
5146
+ const attachmentValue = args[initAttachmentsProperty];
5147
+ const attachmentPaths = Array.isArray(attachmentValue) ? attachmentValue : [attachmentValue];
5148
+ const resolvedAttachments = [];
5149
+ for (const attachmentPath of attachmentPaths) {
5150
+ if (typeof attachmentPath === "string" && attachmentPath.startsWith("/attachments/")) {
5151
+ try {
5152
+ const statResult = await state.thread.instance.statFile(attachmentPath);
5153
+ if (statResult.success && statResult.file) {
5154
+ resolvedAttachments.push({
5155
+ id: crypto.randomUUID(),
5156
+ type: "file",
5157
+ path: attachmentPath,
5158
+ name: statResult.file.name,
5159
+ mimeType: statResult.file.mimeType,
5160
+ width: statResult.file.width ?? void 0,
5161
+ height: statResult.file.height ?? void 0
5162
+ });
5163
+ }
5164
+ } catch (e) {
5165
+ console.error(`[FlowEngine] Failed to resolve attachment ${attachmentPath}:`, e);
5166
+ }
5167
+ }
5168
+ }
5169
+ if (resolvedAttachments.length > 0) {
5170
+ userMessageAttachments = JSON.stringify(resolvedAttachments);
5171
+ }
5172
+ }
5117
5173
  state.currentSide = "a";
5118
5174
  state.prompt = state.prompts.sideA;
5119
5175
  state.promptPath = [sideAPrompt.name];
5176
+ if (userMessageContent || userMessageAttachments) {
5177
+ const handoffMessageId = crypto.randomUUID();
5178
+ const handoffTimestamp = Date.now() * 1e3;
5179
+ const handoffMessage = {
5180
+ id: handoffMessageId,
5181
+ role: "user",
5182
+ content: userMessageContent || "",
5183
+ created_at: handoffTimestamp,
5184
+ attachments: userMessageAttachments
5185
+ };
5186
+ await state.storage.sql.exec(
5187
+ `INSERT INTO messages (id, role, content, attachments, created_at, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
5188
+ handoffMessage.id,
5189
+ handoffMessage.role,
5190
+ handoffMessage.content,
5191
+ handoffMessage.attachments || null,
5192
+ handoffMessage.created_at,
5193
+ sideAPrompt.name
5194
+ );
5195
+ state.messageHistory.push(handoffMessage);
5196
+ if (state.emitMessage) {
5197
+ state.emitMessage(handoffMessage);
5198
+ }
5199
+ }
5120
5200
  state.pendingHandoff = void 0;
5121
5201
  state.emitTelemetry?.({
5122
5202
  type: "agent_handoff",
@@ -5459,26 +5539,35 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5459
5539
  );
5460
5540
  tools.push(...selectedTools);
5461
5541
  const foundToolNames = new Set(selectedTools.map((t) => t.function.name));
5542
+ const { z: z4 } = await import('zod');
5462
5543
  for (const toolName of regularToolNames) {
5463
5544
  if (foundToolNames.has(toolName)) continue;
5464
5545
  try {
5465
5546
  const agentDef = await state.thread.instance.loadAgent(toolName);
5466
5547
  if (agentDef && agentDef.type === "ai_human") {
5548
+ let parameters;
5549
+ const sideAPromptName = agentDef.sideA?.prompt;
5550
+ if (sideAPromptName) {
5551
+ try {
5552
+ const promptDef = await state.thread.instance.loadPrompt(sideAPromptName);
5553
+ if (promptDef.requiredSchema) {
5554
+ const jsonSchema = z4.toJSONSchema(promptDef.requiredSchema);
5555
+ parameters = {
5556
+ type: "object",
5557
+ properties: jsonSchema.properties || {},
5558
+ required: jsonSchema.required || []
5559
+ };
5560
+ }
5561
+ } catch (promptError) {
5562
+ console.error(`Error loading prompt schema for agent ${toolName}:`, promptError);
5563
+ }
5564
+ }
5467
5565
  tools.push({
5468
5566
  type: "function",
5469
5567
  function: {
5470
- name: agentDef.title || toolName,
5568
+ name: toolName,
5471
5569
  description: agentDef.toolDescription || `Hand off conversation to ${agentDef.title || toolName} agent`,
5472
- parameters: {
5473
- type: "object",
5474
- properties: {
5475
- input: {
5476
- type: "string",
5477
- description: "Input message for the agent"
5478
- }
5479
- },
5480
- required: ["input"]
5481
- }
5570
+ parameters
5482
5571
  }
5483
5572
  });
5484
5573
  }
@@ -5713,25 +5802,34 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5713
5802
  const tools = [];
5714
5803
  try {
5715
5804
  const agentNames = state.thread.instance.getAgentNames();
5805
+ const { z: z4 } = await import('zod');
5716
5806
  for (const name of agentNames) {
5717
5807
  try {
5718
5808
  const agentDef = await state.thread.instance.loadAgent(name);
5719
5809
  if (agentDef.exposeAsTool) {
5810
+ let parameters;
5811
+ const sideAPromptName = agentDef.sideA?.prompt;
5812
+ if (sideAPromptName) {
5813
+ try {
5814
+ const promptDef = await state.thread.instance.loadPrompt(sideAPromptName);
5815
+ if (promptDef.requiredSchema) {
5816
+ const jsonSchema = z4.toJSONSchema(promptDef.requiredSchema);
5817
+ parameters = {
5818
+ type: "object",
5819
+ properties: jsonSchema.properties || {},
5820
+ required: jsonSchema.required || []
5821
+ };
5822
+ }
5823
+ } catch (promptError) {
5824
+ console.error(`Error loading prompt schema for agent ${name}:`, promptError);
5825
+ }
5826
+ }
5720
5827
  tools.push({
5721
5828
  type: "function",
5722
5829
  function: {
5723
- name: agentDef.title || name,
5830
+ name,
5724
5831
  description: agentDef.toolDescription || `Execute the ${agentDef.title || name} agent`,
5725
- parameters: {
5726
- type: "object",
5727
- properties: {
5728
- input: {
5729
- type: "string",
5730
- description: "Input message for the agent"
5731
- }
5732
- },
5733
- required: ["input"]
5734
- }
5832
+ parameters
5735
5833
  }
5736
5834
  });
5737
5835
  }
@@ -5985,13 +6083,14 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5985
6083
  const now = Date.now() * TIMESTAMP_MULTIPLIER;
5986
6084
  message.created_at = now;
5987
6085
  message.request_sent_at = now;
6086
+ const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
5988
6087
  await state.storage.sql.exec(
5989
6088
  `
5990
6089
  INSERT INTO messages (
5991
6090
  id, role, content, tool_calls, log_id, created_at,
5992
- request_sent_at, response_completed_at, status, parent_id, depth, reasoning_content
6091
+ request_sent_at, response_completed_at, status, parent_id, depth, reasoning_content, prompt
5993
6092
  )
5994
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
6093
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
5995
6094
  `,
5996
6095
  message.id,
5997
6096
  message.role,
@@ -6004,8 +6103,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
6004
6103
  message.status,
6005
6104
  message.parent_id,
6006
6105
  message.depth,
6007
- null
6106
+ null,
6008
6107
  // reasoning_content - will be set when message is updated with LLM response
6108
+ currentPrompt
6009
6109
  );
6010
6110
  await this.runAfterCreateMessageHook(state, message);
6011
6111
  state.messageHistory.push(message);
@@ -6263,10 +6363,11 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
6263
6363
  depth: state.depth,
6264
6364
  attachments: JSON.stringify([attachmentRef])
6265
6365
  };
6366
+ const currentPromptForAttachment = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
6266
6367
  await state.storage.sql.exec(
6267
6368
  `
6268
- INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments)
6269
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)
6369
+ INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, prompt)
6370
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)
6270
6371
  `,
6271
6372
  toolMessage.id,
6272
6373
  toolMessage.role,
@@ -6277,7 +6378,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
6277
6378
  toolMessage.tool_status,
6278
6379
  toolMessage.parent_id,
6279
6380
  toolMessage.depth,
6280
- toolMessage.attachments
6381
+ toolMessage.attachments,
6382
+ currentPromptForAttachment
6281
6383
  );
6282
6384
  state.messageHistory.push(toolMessage);
6283
6385
  if (state.emitMessage) {
@@ -6807,8 +6909,9 @@ async function injectMessage(flow, options) {
6807
6909
  }
6808
6910
  message.created_at = targetMessage.created_at - 1;
6809
6911
  }
6912
+ const currentPrompt = flow.promptPath.length > 0 ? flow.promptPath[flow.promptPath.length - 1] : null;
6810
6913
  await flow.storage.sql.exec(
6811
- `INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
6914
+ `INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
6812
6915
  messageId,
6813
6916
  message.role,
6814
6917
  message.content,
@@ -6818,7 +6921,8 @@ async function injectMessage(flow, options) {
6818
6921
  message.status,
6819
6922
  silent ? 1 : 0,
6820
6923
  message.parent_id,
6821
- message.depth
6924
+ message.depth,
6925
+ currentPrompt
6822
6926
  );
6823
6927
  if (!silent) {
6824
6928
  flow.messageHistory.push(message);
@@ -7671,6 +7775,74 @@ var TSCONFIG_CONTENT = `{
7671
7775
  "include": ["types.d.ts", "virtual-module.d.ts"]
7672
7776
  }
7673
7777
  `;
7778
+ function extractSchemaFields(content) {
7779
+ const fields = [];
7780
+ const schemaMatch = content.match(/requiredSchema:\s*z\.object\(\s*\{([^}]+)\}/s);
7781
+ if (!schemaMatch) {
7782
+ return fields;
7783
+ }
7784
+ const schemaContent = schemaMatch[1];
7785
+ const fieldMatches = schemaContent.matchAll(/(?:['"]([^'"]+)['"]|(\w+))\s*:/g);
7786
+ for (const match of fieldMatches) {
7787
+ const fieldName = match[1] || match[2];
7788
+ if (fieldName && !fieldName.startsWith("z.")) {
7789
+ fields.push(fieldName);
7790
+ }
7791
+ }
7792
+ return fields;
7793
+ }
7794
+ function scanPromptsWithSchemas(dir) {
7795
+ const results = [];
7796
+ if (!fs2.existsSync(dir)) {
7797
+ return results;
7798
+ }
7799
+ try {
7800
+ const entries = fs2.readdirSync(dir, { withFileTypes: true });
7801
+ for (const entry of entries) {
7802
+ if (entry.isFile() && entry.name.endsWith(".ts")) {
7803
+ const filePath = path3.join(dir, entry.name);
7804
+ const content = fs2.readFileSync(filePath, "utf-8");
7805
+ const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
7806
+ if (nameMatch) {
7807
+ const name = nameMatch[1];
7808
+ const schemaFields = extractSchemaFields(content);
7809
+ results.push({ name, schemaFields });
7810
+ }
7811
+ }
7812
+ }
7813
+ } catch (error) {
7814
+ console.error(`Error scanning prompts directory ${dir}:`, error);
7815
+ }
7816
+ return results;
7817
+ }
7818
+ function scanAgentsWithSideA(dir) {
7819
+ const results = [];
7820
+ if (!fs2.existsSync(dir)) {
7821
+ return results;
7822
+ }
7823
+ try {
7824
+ const entries = fs2.readdirSync(dir, { withFileTypes: true });
7825
+ for (const entry of entries) {
7826
+ if (entry.isFile() && entry.name.endsWith(".ts")) {
7827
+ const filePath = path3.join(dir, entry.name);
7828
+ const content = fs2.readFileSync(filePath, "utf-8");
7829
+ const nameMatch = content.match(/name:\s*['"]([^'"]+)['"]/);
7830
+ if (nameMatch) {
7831
+ const name = nameMatch[1];
7832
+ let sideAPrompt = null;
7833
+ const sideAMatch = content.match(/sideA:\s*\{[^}]*prompt:\s*['"]([^'"]+)['"]/);
7834
+ if (sideAMatch) {
7835
+ sideAPrompt = sideAMatch[1];
7836
+ }
7837
+ results.push({ name, sideAPrompt });
7838
+ }
7839
+ }
7840
+ }
7841
+ } catch (error) {
7842
+ console.error(`Error scanning agents directory ${dir}:`, error);
7843
+ }
7844
+ return results;
7845
+ }
7674
7846
  function scanForNames(dir, useFilename = false) {
7675
7847
  const names = [];
7676
7848
  if (!fs2.existsSync(dir)) {
@@ -7706,11 +7878,38 @@ function generateRegistryProperties(names) {
7706
7878
  }
7707
7879
  return names.map((n) => `'${n}': true;`).join("\n ");
7708
7880
  }
7881
+ function generateSchemaRegistryProperties(promptResults, agentResults) {
7882
+ const entries = [];
7883
+ const promptSchemaMap = /* @__PURE__ */ new Map();
7884
+ for (const prompt of promptResults) {
7885
+ if (prompt.schemaFields.length > 0) {
7886
+ promptSchemaMap.set(prompt.name, prompt.schemaFields);
7887
+ }
7888
+ }
7889
+ for (const prompt of promptResults) {
7890
+ if (prompt.schemaFields.length > 0) {
7891
+ const fieldsUnion = prompt.schemaFields.map((f) => `'${f}'`).join(" | ");
7892
+ entries.push(`'${prompt.name}': ${fieldsUnion};`);
7893
+ }
7894
+ }
7895
+ for (const agent of agentResults) {
7896
+ if (agent.sideAPrompt) {
7897
+ const schemaFields = promptSchemaMap.get(agent.sideAPrompt);
7898
+ if (schemaFields && schemaFields.length > 0) {
7899
+ const fieldsUnion = schemaFields.map((f) => `'${f}'`).join(" | ");
7900
+ entries.push(`'${agent.name}': ${fieldsUnion};`);
7901
+ }
7902
+ }
7903
+ }
7904
+ return entries.join("\n ");
7905
+ }
7709
7906
  function generateTypesContent(config) {
7710
7907
  const models = scanForNames(config.modelsDir);
7711
- const prompts = scanForNames(config.promptsDir);
7712
- const agents = scanForNames(config.agentsDir);
7908
+ const promptResults = scanPromptsWithSchemas(config.promptsDir);
7909
+ const agentResults = scanAgentsWithSideA(config.agentsDir);
7713
7910
  const tools = scanForNames(config.toolsDir, true);
7911
+ const prompts = promptResults.map((p) => p.name);
7912
+ const agents = agentResults.map((a) => a.name);
7714
7913
  const callables = [...prompts, ...agents, ...tools];
7715
7914
  return `// Auto-generated by @standardagents/builder - DO NOT EDIT
7716
7915
  // Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}
@@ -7751,6 +7950,11 @@ declare global {
7751
7950
  interface CallableRegistry {
7752
7951
  ${generateRegistryProperties(callables)}
7753
7952
  }
7953
+
7954
+ /** Schema field names for prompts and agents (used for initUserMessageProperty autocomplete) */
7955
+ interface PromptSchemaRegistry {
7956
+ ${generateSchemaRegistryProperties(promptResults, agentResults)}
7957
+ }
7754
7958
  }
7755
7959
  }
7756
7960
 
@@ -12074,8 +12278,24 @@ var migration21 = {
12074
12278
  }
12075
12279
  };
12076
12280
 
12281
+ // src/durable-objects/migrations/022_add_prompt_to_messages.ts
12282
+ var migration22 = {
12283
+ version: 22,
12284
+ async up(sql) {
12285
+ await sql.exec(`
12286
+ ALTER TABLE messages ADD COLUMN prompt TEXT
12287
+ `);
12288
+ await sql.exec(`
12289
+ CREATE INDEX IF NOT EXISTS idx_messages_prompt ON messages(prompt)
12290
+ `);
12291
+ await sql.exec(`
12292
+ UPDATE _metadata SET value = '22' WHERE key = 'schema_version'
12293
+ `);
12294
+ }
12295
+ };
12296
+
12077
12297
  // src/durable-objects/migrations/index.ts
12078
- var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21];
12298
+ var migrations = [migration, migration2, migration3, migration4, migration5, migration6, migration7, migration8, migration9, migration10, migration11, migration12, migration13, migration14, migration15, migration16, migration17, migration18, migration19, migration20, migration21, migration22];
12079
12299
  var LATEST_SCHEMA_VERSION = migrations.length;
12080
12300
 
12081
12301
  // src/durable-objects/DurableThread.ts
@@ -12659,9 +12879,9 @@ var DurableThread = class extends DurableObject {
12659
12879
  * Each migration is run in order, starting from the current version + 1.
12660
12880
  */
12661
12881
  async runMigrations(fromVersion) {
12662
- for (const migration24 of migrations) {
12663
- if (migration24.version > fromVersion) {
12664
- await migration24.up(this.ctx.storage.sql);
12882
+ for (const migration25 of migrations) {
12883
+ if (migration25.version > fromVersion) {
12884
+ await migration25.up(this.ctx.storage.sql);
12665
12885
  }
12666
12886
  }
12667
12887
  }
@@ -12818,14 +13038,15 @@ var DurableThread = class extends DurableObject {
12818
13038
  if (responses.length === 0) {
12819
13039
  const toolResponseId = crypto.randomUUID();
12820
13040
  await this.ctx.storage.sql.exec(
12821
- `INSERT INTO messages (id, role, content, tool_call_id, tool_status, created_at, status) VALUES (?, ?, ?, ?, ?, ?, ?)`,
13041
+ `INSERT INTO messages (id, role, content, tool_call_id, tool_status, created_at, status, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
12822
13042
  toolResponseId,
12823
13043
  "tool",
12824
13044
  "Execution stopped by user",
12825
13045
  tc.id,
12826
13046
  "error",
12827
13047
  now,
12828
- "completed"
13048
+ "completed",
13049
+ null
12829
13050
  );
12830
13051
  this.broadcastMessage({
12831
13052
  id: toolResponseId,
@@ -12846,12 +13067,13 @@ var DurableThread = class extends DurableObject {
12846
13067
  const interruptionMessageId = crypto.randomUUID();
12847
13068
  const timestamp = Date.now() * TIMESTAMP_MULTIPLIER;
12848
13069
  await this.ctx.storage.sql.exec(
12849
- `INSERT INTO messages (id, role, content, created_at, status) VALUES (?, ?, ?, ?, ?)`,
13070
+ `INSERT INTO messages (id, role, content, created_at, status, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
12850
13071
  interruptionMessageId,
12851
13072
  "system",
12852
13073
  "Execution stopped by user",
12853
13074
  timestamp,
12854
- "completed"
13075
+ "completed",
13076
+ null
12855
13077
  );
12856
13078
  this.broadcastMessage({
12857
13079
  id: interruptionMessageId,
@@ -13090,14 +13312,15 @@ var DurableThread = class extends DurableObject {
13090
13312
  for (const msg of args.messages) {
13091
13313
  await this.ctx.storage.sql.exec(
13092
13314
  `
13093
- INSERT INTO messages (id, role, content, created_at, log_id)
13094
- VALUES (?, ?, ?, ?, ?)
13315
+ INSERT INTO messages (id, role, content, created_at, log_id, prompt)
13316
+ VALUES (?, ?, ?, ?, ?, ?)
13095
13317
  `,
13096
13318
  msg.id,
13097
13319
  msg.role,
13098
13320
  msg.content,
13099
13321
  msg.created_at,
13100
- msg.log_id ?? null
13322
+ msg.log_id ?? null,
13323
+ null
13101
13324
  );
13102
13325
  }
13103
13326
  return {
@@ -13675,14 +13898,15 @@ var DurableThread = class extends DurableObject {
13675
13898
  }));
13676
13899
  for (const msg of messagesToStore) {
13677
13900
  await this.ctx.storage.sql.exec(
13678
- `INSERT INTO messages (id, role, content, name, tool_calls, tool_call_id, created_at) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)`,
13901
+ `INSERT INTO messages (id, role, content, name, tool_calls, tool_call_id, created_at, prompt) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)`,
13679
13902
  msg.id,
13680
13903
  msg.role,
13681
13904
  msg.content || null,
13682
13905
  msg.name || null,
13683
13906
  msg.tool_calls ? JSON.stringify(msg.tool_calls) : null,
13684
13907
  msg.tool_call_id || null,
13685
- msg.created_at
13908
+ msg.created_at,
13909
+ null
13686
13910
  );
13687
13911
  if (msg.role === "user") {
13688
13912
  rootMessageId = msg.id;
@@ -13692,11 +13916,12 @@ var DurableThread = class extends DurableObject {
13692
13916
  if (!rootMessageId) {
13693
13917
  rootMessageId = crypto.randomUUID();
13694
13918
  await this.ctx.storage.sql.exec(
13695
- `INSERT INTO messages (id, role, content, created_at) VALUES (?1, ?2, ?3, ?4)`,
13919
+ `INSERT INTO messages (id, role, content, created_at, prompt) VALUES (?1, ?2, ?3, ?4, ?5)`,
13696
13920
  rootMessageId,
13697
13921
  "system",
13698
13922
  null,
13699
- Date.now() * 1e3
13923
+ Date.now() * 1e3,
13924
+ null
13700
13925
  );
13701
13926
  }
13702
13927
  await FlowEngine2.execute({
@@ -13819,13 +14044,15 @@ var DurableThread = class extends DurableObject {
13819
14044
  };
13820
14045
  const { FlowEngine: FlowEngine2 } = await Promise.resolve().then(() => (init_FlowEngine(), FlowEngine_exports));
13821
14046
  message = await FlowEngine2.runBeforeCreateMessageHook(state, message);
14047
+ const currentPrompt = agentDef.sideA?.prompt || null;
13822
14048
  await this.ctx.storage.sql.exec(
13823
- `INSERT INTO messages (id, role, content, attachments, created_at) VALUES (?, ?, ?, ?, ?)`,
14049
+ `INSERT INTO messages (id, role, content, attachments, created_at, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
13824
14050
  message.id,
13825
14051
  message.role,
13826
14052
  message.content,
13827
14053
  message.attachments,
13828
- message.created_at
14054
+ message.created_at,
14055
+ currentPrompt
13829
14056
  );
13830
14057
  await FlowEngine2.runAfterCreateMessageHook(state, message);
13831
14058
  this.broadcastMessage({
@@ -14036,12 +14263,13 @@ var DurableThread = class extends DurableObject {
14036
14263
  }
14037
14264
  ]);
14038
14265
  await this.ctx.storage.sql.exec(
14039
- `INSERT INTO messages (id, role, content, tool_calls, created_at)
14040
- VALUES (?, 'assistant', ?, ?, ?)`,
14266
+ `INSERT INTO messages (id, role, content, tool_calls, created_at, prompt)
14267
+ VALUES (?, 'assistant', ?, ?, ?, ?)`,
14041
14268
  messageId,
14042
14269
  params.content || null,
14043
14270
  toolCalls,
14044
- Date.now() * 1e3
14271
+ Date.now() * 1e3,
14272
+ null
14045
14273
  );
14046
14274
  return Response.json({
14047
14275
  status: "inserted",
@@ -14553,7 +14781,7 @@ var DurableThread = class extends DurableObject {
14553
14781
  };
14554
14782
 
14555
14783
  // src/durable-objects/agentbuilder-migrations/0001_initial.ts
14556
- var migration22 = {
14784
+ var migration23 = {
14557
14785
  version: 1,
14558
14786
  async up(sql) {
14559
14787
  sql.exec(`
@@ -14652,7 +14880,7 @@ var migration22 = {
14652
14880
  };
14653
14881
 
14654
14882
  // src/durable-objects/agentbuilder-migrations/0002_add_tenvs_properties.ts
14655
- var migration23 = {
14883
+ var migration24 = {
14656
14884
  version: 2,
14657
14885
  async up(sql) {
14658
14886
  sql.exec(`ALTER TABLE threads ADD COLUMN tenvs TEXT`);
@@ -14664,7 +14892,7 @@ var migration23 = {
14664
14892
  };
14665
14893
 
14666
14894
  // src/durable-objects/agentbuilder-migrations/index.ts
14667
- var migrations2 = [migration22, migration23];
14895
+ var migrations2 = [migration23, migration24];
14668
14896
  var LATEST_SCHEMA_VERSION2 = 2;
14669
14897
 
14670
14898
  // src/utils/crypto.ts
@@ -14841,9 +15069,9 @@ var DurableAgentBuilder = class extends DurableObject {
14841
15069
  }
14842
15070
  }
14843
15071
  async runMigrations(fromVersion) {
14844
- for (const migration24 of migrations2) {
14845
- if (migration24.version > fromVersion) {
14846
- await migration24.up(this.ctx.storage.sql);
15072
+ for (const migration25 of migrations2) {
15073
+ if (migration25.version > fromVersion) {
15074
+ await migration25.up(this.ctx.storage.sql);
14847
15075
  }
14848
15076
  }
14849
15077
  }
@@ -15611,7 +15839,7 @@ var FlowStateSdk = class _FlowStateSdk {
15611
15839
  * The tool will be executed as part of the normal flow processing.
15612
15840
  *
15613
15841
  * @param flow - The current FlowState
15614
- * @param toolName - The name of the tool to call
15842
+ * @param toolName - The name of the tool to call (autocompletes from available tools)
15615
15843
  * @param args - The arguments to pass to the tool
15616
15844
  *
15617
15845
  * @example
@@ -15697,8 +15925,9 @@ var FlowStateSdk = class _FlowStateSdk {
15697
15925
  }
15698
15926
  message.created_at = targetMessage.created_at - 1;
15699
15927
  }
15928
+ const currentPrompt = flow.promptPath.length > 0 ? flow.promptPath[flow.promptPath.length - 1] : null;
15700
15929
  await flow.storage.sql.exec(
15701
- `INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
15930
+ `INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
15702
15931
  messageId,
15703
15932
  message.role,
15704
15933
  message.content,
@@ -15708,7 +15937,8 @@ var FlowStateSdk = class _FlowStateSdk {
15708
15937
  message.status,
15709
15938
  silent ? 1 : 0,
15710
15939
  message.parent_id,
15711
- message.depth
15940
+ message.depth,
15941
+ currentPrompt
15712
15942
  );
15713
15943
  if (!silent) {
15714
15944
  flow.messageHistory.push(message);