@rallycry/conveyor-agent 8.11.0 → 8.13.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.
- package/dist/{chunk-IB6M4OVT.js → chunk-L7Q2JZJX.js} +100 -31
- package/dist/chunk-L7Q2JZJX.js.map +1 -0
- package/dist/cli.js +106 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-IB6M4OVT.js.map +0 -1
|
@@ -177,18 +177,72 @@ var AgentConnection = class _AgentConnection {
|
|
|
177
177
|
return this.socket?.connected ?? false;
|
|
178
178
|
}
|
|
179
179
|
// ── Typed service method call ──────────────────────────────────────────
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
// Socket.IO keeps the SAME Socket instance across transport-level
|
|
181
|
+
// reconnects (it only goes null on an explicit disconnect() teardown), so a
|
|
182
|
+
// brief flap leaves `this.socket` non-null but `.connected === false`. Rather
|
|
183
|
+
// than failing a tool call instantly (which the spawned `claude` surfaces as
|
|
184
|
+
// "Conveyor MCP disconnected" and an excuse to go idle), we wait out a short
|
|
185
|
+
// reconnect window, then emit with an ack timeout so a buffered packet whose
|
|
186
|
+
// ack never returns can't hang the call forever. We do NOT auto-retry the
|
|
187
|
+
// emit — re-sending a write could double-apply it; the agent prompt instructs
|
|
188
|
+
// the model to retry the tool, which is the safe place to decide idempotency.
|
|
189
|
+
static CALL_CONNECT_WAIT_MS = 2e4;
|
|
190
|
+
static CALL_ACK_TIMEOUT_MS = 3e4;
|
|
191
|
+
async call(method, payload) {
|
|
192
|
+
const socket = this.socket;
|
|
193
|
+
if (!socket) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`Not connected (method: ${String(method)}, session: ${this.config.sessionId})`
|
|
184
196
|
);
|
|
185
197
|
}
|
|
186
|
-
|
|
198
|
+
if (!socket.connected) {
|
|
199
|
+
await this.waitForConnected(socket, _AgentConnection.CALL_CONNECT_WAIT_MS, String(method));
|
|
200
|
+
}
|
|
201
|
+
return await this.emitWithAck(socket, method, payload);
|
|
202
|
+
}
|
|
203
|
+
/** Resolve once `socket` reports connected, or reject after `timeoutMs`. */
|
|
204
|
+
waitForConnected(socket, timeoutMs, method) {
|
|
205
|
+
if (socket.connected) return Promise.resolve();
|
|
187
206
|
return new Promise((resolve2, reject) => {
|
|
207
|
+
const cleanup = () => {
|
|
208
|
+
clearTimeout(timer);
|
|
209
|
+
socket.off("connect", onConnect);
|
|
210
|
+
};
|
|
211
|
+
const onConnect = () => {
|
|
212
|
+
cleanup();
|
|
213
|
+
resolve2();
|
|
214
|
+
};
|
|
215
|
+
const timer = setTimeout(() => {
|
|
216
|
+
cleanup();
|
|
217
|
+
reject(
|
|
218
|
+
new Error(
|
|
219
|
+
`Not connected \u2014 socket did not reconnect within ${timeoutMs / 1e3}s (method: ${method}, session: ${this.config.sessionId}). Transient; retry.`
|
|
220
|
+
)
|
|
221
|
+
);
|
|
222
|
+
}, timeoutMs);
|
|
223
|
+
socket.once("connect", onConnect);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
/** Emit an RPC and resolve on ack, rejecting if no ack arrives in time. */
|
|
227
|
+
emitWithAck(socket, method, payload) {
|
|
228
|
+
return new Promise((resolve2, reject) => {
|
|
229
|
+
let settled = false;
|
|
230
|
+
const timer = setTimeout(() => {
|
|
231
|
+
if (settled) return;
|
|
232
|
+
settled = true;
|
|
233
|
+
reject(
|
|
234
|
+
new Error(
|
|
235
|
+
`Service call timed out after ${_AgentConnection.CALL_ACK_TIMEOUT_MS / 1e3}s (method: ${String(method)}, session: ${this.config.sessionId}). Usually a transient reconnect; retry.`
|
|
236
|
+
)
|
|
237
|
+
);
|
|
238
|
+
}, _AgentConnection.CALL_ACK_TIMEOUT_MS);
|
|
188
239
|
socket.emit(
|
|
189
240
|
`agentSessionService:${String(method)}`,
|
|
190
241
|
payload,
|
|
191
242
|
(response) => {
|
|
243
|
+
if (settled) return;
|
|
244
|
+
settled = true;
|
|
245
|
+
clearTimeout(timer);
|
|
192
246
|
if (response.success && response.data !== void 0) {
|
|
193
247
|
resolve2(response.data);
|
|
194
248
|
} else {
|
|
@@ -2315,10 +2369,12 @@ function buildPackRunnerSystemPrompt(context, config, setupLog) {
|
|
|
2315
2369
|
}
|
|
2316
2370
|
parts.push(
|
|
2317
2371
|
``,
|
|
2318
|
-
`Your
|
|
2319
|
-
`
|
|
2320
|
-
`
|
|
2321
|
-
`Use read_task_chat only if you need to re-read earlier messages beyond the chat context above
|
|
2372
|
+
`Your turn output appears ONLY in the live agent terminal \u2014 it is NOT posted to the task chat. The team does NOT see your replies unless you post them.`,
|
|
2373
|
+
`Use post_to_chat (omit task_id \u2192 this task's chat) to report which children you fired, status as you orchestrate, and any blocker or escalation the team needs to act on.`,
|
|
2374
|
+
`Pass task_id only to message a DIFFERENT task's chat (e.g. a child task).`,
|
|
2375
|
+
`Use read_task_chat only if you need to re-read earlier messages beyond the chat context above.`,
|
|
2376
|
+
``,
|
|
2377
|
+
`If a Conveyor tool call fails or reports the MCP server is unavailable/disconnected, this is almost always a transient socket reconnect \u2014 RETRY the same call; it will succeed once the connection re-establishes. A tool error is NOT a reason to go idle or stop the loop. (Going idle is only correct when you are genuinely waiting on child-task status changes or CI \u2014 see the loop above.)`
|
|
2322
2378
|
);
|
|
2323
2379
|
return parts.join("\n");
|
|
2324
2380
|
}
|
|
@@ -3028,7 +3084,7 @@ Environment (ready, no setup required):`,
|
|
|
3028
3084
|
Workflow:`,
|
|
3029
3085
|
`- You can draft and iterate on plans in .claude/plans/*.md \u2014 these files are automatically synced to the task.`,
|
|
3030
3086
|
`- You can also use update_task_plan directly to save the plan to the task.`,
|
|
3031
|
-
`- After saving the plan,
|
|
3087
|
+
`- After saving the plan, call post_to_chat with a short summary for the team (your turn output is NOT posted to chat \u2014 they only see what you post), then end your turn. Do NOT attempt to execute the plan yourself.`,
|
|
3032
3088
|
`- A separate task agent will handle execution after the team reviews and approves your plan.`
|
|
3033
3089
|
];
|
|
3034
3090
|
if (context.isParentTask) {
|
|
@@ -3160,10 +3216,12 @@ ${config.instructions}`);
|
|
|
3160
3216
|
}
|
|
3161
3217
|
parts.push(
|
|
3162
3218
|
`
|
|
3163
|
-
Your
|
|
3164
|
-
`
|
|
3165
|
-
`
|
|
3166
|
-
`Use read_task_chat only if you need to re-read earlier messages beyond the chat context above
|
|
3219
|
+
Your turn output appears ONLY in the live agent terminal \u2014 it is NOT posted to the task chat. The team does NOT see your replies unless you post them.`,
|
|
3220
|
+
`Use post_to_chat (omit task_id \u2192 your own task's chat) to share meaningful status as you work, a summary when you finish, and any blocker or question you need a human to answer.`,
|
|
3221
|
+
`Pass task_id only to message a DIFFERENT task's chat (e.g. a parent task via get_task).`,
|
|
3222
|
+
`Use read_task_chat only if you need to re-read earlier messages beyond the chat context above.`,
|
|
3223
|
+
`
|
|
3224
|
+
If a Conveyor tool call fails or reports the MCP server is unavailable/disconnected, this is almost always a transient socket reconnect \u2014 simply RETRY the same call and it will succeed once the connection re-establishes. Do NOT stop work, go idle, or treat a tool error as a reason to end your turn. Keep making progress on the code; only post_to_chat to ask for a human if a tool keeps failing across several retries over a sustained period.`
|
|
3167
3225
|
);
|
|
3168
3226
|
if (!isPm || isPmActive) {
|
|
3169
3227
|
parts.push(
|
|
@@ -3302,7 +3360,7 @@ Address the requested changes. Do NOT re-investigate the codebase from scratch o
|
|
|
3302
3360
|
);
|
|
3303
3361
|
} else {
|
|
3304
3362
|
parts.push(
|
|
3305
|
-
`
|
|
3363
|
+
`Post a brief status update with post_to_chat (your turn output is NOT shown in chat \u2014 post_to_chat is how the team sees it), then wait for further instructions.`
|
|
3306
3364
|
);
|
|
3307
3365
|
}
|
|
3308
3366
|
if (context.githubPRUrl) {
|
|
@@ -3411,7 +3469,7 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
|
|
|
3411
3469
|
`Review existing subtasks via \`list_subtasks\` and the chat history before taking action.`,
|
|
3412
3470
|
`Read the task description and chat history carefully \u2014 the team has provided the initial context below. Acknowledge what they've asked for and respond in chat before taking silent tool actions.`,
|
|
3413
3471
|
`Start planning now \u2014 explore the codebase, ask clarifying questions if needed, and propose a subtask breakdown. Do not wait for additional team input before engaging.`,
|
|
3414
|
-
`When you finish planning, save the plan with update_task_plan
|
|
3472
|
+
`When you finish planning, save the plan with update_task_plan, post a short summary for the team with post_to_chat (your turn output is NOT shown in chat), then end your turn.`
|
|
3415
3473
|
];
|
|
3416
3474
|
}
|
|
3417
3475
|
if (isPm) {
|
|
@@ -3419,14 +3477,14 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
|
|
|
3419
3477
|
`You are the project manager for this task.`,
|
|
3420
3478
|
`Read the task description and chat history carefully \u2014 the team has provided the initial context below. Acknowledge what they've asked for and respond in chat before taking silent tool actions.`,
|
|
3421
3479
|
`Start planning now \u2014 explore the codebase, ask clarifying questions if needed, and draft a plan. Do not wait for additional team input before engaging; the initial message IS the team engaging.`,
|
|
3422
|
-
`When you finish planning, save the plan with update_task_plan
|
|
3480
|
+
`When you finish planning, save the plan with update_task_plan, post a summary of the plan for the team with post_to_chat (your turn output is NOT shown in chat), then end your turn. A separate task agent will execute the plan after review.`
|
|
3423
3481
|
];
|
|
3424
3482
|
}
|
|
3425
3483
|
const parts = [
|
|
3426
3484
|
`Begin executing the task plan above immediately.`,
|
|
3427
3485
|
`Your FIRST action should be reading the relevant source files mentioned in the plan, then writing code. Do NOT run install, build, lint, test, or dev server commands first \u2014 the environment is already set up.`,
|
|
3428
3486
|
`Work on the git branch "${context.githubBranch}". Stay on this branch for the entire task. Do not checkout or create other branches.`,
|
|
3429
|
-
`
|
|
3487
|
+
`Use post_to_chat to keep the team informed (your turn output is NOT shown in chat \u2014 post_to_chat is the only way they see it): briefly post what you're doing when you begin meaningful implementation, and again when the PR is ready.`,
|
|
3430
3488
|
`Before opening the PR, run the quality gates: \`bun run lint && bun run typecheck && bun run test\`. Fix any failures. Do NOT open a PR with known failing gates \u2014 scope the test run to affected packages if the full suite is prohibitively slow, and state the scope in the PR body.`,
|
|
3431
3489
|
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`
|
|
3432
3490
|
];
|
|
@@ -3533,7 +3591,7 @@ function buildIdleRelaunchInstructions(context, isPm, agentMode, isAuto) {
|
|
|
3533
3591
|
);
|
|
3534
3592
|
} else {
|
|
3535
3593
|
parts.push(
|
|
3536
|
-
`
|
|
3594
|
+
`Post a brief status update summarizing where things stand with post_to_chat (your turn output is NOT shown in chat \u2014 post_to_chat is how the team sees it).`,
|
|
3537
3595
|
`Then wait for further instructions \u2014 do NOT redo work that was already completed.`
|
|
3538
3596
|
);
|
|
3539
3597
|
}
|
|
@@ -3805,7 +3863,7 @@ import { z as z6 } from "zod";
|
|
|
3805
3863
|
function buildPostToChatTool(connection) {
|
|
3806
3864
|
return defineTool(
|
|
3807
3865
|
"post_to_chat",
|
|
3808
|
-
"Post
|
|
3866
|
+
"Post a message to the task chat for the team to see. Your turn output is NOT shown in chat, so this is the only way the team sees your status, summaries, and questions. Omit task_id to post to the current task's chat; pass a child's ID to message its chat.",
|
|
3809
3867
|
{
|
|
3810
3868
|
message: z6.string().describe("The message to post to the team"),
|
|
3811
3869
|
task_id: z6.string().optional().describe("Child task ID to post to. Omit to post to the current task's chat.")
|
|
@@ -7063,6 +7121,18 @@ function latestUserMessageText(context) {
|
|
|
7063
7121
|
}
|
|
7064
7122
|
return null;
|
|
7065
7123
|
}
|
|
7124
|
+
function selectInitialPromptInput(promptDelivery, initialPrompt, context, baseAppendSystemPrompt) {
|
|
7125
|
+
if (promptDelivery === "prefill") {
|
|
7126
|
+
return {
|
|
7127
|
+
prompt: latestUserMessageText(context) ?? "",
|
|
7128
|
+
appendSystemPrompt: [baseAppendSystemPrompt, initialPrompt].filter(Boolean).join("\n\n").slice(0, APPEND_SYSTEM_PROMPT_MAX_CHARS)
|
|
7129
|
+
};
|
|
7130
|
+
}
|
|
7131
|
+
return {
|
|
7132
|
+
prompt: buildMultimodalPrompt(initialPrompt, context),
|
|
7133
|
+
appendSystemPrompt: baseAppendSystemPrompt
|
|
7134
|
+
};
|
|
7135
|
+
}
|
|
7066
7136
|
async function runInitialQuery(host, context, options, resume, promptDelivery) {
|
|
7067
7137
|
const initialPrompt = await buildInitialPrompt(
|
|
7068
7138
|
host.config.mode,
|
|
@@ -7070,15 +7140,13 @@ async function runInitialQuery(host, context, options, resume, promptDelivery) {
|
|
|
7070
7140
|
host.isAuto,
|
|
7071
7141
|
host.agentMode
|
|
7072
7142
|
);
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
prompt = buildMultimodalPrompt(initialPrompt, context);
|
|
7081
|
-
}
|
|
7143
|
+
const { prompt, appendSystemPrompt } = selectInitialPromptInput(
|
|
7144
|
+
promptDelivery,
|
|
7145
|
+
initialPrompt,
|
|
7146
|
+
context,
|
|
7147
|
+
options.appendSystemPrompt
|
|
7148
|
+
);
|
|
7149
|
+
const queryOptions = { ...options, appendSystemPrompt };
|
|
7082
7150
|
let agentQuery = host.harness.executeQuery({
|
|
7083
7151
|
prompt: host.createInputStream(prompt),
|
|
7084
7152
|
options: queryOptions,
|
|
@@ -8078,6 +8146,7 @@ var SessionRunner = class _SessionRunner {
|
|
|
8078
8146
|
if (msg.delivery !== "prefill") return false;
|
|
8079
8147
|
if (this.pendingMessages.length > 0) return false;
|
|
8080
8148
|
if (this.queryBridge?.harnessKind !== "pty") return false;
|
|
8149
|
+
if (this.mode.isAuto) return false;
|
|
8081
8150
|
if (msg.source && msg.source !== "mode_change" && msg.source !== "user") return false;
|
|
8082
8151
|
const m = this.mode.effectiveMode;
|
|
8083
8152
|
return m === "discovery" || m === "review" || m === "help";
|
|
@@ -9599,7 +9668,7 @@ function buildPostToChatTool2(connection, getRequestingUserId) {
|
|
|
9599
9668
|
const projectId = connection.projectId;
|
|
9600
9669
|
return defineTool(
|
|
9601
9670
|
"post_to_chat",
|
|
9602
|
-
"Post
|
|
9671
|
+
"Post a message into a chat for the team to see. Your turn output is NOT shown in chat, so this is the only way the team sees your status, summaries, and questions. Omit task_id to post into the project chat; pass task_id to post into a specific task's chat.",
|
|
9603
9672
|
{
|
|
9604
9673
|
message: z17.string().describe("The message content to post"),
|
|
9605
9674
|
task_id: z17.string().optional().describe("Task ID to post into a specific task's chat. Omit for the project chat.")
|
|
@@ -10802,4 +10871,4 @@ export {
|
|
|
10802
10871
|
loadConveyorConfig,
|
|
10803
10872
|
unshallowRepo
|
|
10804
10873
|
};
|
|
10805
|
-
//# sourceMappingURL=chunk-
|
|
10874
|
+
//# sourceMappingURL=chunk-L7Q2JZJX.js.map
|