@rallycry/conveyor-agent 5.7.0 → 5.9.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.
@@ -688,7 +688,7 @@ function errorMeta(error) {
688
688
  import { randomUUID as randomUUID2 } from "crypto";
689
689
  import { execSync as execSync4 } from "child_process";
690
690
 
691
- // src/execution/event-processor.ts
691
+ // src/execution/event-handlers.ts
692
692
  function epochSecondsToISO(value) {
693
693
  if (typeof value === "string") return value;
694
694
  if (typeof value !== "number" || value <= 0) return void 0;
@@ -887,114 +887,138 @@ async function handleSystemEvent(event, host, context, sessionIdStored) {
887
887
  });
888
888
  return !!(event.session_id && !sessionIdStored);
889
889
  }
890
+ function handleSystemSubevents(systemEvent, host) {
891
+ if (systemEvent.subtype === "compact_boundary") {
892
+ void host.callbacks.onEvent({
893
+ type: "context_compacted",
894
+ trigger: systemEvent.compact_metadata.trigger,
895
+ preTokens: systemEvent.compact_metadata.pre_tokens
896
+ });
897
+ } else if (systemEvent.subtype === "task_started") {
898
+ void host.callbacks.onEvent({
899
+ type: "subagent_started",
900
+ sdkTaskId: systemEvent.task_id,
901
+ description: systemEvent.description
902
+ });
903
+ } else if (systemEvent.subtype === "task_progress") {
904
+ void host.callbacks.onEvent({
905
+ type: "subagent_progress",
906
+ sdkTaskId: systemEvent.task_id,
907
+ description: systemEvent.description,
908
+ toolUses: systemEvent.usage?.tool_uses ?? 0,
909
+ durationMs: systemEvent.usage?.duration_ms ?? 0
910
+ });
911
+ }
912
+ }
913
+ function handleToolProgressEvent(event, host) {
914
+ const msg = event;
915
+ void host.callbacks.onEvent({
916
+ type: "tool_progress",
917
+ toolName: msg.tool_name ?? "",
918
+ elapsedSeconds: msg.elapsed_time_seconds ?? 0
919
+ });
920
+ }
921
+ async function handleAssistantCase(event, host, turnToolCalls) {
922
+ await processAssistantEvent(event, host, turnToolCalls);
923
+ const msgUsage = event.message.usage;
924
+ return msgUsage ?? void 0;
925
+ }
926
+ async function handleResultCase(event, host, context, startTime, isTyping, lastAssistantUsage) {
927
+ let stoppedTyping = false;
928
+ if (isTyping) {
929
+ host.connection.sendTypingStop();
930
+ stoppedTyping = true;
931
+ }
932
+ const resultInfo = await emitResultEvent(event, host, context, startTime, lastAssistantUsage);
933
+ return {
934
+ retriable: resultInfo.retriable,
935
+ resultSummary: resultInfo.resultSummary,
936
+ staleSession: resultInfo.staleSession,
937
+ stoppedTyping
938
+ };
939
+ }
940
+
941
+ // src/execution/event-processor.ts
942
+ function stopTypingIfNeeded(host, isTyping) {
943
+ if (isTyping) host.connection.sendTypingStop();
944
+ }
945
+ async function processSystemCase(event, host, context, state) {
946
+ if (event.subtype === "init") {
947
+ const stored = await handleSystemEvent(event, host, context, state.sessionIdStored);
948
+ if (stored) state.sessionIdStored = true;
949
+ } else {
950
+ handleSystemSubevents(
951
+ event,
952
+ host
953
+ );
954
+ }
955
+ }
956
+ async function processAssistantCase(event, host, state) {
957
+ if (!state.isTyping) {
958
+ setTimeout(() => host.connection.sendTypingStart(), 200);
959
+ state.isTyping = true;
960
+ }
961
+ const usage = await handleAssistantCase(event, host, state.turnToolCalls);
962
+ if (usage) state.lastAssistantUsage = usage;
963
+ }
964
+ async function processResultCase(event, host, context, startTime, state) {
965
+ const info = await handleResultCase(
966
+ event,
967
+ host,
968
+ context,
969
+ startTime,
970
+ state.isTyping,
971
+ state.lastAssistantUsage
972
+ );
973
+ if (info.stoppedTyping) state.isTyping = false;
974
+ state.retriable = info.retriable;
975
+ state.resultSummary = info.resultSummary;
976
+ if (info.staleSession) state.staleSession = true;
977
+ }
890
978
  async function processEvents(events, context, host) {
891
979
  const startTime = Date.now();
892
- let sessionIdStored = false;
893
- let isTyping = false;
894
- let retriable = false;
895
- let resultSummary;
896
- let rateLimitResetsAt;
897
- let staleSession;
898
- let lastAssistantUsage;
899
- const turnToolCalls = [];
980
+ const state = {
981
+ sessionIdStored: false,
982
+ isTyping: false,
983
+ retriable: false,
984
+ resultSummary: void 0,
985
+ rateLimitResetsAt: void 0,
986
+ staleSession: void 0,
987
+ lastAssistantUsage: void 0,
988
+ turnToolCalls: []
989
+ };
900
990
  for await (const event of events) {
901
991
  if (host.isStopped()) break;
902
992
  if (host.pendingModeRestart) {
903
- if (isTyping) {
904
- host.connection.sendTypingStop();
905
- }
993
+ stopTypingIfNeeded(host, state.isTyping);
906
994
  return { retriable: false, modeRestart: true };
907
995
  }
908
996
  switch (event.type) {
909
- case "system": {
910
- const systemEvent = event;
911
- if (systemEvent.subtype === "init") {
912
- const stored = await handleSystemEvent(systemEvent, host, context, sessionIdStored);
913
- if (stored) sessionIdStored = true;
914
- } else if (systemEvent.subtype === "compact_boundary") {
915
- const meta = systemEvent.compact_metadata;
916
- if (meta) {
917
- void host.callbacks.onEvent({
918
- type: "context_compacted",
919
- trigger: meta.trigger,
920
- preTokens: meta.pre_tokens
921
- });
922
- }
923
- } else if (systemEvent.subtype === "task_started") {
924
- const msg = systemEvent;
925
- void host.callbacks.onEvent({
926
- type: "subagent_started",
927
- sdkTaskId: msg.task_id ?? "",
928
- description: msg.description ?? ""
929
- });
930
- } else if (systemEvent.subtype === "task_progress") {
931
- const msg = systemEvent;
932
- void host.callbacks.onEvent({
933
- type: "subagent_progress",
934
- sdkTaskId: msg.task_id ?? "",
935
- description: msg.description ?? "",
936
- toolUses: msg.usage?.tool_uses ?? 0,
937
- durationMs: msg.usage?.duration_ms ?? 0
938
- });
939
- }
997
+ case "system":
998
+ await processSystemCase(event, host, context, state);
940
999
  break;
941
- }
942
- case "assistant": {
943
- if (!isTyping) {
944
- setTimeout(() => host.connection.sendTypingStart(), 200);
945
- isTyping = true;
946
- }
947
- const assistantEvent = event;
948
- await processAssistantEvent(assistantEvent, host, turnToolCalls);
949
- const msgUsage = assistantEvent.message.usage;
950
- if (msgUsage) {
951
- lastAssistantUsage = msgUsage;
952
- }
1000
+ case "assistant":
1001
+ await processAssistantCase(event, host, state);
953
1002
  break;
954
- }
955
- case "result": {
956
- if (isTyping) {
957
- host.connection.sendTypingStop();
958
- isTyping = false;
959
- }
960
- const resultInfo = await emitResultEvent(
961
- event,
962
- host,
963
- context,
964
- startTime,
965
- lastAssistantUsage
966
- );
967
- retriable = resultInfo.retriable;
968
- resultSummary = resultInfo.resultSummary;
969
- if (resultInfo.staleSession) {
970
- staleSession = true;
971
- }
1003
+ case "result":
1004
+ await processResultCase(event, host, context, startTime, state);
972
1005
  break;
973
- }
974
1006
  case "rate_limit_event": {
975
1007
  const resetsAt = handleRateLimitEvent(event, host);
976
- if (resetsAt) rateLimitResetsAt = resetsAt;
1008
+ if (resetsAt) state.rateLimitResetsAt = resetsAt;
977
1009
  break;
978
1010
  }
979
- case "tool_progress": {
980
- const msg = event;
981
- void host.callbacks.onEvent({
982
- type: "tool_progress",
983
- toolName: msg.tool_name ?? "",
984
- elapsedSeconds: msg.elapsed_time_seconds ?? 0
985
- });
1011
+ case "tool_progress":
1012
+ handleToolProgressEvent(event, host);
986
1013
  break;
987
- }
988
1014
  }
989
1015
  }
990
- if (isTyping) {
991
- host.connection.sendTypingStop();
992
- }
1016
+ stopTypingIfNeeded(host, state.isTyping);
993
1017
  return {
994
- retriable,
995
- resultSummary,
996
- rateLimitResetsAt,
997
- ...staleSession && { staleSession }
1018
+ retriable: state.retriable,
1019
+ resultSummary: state.resultSummary,
1020
+ rateLimitResetsAt: state.rateLimitResetsAt,
1021
+ ...state.staleSession && { staleSession: state.staleSession }
998
1022
  };
999
1023
  }
