chatroom-cli 1.58.0 → 1.58.1
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 +192 -89
- package/dist/index.js.map +22 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31677,7 +31677,7 @@ function isClassifiableHarnessLogLine(line) {
|
|
|
31677
31677
|
return true;
|
|
31678
31678
|
if (line.includes(" error]"))
|
|
31679
31679
|
return true;
|
|
31680
|
-
if (
|
|
31680
|
+
if (line.includes(" run-error]"))
|
|
31681
31681
|
return true;
|
|
31682
31682
|
return false;
|
|
31683
31683
|
}
|
|
@@ -31716,7 +31716,7 @@ function formatTerminalProviderFailureMessage(logLines) {
|
|
|
31716
31716
|
`).trim();
|
|
31717
31717
|
return blob ? `Provider rate limit or quota error (non-retryable): ${blob.slice(-500)}` : "Provider rate limit or quota error (non-retryable)";
|
|
31718
31718
|
}
|
|
31719
|
-
var QUOTA_PHRASES, PROVIDER_ERROR_NAMES
|
|
31719
|
+
var QUOTA_PHRASES, PROVIDER_ERROR_NAMES;
|
|
31720
31720
|
var init_terminal_provider_error = __esm(() => {
|
|
31721
31721
|
QUOTA_PHRASES = [
|
|
31722
31722
|
"usagelimit",
|
|
@@ -31730,7 +31730,6 @@ var init_terminal_provider_error = __esm(() => {
|
|
|
31730
31730
|
"exceeded your weekly"
|
|
31731
31731
|
];
|
|
31732
31732
|
PROVIDER_ERROR_NAMES = ["ai_apicallerror", "ai_retryerror"];
|
|
31733
|
-
HARNESS_LOG_PREFIX = /^\[[^\]]+\] role:/;
|
|
31734
31733
|
});
|
|
31735
31734
|
|
|
31736
31735
|
// src/infrastructure/services/remote-agents/opencode-sdk/session-event-forwarder.ts
|
|
@@ -75562,6 +75561,12 @@ Put your **complete** deliverable in the handoff message — not in session text
|
|
|
75562
75561
|
---`;
|
|
75563
75562
|
}
|
|
75564
75563
|
|
|
75564
|
+
// ../../services/backend/prompts/utils/code-change-verification.ts
|
|
75565
|
+
var CODE_CHANGE_VERIFICATION_COMMAND = "pnpm typecheck && pnpm test", CODE_CHANGE_VERIFICATION_CONFIRMATION;
|
|
75566
|
+
var init_code_change_verification = __esm(() => {
|
|
75567
|
+
CODE_CHANGE_VERIFICATION_CONFIRMATION = `- [ ] I confirm that I have run \`${CODE_CHANGE_VERIFICATION_COMMAND}\` (only required if code changes were made)`;
|
|
75568
|
+
});
|
|
75569
|
+
|
|
75565
75570
|
// ../../services/backend/prompts/teams/duo/handoff-templates/builder-to-planner.ts
|
|
75566
75571
|
function getBuilderToPlannerHandoffTemplate() {
|
|
75567
75572
|
return `${getHandoffRecipientVisibilityCallout("planner")}
|
|
@@ -75586,8 +75591,8 @@ function getBuilderToPlannerHandoffTemplate() {
|
|
|
75586
75591
|
- \`path/to/file.ts\` — <what changed and why>
|
|
75587
75592
|
<evidence the goal was met — list every file you modified>
|
|
75588
75593
|
|
|
75589
|
-
## Verification
|
|
75590
|
-
|
|
75594
|
+
## Code Change Verification
|
|
75595
|
+
${CODE_CHANGE_VERIFICATION_CONFIRMATION}
|
|
75591
75596
|
|
|
75592
75597
|
## Blockers / questions
|
|
75593
75598
|
<anything needing planner decision, or "Not Applicable">
|
|
@@ -75596,18 +75601,18 @@ function getBuilderToPlannerHandoffTemplate() {
|
|
|
75596
75601
|
<specific areas for planner to check, or "Not Applicable">
|
|
75597
75602
|
\`\`\``;
|
|
75598
75603
|
}
|
|
75599
|
-
var init_builder_to_planner = () => {
|
|
75604
|
+
var init_builder_to_planner = __esm(() => {
|
|
75605
|
+
init_code_change_verification();
|
|
75606
|
+
});
|
|
75600
75607
|
|
|
75601
75608
|
// ../../services/backend/prompts/teams/duo/handoff-templates/planner-to-builder.ts
|
|
75602
75609
|
function getPlannerToBuilderHandoffTemplate(nativeIntegration = false) {
|
|
75603
|
-
const sessionManagement = nativeIntegration ?
|
|
75604
|
-
|
|
75605
|
-
**CLI harnesses** (all others): in-session compaction is NOT supported. \`new_session\` requires a hard restart — the daemon stops the agent, cold-starts it, and the agent must rejoin via \`get-next-task\`. \`none\` resumes the prior session (\`wantResume=true\`).`;
|
|
75610
|
+
const sessionManagement = nativeIntegration ? `\`compact\` runs in-session context compaction via the SDK runtime. \`new_session\` starts a completely new session within the same process (not compaction). \`none\` continues the prior session. Tasks continue via injection.` : `\`compact\` is NOT supported — use \`none\` or \`new_session\`. \`new_session\` requires a hard restart (daemon stops agent, cold-starts, agent rejoins via \`get-next-task\`). \`none\` resumes prior session (\`wantResume=true\`).`;
|
|
75606
75611
|
return `${getHandoffRecipientVisibilityCallout("builder")}
|
|
75607
75612
|
|
|
75608
75613
|
**Delegation Brief (Planner → Builder)** — paste into the handoff message and fill in EVERY field. No field is optional: if a section does not apply, write \`Not Applicable\` (do not delete the section).
|
|
75609
75614
|
|
|
75610
|
-
**Division of labor:** You (planner) own architecture and API shape. The builder implements exactly what you specify
|
|
75615
|
+
**Division of labor:** You (planner) own architecture and API shape. The builder implements exactly what you specify and does not redesign or invent alternatives unless blocked.
|
|
75611
75616
|
|
|
75612
75617
|
**Detail bar:** Specify down to **every file** the builder will create or modify (full repo paths). Include code snippets — types, signatures, stubs, or target implementations — until a competent builder **cannot misinterpret** what to write. Vague layers ("update the backend", "fix the component") are not acceptable.
|
|
75613
75618
|
|
|
@@ -75659,7 +75664,6 @@ Cross-file types, interfaces, or patterns that apply beyond a single file. Write
|
|
|
75659
75664
|
|
|
75660
75665
|
## Requirements (acceptance criteria)
|
|
75661
75666
|
- <verifiable outcome the builder can self-check>
|
|
75662
|
-
- Verify: \`pnpm typecheck && pnpm test\`
|
|
75663
75667
|
|
|
75664
75668
|
## What to avoid
|
|
75665
75669
|
- <anti-patterns, recurring mistakes, or scope creep for this slice — be explicit>
|
|
@@ -75671,11 +75675,12 @@ Cross-file types, interfaces, or patterns that apply beyond a single file. Write
|
|
|
75671
75675
|
## Out of scope
|
|
75672
75676
|
- <files or areas the builder must NOT touch in this slice, or "Not Applicable">
|
|
75673
75677
|
|
|
75674
|
-
## Session
|
|
75675
|
-
Valid values: \`
|
|
75676
|
-
- \`new_session\` — start a fresh agent session (default)
|
|
75678
|
+
## Session Augmentation
|
|
75679
|
+
Valid values: \`none\` | \`compact\` | \`new_session\`
|
|
75677
75680
|
- \`none\` — continue prior session context
|
|
75678
|
-
|
|
75681
|
+
- \`compact\` — run in-session context compaction (native SDK harnesses only)
|
|
75682
|
+
- \`new_session\` — start a completely new session (default)
|
|
75683
|
+
// data:agent.session_augmentation=new_session
|
|
75679
75684
|
|
|
75680
75685
|
${sessionManagement}
|
|
75681
75686
|
|
|
@@ -75733,14 +75738,16 @@ flowchart TD
|
|
|
75733
75738
|
A[Component] --> B[Component]
|
|
75734
75739
|
\`\`\`
|
|
75735
75740
|
|
|
75736
|
-
## Verification
|
|
75737
|
-
|
|
75741
|
+
## Code Change Verification
|
|
75742
|
+
${CODE_CHANGE_VERIFICATION_CONFIRMATION}
|
|
75738
75743
|
|
|
75739
75744
|
## Notes / Next steps
|
|
75740
75745
|
<anything the user should know, follow-ups, or open questions, or "Not Applicable">
|
|
75741
75746
|
\`\`\``;
|
|
75742
75747
|
}
|
|
75743
|
-
var init_planner_to_user = () => {
|
|
75748
|
+
var init_planner_to_user = __esm(() => {
|
|
75749
|
+
init_code_change_verification();
|
|
75750
|
+
});
|
|
75744
75751
|
|
|
75745
75752
|
// ../../services/backend/prompts/teams/duo/handoff-templates/index.ts
|
|
75746
75753
|
function getDuoHandoffTemplate(query) {
|
|
@@ -75790,9 +75797,6 @@ flowchart TD
|
|
|
75790
75797
|
A[Component] --> B[Component]
|
|
75791
75798
|
\`\`\`
|
|
75792
75799
|
|
|
75793
|
-
## Verification
|
|
75794
|
-
- \`pnpm typecheck && pnpm test\` — <result>
|
|
75795
|
-
|
|
75796
75800
|
## Notes / Next steps
|
|
75797
75801
|
<anything the user should know, follow-ups, or open questions, or "Not Applicable">
|
|
75798
75802
|
\`\`\``;
|
|
@@ -85789,6 +85793,9 @@ function isInjectableNativeAction(action) {
|
|
|
85789
85793
|
return true;
|
|
85790
85794
|
return action === NATIVE_WAITING_ACTION;
|
|
85791
85795
|
}
|
|
85796
|
+
function shouldEmitNativeWaitingOnTurnEnd(lastStatus) {
|
|
85797
|
+
return lastStatus !== "task.acknowledged" && lastStatus !== "task.inProgress";
|
|
85798
|
+
}
|
|
85792
85799
|
function isNativeIdleAfterTaskComplete(participant) {
|
|
85793
85800
|
return participant.lastSeenAction === NATIVE_TASK_INJECTED_ACTION && participant.lastStatus === "task.completed";
|
|
85794
85801
|
}
|
|
@@ -85858,13 +85865,21 @@ function shouldDeliverNativeTask(task, opts) {
|
|
|
85858
85865
|
return isInjectableNativeAction(task.participant?.lastSeenAction) || isNativeIdleAfterTaskComplete(task.participant ?? {}) || isNativeAcknowledgedInjectionRetry(task);
|
|
85859
85866
|
}
|
|
85860
85867
|
function buildNativeInjectionPrompt(params) {
|
|
85861
|
-
const { taskDeliveryOutput,
|
|
85862
|
-
if (
|
|
85868
|
+
const { taskDeliveryOutput, augmentationMode } = params;
|
|
85869
|
+
if (augmentationMode === "compact") {
|
|
85863
85870
|
return [
|
|
85864
85871
|
"⚠️ Context was compacted. Run `chatroom get-system-prompt` only if role instructions are missing.",
|
|
85865
85872
|
"",
|
|
85866
85873
|
taskDeliveryOutput
|
|
85867
85874
|
].join(`
|
|
85875
|
+
`);
|
|
85876
|
+
}
|
|
85877
|
+
if (augmentationMode === "new_session") {
|
|
85878
|
+
return [
|
|
85879
|
+
"⚠️ Starting a new agent session. Run `chatroom get-system-prompt` to reload role instructions if needed.",
|
|
85880
|
+
"",
|
|
85881
|
+
taskDeliveryOutput
|
|
85882
|
+
].join(`
|
|
85868
85883
|
`);
|
|
85869
85884
|
}
|
|
85870
85885
|
return taskDeliveryOutput;
|
|
@@ -85874,18 +85889,23 @@ var init_native_task_injector_logic = __esm(() => {
|
|
|
85874
85889
|
init_native_integration();
|
|
85875
85890
|
});
|
|
85876
85891
|
|
|
85877
|
-
// ../../services/backend/src/domain/
|
|
85892
|
+
// ../../services/backend/src/domain/entities/team-agent-settings.ts
|
|
85893
|
+
function roleSupportsSessionAugmentation(role) {
|
|
85894
|
+
const normalized = role.toLowerCase();
|
|
85895
|
+
return SESSION_AUGMENTATION_ROLES.some((r) => r === normalized);
|
|
85896
|
+
}
|
|
85897
|
+
var SESSION_AUGMENTATION_ROLES;
|
|
85898
|
+
var init_team_agent_settings = __esm(() => {
|
|
85899
|
+
SESSION_AUGMENTATION_ROLES = ["builder"];
|
|
85900
|
+
});
|
|
85901
|
+
|
|
85902
|
+
// ../../services/backend/src/domain/handoff/parse-session-augmentation.ts
|
|
85878
85903
|
function findSectionIndex(content, headings) {
|
|
85879
85904
|
const indices = headings.map((heading) => content.indexOf(heading)).filter((idx) => idx !== -1);
|
|
85880
85905
|
return indices.length === 0 ? -1 : Math.min(...indices);
|
|
85881
85906
|
}
|
|
85882
85907
|
function normalizeMode(raw) {
|
|
85883
|
-
|
|
85884
|
-
if (value === "reset")
|
|
85885
|
-
return "new_session";
|
|
85886
|
-
if (value === "none")
|
|
85887
|
-
return value;
|
|
85888
|
-
return DEFAULT_MODE;
|
|
85908
|
+
return MODE_ALIASES[raw.toLowerCase()] ?? DEFAULT_MODE;
|
|
85889
85909
|
}
|
|
85890
85910
|
function extractSectionBody(content, sectionIdx) {
|
|
85891
85911
|
const matchedHeading = SECTION_HEADINGS.find((h) => content.indexOf(h, sectionIdx) === sectionIdx) ?? SECTION_HEADINGS[0];
|
|
@@ -85893,7 +85913,7 @@ function extractSectionBody(content, sectionIdx) {
|
|
|
85893
85913
|
const nextHeading = afterSection.slice(matchedHeading.length).search(/\n## /);
|
|
85894
85914
|
return nextHeading === -1 ? afterSection : afterSection.slice(0, matchedHeading.length + nextHeading);
|
|
85895
85915
|
}
|
|
85896
|
-
function
|
|
85916
|
+
function parseSessionAugmentation(handoffContent) {
|
|
85897
85917
|
const sectionIdx = findSectionIndex(handoffContent, SECTION_HEADINGS);
|
|
85898
85918
|
if (sectionIdx === -1)
|
|
85899
85919
|
return DEFAULT_MODE;
|
|
@@ -85902,13 +85922,33 @@ function parseCompressContext(handoffContent) {
|
|
|
85902
85922
|
return DEFAULT_MODE;
|
|
85903
85923
|
return normalizeMode(match17[1]);
|
|
85904
85924
|
}
|
|
85905
|
-
function
|
|
85906
|
-
|
|
85925
|
+
function resolveSessionAugmentationForRole(handoffContent, role) {
|
|
85926
|
+
if (!roleSupportsSessionAugmentation(role)) {
|
|
85927
|
+
return "none";
|
|
85928
|
+
}
|
|
85929
|
+
return parseSessionAugmentation(handoffContent);
|
|
85907
85930
|
}
|
|
85908
|
-
|
|
85909
|
-
|
|
85910
|
-
|
|
85911
|
-
|
|
85931
|
+
function sessionAugmentationToWantResume(mode) {
|
|
85932
|
+
return mode === "none" || mode === "compact";
|
|
85933
|
+
}
|
|
85934
|
+
function sessionAugmentationNewSessionStarted(mode) {
|
|
85935
|
+
return mode === "new_session";
|
|
85936
|
+
}
|
|
85937
|
+
var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session", MODE_ALIASES;
|
|
85938
|
+
var init_parse_session_augmentation = __esm(() => {
|
|
85939
|
+
init_team_agent_settings();
|
|
85940
|
+
SECTION_HEADINGS = [
|
|
85941
|
+
"## Session Augmentation",
|
|
85942
|
+
"## Session Management",
|
|
85943
|
+
"## Restart new context"
|
|
85944
|
+
];
|
|
85945
|
+
DATA_TAG = /\/\/\s*data:agent\.(?:session_augmentation|compress_context)=(none|compact|new_session|reset)\b/i;
|
|
85946
|
+
MODE_ALIASES = {
|
|
85947
|
+
reset: "new_session",
|
|
85948
|
+
none: "none",
|
|
85949
|
+
compact: "compact",
|
|
85950
|
+
new_session: "new_session"
|
|
85951
|
+
};
|
|
85912
85952
|
});
|
|
85913
85953
|
|
|
85914
85954
|
// src/commands/machine/daemon-start/native-task-injector.ts
|
|
@@ -85952,9 +85992,10 @@ function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
|
85952
85992
|
return yield* exports_Effect.fail(deliveryResult.left);
|
|
85953
85993
|
}
|
|
85954
85994
|
const delivery = deliveryResult.right;
|
|
85995
|
+
const augmentationMode = resolveSessionAugmentationForRole(taskContent, role);
|
|
85955
85996
|
const prompt = buildNativeInjectionPrompt({
|
|
85956
85997
|
taskDeliveryOutput: delivery.fullCliOutput,
|
|
85957
|
-
|
|
85998
|
+
augmentationMode
|
|
85958
85999
|
});
|
|
85959
86000
|
yield* exports_Effect.tryPromise({
|
|
85960
86001
|
try: () => deps.backend.mutation(api.participants.join, {
|
|
@@ -85966,6 +86007,21 @@ function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
|
85966
86007
|
}),
|
|
85967
86008
|
catch: (err) => err
|
|
85968
86009
|
}).pipe(exports_Effect.tapError(() => exports_Effect.sync(() => ledger.clearDelivery(taskId, harnessSessionId))));
|
|
86010
|
+
if (roleSupportsSessionAugmentation(role)) {
|
|
86011
|
+
yield* exports_Effect.tryPromise({
|
|
86012
|
+
try: () => deps.backend.mutation(api.machines.emitSessionAugmented, {
|
|
86013
|
+
sessionId: deps.sessionId,
|
|
86014
|
+
machineId: deps.machineId,
|
|
86015
|
+
chatroomId,
|
|
86016
|
+
role,
|
|
86017
|
+
taskId,
|
|
86018
|
+
mode: augmentationMode,
|
|
86019
|
+
newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode),
|
|
86020
|
+
harnessSessionId
|
|
86021
|
+
}),
|
|
86022
|
+
catch: (err) => err
|
|
86023
|
+
}).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
86024
|
+
}
|
|
85969
86025
|
const resumeResult = yield* exports_Effect.tryPromise({
|
|
85970
86026
|
try: () => deps.agentMgr.resumeTurnForSlot({ chatroomId, role, prompt }),
|
|
85971
86027
|
catch: (err) => err
|
|
@@ -85980,7 +86036,8 @@ function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
|
85980
86036
|
}
|
|
85981
86037
|
var init_native_task_injector = __esm(() => {
|
|
85982
86038
|
init_participant();
|
|
85983
|
-
|
|
86039
|
+
init_team_agent_settings();
|
|
86040
|
+
init_parse_session_augmentation();
|
|
85984
86041
|
init_esm();
|
|
85985
86042
|
init_native_task_injector_logic();
|
|
85986
86043
|
init_api3();
|
|
@@ -86024,6 +86081,7 @@ class NativeTaskDeliveryCoordinator {
|
|
|
86024
86081
|
return;
|
|
86025
86082
|
yield* runNativeInjectionEffect(full, harnessSessionId, {
|
|
86026
86083
|
sessionId: sessionDeps.sessionId,
|
|
86084
|
+
machineId: sessionDeps.machineId,
|
|
86027
86085
|
backend: sessionDeps.backend,
|
|
86028
86086
|
agentMgr: {
|
|
86029
86087
|
resumeTurnForSlot: (args2) => exports_Effect.runPromise(agentMgr.resumeTurnForSlot(args2))
|
|
@@ -86221,24 +86279,12 @@ var init_agent_lifecycle = __esm(() => {
|
|
|
86221
86279
|
init_restart_decision();
|
|
86222
86280
|
});
|
|
86223
86281
|
|
|
86224
|
-
// src/domain/agent-lifecycle/policies/cursor-sdk-run-error.ts
|
|
86225
|
-
function isCursorSdkRunErrorInLogs(logLines) {
|
|
86226
|
-
return logLines.some((line) => line.includes(" run-error]"));
|
|
86227
|
-
}
|
|
86228
|
-
function formatCursorSdkRunErrorMessage(logLines) {
|
|
86229
|
-
const line = [...logLines].reverse().find((l) => l.includes(" run-error]"));
|
|
86230
|
-
return line?.trim() ?? "Cursor SDK run failed";
|
|
86231
|
-
}
|
|
86232
|
-
|
|
86233
86282
|
// src/commands/machine/daemon-start/native-harness-session-exit.ts
|
|
86234
86283
|
function isNativeHarnessSessionDiscardedOnExit(ctx) {
|
|
86235
|
-
const { harness, harnessSessionId, stopReason,
|
|
86284
|
+
const { harness, harnessSessionId, stopReason, supportsDaemonMemoryResume } = ctx;
|
|
86236
86285
|
if (!harness || !harnessSessionId) {
|
|
86237
86286
|
return false;
|
|
86238
86287
|
}
|
|
86239
|
-
if (isCursorSdkRunErrorInLogs(recentLogLines ?? [])) {
|
|
86240
|
-
return true;
|
|
86241
|
-
}
|
|
86242
86288
|
if (!supportsDaemonMemoryResume) {
|
|
86243
86289
|
return true;
|
|
86244
86290
|
}
|
|
@@ -86377,8 +86423,17 @@ function appendRecentLogLine(slot, line) {
|
|
|
86377
86423
|
}
|
|
86378
86424
|
var RECENT_LOG_LINE_CAP2 = 100;
|
|
86379
86425
|
|
|
86426
|
+
// src/domain/agent-lifecycle/policies/cursor-sdk-run-error.ts
|
|
86427
|
+
function isCursorSdkRunErrorInLogs(logLines) {
|
|
86428
|
+
return logLines.some((line) => line.includes(" run-error]"));
|
|
86429
|
+
}
|
|
86430
|
+
function formatCursorSdkRunErrorMessage(logLines) {
|
|
86431
|
+
const line = [...logLines].reverse().find((l) => l.includes(" run-error]"));
|
|
86432
|
+
return line?.trim() ?? "Cursor SDK run failed";
|
|
86433
|
+
}
|
|
86434
|
+
|
|
86380
86435
|
// src/domain/agent-lifecycle/policies/cursor-sdk-session-reopen-retry.ts
|
|
86381
|
-
var CURSOR_SDK_SESSION_REOPEN_MAX_ATTEMPTS = 20, CURSOR_SDK_SESSION_REOPEN_INTERVAL_MS = 5000, CURSOR_SDK_SESSION_REOPEN_REASON = "platform.cursor_sdk_session_reopen";
|
|
86436
|
+
var CURSOR_SDK_SESSION_REOPEN_MAX_ATTEMPTS = 20, CURSOR_SDK_SESSION_REOPEN_INTERVAL_MS = 5000, CURSOR_SDK_SESSION_REOPEN_REASON = "platform.cursor_sdk_session_reopen", CURSOR_SDK_SESSION_RESUME_FIRST_ATTEMPTS = 3;
|
|
86382
86437
|
|
|
86383
86438
|
// src/domain/agent-lifecycle/use-cases/handle-turn-completed.ts
|
|
86384
86439
|
async function handleTurnCompleted(deps, input, slot) {
|
|
@@ -86988,8 +87043,10 @@ class AgentProcessManager {
|
|
|
86988
87043
|
console.log(`[AgentProcessManager] ⛔ Terminal provider error for ${opts.role} — emitted agent.startFailed`);
|
|
86989
87044
|
return;
|
|
86990
87045
|
}
|
|
86991
|
-
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.harness);
|
|
86992
|
-
|
|
87046
|
+
const emitted = await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.harness, "turn-end");
|
|
87047
|
+
if (emitted) {
|
|
87048
|
+
console.log(`[AgentProcessManager] ✅ Native harness idle for ${opts.role} (native:waiting)`);
|
|
87049
|
+
}
|
|
86993
87050
|
}
|
|
86994
87051
|
async handleExit(opts) {
|
|
86995
87052
|
const key = agentKey3(opts.chatroomId, opts.role);
|
|
@@ -87051,14 +87108,10 @@ class AgentProcessManager {
|
|
|
87051
87108
|
});
|
|
87052
87109
|
}
|
|
87053
87110
|
async preserveHarnessSessionOnExit(key, slot, ctx) {
|
|
87054
|
-
const { harness, harnessSessionId, stopReason
|
|
87111
|
+
const { harness, harnessSessionId, stopReason } = ctx;
|
|
87055
87112
|
if (!harness || !harnessSessionId) {
|
|
87056
87113
|
return;
|
|
87057
87114
|
}
|
|
87058
|
-
if (isCursorSdkRunErrorInLogs(recentLogLines ?? [])) {
|
|
87059
|
-
this.clearLastHarnessSession(key);
|
|
87060
|
-
return;
|
|
87061
|
-
}
|
|
87062
87115
|
const service3 = this.deps.agentServices.get(harness);
|
|
87063
87116
|
if (!service3?.resumeFromDaemonMemory) {
|
|
87064
87117
|
return;
|
|
@@ -87108,17 +87161,15 @@ class AgentProcessManager {
|
|
|
87108
87161
|
}
|
|
87109
87162
|
this.maybeRestartAgent(opts, ctx);
|
|
87110
87163
|
}
|
|
87111
|
-
|
|
87164
|
+
hasCursorSdkRunErrorInContext(recentLogLines) {
|
|
87112
87165
|
if (!isCursorSdkRunErrorInLogs(recentLogLines)) {
|
|
87113
87166
|
return false;
|
|
87114
87167
|
}
|
|
87115
|
-
console.log(`[AgentProcessManager] cursor-sdk run-error
|
|
87116
|
-
this.clearLastHarnessSession(key);
|
|
87168
|
+
console.log(`[AgentProcessManager] cursor-sdk run-error detected: ${formatCursorSdkRunErrorMessage(recentLogLines)}`);
|
|
87117
87169
|
return true;
|
|
87118
87170
|
}
|
|
87119
87171
|
maybeRestartAgent(opts, ctx) {
|
|
87120
87172
|
const { harness, model, workingDir, recentLogLines } = ctx;
|
|
87121
|
-
const key = agentKey3(opts.chatroomId, opts.role);
|
|
87122
87173
|
const logs = recentLogLines ?? [];
|
|
87123
87174
|
if (!harness || !workingDir) {
|
|
87124
87175
|
console.log(`[AgentProcessManager] ⚠️ Cannot restart — missing harness or workingDir ` + `(role: ${opts.role}, harness: ${harness ?? "none"}, workingDir: ${workingDir ?? "none"})`);
|
|
@@ -87128,9 +87179,9 @@ class AgentProcessManager {
|
|
|
87128
87179
|
this.handlePermanentFailureForRestart(opts, recentLogLines, ctx.terminalProviderFailureHandled);
|
|
87129
87180
|
return;
|
|
87130
87181
|
}
|
|
87131
|
-
const
|
|
87182
|
+
const hadRunError = this.hasCursorSdkRunErrorInContext(logs);
|
|
87132
87183
|
if (harness === "cursor-sdk") {
|
|
87133
|
-
this.retryCursorSdkSessionReopen(opts, ctx,
|
|
87184
|
+
this.retryCursorSdkSessionReopen(opts, ctx, hadRunError);
|
|
87134
87185
|
return;
|
|
87135
87186
|
}
|
|
87136
87187
|
this.ensureRunning({
|
|
@@ -87140,7 +87191,7 @@ class AgentProcessManager {
|
|
|
87140
87191
|
model,
|
|
87141
87192
|
workingDir,
|
|
87142
87193
|
reason: "platform.crash_recovery",
|
|
87143
|
-
wantResume:
|
|
87194
|
+
wantResume: hadRunError ? false : ctx.wantResume ?? true
|
|
87144
87195
|
}).then((result) => {
|
|
87145
87196
|
if (!result.success) {
|
|
87146
87197
|
console.log(`[AgentProcessManager] ⚠️ Agent restart did not complete for ${opts.role}: ${result.error ?? "unknown"}`);
|
|
@@ -87150,7 +87201,27 @@ class AgentProcessManager {
|
|
|
87150
87201
|
this.emitStartFailedEvent(opts.role, opts.chatroomId, err.message);
|
|
87151
87202
|
});
|
|
87152
87203
|
}
|
|
87153
|
-
|
|
87204
|
+
clearHarnessSessionAfterResumePhaseFailure(key, opts) {
|
|
87205
|
+
const stored = this.lastHarnessSessions.get(key);
|
|
87206
|
+
this.clearLastHarnessSession(key);
|
|
87207
|
+
if (stored?.harnessSessionId) {
|
|
87208
|
+
notifyNativeSessionLost({
|
|
87209
|
+
chatroomId: opts.chatroomId,
|
|
87210
|
+
role: opts.role,
|
|
87211
|
+
harnessSessionId: stored.harnessSessionId
|
|
87212
|
+
});
|
|
87213
|
+
}
|
|
87214
|
+
}
|
|
87215
|
+
resolveCursorSdkReopenWantResume(hadRunError, attempt, ctx) {
|
|
87216
|
+
if (hadRunError && attempt <= CURSOR_SDK_SESSION_RESUME_FIRST_ATTEMPTS) {
|
|
87217
|
+
return true;
|
|
87218
|
+
}
|
|
87219
|
+
if (hadRunError) {
|
|
87220
|
+
return false;
|
|
87221
|
+
}
|
|
87222
|
+
return ctx.wantResume ?? true;
|
|
87223
|
+
}
|
|
87224
|
+
async retryCursorSdkSessionReopen(opts, ctx, hadRunError) {
|
|
87154
87225
|
const key = agentKey3(opts.chatroomId, opts.role);
|
|
87155
87226
|
if (this.sessionReopenRetryInFlight.has(key)) {
|
|
87156
87227
|
return;
|
|
@@ -87159,11 +87230,14 @@ class AgentProcessManager {
|
|
|
87159
87230
|
const harness = ctx.harness;
|
|
87160
87231
|
const model = ctx.model;
|
|
87161
87232
|
const workingDir = ctx.workingDir;
|
|
87162
|
-
const wantResume = coldRestartAfterRunError ? false : ctx.wantResume ?? true;
|
|
87163
|
-
const storedSessionId = this.lastHarnessSessions.get(key)?.harnessSessionId;
|
|
87164
87233
|
let lastError = "unknown";
|
|
87165
87234
|
try {
|
|
87166
87235
|
for (let attempt = 1;attempt <= CURSOR_SDK_SESSION_REOPEN_MAX_ATTEMPTS; attempt++) {
|
|
87236
|
+
if (hadRunError && attempt === CURSOR_SDK_SESSION_RESUME_FIRST_ATTEMPTS + 1) {
|
|
87237
|
+
this.clearHarnessSessionAfterResumePhaseFailure(key, opts);
|
|
87238
|
+
}
|
|
87239
|
+
const wantResume = this.resolveCursorSdkReopenWantResume(hadRunError, attempt, ctx);
|
|
87240
|
+
const storedSessionId = this.lastHarnessSessions.get(key)?.harnessSessionId;
|
|
87167
87241
|
await this.emitSessionReopenRetry(opts.chatroomId, opts.role, attempt, attempt > 1 ? lastError : undefined, storedSessionId);
|
|
87168
87242
|
const result = await this.ensureRunning({
|
|
87169
87243
|
chatroomId: opts.chatroomId,
|
|
@@ -87345,13 +87419,6 @@ class AgentProcessManager {
|
|
|
87345
87419
|
try {
|
|
87346
87420
|
await this.killExistingBeforeSpawn(opts.chatroomId, opts.role);
|
|
87347
87421
|
const result = await this.doEnsureRunning(key, slot, opts);
|
|
87348
|
-
if (!result.success && opts.reason === "platform.auto_restart_on_new_context") {
|
|
87349
|
-
console.log(`[AgentProcessManager] Context auto-restart failed (${result.error ?? "unknown"}), ` + `attempting crash recovery (rate-limited)`);
|
|
87350
|
-
return await this.doEnsureRunning(key, slot, {
|
|
87351
|
-
...opts,
|
|
87352
|
-
reason: "platform.crash_recovery"
|
|
87353
|
-
});
|
|
87354
|
-
}
|
|
87355
87422
|
return result;
|
|
87356
87423
|
} finally {
|
|
87357
87424
|
if (slot.pendingOperation) {
|
|
@@ -87744,9 +87811,25 @@ class AgentProcessManager {
|
|
|
87744
87811
|
this.registerSpawnCallbacks(slot, opts, spawnResult, pid);
|
|
87745
87812
|
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
|
|
87746
87813
|
}
|
|
87747
|
-
async emitNativeWaiting(chatroomId, role, harness) {
|
|
87814
|
+
async emitNativeWaiting(chatroomId, role, harness, reason = "spawn") {
|
|
87748
87815
|
if (!getHarnessCapabilities(harness).supportsNativeIntegration)
|
|
87749
|
-
return;
|
|
87816
|
+
return false;
|
|
87817
|
+
if (reason === "turn-end") {
|
|
87818
|
+
try {
|
|
87819
|
+
const participant = await this.deps.backend.query(api.participants.getByRole, {
|
|
87820
|
+
sessionId: this.deps.sessionId,
|
|
87821
|
+
chatroomId,
|
|
87822
|
+
role
|
|
87823
|
+
});
|
|
87824
|
+
if (!shouldEmitNativeWaitingOnTurnEnd(participant?.lastStatus)) {
|
|
87825
|
+
console.log(`[AgentProcessManager] Skipping native:waiting for ${role} — active work (${participant?.lastStatus})`);
|
|
87826
|
+
return false;
|
|
87827
|
+
}
|
|
87828
|
+
} catch (err) {
|
|
87829
|
+
console.log(` ⚠️ Failed to check status before native:waiting for ${role}: ${err.message}`);
|
|
87830
|
+
return false;
|
|
87831
|
+
}
|
|
87832
|
+
}
|
|
87750
87833
|
try {
|
|
87751
87834
|
await this.deps.backend.mutation(api.participants.join, {
|
|
87752
87835
|
sessionId: this.deps.sessionId,
|
|
@@ -87754,8 +87837,10 @@ class AgentProcessManager {
|
|
|
87754
87837
|
role,
|
|
87755
87838
|
action: NATIVE_WAITING_ACTION
|
|
87756
87839
|
});
|
|
87840
|
+
return true;
|
|
87757
87841
|
} catch (err) {
|
|
87758
87842
|
console.log(` ⚠️ Failed to emit native:waiting for ${role}: ${err.message}`);
|
|
87843
|
+
return false;
|
|
87759
87844
|
}
|
|
87760
87845
|
}
|
|
87761
87846
|
async doEnsureRunning(key, slot, opts) {
|
|
@@ -87909,11 +87994,13 @@ var init_agent_process_manager = __esm(() => {
|
|
|
87909
87994
|
init_api3();
|
|
87910
87995
|
init_orphan_tracker();
|
|
87911
87996
|
init_native_harness_session_exit();
|
|
87997
|
+
init_native_task_delivery_coordinator();
|
|
87912
87998
|
init_agent_lifecycle();
|
|
87913
87999
|
init_abort_resume_storm();
|
|
87914
88000
|
init_classify_resume_storm_reason();
|
|
87915
88001
|
init_terminal_provider_error();
|
|
87916
88002
|
init_handle_turn_completed();
|
|
88003
|
+
init_predicates();
|
|
87917
88004
|
init_spawn_policy();
|
|
87918
88005
|
init_agent_lifecycle_runtime();
|
|
87919
88006
|
init_agent_lifecycle_types();
|
|
@@ -87927,7 +88014,7 @@ class SpawnRateLimiter {
|
|
|
87927
88014
|
this.config = { ...DEFAULT_CONFIG2, ...config3 };
|
|
87928
88015
|
}
|
|
87929
88016
|
tryConsume(chatroomId, reason) {
|
|
87930
|
-
if (reason.startsWith("user.") || reason === "platform.
|
|
88017
|
+
if (reason.startsWith("user.") || reason === "platform.cursor_sdk_session_reopen") {
|
|
87931
88018
|
return { allowed: true };
|
|
87932
88019
|
}
|
|
87933
88020
|
const bucket = this._getOrCreateBucket(chatroomId);
|
|
@@ -89278,15 +89365,15 @@ var init_assigned_task_signals = __esm(() => {
|
|
|
89278
89365
|
|
|
89279
89366
|
// src/commands/machine/daemon-start/task-monitor.ts
|
|
89280
89367
|
function resolveTaskWantResume(task) {
|
|
89281
|
-
return
|
|
89368
|
+
return sessionAugmentationToWantResume(resolveSessionAugmentationForRole(task.taskContent ?? "", task.agentConfig.role));
|
|
89282
89369
|
}
|
|
89283
89370
|
function buildCliNudgeLogLine(task) {
|
|
89284
89371
|
const { chatroomId, agentConfig } = task;
|
|
89285
89372
|
const { role } = agentConfig;
|
|
89286
89373
|
const lastSeenAction = task.participant?.lastSeenAction ?? "unknown";
|
|
89287
|
-
const
|
|
89374
|
+
const augmentationMode = resolveSessionAugmentationForRole(task.taskContent ?? "", role);
|
|
89288
89375
|
const wantResume = resolveTaskWantResume(task);
|
|
89289
|
-
return `[TaskMonitor] nudging ${role}@${chatroomId} — pending task ${task.taskId}, lastSeenAction=${lastSeenAction},
|
|
89376
|
+
return `[TaskMonitor] nudging ${role}@${chatroomId} — pending task ${task.taskId}, lastSeenAction=${lastSeenAction}, session_augmentation=${augmentationMode}, wantResume=${wantResume}`;
|
|
89290
89377
|
}
|
|
89291
89378
|
function resolveTaskRunnerContextFromFull(task) {
|
|
89292
89379
|
const { chatroomId, agentConfig } = task;
|
|
@@ -89302,11 +89389,12 @@ function resolveTaskRunnerContextFromFull(task) {
|
|
|
89302
89389
|
wantResume: resolveTaskWantResume(task)
|
|
89303
89390
|
};
|
|
89304
89391
|
}
|
|
89305
|
-
function executeCliNudge(task, runtime4, effectContext2, agentMgr) {
|
|
89392
|
+
function executeCliNudge(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
89306
89393
|
const ctx = resolveTaskRunnerContextFromFull(task);
|
|
89307
89394
|
if (!ctx)
|
|
89308
89395
|
return;
|
|
89309
89396
|
const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
|
|
89397
|
+
const augmentationMode = resolveSessionAugmentationForRole(task.taskContent ?? "", role);
|
|
89310
89398
|
exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
|
|
89311
89399
|
yield* agentMgr.stop({ chatroomId, role, reason: "platform.task_monitor_nudge" });
|
|
89312
89400
|
yield* agentMgr.ensureRunning({
|
|
@@ -89318,6 +89406,20 @@ function executeCliNudge(task, runtime4, effectContext2, agentMgr) {
|
|
|
89318
89406
|
reason: "platform.task_monitor_nudge",
|
|
89319
89407
|
wantResume
|
|
89320
89408
|
});
|
|
89409
|
+
if (roleSupportsSessionAugmentation(role)) {
|
|
89410
|
+
yield* exports_Effect.tryPromise({
|
|
89411
|
+
try: () => sessionDeps.backend.mutation(api.machines.emitSessionAugmented, {
|
|
89412
|
+
sessionId: sessionDeps.sessionId,
|
|
89413
|
+
machineId,
|
|
89414
|
+
chatroomId,
|
|
89415
|
+
role,
|
|
89416
|
+
taskId: task.taskId,
|
|
89417
|
+
mode: augmentationMode,
|
|
89418
|
+
newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode)
|
|
89419
|
+
}),
|
|
89420
|
+
catch: (err) => err
|
|
89421
|
+
}).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89422
|
+
}
|
|
89321
89423
|
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] nudge failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
|
|
89322
89424
|
}
|
|
89323
89425
|
function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
|
|
@@ -89347,16 +89449,16 @@ async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
|
|
|
89347
89449
|
});
|
|
89348
89450
|
return result;
|
|
89349
89451
|
}
|
|
89350
|
-
function runCliNudgeEffect(task, runtime4, effectContext2, agentMgr) {
|
|
89452
|
+
function runCliNudgeEffect(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
89351
89453
|
console.log(buildCliNudgeLogLine(task));
|
|
89352
|
-
executeCliNudge(task, runtime4, effectContext2, agentMgr);
|
|
89454
|
+
executeCliNudge(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
89353
89455
|
}
|
|
89354
89456
|
async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
89355
89457
|
for (const row of listTasksReadyForNudge(tasks, now, cooldown)) {
|
|
89356
89458
|
const full = await fetchTaskForAction(sessionDeps, machineId, row);
|
|
89357
89459
|
if (!full)
|
|
89358
89460
|
continue;
|
|
89359
|
-
runCliNudgeEffect(full, runtime4, effectContext2, agentMgr);
|
|
89461
|
+
runCliNudgeEffect(full, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
89360
89462
|
}
|
|
89361
89463
|
}
|
|
89362
89464
|
async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
@@ -89460,7 +89562,8 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
|
89460
89562
|
};
|
|
89461
89563
|
});
|
|
89462
89564
|
var init_task_monitor = __esm(() => {
|
|
89463
|
-
|
|
89565
|
+
init_team_agent_settings();
|
|
89566
|
+
init_parse_session_augmentation();
|
|
89464
89567
|
init_esm();
|
|
89465
89568
|
init_daemon_services();
|
|
89466
89569
|
init_native_task_delivery_coordinator();
|
|
@@ -90975,4 +91078,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
90975
91078
|
});
|
|
90976
91079
|
program2.parse();
|
|
90977
91080
|
|
|
90978
|
-
//# debugId=
|
|
91081
|
+
//# debugId=D22ED479E2182D5A64756E2164756E21
|