@rallycry/conveyor-agent 5.2.0 → 5.3.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-R37YJZWE.js → chunk-DMWUXQ4M.js} +126 -145
- package/dist/chunk-DMWUXQ4M.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-R37YJZWE.js.map +0 -1
|
@@ -752,7 +752,7 @@ function aggregateModelUsage(modelUsage) {
|
|
|
752
752
|
}
|
|
753
753
|
return { queryInputTokens, contextWindow, totalInputTokens, totalCacheRead, totalCacheCreation };
|
|
754
754
|
}
|
|
755
|
-
function emitContextUpdate(modelUsage, host, context) {
|
|
755
|
+
function emitContextUpdate(modelUsage, host, context, lastAssistantUsage) {
|
|
756
756
|
const usage = aggregateModelUsage(modelUsage);
|
|
757
757
|
let { contextWindow } = usage;
|
|
758
758
|
const settings = context.agentSettings ?? host.config.agentSettings ?? {};
|
|
@@ -761,13 +761,15 @@ function emitContextUpdate(modelUsage, host, context) {
|
|
|
761
761
|
contextWindow = 1e6;
|
|
762
762
|
}
|
|
763
763
|
if (contextWindow > 0) {
|
|
764
|
+
const currentContextTokens = lastAssistantUsage ? (lastAssistantUsage.input_tokens ?? 0) + (lastAssistantUsage.cache_read_input_tokens ?? 0) + (lastAssistantUsage.cache_creation_input_tokens ?? 0) : usage.queryInputTokens;
|
|
764
765
|
host.connection.sendEvent({
|
|
765
766
|
type: "context_update",
|
|
766
|
-
contextTokens:
|
|
767
|
+
contextTokens: currentContextTokens,
|
|
767
768
|
contextWindow,
|
|
768
769
|
inputTokens: usage.totalInputTokens,
|
|
769
770
|
cacheReadInputTokens: usage.totalCacheRead,
|
|
770
|
-
cacheCreationInputTokens: usage.totalCacheCreation
|
|
771
|
+
cacheCreationInputTokens: usage.totalCacheCreation,
|
|
772
|
+
totalTokensUsed: usage.queryInputTokens
|
|
771
773
|
});
|
|
772
774
|
}
|
|
773
775
|
}
|
|
@@ -783,7 +785,7 @@ function trackCostSpending(host, context, cumulativeTotal) {
|
|
|
783
785
|
});
|
|
784
786
|
}
|
|
785
787
|
}
|
|
786
|
-
function handleSuccessResult(event, host, context, startTime) {
|
|
788
|
+
function handleSuccessResult(event, host, context, startTime, lastAssistantUsage) {
|
|
787
789
|
const durationMs = Date.now() - startTime;
|
|
788
790
|
const summary = event.result || "Task completed.";
|
|
789
791
|
const retriable = isRetriableMessage(summary);
|
|
@@ -794,28 +796,38 @@ function handleSuccessResult(event, host, context, startTime) {
|
|
|
794
796
|
}
|
|
795
797
|
host.connection.sendEvent({ type: "completed", summary, costUsd: cumulativeTotal, durationMs });
|
|
796
798
|
if (modelUsage && typeof modelUsage === "object") {
|
|
797
|
-
emitContextUpdate(modelUsage, host, context);
|
|
799
|
+
emitContextUpdate(modelUsage, host, context, lastAssistantUsage);
|
|
798
800
|
}
|
|
799
801
|
trackCostSpending(host, context, cumulativeTotal);
|
|
800
802
|
return { totalCostUsd: cumulativeTotal, retriable };
|
|
801
803
|
}
|
|
802
804
|
function handleErrorResult(event, host) {
|
|
803
805
|
const errorMsg = event.errors.length > 0 ? event.errors.join(", ") : `Agent stopped: ${event.subtype}`;
|
|
806
|
+
const isStaleSession = errorMsg.includes("No conversation found with session ID");
|
|
807
|
+
if (isStaleSession) {
|
|
808
|
+
return { retriable: false, staleSession: true };
|
|
809
|
+
}
|
|
804
810
|
const retriable = isRetriableMessage(errorMsg);
|
|
805
811
|
host.connection.sendEvent({ type: "error", message: errorMsg });
|
|
806
812
|
return { retriable };
|
|
807
813
|
}
|
|
808
|
-
function handleResultEvent(event, host, context, startTime) {
|
|
814
|
+
function handleResultEvent(event, host, context, startTime, lastAssistantUsage) {
|
|
809
815
|
const resultSummary = event.subtype === "success" ? event.result : event.errors.join(", ");
|
|
810
816
|
if (event.subtype === "success") {
|
|
811
|
-
const result2 = handleSuccessResult(
|
|
817
|
+
const result2 = handleSuccessResult(
|
|
818
|
+
event,
|
|
819
|
+
host,
|
|
820
|
+
context,
|
|
821
|
+
startTime,
|
|
822
|
+
lastAssistantUsage
|
|
823
|
+
);
|
|
812
824
|
return { ...result2, resultSummary };
|
|
813
825
|
}
|
|
814
826
|
const result = handleErrorResult(event, host);
|
|
815
827
|
return { totalCostUsd: 0, ...result, resultSummary };
|
|
816
828
|
}
|
|
817
|
-
async function emitResultEvent(event, host, context, startTime) {
|
|
818
|
-
const result = handleResultEvent(event, host, context, startTime);
|
|
829
|
+
async function emitResultEvent(event, host, context, startTime, lastAssistantUsage) {
|
|
830
|
+
const result = handleResultEvent(event, host, context, startTime, lastAssistantUsage);
|
|
819
831
|
const durationMs = Date.now() - startTime;
|
|
820
832
|
if (event.subtype === "success") {
|
|
821
833
|
const successEvent = event;
|
|
@@ -826,12 +838,16 @@ async function emitResultEvent(event, host, context, startTime) {
|
|
|
826
838
|
costUsd: result.totalCostUsd,
|
|
827
839
|
durationMs
|
|
828
840
|
});
|
|
829
|
-
} else {
|
|
841
|
+
} else if (!result.staleSession) {
|
|
830
842
|
const errorEvent = event;
|
|
831
843
|
const errorMsg = errorEvent.errors.length > 0 ? errorEvent.errors.join(", ") : `Agent stopped: ${errorEvent.subtype}`;
|
|
832
844
|
await host.callbacks.onEvent({ type: "error", message: errorMsg });
|
|
833
845
|
}
|
|
834
|
-
return {
|
|
846
|
+
return {
|
|
847
|
+
retriable: result.retriable,
|
|
848
|
+
resultSummary: result.resultSummary,
|
|
849
|
+
staleSession: result.staleSession
|
|
850
|
+
};
|
|
835
851
|
}
|
|
836
852
|
function handleRateLimitEvent(event, host) {
|
|
837
853
|
const { rate_limit_info } = event;
|
|
@@ -878,6 +894,8 @@ async function processEvents(events, context, host) {
|
|
|
878
894
|
let retriable = false;
|
|
879
895
|
let resultSummary;
|
|
880
896
|
let rateLimitResetsAt;
|
|
897
|
+
let staleSession;
|
|
898
|
+
let lastAssistantUsage;
|
|
881
899
|
const turnToolCalls = [];
|
|
882
900
|
for await (const event of events) {
|
|
883
901
|
if (host.isStopped()) break;
|
|
@@ -899,7 +917,12 @@ async function processEvents(events, context, host) {
|
|
|
899
917
|
setTimeout(() => host.connection.sendTypingStart(), 200);
|
|
900
918
|
isTyping = true;
|
|
901
919
|
}
|
|
902
|
-
|
|
920
|
+
const assistantEvent = event;
|
|
921
|
+
await processAssistantEvent(assistantEvent, host, turnToolCalls);
|
|
922
|
+
const msgUsage = assistantEvent.message.usage;
|
|
923
|
+
if (msgUsage) {
|
|
924
|
+
lastAssistantUsage = msgUsage;
|
|
925
|
+
}
|
|
903
926
|
break;
|
|
904
927
|
}
|
|
905
928
|
case "result": {
|
|
@@ -911,10 +934,14 @@ async function processEvents(events, context, host) {
|
|
|
911
934
|
event,
|
|
912
935
|
host,
|
|
913
936
|
context,
|
|
914
|
-
startTime
|
|
937
|
+
startTime,
|
|
938
|
+
lastAssistantUsage
|
|
915
939
|
);
|
|
916
940
|
retriable = resultInfo.retriable;
|
|
917
941
|
resultSummary = resultInfo.resultSummary;
|
|
942
|
+
if (resultInfo.staleSession) {
|
|
943
|
+
staleSession = true;
|
|
944
|
+
}
|
|
918
945
|
break;
|
|
919
946
|
}
|
|
920
947
|
case "rate_limit_event": {
|
|
@@ -927,7 +954,12 @@ async function processEvents(events, context, host) {
|
|
|
927
954
|
if (isTyping) {
|
|
928
955
|
host.connection.sendTypingStop();
|
|
929
956
|
}
|
|
930
|
-
return {
|
|
957
|
+
return {
|
|
958
|
+
retriable,
|
|
959
|
+
resultSummary,
|
|
960
|
+
rateLimitResetsAt,
|
|
961
|
+
...staleSession && { staleSession }
|
|
962
|
+
};
|
|
931
963
|
}
|
|
932
964
|
|
|
933
965
|
// src/execution/query-executor.ts
|
|
@@ -1323,7 +1355,7 @@ Your responses are sent directly to the task chat \u2014 the team sees everythin
|
|
|
1323
1355
|
);
|
|
1324
1356
|
if (!isPm || isPmActive) {
|
|
1325
1357
|
parts.push(
|
|
1326
|
-
`Use the
|
|
1358
|
+
`Use the mcp__conveyor__create_pull_request tool to open PRs \u2014 do NOT use gh CLI or shell commands for PR creation.`
|
|
1327
1359
|
);
|
|
1328
1360
|
}
|
|
1329
1361
|
const modePrompt = buildModePrompt(agentMode, context);
|
|
@@ -1394,7 +1426,7 @@ Address the requested changes. Do NOT re-investigate the codebase from scratch o
|
|
|
1394
1426
|
);
|
|
1395
1427
|
} else {
|
|
1396
1428
|
parts.push(
|
|
1397
|
-
`When finished, use the
|
|
1429
|
+
`When finished, use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`
|
|
1398
1430
|
);
|
|
1399
1431
|
}
|
|
1400
1432
|
} else {
|
|
@@ -1501,12 +1533,12 @@ function buildFreshInstructions(isPm, isAutoMode, context, agentMode) {
|
|
|
1501
1533
|
`Your plan has been approved. Begin implementing it now.`,
|
|
1502
1534
|
`Work on the git branch "${context.githubBranch}". Stay on this branch \u2014 do not checkout or create other branches.`,
|
|
1503
1535
|
`Start by reading the relevant source files mentioned in the plan, then write code.`,
|
|
1504
|
-
`When finished, commit and push your changes, then use the
|
|
1536
|
+
`When finished, commit and push your changes, then use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI.`,
|
|
1505
1537
|
`
|
|
1506
1538
|
CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
|
|
1507
1539
|
`Your FIRST action must be reading source files from the plan, then immediately writing code.`,
|
|
1508
1540
|
`Do NOT summarize the plan or say "ready to implement" \u2014 start implementing.`,
|
|
1509
|
-
`When all changes are committed and pushed, use
|
|
1541
|
+
`When all changes are committed and pushed, use mcp__conveyor__create_pull_request to open a PR.`,
|
|
1510
1542
|
`If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
|
|
1511
1543
|
];
|
|
1512
1544
|
}
|
|
@@ -1540,14 +1572,14 @@ CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or g
|
|
|
1540
1572
|
`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.`,
|
|
1541
1573
|
`Work on the git branch "${context.githubBranch}". Stay on this branch for the entire task. Do not checkout or create other branches.`,
|
|
1542
1574
|
`Your replies are visible to the team in chat \u2014 briefly describe what you're doing when you begin meaningful implementation, and again when the PR is ready.`,
|
|
1543
|
-
`When finished, commit your changes, then run \`git fetch origin ${context.githubBranch}\` and \`git push origin ${context.githubBranch}\` (use --force-with-lease if push fails). Then use the
|
|
1575
|
+
`When finished, commit your changes, then run \`git fetch origin ${context.githubBranch}\` and \`git push origin ${context.githubBranch}\` (use --force-with-lease if push fails). Then use the mcp__conveyor__create_pull_request tool to open a PR. Do NOT use gh CLI or any other method to create PRs.`
|
|
1544
1576
|
];
|
|
1545
1577
|
if (isAutoMode) {
|
|
1546
1578
|
parts.push(
|
|
1547
1579
|
`
|
|
1548
1580
|
CRITICAL: You are in Auto mode. Do NOT report status, ask for confirmation, or go idle without making code changes.`,
|
|
1549
1581
|
`Do NOT summarize the plan or say "ready to implement" \u2014 start implementing immediately.`,
|
|
1550
|
-
`When all changes are committed and pushed, you MUST use
|
|
1582
|
+
`When all changes are committed and pushed, you MUST use mcp__conveyor__create_pull_request to open a PR before finishing.`,
|
|
1551
1583
|
`If you are genuinely blocked, explain the specific blocker \u2014 do not go idle silently.`
|
|
1552
1584
|
);
|
|
1553
1585
|
}
|
|
@@ -1584,7 +1616,7 @@ Address the requested changes directly. Do NOT re-investigate the codebase from
|
|
|
1584
1616
|
);
|
|
1585
1617
|
} else {
|
|
1586
1618
|
parts.push(
|
|
1587
|
-
`When finished, use the
|
|
1619
|
+
`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.`
|
|
1588
1620
|
);
|
|
1589
1621
|
}
|
|
1590
1622
|
return parts;
|
|
@@ -1896,6 +1928,30 @@ function buildGetTaskIncidentsTool(connection) {
|
|
|
1896
1928
|
{ annotations: { readOnlyHint: true } }
|
|
1897
1929
|
);
|
|
1898
1930
|
}
|
|
1931
|
+
function buildCreatePullRequestTool(connection) {
|
|
1932
|
+
return tool(
|
|
1933
|
+
"create_pull_request",
|
|
1934
|
+
"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.",
|
|
1935
|
+
{
|
|
1936
|
+
title: z.string().describe("The PR title"),
|
|
1937
|
+
body: z.string().describe("The PR description/body in markdown")
|
|
1938
|
+
},
|
|
1939
|
+
async ({ title, body }) => {
|
|
1940
|
+
try {
|
|
1941
|
+
const result = await connection.createPR({ title, body });
|
|
1942
|
+
connection.sendEvent({
|
|
1943
|
+
type: "pr_created",
|
|
1944
|
+
url: result.url,
|
|
1945
|
+
number: result.number
|
|
1946
|
+
});
|
|
1947
|
+
return textResult(`Pull request #${result.number} created: ${result.url}`);
|
|
1948
|
+
} catch (error) {
|
|
1949
|
+
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
1950
|
+
return textResult(`Failed to create pull request: ${msg}`);
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
);
|
|
1954
|
+
}
|
|
1899
1955
|
function buildCommonTools(connection, config) {
|
|
1900
1956
|
return [
|
|
1901
1957
|
buildReadTaskChatTool(connection),
|
|
@@ -1907,7 +1963,8 @@ function buildCommonTools(connection, config) {
|
|
|
1907
1963
|
buildListTaskFilesTool(connection),
|
|
1908
1964
|
buildGetTaskFileTool(connection),
|
|
1909
1965
|
buildSearchIncidentsTool(connection),
|
|
1910
|
-
buildGetTaskIncidentsTool(connection)
|
|
1966
|
+
buildGetTaskIncidentsTool(connection),
|
|
1967
|
+
buildCreatePullRequestTool(connection)
|
|
1911
1968
|
];
|
|
1912
1969
|
}
|
|
1913
1970
|
|
|
@@ -2075,42 +2132,12 @@ function buildPackTools(connection) {
|
|
|
2075
2132
|
];
|
|
2076
2133
|
}
|
|
2077
2134
|
|
|
2078
|
-
// src/tools/
|
|
2135
|
+
// src/tools/discovery-tools.ts
|
|
2079
2136
|
import { tool as tool3 } from "@anthropic-ai/claude-agent-sdk";
|
|
2080
2137
|
import { z as z3 } from "zod";
|
|
2081
|
-
function buildTaskTools(connection) {
|
|
2082
|
-
return [
|
|
2083
|
-
tool3(
|
|
2084
|
-
"create_pull_request",
|
|
2085
|
-
"Create a GitHub pull request for this task. Use this instead of gh CLI or git commands to create PRs.",
|
|
2086
|
-
{
|
|
2087
|
-
title: z3.string().describe("The PR title"),
|
|
2088
|
-
body: z3.string().describe("The PR description/body in markdown")
|
|
2089
|
-
},
|
|
2090
|
-
async ({ title, body }) => {
|
|
2091
|
-
try {
|
|
2092
|
-
const result = await connection.createPR({ title, body });
|
|
2093
|
-
connection.sendEvent({
|
|
2094
|
-
type: "pr_created",
|
|
2095
|
-
url: result.url,
|
|
2096
|
-
number: result.number
|
|
2097
|
-
});
|
|
2098
|
-
return textResult(`Pull request #${result.number} created: ${result.url}`);
|
|
2099
|
-
} catch (error) {
|
|
2100
|
-
const msg = error instanceof Error ? error.message : "Unknown error";
|
|
2101
|
-
return textResult(`Failed to create pull request: ${msg}`);
|
|
2102
|
-
}
|
|
2103
|
-
}
|
|
2104
|
-
)
|
|
2105
|
-
];
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
// src/tools/discovery-tools.ts
|
|
2109
|
-
import { tool as tool4 } from "@anthropic-ai/claude-agent-sdk";
|
|
2110
|
-
import { z as z4 } from "zod";
|
|
2111
2138
|
function buildIconTools(connection) {
|
|
2112
2139
|
return [
|
|
2113
|
-
|
|
2140
|
+
tool3(
|
|
2114
2141
|
"list_icons",
|
|
2115
2142
|
"List available icons (default library + user-created). Returns icon IDs, names, and whether they're defaults. Call this FIRST before set_task_icon to check for existing matches.",
|
|
2116
2143
|
{},
|
|
@@ -2126,11 +2153,11 @@ function buildIconTools(connection) {
|
|
|
2126
2153
|
},
|
|
2127
2154
|
{ annotations: { readOnlyHint: true } }
|
|
2128
2155
|
),
|
|
2129
|
-
|
|
2156
|
+
tool3(
|
|
2130
2157
|
"set_task_icon",
|
|
2131
2158
|
"Assign an existing icon to this task by its ID. Use list_icons first to find a matching icon.",
|
|
2132
2159
|
{
|
|
2133
|
-
iconId:
|
|
2160
|
+
iconId: z3.string().describe("The icon ID to assign")
|
|
2134
2161
|
},
|
|
2135
2162
|
async ({ iconId }) => {
|
|
2136
2163
|
try {
|
|
@@ -2143,14 +2170,14 @@ function buildIconTools(connection) {
|
|
|
2143
2170
|
}
|
|
2144
2171
|
}
|
|
2145
2172
|
),
|
|
2146
|
-
|
|
2173
|
+
tool3(
|
|
2147
2174
|
"generate_task_icon",
|
|
2148
2175
|
"Generate a new SVG icon using AI and assign it to this task. Only use if no existing icon from list_icons is a good fit. Provide a concise visual description.",
|
|
2149
2176
|
{
|
|
2150
|
-
prompt:
|
|
2177
|
+
prompt: z3.string().describe(
|
|
2151
2178
|
"Description of the icon to generate (e.g. 'minimal flat gear and wrench icon')"
|
|
2152
2179
|
),
|
|
2153
|
-
aspectRatio:
|
|
2180
|
+
aspectRatio: z3.enum(["auto", "portrait", "landscape", "square"]).optional().describe("Icon aspect ratio, defaults to square")
|
|
2154
2181
|
},
|
|
2155
2182
|
async ({ prompt, aspectRatio }) => {
|
|
2156
2183
|
try {
|
|
@@ -2168,10 +2195,10 @@ function buildIconTools(connection) {
|
|
|
2168
2195
|
function buildDiscoveryTools(connection, context) {
|
|
2169
2196
|
const spDescription = buildStoryPointDescription(context?.storyPoints);
|
|
2170
2197
|
return [
|
|
2171
|
-
|
|
2198
|
+
tool3(
|
|
2172
2199
|
"set_story_points",
|
|
2173
2200
|
"Set the story point estimate for this task. Use after understanding the scope of the work.",
|
|
2174
|
-
{ value:
|
|
2201
|
+
{ value: z3.number().describe(spDescription) },
|
|
2175
2202
|
async ({ value }) => {
|
|
2176
2203
|
try {
|
|
2177
2204
|
await Promise.resolve(connection.updateTaskProperties({ storyPointValue: value }));
|
|
@@ -2183,11 +2210,11 @@ function buildDiscoveryTools(connection, context) {
|
|
|
2183
2210
|
}
|
|
2184
2211
|
}
|
|
2185
2212
|
),
|
|
2186
|
-
|
|
2213
|
+
tool3(
|
|
2187
2214
|
"set_task_tags",
|
|
2188
2215
|
"Assign tags to this task from the project's available tags. Use the tag IDs from the project tags list.",
|
|
2189
2216
|
{
|
|
2190
|
-
tagIds:
|
|
2217
|
+
tagIds: z3.array(z3.string()).describe("Array of tag IDs to assign")
|
|
2191
2218
|
},
|
|
2192
2219
|
async ({ tagIds }) => {
|
|
2193
2220
|
try {
|
|
@@ -2200,11 +2227,11 @@ function buildDiscoveryTools(connection, context) {
|
|
|
2200
2227
|
}
|
|
2201
2228
|
}
|
|
2202
2229
|
),
|
|
2203
|
-
|
|
2230
|
+
tool3(
|
|
2204
2231
|
"set_task_title",
|
|
2205
2232
|
"Update the task title to better reflect the planned work.",
|
|
2206
2233
|
{
|
|
2207
|
-
title:
|
|
2234
|
+
title: z3.string().describe("The new task title")
|
|
2208
2235
|
},
|
|
2209
2236
|
async ({ title }) => {
|
|
2210
2237
|
try {
|
|
@@ -2231,10 +2258,7 @@ function imageBlock(data, mimeType) {
|
|
|
2231
2258
|
function getModeTools(agentMode, connection, config, context) {
|
|
2232
2259
|
switch (agentMode) {
|
|
2233
2260
|
case "building":
|
|
2234
|
-
return context?.isParentTask ? [
|
|
2235
|
-
...buildTaskTools(connection),
|
|
2236
|
-
...buildPmTools(connection, context?.storyPoints, { includePackTools: true })
|
|
2237
|
-
] : buildTaskTools(connection);
|
|
2261
|
+
return context?.isParentTask ? buildPmTools(connection, context?.storyPoints, { includePackTools: true }) : [];
|
|
2238
2262
|
case "review":
|
|
2239
2263
|
case "auto":
|
|
2240
2264
|
case "discovery":
|
|
@@ -2243,7 +2267,7 @@ function getModeTools(agentMode, connection, config, context) {
|
|
|
2243
2267
|
includePackTools: !!context?.isParentTask
|
|
2244
2268
|
});
|
|
2245
2269
|
default:
|
|
2246
|
-
return config.mode === "pm" ? buildPmTools(connection, context?.storyPoints, { includePackTools: false }) :
|
|
2270
|
+
return config.mode === "pm" ? buildPmTools(connection, context?.storyPoints, { includePackTools: false }) : [];
|
|
2247
2271
|
}
|
|
2248
2272
|
}
|
|
2249
2273
|
function createConveyorMcpServer(connection, config, context, agentMode) {
|
|
@@ -2696,16 +2720,15 @@ async function runWithRetry(initialQuery, context, host, options) {
|
|
|
2696
2720
|
if (host.isStopped()) return;
|
|
2697
2721
|
const agentQuery = attempt === 0 ? initialQuery : buildRetryQuery(host, context, options, lastErrorWasImage);
|
|
2698
2722
|
try {
|
|
2699
|
-
const { retriable, resultSummary, modeRestart, rateLimitResetsAt } = await processEvents(
|
|
2700
|
-
agentQuery,
|
|
2701
|
-
context,
|
|
2702
|
-
host
|
|
2703
|
-
);
|
|
2723
|
+
const { retriable, resultSummary, modeRestart, rateLimitResetsAt, staleSession } = await processEvents(agentQuery, context, host);
|
|
2704
2724
|
if (modeRestart || host.isStopped()) return;
|
|
2705
2725
|
if (rateLimitResetsAt) {
|
|
2706
2726
|
handleRateLimitPause(host, rateLimitResetsAt);
|
|
2707
2727
|
return;
|
|
2708
2728
|
}
|
|
2729
|
+
if (staleSession && context.claudeSessionId) {
|
|
2730
|
+
return handleStaleSession(context, host, options);
|
|
2731
|
+
}
|
|
2709
2732
|
if (!retriable) return;
|
|
2710
2733
|
lastErrorWasImage = IMAGE_ERROR_PATTERN2.test(resultSummary ?? "");
|
|
2711
2734
|
} catch (error) {
|
|
@@ -2925,39 +2948,6 @@ async function runSetupSafe(runnerConfig, connection, callbacks, setupLog, _effe
|
|
|
2925
2948
|
if (!await checkoutTaskBranch(runnerConfig, connection, callbacks, setupLog)) {
|
|
2926
2949
|
return { ok: false, deferredStartConfig: null };
|
|
2927
2950
|
}
|
|
2928
|
-
const taskBranch = process.env.CONVEYOR_TASK_BRANCH;
|
|
2929
|
-
if (taskBranch) {
|
|
2930
|
-
pushSetupLog(setupLog, `[conveyor] Switching to task branch ${taskBranch}...`);
|
|
2931
|
-
connection.sendEvent({
|
|
2932
|
-
type: "setup_output",
|
|
2933
|
-
stream: "stdout",
|
|
2934
|
-
data: `Switching to task branch ${taskBranch}...
|
|
2935
|
-
`
|
|
2936
|
-
});
|
|
2937
|
-
try {
|
|
2938
|
-
await runSetupCommand(
|
|
2939
|
-
`git fetch origin ${taskBranch} && git checkout ${taskBranch}`,
|
|
2940
|
-
runnerConfig.workspaceDir,
|
|
2941
|
-
(stream, data) => {
|
|
2942
|
-
connection.sendEvent({ type: "setup_output", stream, data });
|
|
2943
|
-
for (const line of data.split("\n").filter(Boolean)) {
|
|
2944
|
-
pushSetupLog(setupLog, `[${stream}] ${line}`);
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
);
|
|
2948
|
-
pushSetupLog(setupLog, `[conveyor] Switched to ${taskBranch}`);
|
|
2949
|
-
} catch (error) {
|
|
2950
|
-
const message = `Failed to checkout ${taskBranch}: ${error instanceof Error ? error.message : "unknown error"}`;
|
|
2951
|
-
connection.sendEvent({ type: "setup_error", message });
|
|
2952
|
-
await callbacks.onEvent({ type: "setup_error", message });
|
|
2953
|
-
connection.postChatMessage(
|
|
2954
|
-
`Failed to switch to task branch \`${taskBranch}\`.
|
|
2955
|
-
|
|
2956
|
-
${message}`
|
|
2957
|
-
);
|
|
2958
|
-
return { ok: false, deferredStartConfig: null };
|
|
2959
|
-
}
|
|
2960
|
-
}
|
|
2961
2951
|
const config = await loadConveyorConfig(runnerConfig.workspaceDir);
|
|
2962
2952
|
if (!config) {
|
|
2963
2953
|
connection.sendEvent({ type: "setup_complete" });
|
|
@@ -3295,47 +3285,38 @@ var AgentRunner = class {
|
|
|
3295
3285
|
} catch {
|
|
3296
3286
|
}
|
|
3297
3287
|
}
|
|
3298
|
-
|
|
3288
|
+
needsPRNudge() {
|
|
3299
3289
|
if (!this.config.isAuto || this.stopped) return false;
|
|
3300
3290
|
const maxNudges = this.taskContext?.agentSettings?.maxPrNudges ?? this.config.agentSettings?.maxPrNudges ?? 3;
|
|
3301
3291
|
if (this.prNudgeCount >= maxNudges) return false;
|
|
3292
|
+
const status = this.taskContext?.status;
|
|
3293
|
+
return status === "InProgress" && !this.taskContext?.githubPRUrl;
|
|
3294
|
+
}
|
|
3295
|
+
async maybeSendPRNudge() {
|
|
3302
3296
|
const fresh = await this.connection.fetchTaskContext().catch(() => null);
|
|
3303
3297
|
if (fresh) this.taskContext = fresh;
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
this.stop();
|
|
3315
|
-
return true;
|
|
3316
|
-
}
|
|
3317
|
-
if (this.prNudgeCount === 1) {
|
|
3318
|
-
this.connection.postChatMessage(
|
|
3319
|
-
"Auto-nudge: Task is still In Progress with no PR. Prompting agent to continue..."
|
|
3320
|
-
);
|
|
3321
|
-
await this.setState("running");
|
|
3322
|
-
await this.runQuerySafe(
|
|
3323
|
-
ctx,
|
|
3324
|
-
"You are in Auto mode and your task is still In Progress with no pull request. You MUST create a pull request before finishing. Use the create_pull_request tool now to open a PR for your changes. If you are blocked, explain what is preventing you from creating a PR."
|
|
3325
|
-
);
|
|
3326
|
-
} else {
|
|
3327
|
-
this.connection.postChatMessage(
|
|
3328
|
-
`Auto-nudge (attempt ${this.prNudgeCount}/${maxNudges}): Task still has no PR. Prompting agent again...`
|
|
3329
|
-
);
|
|
3330
|
-
await this.setState("running");
|
|
3331
|
-
await this.runQuerySafe(
|
|
3332
|
-
ctx,
|
|
3333
|
-
`This is reminder ${this.prNudgeCount} of ${maxNudges}. You MUST open a pull request using create_pull_request NOW or explain what is blocking you. Do NOT go idle \u2014 either create the PR or describe the specific blocker.`
|
|
3334
|
-
);
|
|
3335
|
-
}
|
|
3298
|
+
if (!this.needsPRNudge()) return false;
|
|
3299
|
+
this.prNudgeCount++;
|
|
3300
|
+
const ctx = this.taskContext ?? fresh;
|
|
3301
|
+
if (!ctx) return false;
|
|
3302
|
+
const maxNudges = this.taskContext?.agentSettings?.maxPrNudges ?? this.config.agentSettings?.maxPrNudges ?? 3;
|
|
3303
|
+
if (this.prNudgeCount >= maxNudges) {
|
|
3304
|
+
this.connection.postChatMessage(
|
|
3305
|
+
`Auto-mode agent failed to open a PR after ${maxNudges} nudges. Shutting down.`
|
|
3306
|
+
);
|
|
3307
|
+
this.stop();
|
|
3336
3308
|
return true;
|
|
3337
3309
|
}
|
|
3338
|
-
|
|
3310
|
+
await this.sendPRNudgeQuery(ctx, maxNudges);
|
|
3311
|
+
return true;
|
|
3312
|
+
}
|
|
3313
|
+
async sendPRNudgeQuery(ctx, maxNudges) {
|
|
3314
|
+
const isFirst = this.prNudgeCount === 1;
|
|
3315
|
+
const chatMsg = isFirst ? "Auto-nudge: Task is still In Progress with no PR. Prompting agent to continue..." : `Auto-nudge (attempt ${this.prNudgeCount}/${maxNudges}): Task still has no PR. Prompting agent again...`;
|
|
3316
|
+
const prompt = isFirst ? "You are in Auto mode and your task is still In Progress with no pull request. You MUST create a pull request before finishing. Use the create_pull_request tool now to open a PR for your changes. If you are blocked, explain what is preventing you from creating a PR." : `This is reminder ${this.prNudgeCount} of ${maxNudges}. You MUST open a pull request using create_pull_request NOW or explain what is blocking you. Do NOT go idle \u2014 either create the PR or describe the specific blocker.`;
|
|
3317
|
+
this.connection.postChatMessage(chatMsg);
|
|
3318
|
+
await this.setState("running");
|
|
3319
|
+
await this.runQuerySafe(ctx, prompt);
|
|
3339
3320
|
}
|
|
3340
3321
|
async executeInitialMode() {
|
|
3341
3322
|
if (!this.taskContext) return;
|
|
@@ -3838,7 +3819,7 @@ var ProjectRunner = class {
|
|
|
3838
3819
|
projectId: config.projectId
|
|
3839
3820
|
});
|
|
3840
3821
|
}
|
|
3841
|
-
|
|
3822
|
+
checkoutWorkspaceBranch() {
|
|
3842
3823
|
const workspaceBranch = process.env.CONVEYOR_WORKSPACE_BRANCH;
|
|
3843
3824
|
if (!workspaceBranch) return;
|
|
3844
3825
|
try {
|
|
@@ -3853,7 +3834,7 @@ var ProjectRunner = class {
|
|
|
3853
3834
|
}
|
|
3854
3835
|
}
|
|
3855
3836
|
async start() {
|
|
3856
|
-
|
|
3837
|
+
this.checkoutWorkspaceBranch();
|
|
3857
3838
|
await this.connection.connect();
|
|
3858
3839
|
this.connection.onTaskAssignment((assignment) => {
|
|
3859
3840
|
this.handleAssignment(assignment);
|
|
@@ -4068,4 +4049,4 @@ export {
|
|
|
4068
4049
|
ProjectRunner,
|
|
4069
4050
|
FileCache
|
|
4070
4051
|
};
|
|
4071
|
-
//# sourceMappingURL=chunk-
|
|
4052
|
+
//# sourceMappingURL=chunk-DMWUXQ4M.js.map
|