1000
1024
 
@@ -1666,7 +1690,7 @@ function buildInstructions(mode, context, scenario, agentMode) {
1666
1690
  return parts;
1667
1691
  }
1668
1692
  if (scenario === "idle_relaunch") {
1669
- if (isPm && (agentMode === "building" || agentMode === "review")) {
1693
+ if (isPm && (agentMode === "building" || agentMode === "review" || agentMode === "auto")) {
1670
1694
  parts.push(
1671
1695
  `You were relaunched but no new instructions have been given since your last run.`,
1672
1696
  `Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
@@ -2086,27 +2110,27 @@ function buildSubtaskTools(connection, spDescription) {
2086
2110
  )
2087
2111
  ];
2088
2112
  }
2113
+ function buildUpdateTaskTool(connection) {
2114
+ return tool2(
2115
+ "update_task",
2116
+ "Save the finalized task plan and/or description",
2117
+ {
2118
+ plan: z2.string().optional().describe("The task plan in markdown"),
2119
+ description: z2.string().optional().describe("Updated task description")
2120
+ },
2121
+ async ({ plan, description }) => {
2122
+ try {
2123
+ await Promise.resolve(connection.updateTaskFields({ plan, description }));
2124
+ return textResult("Task updated successfully.");
2125
+ } catch {
2126
+ return textResult("Failed to update task.");
2127
+ }
2128
+ }
2129
+ );
2130
+ }
2089
2131
  function buildPmTools(connection, storyPoints, options) {
2090
2132
  const spDescription = buildStoryPointDescription(storyPoints);
2091
- const tools = [
2092
- tool2(
2093
- "update_task",
2094
- "Save the finalized task plan and/or description",
2095
- {
2096
- plan: z2.string().optional().describe("The task plan in markdown"),
2097
- description: z2.string().optional().describe("Updated task description")
2098
- },
2099
- async ({ plan, description }) => {
2100
- try {
2101
- await Promise.resolve(connection.updateTaskFields({ plan, description }));
2102
- return textResult("Task updated successfully.");
2103
- } catch {
2104
- return textResult("Failed to update task.");
2105
- }
2106
- }
2107
- ),
2108
- ...buildSubtaskTools(connection, spDescription)
2109
- ];
2133
+ const tools = [buildUpdateTaskTool(connection), ...buildSubtaskTools(connection, spDescription)];
2110
2134
  if (!options?.includePackTools) return tools;
2111
2135
  return [...tools, ...buildPackTools(connection)];
2112
2136
  }
@@ -2296,7 +2320,14 @@ function textResult(text) {
2296
2320
  function imageBlock(data, mimeType) {
2297
2321
  return { type: "image", data, mimeType };
2298
2322
  }
2323
+ function getTaskModeTools(agentMode, connection) {
2324
+ if (agentMode === "discovery" || agentMode === "auto") {
2325
+ return [buildUpdateTaskTool(connection)];
2326
+ }
2327
+ return [];
2328
+ }
2299
2329
  function getModeTools(agentMode, connection, config, context) {
2330
+ if (config.mode === "task") return getTaskModeTools(agentMode, connection);
2300
2331
  switch (agentMode) {
2301
2332
  case "building":
2302
2333
  return context?.isParentTask ? buildPmTools(connection, context?.storyPoints, { includePackTools: true }) : [];
@@ -2392,6 +2423,7 @@ function handleAutoToolAccess(toolName, input, hasExitedPlanMode, isParentTask)
2392
2423
  }
2393
2424
  async function handleExitPlanMode(host, input) {
2394
2425
  try {
2426
+ host.syncPlanFile();
2395
2427
  const taskProps = await host.connection.getTaskProperties();
2396
2428
  const missingProps = [];
2397
2429
  if (!taskProps.plan?.trim()) missingProps.push("plan (save via update_task)");
@@ -2636,7 +2668,8 @@ async function runSdkQuery(host, context, followUpContent) {
2636
2668
  if (host.isStopped()) return;
2637
2669
  const mode = host.agentMode;
2638
2670
  const isDiscoveryLike = mode === "discovery" || mode === "help";
2639
- if (isDiscoveryLike) {
2671
+ const needsPlanSync = isDiscoveryLike || mode === "auto" && !host.hasExitedPlanMode;
2672
+ if (needsPlanSync) {
2640
2673
  host.snapshotPlanFiles();
2641
2674
  }
2642
2675
  const options = buildQueryOptions(host, context);
@@ -2669,7 +2702,7 @@ async function runSdkQuery(host, context, followUpContent) {
2669
2702
  host.activeQuery = null;
2670
2703
  }
2671
2704
  }
2672
- if (isDiscoveryLike) {
2705
+ if (needsPlanSync) {
2673
2706
  host.syncPlanFile();
2674
2707
  }
2675
2708
  }
@@ -2927,6 +2960,7 @@ async function executeSetupConfig(config, runnerConfig, connection, setupLog) {
2927
2960
  pushSetupLog(setupLog, `$ ${config.setupCommand}`);
2928
2961
  await runSetupCommand(config.setupCommand, runnerConfig.workspaceDir, (stream, data) => {
2929
2962
  connection.sendEvent({ type: "setup_output", stream, data });
2963
+ (stream === "stderr" ? process.stderr : process.stdout).write(data);
2930
2964
  for (const line of data.split("\n").filter(Boolean)) {
2931
2965
  pushSetupLog(setupLog, `[${stream}] ${line}`);
2932
2966
  }
@@ -2937,6 +2971,7 @@ async function executeSetupConfig(config, runnerConfig, connection, setupLog) {
2937
2971
  pushSetupLog(setupLog, `$ ${config.startCommand} & (background)`);
2938
2972
  runStartCommand(config.startCommand, runnerConfig.workspaceDir, (stream, data) => {
2939
2973
  connection.sendEvent({ type: "start_command_output", stream, data });
2974
+ (stream === "stderr" ? process.stderr : process.stdout).write(data);
2940
2975
  });
2941
2976
  }
2942
2977
  }
@@ -3030,6 +3065,7 @@ function rerunStartCommand(conveyorConfig, runnerConfig, connection, setupLog) {
3030
3065
  connection.sendEvent({ type: "start_command_started" });
3031
3066
  runStartCommand(conveyorConfig.startCommand, runnerConfig.workspaceDir, (stream, data) => {
3032
3067
  connection.sendEvent({ type: "start_command_output", stream, data });
3068
+ (stream === "stderr" ? process.stderr : process.stdout).write(data);
3033
3069
  });
3034
3070
  const setupEvent = {
3035
3071
  type: "setup_complete",
@@ -3233,7 +3269,7 @@ var AgentRunner = class {
3233
3269
  await this.setState("connected");
3234
3270
  this.connection.sendEvent({ type: "connected", taskId: this.config.taskId });
3235
3271
  this.startHeartbeat();
3236
- if (this.config.mode !== "pm" && process.env.CODESPACES === "true") {
3272
+ if (process.env.CODESPACES === "true") {
3237
3273
  const result = await runSetupSafe(
3238
3274
  this.config,
3239
3275
  this.connection,
@@ -4079,4 +4115,4 @@ export {
4079
4115
  ProjectRunner,
4080
4116
  FileCache
4081
4117
  };
4082
- //# sourceMappingURL=chunk-LYXKPBQN.js.map
4118
+ //# sourceMappingURL=chunk-TYRSIHW2.js.map