@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.
@@ -2899,8 +2899,22 @@ ${errorLines.join("\n")}`);
2899
2899
  }
2900
2900
  const agentType = agentDef.type;
2901
2901
  if (agentType === "ai_human") {
2902
+ let args2 = {};
2903
+ try {
2904
+ args2 = JSON.parse(call.function.arguments);
2905
+ } catch {
2906
+ }
2907
+ const parentToolConfigs = state.prompt._tools || [];
2908
+ const toolConfig = parentToolConfigs.find(
2909
+ (t) => typeof t === "string" ? t === agentName : t.name === agentName
2910
+ );
2902
2911
  state.pendingHandoff = {
2903
- agentId: agentName
2912
+ agentId: agentName,
2913
+ args: args2,
2914
+ toolConfig: typeof toolConfig === "object" ? {
2915
+ initUserMessageProperty: toolConfig.initUserMessageProperty,
2916
+ initAttachmentsProperty: toolConfig.initAttachmentsProperty
2917
+ } : void 0
2904
2918
  };
2905
2919
  const text3 = "Handoff complete";
2906
2920
  return {
@@ -3042,10 +3056,11 @@ ${attachmentPaths}`;
3042
3056
  };
3043
3057
  message = await FlowEngine2.runBeforeCreateMessageHook(state, message);
3044
3058
  message.created_at = Date.now() * TIMESTAMP_MULTIPLIER;
3059
+ const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
3045
3060
  await state.storage.sql.exec(
3046
3061
  `
3047
- INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments)
3048
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)
3062
+ INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, prompt)
3063
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)
3049
3064
  `,
3050
3065
  message.id,
3051
3066
  message.role,
@@ -3056,7 +3071,8 @@ ${attachmentPaths}`;
3056
3071
  message.tool_status,
3057
3072
  message.parent_id,
3058
3073
  message.depth,
3059
- message.attachments
3074
+ message.attachments,
3075
+ currentPrompt
3060
3076
  );
3061
3077
  await FlowEngine2.runAfterCreateMessageHook(state, message);
3062
3078
  const parentLogId = state.currentLogId || null;
@@ -4611,13 +4627,15 @@ var init_FlowEngine = __esm({
4611
4627
  status: "completed"
4612
4628
  };
4613
4629
  interruptionMessage = await this.runBeforeCreateMessageHook(state, interruptionMessage);
4630
+ const currentPromptName = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
4614
4631
  await state.storage.sql.exec(
4615
- `INSERT INTO messages (id, role, content, created_at, status) VALUES (?, ?, ?, ?, ?)`,
4632
+ `INSERT INTO messages (id, role, content, created_at, status, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
4616
4633
  interruptionMessage.id,
4617
4634
  interruptionMessage.role,
4618
4635
  interruptionMessage.content,
4619
4636
  interruptionMessage.created_at,
4620
- interruptionMessage.status
4637
+ interruptionMessage.status,
4638
+ currentPromptName
4621
4639
  );
4622
4640
  await this.runAfterCreateMessageHook(state, interruptionMessage);
4623
4641
  if (state.emitMessage) {
@@ -4903,8 +4921,8 @@ var init_FlowEngine = __esm({
4903
4921
  );
4904
4922
  return !hasExistingResult;
4905
4923
  });
4906
- if (toolsToExecute && toolsToExecute.length > 0) {
4907
- await ToolExecutor.executeSequence(state, toolsToExecute);
4924
+ if (toolsToExecute && toolsToExecute.length > 0 || state.sequence.queue.length > 0) {
4925
+ await ToolExecutor.executeSequence(state, toolsToExecute || []);
4908
4926
  }
4909
4927
  if (await state.thread.instance.shouldStop() || state.abortController?.signal.aborted) {
4910
4928
  throw new Error("aborted");
@@ -5002,10 +5020,72 @@ var init_FlowEngine = __esm({
5002
5020
  state.agentConfig = agentConfig;
5003
5021
  state.prompts.sideA = sideAPrompt;
5004
5022
  state.prompts.sideB = sideBPrompt;
5005
- state.extraMessages = [];
5023
+ const args = state.pendingHandoff?.args || {};
5024
+ const toolConfig = state.pendingHandoff?.toolConfig;
5025
+ const initUserMessageProperty = toolConfig?.initUserMessageProperty;
5026
+ const initAttachmentsProperty = toolConfig?.initAttachmentsProperty;
5027
+ state.context = { ...state.context, ...args };
5028
+ let userMessageContent;
5029
+ let userMessageAttachments;
5030
+ if (initUserMessageProperty && args[initUserMessageProperty] !== void 0) {
5031
+ const propertyValue = args[initUserMessageProperty];
5032
+ userMessageContent = typeof propertyValue === "string" ? propertyValue : JSON.stringify(propertyValue);
5033
+ }
5034
+ if (initAttachmentsProperty && args[initAttachmentsProperty] !== void 0) {
5035
+ const attachmentValue = args[initAttachmentsProperty];
5036
+ const attachmentPaths = Array.isArray(attachmentValue) ? attachmentValue : [attachmentValue];
5037
+ const resolvedAttachments = [];
5038
+ for (const attachmentPath of attachmentPaths) {
5039
+ if (typeof attachmentPath === "string" && attachmentPath.startsWith("/attachments/")) {
5040
+ try {
5041
+ const statResult = await state.thread.instance.statFile(attachmentPath);
5042
+ if (statResult.success && statResult.file) {
5043
+ resolvedAttachments.push({
5044
+ id: crypto.randomUUID(),
5045
+ type: "file",
5046
+ path: attachmentPath,
5047
+ name: statResult.file.name,
5048
+ mimeType: statResult.file.mimeType,
5049
+ width: statResult.file.width ?? void 0,
5050
+ height: statResult.file.height ?? void 0
5051
+ });
5052
+ }
5053
+ } catch (e) {
5054
+ console.error(`[FlowEngine] Failed to resolve attachment ${attachmentPath}:`, e);
5055
+ }
5056
+ }
5057
+ }
5058
+ if (resolvedAttachments.length > 0) {
5059
+ userMessageAttachments = JSON.stringify(resolvedAttachments);
5060
+ }
5061
+ }
5006
5062
  state.currentSide = "a";
5007
5063
  state.prompt = state.prompts.sideA;
5008
5064
  state.promptPath = [sideAPrompt.name];
5065
+ if (userMessageContent || userMessageAttachments) {
5066
+ const handoffMessageId = crypto.randomUUID();
5067
+ const handoffTimestamp = Date.now() * 1e3;
5068
+ const handoffMessage = {
5069
+ id: handoffMessageId,
5070
+ role: "user",
5071
+ content: userMessageContent || "",
5072
+ created_at: handoffTimestamp,
5073
+ attachments: userMessageAttachments
5074
+ };
5075
+ await state.storage.sql.exec(
5076
+ `INSERT INTO messages (id, role, content, attachments, created_at, prompt) VALUES (?, ?, ?, ?, ?, ?)`,
5077
+ handoffMessage.id,
5078
+ handoffMessage.role,
5079
+ handoffMessage.content,
5080
+ handoffMessage.attachments || null,
5081
+ handoffMessage.created_at,
5082
+ sideAPrompt.name
5083
+ );
5084
+ state.messageHistory.push(handoffMessage);
5085
+ if (state.emitMessage) {
5086
+ state.emitMessage(handoffMessage);
5087
+ }
5088
+ }
5009
5089
  state.pendingHandoff = void 0;
5010
5090
  state.emitTelemetry?.({
5011
5091
  type: "agent_handoff",
@@ -5348,26 +5428,35 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5348
5428
  );
5349
5429
  tools.push(...selectedTools);
5350
5430
  const foundToolNames = new Set(selectedTools.map((t) => t.function.name));
5431
+ const { z: z182 } = await import('zod');
5351
5432
  for (const toolName of regularToolNames) {
5352
5433
  if (foundToolNames.has(toolName)) continue;
5353
5434
  try {
5354
5435
  const agentDef = await state.thread.instance.loadAgent(toolName);
5355
5436
  if (agentDef && agentDef.type === "ai_human") {
5437
+ let parameters;
5438
+ const sideAPromptName = agentDef.sideA?.prompt;
5439
+ if (sideAPromptName) {
5440
+ try {
5441
+ const promptDef = await state.thread.instance.loadPrompt(sideAPromptName);
5442
+ if (promptDef.requiredSchema) {
5443
+ const jsonSchema = z182.toJSONSchema(promptDef.requiredSchema);
5444
+ parameters = {
5445
+ type: "object",
5446
+ properties: jsonSchema.properties || {},
5447
+ required: jsonSchema.required || []
5448
+ };
5449
+ }
5450
+ } catch (promptError) {
5451
+ console.error(`Error loading prompt schema for agent ${toolName}:`, promptError);
5452
+ }
5453
+ }
5356
5454
  tools.push({
5357
5455
  type: "function",
5358
5456
  function: {
5359
- name: agentDef.title || toolName,
5457
+ name: toolName,
5360
5458
  description: agentDef.toolDescription || `Hand off conversation to ${agentDef.title || toolName} agent`,
5361
- parameters: {
5362
- type: "object",
5363
- properties: {
5364
- input: {
5365
- type: "string",
5366
- description: "Input message for the agent"
5367
- }
5368
- },
5369
- required: ["input"]
5370
- }
5459
+ parameters
5371
5460
  }
5372
5461
  });
5373
5462
  }
@@ -5602,25 +5691,34 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5602
5691
  const tools = [];
5603
5692
  try {
5604
5693
  const agentNames = state.thread.instance.getAgentNames();
5694
+ const { z: z182 } = await import('zod');
5605
5695
  for (const name of agentNames) {
5606
5696
  try {
5607
5697
  const agentDef = await state.thread.instance.loadAgent(name);
5608
5698
  if (agentDef.exposeAsTool) {
5699
+ let parameters;
5700
+ const sideAPromptName = agentDef.sideA?.prompt;
5701
+ if (sideAPromptName) {
5702
+ try {
5703
+ const promptDef = await state.thread.instance.loadPrompt(sideAPromptName);
5704
+ if (promptDef.requiredSchema) {
5705
+ const jsonSchema = z182.toJSONSchema(promptDef.requiredSchema);
5706
+ parameters = {
5707
+ type: "object",
5708
+ properties: jsonSchema.properties || {},
5709
+ required: jsonSchema.required || []
5710
+ };
5711
+ }
5712
+ } catch (promptError) {
5713
+ console.error(`Error loading prompt schema for agent ${name}:`, promptError);
5714
+ }
5715
+ }
5609
5716
  tools.push({
5610
5717
  type: "function",
5611
5718
  function: {
5612
- name: agentDef.title || name,
5719
+ name,
5613
5720
  description: agentDef.toolDescription || `Execute the ${agentDef.title || name} agent`,
5614
- parameters: {
5615
- type: "object",
5616
- properties: {
5617
- input: {
5618
- type: "string",
5619
- description: "Input message for the agent"
5620
- }
5621
- },
5622
- required: ["input"]
5623
- }
5721
+ parameters
5624
5722
  }
5625
5723
  });
5626
5724
  }
@@ -5874,13 +5972,14 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5874
5972
  const now = Date.now() * TIMESTAMP_MULTIPLIER;
5875
5973
  message.created_at = now;
5876
5974
  message.request_sent_at = now;
5975
+ const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
5877
5976
  await state.storage.sql.exec(
5878
5977
  `
5879
5978
  INSERT INTO messages (
5880
5979
  id, role, content, tool_calls, log_id, created_at,
5881
- request_sent_at, response_completed_at, status, parent_id, depth, reasoning_content
5980
+ request_sent_at, response_completed_at, status, parent_id, depth, reasoning_content, prompt
5882
5981
  )
5883
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
5982
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
5884
5983
  `,
5885
5984
  message.id,
5886
5985
  message.role,
@@ -5893,8 +5992,9 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
5893
5992
  message.status,
5894
5993
  message.parent_id,
5895
5994
  message.depth,
5896
- null
5995
+ null,
5897
5996
  // reasoning_content - will be set when message is updated with LLM response
5997
+ currentPrompt
5898
5998
  );
5899
5999
  await this.runAfterCreateMessageHook(state, message);
5900
6000
  state.messageHistory.push(message);
@@ -6152,10 +6252,11 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
6152
6252
  depth: state.depth,
6153
6253
  attachments: JSON.stringify([attachmentRef])
6154
6254
  };
6255
+ const currentPromptForAttachment = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
6155
6256
  await state.storage.sql.exec(
6156
6257
  `
6157
- INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments)
6158
- VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)
6258
+ INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, prompt)
6259
+ VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)
6159
6260
  `,
6160
6261
  toolMessage.id,
6161
6262
  toolMessage.role,
@@ -6166,7 +6267,8 @@ ${msg.content}` : `${imageDescriptions}${nonImageList}`;
6166
6267
  toolMessage.tool_status,
6167
6268
  toolMessage.parent_id,
6168
6269
  toolMessage.depth,
6169
- toolMessage.attachments
6270
+ toolMessage.attachments,
6271
+ currentPromptForAttachment
6170
6272
  );
6171
6273
  state.messageHistory.push(toolMessage);
6172
6274
  if (state.emitMessage) {
@@ -6696,8 +6798,9 @@ async function injectMessage(flow, options) {
6696
6798
  }
6697
6799
  message.created_at = targetMessage.created_at - 1;
6698
6800
  }
6801
+ const currentPrompt = flow.promptPath.length > 0 ? flow.promptPath[flow.promptPath.length - 1] : null;
6699
6802
  await flow.storage.sql.exec(
6700
- `INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
6803
+ `INSERT INTO messages (id, role, content, name, tool_call_id, created_at, status, silent, parent_id, depth, prompt) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
6701
6804
  messageId,
6702
6805
  message.role,
6703
6806
  message.content,
@@ -6707,7 +6810,8 @@ async function injectMessage(flow, options) {
6707
6810
  message.status,
6708
6811
  silent ? 1 : 0,
6709
6812
  message.parent_id,
6710
- message.depth
6813
+ message.depth,
6814
+ currentPrompt
6711
6815
  );
6712
6816
  if (!silent) {
6713
6817
  flow.messageHistory.push(message);
@@ -22712,6 +22816,26 @@ var tools_get_default = defineController(async ({ url, tools, prompts, promptNam
22712
22816
  })
22713
22817
  );
22714
22818
  }
22819
+ if (agents && agentNames) {
22820
+ await Promise.all(
22821
+ agentNames.map(async (name) => {
22822
+ try {
22823
+ const loader = agents[name];
22824
+ if (!loader) return;
22825
+ const definition = await loader();
22826
+ const agentToolType = definition.type === "ai_human" ? "handoff" : "subagent";
22827
+ result[name] = {
22828
+ description: definition.toolDescription || `Execute the ${definition.title || name} agent`,
22829
+ schema: null,
22830
+ hasError: false,
22831
+ type: agentToolType
22832
+ };
22833
+ } catch (error) {
22834
+ console.error(`Error loading agent ${name}:`, error);
22835
+ }
22836
+ })
22837
+ );
22838
+ }
22715
22839
  return Response.json(result);
22716
22840
  });
22717
22841