chatroom-cli 1.58.0 → 1.58.2
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 +323 -202
- package/dist/index.js.map +26 -24
- 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
|
|
|
@@ -75696,6 +75701,12 @@ function getPlannerToUserReportTemplate() {
|
|
|
75696
75701
|
## Template Disclosure Confirmation
|
|
75697
75702
|
- [ ] I confirm that I have seen this template at the start of any planning, before working on or delegating any task to the team
|
|
75698
75703
|
|
|
75704
|
+
## Proof of Planning
|
|
75705
|
+
<!-- Demonstrate the goal was decomposed into actionable steps with clear outcomes before implementation. -->
|
|
75706
|
+
- <step 1: concrete artifact or outcome>
|
|
75707
|
+
- <step 2: concrete artifact or outcome>
|
|
75708
|
+
<List the planned slices/steps the planner defined (or would have defined) before delegating. Each step should name a verifiable deliverable — not vague layers like "backend work". Write \`Not Applicable\` only for trivial single-step tasks.>
|
|
75709
|
+
|
|
75699
75710
|
## Proof of Principle
|
|
75700
75711
|
<!-- Demonstrate adherence to:
|
|
75701
75712
|
- Organization & Maintainability: a small change in requirements should result in a small change in code in a small number of files and folders.
|
|
@@ -75733,14 +75744,16 @@ flowchart TD
|
|
|
75733
75744
|
A[Component] --> B[Component]
|
|
75734
75745
|
\`\`\`
|
|
75735
75746
|
|
|
75736
|
-
## Verification
|
|
75737
|
-
|
|
75747
|
+
## Code Change Verification
|
|
75748
|
+
${CODE_CHANGE_VERIFICATION_CONFIRMATION}
|
|
75738
75749
|
|
|
75739
75750
|
## Notes / Next steps
|
|
75740
75751
|
<anything the user should know, follow-ups, or open questions, or "Not Applicable">
|
|
75741
75752
|
\`\`\``;
|
|
75742
75753
|
}
|
|
75743
|
-
var init_planner_to_user = () => {
|
|
75754
|
+
var init_planner_to_user = __esm(() => {
|
|
75755
|
+
init_code_change_verification();
|
|
75756
|
+
});
|
|
75744
75757
|
|
|
75745
75758
|
// ../../services/backend/prompts/teams/duo/handoff-templates/index.ts
|
|
75746
75759
|
function getDuoHandoffTemplate(query) {
|
|
@@ -75790,9 +75803,6 @@ flowchart TD
|
|
|
75790
75803
|
A[Component] --> B[Component]
|
|
75791
75804
|
\`\`\`
|
|
75792
75805
|
|
|
75793
|
-
## Verification
|
|
75794
|
-
- \`pnpm typecheck && pnpm test\` — <result>
|
|
75795
|
-
|
|
75796
75806
|
## Notes / Next steps
|
|
75797
75807
|
<anything the user should know, follow-ups, or open questions, or "Not Applicable">
|
|
75798
75808
|
\`\`\``;
|
|
@@ -85789,6 +85799,9 @@ function isInjectableNativeAction(action) {
|
|
|
85789
85799
|
return true;
|
|
85790
85800
|
return action === NATIVE_WAITING_ACTION;
|
|
85791
85801
|
}
|
|
85802
|
+
function shouldEmitNativeWaitingOnTurnEnd(lastStatus) {
|
|
85803
|
+
return lastStatus !== "task.acknowledged" && lastStatus !== "task.inProgress";
|
|
85804
|
+
}
|
|
85792
85805
|
function isNativeIdleAfterTaskComplete(participant) {
|
|
85793
85806
|
return participant.lastSeenAction === NATIVE_TASK_INJECTED_ACTION && participant.lastStatus === "task.completed";
|
|
85794
85807
|
}
|
|
@@ -85858,13 +85871,21 @@ function shouldDeliverNativeTask(task, opts) {
|
|
|
85858
85871
|
return isInjectableNativeAction(task.participant?.lastSeenAction) || isNativeIdleAfterTaskComplete(task.participant ?? {}) || isNativeAcknowledgedInjectionRetry(task);
|
|
85859
85872
|
}
|
|
85860
85873
|
function buildNativeInjectionPrompt(params) {
|
|
85861
|
-
const { taskDeliveryOutput,
|
|
85862
|
-
if (
|
|
85874
|
+
const { taskDeliveryOutput, augmentationMode } = params;
|
|
85875
|
+
if (augmentationMode === "compact") {
|
|
85863
85876
|
return [
|
|
85864
85877
|
"⚠️ Context was compacted. Run `chatroom get-system-prompt` only if role instructions are missing.",
|
|
85865
85878
|
"",
|
|
85866
85879
|
taskDeliveryOutput
|
|
85867
85880
|
].join(`
|
|
85881
|
+
`);
|
|
85882
|
+
}
|
|
85883
|
+
if (augmentationMode === "new_session") {
|
|
85884
|
+
return [
|
|
85885
|
+
"⚠️ Starting a new agent session. Run `chatroom get-system-prompt` to reload role instructions if needed.",
|
|
85886
|
+
"",
|
|
85887
|
+
taskDeliveryOutput
|
|
85888
|
+
].join(`
|
|
85868
85889
|
`);
|
|
85869
85890
|
}
|
|
85870
85891
|
return taskDeliveryOutput;
|
|
@@ -85874,18 +85895,23 @@ var init_native_task_injector_logic = __esm(() => {
|
|
|
85874
85895
|
init_native_integration();
|
|
85875
85896
|
});
|
|
85876
85897
|
|
|
85877
|
-
// ../../services/backend/src/domain/
|
|
85898
|
+
// ../../services/backend/src/domain/entities/team-agent-settings.ts
|
|
85899
|
+
function roleSupportsSessionAugmentation(role) {
|
|
85900
|
+
const normalized = role.toLowerCase();
|
|
85901
|
+
return SESSION_AUGMENTATION_ROLES.some((r) => r === normalized);
|
|
85902
|
+
}
|
|
85903
|
+
var SESSION_AUGMENTATION_ROLES;
|
|
85904
|
+
var init_team_agent_settings = __esm(() => {
|
|
85905
|
+
SESSION_AUGMENTATION_ROLES = ["builder"];
|
|
85906
|
+
});
|
|
85907
|
+
|
|
85908
|
+
// ../../services/backend/src/domain/handoff/parse-session-augmentation.ts
|
|
85878
85909
|
function findSectionIndex(content, headings) {
|
|
85879
85910
|
const indices = headings.map((heading) => content.indexOf(heading)).filter((idx) => idx !== -1);
|
|
85880
85911
|
return indices.length === 0 ? -1 : Math.min(...indices);
|
|
85881
85912
|
}
|
|
85882
85913
|
function normalizeMode(raw) {
|
|
85883
|
-
|
|
85884
|
-
if (value === "reset")
|
|
85885
|
-
return "new_session";
|
|
85886
|
-
if (value === "none")
|
|
85887
|
-
return value;
|
|
85888
|
-
return DEFAULT_MODE;
|
|
85914
|
+
return MODE_ALIASES[raw.toLowerCase()] ?? DEFAULT_MODE;
|
|
85889
85915
|
}
|
|
85890
85916
|
function extractSectionBody(content, sectionIdx) {
|
|
85891
85917
|
const matchedHeading = SECTION_HEADINGS.find((h) => content.indexOf(h, sectionIdx) === sectionIdx) ?? SECTION_HEADINGS[0];
|
|
@@ -85893,7 +85919,7 @@ function extractSectionBody(content, sectionIdx) {
|
|
|
85893
85919
|
const nextHeading = afterSection.slice(matchedHeading.length).search(/\n## /);
|
|
85894
85920
|
return nextHeading === -1 ? afterSection : afterSection.slice(0, matchedHeading.length + nextHeading);
|
|
85895
85921
|
}
|
|
85896
|
-
function
|
|
85922
|
+
function parseSessionAugmentation(handoffContent) {
|
|
85897
85923
|
const sectionIdx = findSectionIndex(handoffContent, SECTION_HEADINGS);
|
|
85898
85924
|
if (sectionIdx === -1)
|
|
85899
85925
|
return DEFAULT_MODE;
|
|
@@ -85902,13 +85928,33 @@ function parseCompressContext(handoffContent) {
|
|
|
85902
85928
|
return DEFAULT_MODE;
|
|
85903
85929
|
return normalizeMode(match17[1]);
|
|
85904
85930
|
}
|
|
85905
|
-
function
|
|
85906
|
-
|
|
85931
|
+
function resolveSessionAugmentationForRole(handoffContent, role) {
|
|
85932
|
+
if (!roleSupportsSessionAugmentation(role)) {
|
|
85933
|
+
return "none";
|
|
85934
|
+
}
|
|
85935
|
+
return parseSessionAugmentation(handoffContent);
|
|
85936
|
+
}
|
|
85937
|
+
function sessionAugmentationToWantResume(mode) {
|
|
85938
|
+
return mode === "none" || mode === "compact";
|
|
85939
|
+
}
|
|
85940
|
+
function sessionAugmentationNewSessionStarted(mode) {
|
|
85941
|
+
return mode === "new_session";
|
|
85907
85942
|
}
|
|
85908
|
-
var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session";
|
|
85909
|
-
var
|
|
85910
|
-
|
|
85911
|
-
|
|
85943
|
+
var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session", MODE_ALIASES;
|
|
85944
|
+
var init_parse_session_augmentation = __esm(() => {
|
|
85945
|
+
init_team_agent_settings();
|
|
85946
|
+
SECTION_HEADINGS = [
|
|
85947
|
+
"## Session Augmentation",
|
|
85948
|
+
"## Session Management",
|
|
85949
|
+
"## Restart new context"
|
|
85950
|
+
];
|
|
85951
|
+
DATA_TAG = /\/\/\s*data:agent\.(?:session_augmentation|compress_context)=(none|compact|new_session|reset)\b/i;
|
|
85952
|
+
MODE_ALIASES = {
|
|
85953
|
+
reset: "new_session",
|
|
85954
|
+
none: "none",
|
|
85955
|
+
compact: "compact",
|
|
85956
|
+
new_session: "new_session"
|
|
85957
|
+
};
|
|
85912
85958
|
});
|
|
85913
85959
|
|
|
85914
85960
|
// src/commands/machine/daemon-start/native-task-injector.ts
|
|
@@ -85952,9 +85998,10 @@ function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
|
85952
85998
|
return yield* exports_Effect.fail(deliveryResult.left);
|
|
85953
85999
|
}
|
|
85954
86000
|
const delivery = deliveryResult.right;
|
|
86001
|
+
const augmentationMode = resolveSessionAugmentationForRole(taskContent, role);
|
|
85955
86002
|
const prompt = buildNativeInjectionPrompt({
|
|
85956
86003
|
taskDeliveryOutput: delivery.fullCliOutput,
|
|
85957
|
-
|
|
86004
|
+
augmentationMode
|
|
85958
86005
|
});
|
|
85959
86006
|
yield* exports_Effect.tryPromise({
|
|
85960
86007
|
try: () => deps.backend.mutation(api.participants.join, {
|
|
@@ -85966,6 +86013,21 @@ function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
|
85966
86013
|
}),
|
|
85967
86014
|
catch: (err) => err
|
|
85968
86015
|
}).pipe(exports_Effect.tapError(() => exports_Effect.sync(() => ledger.clearDelivery(taskId, harnessSessionId))));
|
|
86016
|
+
if (roleSupportsSessionAugmentation(role)) {
|
|
86017
|
+
yield* exports_Effect.tryPromise({
|
|
86018
|
+
try: () => deps.backend.mutation(api.machines.emitSessionAugmented, {
|
|
86019
|
+
sessionId: deps.sessionId,
|
|
86020
|
+
machineId: deps.machineId,
|
|
86021
|
+
chatroomId,
|
|
86022
|
+
role,
|
|
86023
|
+
taskId,
|
|
86024
|
+
mode: augmentationMode,
|
|
86025
|
+
newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode),
|
|
86026
|
+
harnessSessionId
|
|
86027
|
+
}),
|
|
86028
|
+
catch: (err) => err
|
|
86029
|
+
}).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
86030
|
+
}
|
|
85969
86031
|
const resumeResult = yield* exports_Effect.tryPromise({
|
|
85970
86032
|
try: () => deps.agentMgr.resumeTurnForSlot({ chatroomId, role, prompt }),
|
|
85971
86033
|
catch: (err) => err
|
|
@@ -85980,7 +86042,8 @@ function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
|
|
|
85980
86042
|
}
|
|
85981
86043
|
var init_native_task_injector = __esm(() => {
|
|
85982
86044
|
init_participant();
|
|
85983
|
-
|
|
86045
|
+
init_team_agent_settings();
|
|
86046
|
+
init_parse_session_augmentation();
|
|
85984
86047
|
init_esm();
|
|
85985
86048
|
init_native_task_injector_logic();
|
|
85986
86049
|
init_api3();
|
|
@@ -86024,6 +86087,7 @@ class NativeTaskDeliveryCoordinator {
|
|
|
86024
86087
|
return;
|
|
86025
86088
|
yield* runNativeInjectionEffect(full, harnessSessionId, {
|
|
86026
86089
|
sessionId: sessionDeps.sessionId,
|
|
86090
|
+
machineId: sessionDeps.machineId,
|
|
86027
86091
|
backend: sessionDeps.backend,
|
|
86028
86092
|
agentMgr: {
|
|
86029
86093
|
resumeTurnForSlot: (args2) => exports_Effect.runPromise(agentMgr.resumeTurnForSlot(args2))
|
|
@@ -86221,24 +86285,12 @@ var init_agent_lifecycle = __esm(() => {
|
|
|
86221
86285
|
init_restart_decision();
|
|
86222
86286
|
});
|
|
86223
86287
|
|
|
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
86288
|
// src/commands/machine/daemon-start/native-harness-session-exit.ts
|
|
86234
86289
|
function isNativeHarnessSessionDiscardedOnExit(ctx) {
|
|
86235
|
-
const { harness, harnessSessionId, stopReason,
|
|
86290
|
+
const { harness, harnessSessionId, stopReason, supportsDaemonMemoryResume } = ctx;
|
|
86236
86291
|
if (!harness || !harnessSessionId) {
|
|
86237
86292
|
return false;
|
|
86238
86293
|
}
|
|
86239
|
-
if (isCursorSdkRunErrorInLogs(recentLogLines ?? [])) {
|
|
86240
|
-
return true;
|
|
86241
|
-
}
|
|
86242
86294
|
if (!supportsDaemonMemoryResume) {
|
|
86243
86295
|
return true;
|
|
86244
86296
|
}
|
|
@@ -86377,8 +86429,17 @@ function appendRecentLogLine(slot, line) {
|
|
|
86377
86429
|
}
|
|
86378
86430
|
var RECENT_LOG_LINE_CAP2 = 100;
|
|
86379
86431
|
|
|
86432
|
+
// src/domain/agent-lifecycle/policies/cursor-sdk-run-error.ts
|
|
86433
|
+
function isCursorSdkRunErrorInLogs(logLines) {
|
|
86434
|
+
return logLines.some((line) => line.includes(" run-error]"));
|
|
86435
|
+
}
|
|
86436
|
+
function formatCursorSdkRunErrorMessage(logLines) {
|
|
86437
|
+
const line = [...logLines].reverse().find((l) => l.includes(" run-error]"));
|
|
86438
|
+
return line?.trim() ?? "Cursor SDK run failed";
|
|
86439
|
+
}
|
|
86440
|
+
|
|
86380
86441
|
// 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";
|
|
86442
|
+
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
86443
|
|
|
86383
86444
|
// src/domain/agent-lifecycle/use-cases/handle-turn-completed.ts
|
|
86384
86445
|
async function handleTurnCompleted(deps, input, slot) {
|
|
@@ -86988,8 +87049,10 @@ class AgentProcessManager {
|
|
|
86988
87049
|
console.log(`[AgentProcessManager] ⛔ Terminal provider error for ${opts.role} — emitted agent.startFailed`);
|
|
86989
87050
|
return;
|
|
86990
87051
|
}
|
|
86991
|
-
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.harness);
|
|
86992
|
-
|
|
87052
|
+
const emitted = await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.harness, "turn-end");
|
|
87053
|
+
if (emitted) {
|
|
87054
|
+
console.log(`[AgentProcessManager] ✅ Native harness idle for ${opts.role} (native:waiting)`);
|
|
87055
|
+
}
|
|
86993
87056
|
}
|
|
86994
87057
|
async handleExit(opts) {
|
|
86995
87058
|
const key = agentKey3(opts.chatroomId, opts.role);
|
|
@@ -87051,14 +87114,10 @@ class AgentProcessManager {
|
|
|
87051
87114
|
});
|
|
87052
87115
|
}
|
|
87053
87116
|
async preserveHarnessSessionOnExit(key, slot, ctx) {
|
|
87054
|
-
const { harness, harnessSessionId, stopReason
|
|
87117
|
+
const { harness, harnessSessionId, stopReason } = ctx;
|
|
87055
87118
|
if (!harness || !harnessSessionId) {
|
|
87056
87119
|
return;
|
|
87057
87120
|
}
|
|
87058
|
-
if (isCursorSdkRunErrorInLogs(recentLogLines ?? [])) {
|
|
87059
|
-
this.clearLastHarnessSession(key);
|
|
87060
|
-
return;
|
|
87061
|
-
}
|
|
87062
87121
|
const service3 = this.deps.agentServices.get(harness);
|
|
87063
87122
|
if (!service3?.resumeFromDaemonMemory) {
|
|
87064
87123
|
return;
|
|
@@ -87108,17 +87167,15 @@ class AgentProcessManager {
|
|
|
87108
87167
|
}
|
|
87109
87168
|
this.maybeRestartAgent(opts, ctx);
|
|
87110
87169
|
}
|
|
87111
|
-
|
|
87170
|
+
hasCursorSdkRunErrorInContext(recentLogLines) {
|
|
87112
87171
|
if (!isCursorSdkRunErrorInLogs(recentLogLines)) {
|
|
87113
87172
|
return false;
|
|
87114
87173
|
}
|
|
87115
|
-
console.log(`[AgentProcessManager] cursor-sdk run-error
|
|
87116
|
-
this.clearLastHarnessSession(key);
|
|
87174
|
+
console.log(`[AgentProcessManager] cursor-sdk run-error detected: ${formatCursorSdkRunErrorMessage(recentLogLines)}`);
|
|
87117
87175
|
return true;
|
|
87118
87176
|
}
|
|
87119
87177
|
maybeRestartAgent(opts, ctx) {
|
|
87120
87178
|
const { harness, model, workingDir, recentLogLines } = ctx;
|
|
87121
|
-
const key = agentKey3(opts.chatroomId, opts.role);
|
|
87122
87179
|
const logs = recentLogLines ?? [];
|
|
87123
87180
|
if (!harness || !workingDir) {
|
|
87124
87181
|
console.log(`[AgentProcessManager] ⚠️ Cannot restart — missing harness or workingDir ` + `(role: ${opts.role}, harness: ${harness ?? "none"}, workingDir: ${workingDir ?? "none"})`);
|
|
@@ -87128,9 +87185,9 @@ class AgentProcessManager {
|
|
|
87128
87185
|
this.handlePermanentFailureForRestart(opts, recentLogLines, ctx.terminalProviderFailureHandled);
|
|
87129
87186
|
return;
|
|
87130
87187
|
}
|
|
87131
|
-
const
|
|
87188
|
+
const hadRunError = this.hasCursorSdkRunErrorInContext(logs);
|
|
87132
87189
|
if (harness === "cursor-sdk") {
|
|
87133
|
-
this.retryCursorSdkSessionReopen(opts, ctx,
|
|
87190
|
+
this.retryCursorSdkSessionReopen(opts, ctx, hadRunError);
|
|
87134
87191
|
return;
|
|
87135
87192
|
}
|
|
87136
87193
|
this.ensureRunning({
|
|
@@ -87140,7 +87197,7 @@ class AgentProcessManager {
|
|
|
87140
87197
|
model,
|
|
87141
87198
|
workingDir,
|
|
87142
87199
|
reason: "platform.crash_recovery",
|
|
87143
|
-
wantResume:
|
|
87200
|
+
wantResume: hadRunError ? false : ctx.wantResume ?? true
|
|
87144
87201
|
}).then((result) => {
|
|
87145
87202
|
if (!result.success) {
|
|
87146
87203
|
console.log(`[AgentProcessManager] ⚠️ Agent restart did not complete for ${opts.role}: ${result.error ?? "unknown"}`);
|
|
@@ -87150,7 +87207,27 @@ class AgentProcessManager {
|
|
|
87150
87207
|
this.emitStartFailedEvent(opts.role, opts.chatroomId, err.message);
|
|
87151
87208
|
});
|
|
87152
87209
|
}
|
|
87153
|
-
|
|
87210
|
+
clearHarnessSessionAfterResumePhaseFailure(key, opts) {
|
|
87211
|
+
const stored = this.lastHarnessSessions.get(key);
|
|
87212
|
+
this.clearLastHarnessSession(key);
|
|
87213
|
+
if (stored?.harnessSessionId) {
|
|
87214
|
+
notifyNativeSessionLost({
|
|
87215
|
+
chatroomId: opts.chatroomId,
|
|
87216
|
+
role: opts.role,
|
|
87217
|
+
harnessSessionId: stored.harnessSessionId
|
|
87218
|
+
});
|
|
87219
|
+
}
|
|
87220
|
+
}
|
|
87221
|
+
resolveCursorSdkReopenWantResume(hadRunError, attempt, ctx) {
|
|
87222
|
+
if (hadRunError && attempt <= CURSOR_SDK_SESSION_RESUME_FIRST_ATTEMPTS) {
|
|
87223
|
+
return true;
|
|
87224
|
+
}
|
|
87225
|
+
if (hadRunError) {
|
|
87226
|
+
return false;
|
|
87227
|
+
}
|
|
87228
|
+
return ctx.wantResume ?? true;
|
|
87229
|
+
}
|
|
87230
|
+
async retryCursorSdkSessionReopen(opts, ctx, hadRunError) {
|
|
87154
87231
|
const key = agentKey3(opts.chatroomId, opts.role);
|
|
87155
87232
|
if (this.sessionReopenRetryInFlight.has(key)) {
|
|
87156
87233
|
return;
|
|
@@ -87159,11 +87236,14 @@ class AgentProcessManager {
|
|
|
87159
87236
|
const harness = ctx.harness;
|
|
87160
87237
|
const model = ctx.model;
|
|
87161
87238
|
const workingDir = ctx.workingDir;
|
|
87162
|
-
const wantResume = coldRestartAfterRunError ? false : ctx.wantResume ?? true;
|
|
87163
|
-
const storedSessionId = this.lastHarnessSessions.get(key)?.harnessSessionId;
|
|
87164
87239
|
let lastError = "unknown";
|
|
87165
87240
|
try {
|
|
87166
87241
|
for (let attempt = 1;attempt <= CURSOR_SDK_SESSION_REOPEN_MAX_ATTEMPTS; attempt++) {
|
|
87242
|
+
if (hadRunError && attempt === CURSOR_SDK_SESSION_RESUME_FIRST_ATTEMPTS + 1) {
|
|
87243
|
+
this.clearHarnessSessionAfterResumePhaseFailure(key, opts);
|
|
87244
|
+
}
|
|
87245
|
+
const wantResume = this.resolveCursorSdkReopenWantResume(hadRunError, attempt, ctx);
|
|
87246
|
+
const storedSessionId = this.lastHarnessSessions.get(key)?.harnessSessionId;
|
|
87167
87247
|
await this.emitSessionReopenRetry(opts.chatroomId, opts.role, attempt, attempt > 1 ? lastError : undefined, storedSessionId);
|
|
87168
87248
|
const result = await this.ensureRunning({
|
|
87169
87249
|
chatroomId: opts.chatroomId,
|
|
@@ -87345,13 +87425,6 @@ class AgentProcessManager {
|
|
|
87345
87425
|
try {
|
|
87346
87426
|
await this.killExistingBeforeSpawn(opts.chatroomId, opts.role);
|
|
87347
87427
|
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
87428
|
return result;
|
|
87356
87429
|
} finally {
|
|
87357
87430
|
if (slot.pendingOperation) {
|
|
@@ -87744,9 +87817,25 @@ class AgentProcessManager {
|
|
|
87744
87817
|
this.registerSpawnCallbacks(slot, opts, spawnResult, pid);
|
|
87745
87818
|
await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
|
|
87746
87819
|
}
|
|
87747
|
-
async emitNativeWaiting(chatroomId, role, harness) {
|
|
87820
|
+
async emitNativeWaiting(chatroomId, role, harness, reason = "spawn") {
|
|
87748
87821
|
if (!getHarnessCapabilities(harness).supportsNativeIntegration)
|
|
87749
|
-
return;
|
|
87822
|
+
return false;
|
|
87823
|
+
if (reason === "turn-end") {
|
|
87824
|
+
try {
|
|
87825
|
+
const participant = await this.deps.backend.query(api.participants.getByRole, {
|
|
87826
|
+
sessionId: this.deps.sessionId,
|
|
87827
|
+
chatroomId,
|
|
87828
|
+
role
|
|
87829
|
+
});
|
|
87830
|
+
if (!shouldEmitNativeWaitingOnTurnEnd(participant?.lastStatus)) {
|
|
87831
|
+
console.log(`[AgentProcessManager] Skipping native:waiting for ${role} — active work (${participant?.lastStatus})`);
|
|
87832
|
+
return false;
|
|
87833
|
+
}
|
|
87834
|
+
} catch (err) {
|
|
87835
|
+
console.log(` ⚠️ Failed to check status before native:waiting for ${role}: ${err.message}`);
|
|
87836
|
+
return false;
|
|
87837
|
+
}
|
|
87838
|
+
}
|
|
87750
87839
|
try {
|
|
87751
87840
|
await this.deps.backend.mutation(api.participants.join, {
|
|
87752
87841
|
sessionId: this.deps.sessionId,
|
|
@@ -87754,8 +87843,10 @@ class AgentProcessManager {
|
|
|
87754
87843
|
role,
|
|
87755
87844
|
action: NATIVE_WAITING_ACTION
|
|
87756
87845
|
});
|
|
87846
|
+
return true;
|
|
87757
87847
|
} catch (err) {
|
|
87758
87848
|
console.log(` ⚠️ Failed to emit native:waiting for ${role}: ${err.message}`);
|
|
87849
|
+
return false;
|
|
87759
87850
|
}
|
|
87760
87851
|
}
|
|
87761
87852
|
async doEnsureRunning(key, slot, opts) {
|
|
@@ -87909,11 +88000,13 @@ var init_agent_process_manager = __esm(() => {
|
|
|
87909
88000
|
init_api3();
|
|
87910
88001
|
init_orphan_tracker();
|
|
87911
88002
|
init_native_harness_session_exit();
|
|
88003
|
+
init_native_task_delivery_coordinator();
|
|
87912
88004
|
init_agent_lifecycle();
|
|
87913
88005
|
init_abort_resume_storm();
|
|
87914
88006
|
init_classify_resume_storm_reason();
|
|
87915
88007
|
init_terminal_provider_error();
|
|
87916
88008
|
init_handle_turn_completed();
|
|
88009
|
+
init_predicates();
|
|
87917
88010
|
init_spawn_policy();
|
|
87918
88011
|
init_agent_lifecycle_runtime();
|
|
87919
88012
|
init_agent_lifecycle_types();
|
|
@@ -87927,7 +88020,7 @@ class SpawnRateLimiter {
|
|
|
87927
88020
|
this.config = { ...DEFAULT_CONFIG2, ...config3 };
|
|
87928
88021
|
}
|
|
87929
88022
|
tryConsume(chatroomId, reason) {
|
|
87930
|
-
if (reason.startsWith("user.") || reason === "platform.
|
|
88023
|
+
if (reason.startsWith("user.") || reason === "platform.cursor_sdk_session_reopen") {
|
|
87931
88024
|
return { allowed: true };
|
|
87932
88025
|
}
|
|
87933
88026
|
const bucket = this._getOrCreateBucket(chatroomId);
|
|
@@ -88866,6 +88959,9 @@ class WorkingSnapshot {
|
|
|
88866
88959
|
getByKey(key) {
|
|
88867
88960
|
return this.rows.get(key);
|
|
88868
88961
|
}
|
|
88962
|
+
upsertRow(row) {
|
|
88963
|
+
this.rows.set(this.opts.rowKey(row), row);
|
|
88964
|
+
}
|
|
88869
88965
|
getBySignal(signal) {
|
|
88870
88966
|
return this.rows.get(this.opts.signalKey(signal));
|
|
88871
88967
|
}
|
|
@@ -88903,8 +88999,32 @@ function mergeSignalIntoTaskSnapshot(existing, signal) {
|
|
|
88903
88999
|
}
|
|
88904
89000
|
};
|
|
88905
89001
|
}
|
|
89002
|
+
function mergePresenceIntoTaskSnapshot(existing, presence) {
|
|
89003
|
+
if (!existing) {
|
|
89004
|
+
return;
|
|
89005
|
+
}
|
|
89006
|
+
return {
|
|
89007
|
+
...existing,
|
|
89008
|
+
participant: {
|
|
89009
|
+
lastSeenAction: presence.lastSeenAction ?? existing.participant?.lastSeenAction ?? null,
|
|
89010
|
+
lastSeenAt: presence.lastSeenAt,
|
|
89011
|
+
lastStatus: existing.participant?.lastStatus ?? null
|
|
89012
|
+
}
|
|
89013
|
+
};
|
|
89014
|
+
}
|
|
88906
89015
|
function createTaskMonitorSnapshot() {
|
|
88907
|
-
|
|
89016
|
+
const base = new WorkingSnapshot(taskMonitorSnapshotOptions);
|
|
89017
|
+
return Object.assign(base, {
|
|
89018
|
+
mergePresence(presence) {
|
|
89019
|
+
const key = taskSnapshotKey(presence.taskId, presence.role);
|
|
89020
|
+
const existing = base.getByKey(key);
|
|
89021
|
+
const merged = mergePresenceIntoTaskSnapshot(existing, presence);
|
|
89022
|
+
if (merged) {
|
|
89023
|
+
base.upsertRow(merged);
|
|
89024
|
+
}
|
|
89025
|
+
return merged;
|
|
89026
|
+
}
|
|
89027
|
+
});
|
|
88908
89028
|
}
|
|
88909
89029
|
var taskMonitorSnapshotOptions;
|
|
88910
89030
|
var init_task_monitor_snapshot = __esm(() => {
|
|
@@ -89154,106 +89274,46 @@ var runIncrementalSubscribeLive = (opts) => exports_Effect.gen(function* () {
|
|
|
89154
89274
|
yield* exports_Fiber.interrupt(workerFiber);
|
|
89155
89275
|
})
|
|
89156
89276
|
};
|
|
89157
|
-
})
|
|
89158
|
-
const clock4 = yield* IntervalClock;
|
|
89159
|
-
const backoffCfg = opts.backoff ?? { initialMs: 1000, maxMs: 30000 };
|
|
89160
|
-
let backoffMs = opts.intervalMs;
|
|
89161
|
-
let stopped = false;
|
|
89162
|
-
const loopFiber = yield* exports_Effect.forkDaemon(exports_Effect.gen(function* () {
|
|
89163
|
-
while (!stopped) {
|
|
89164
|
-
const pollOutcome = yield* exports_Effect.either(exports_Effect.tryPromise(() => opts.poll(opts.args)));
|
|
89165
|
-
if (pollOutcome._tag === "Left") {
|
|
89166
|
-
backoffMs = Math.min(backoffMs === opts.intervalMs ? backoffCfg.initialMs : backoffMs * 2, backoffCfg.maxMs);
|
|
89167
|
-
yield* clock4.sleep(backoffMs);
|
|
89168
|
-
continue;
|
|
89169
|
-
}
|
|
89170
|
-
yield* opts.onResult(pollOutcome.right);
|
|
89171
|
-
backoffMs = opts.intervalMs;
|
|
89172
|
-
yield* clock4.sleep(opts.intervalMs);
|
|
89173
|
-
}
|
|
89174
|
-
}));
|
|
89175
|
-
return {
|
|
89176
|
-
stop: () => exports_Effect.gen(function* () {
|
|
89177
|
-
stopped = true;
|
|
89178
|
-
yield* exports_Fiber.interrupt(loopFiber);
|
|
89179
|
-
})
|
|
89180
|
-
};
|
|
89181
|
-
}), runReconcilePollLive = (opts) => runReconcilePoll(opts).pipe(exports_Effect.provide(IntervalClockLive));
|
|
89277
|
+
});
|
|
89182
89278
|
var init_feed_runtime = __esm(() => {
|
|
89183
89279
|
init_esm();
|
|
89184
89280
|
init_layers();
|
|
89185
89281
|
init_subscribe_loop();
|
|
89186
89282
|
});
|
|
89187
89283
|
|
|
89188
|
-
// src/infrastructure/incremental-sync/
|
|
89189
|
-
var
|
|
89190
|
-
|
|
89191
|
-
|
|
89192
|
-
|
|
89193
|
-
|
|
89194
|
-
|
|
89195
|
-
yield* opts.onReconcileRows(rows).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89196
|
-
}
|
|
89197
|
-
}
|
|
89198
|
-
const seedKey = yield* exports_Effect.tryPromise(() => opts.seedCursor()).pipe(exports_Effect.orElseSucceed(() => null));
|
|
89199
|
-
const hydrateFromReconcile = async () => {
|
|
89200
|
-
const result = await opts.fetchReconcile();
|
|
89201
|
-
opts.snapshot.replaceAll(opts.extractReconcileRows(result));
|
|
89284
|
+
// src/infrastructure/incremental-sync/feeds/assigned-task-presence.ts
|
|
89285
|
+
var assignedTaskPresenceFeedDef, assignedTaskPresenceSubscribeTarget, ASSIGNED_TASK_PRESENCE_FEED_LIMIT = 50, ASSIGNED_TASK_PRESENCE_FEED_BUFFER;
|
|
89286
|
+
var init_assigned_task_presence = __esm(() => {
|
|
89287
|
+
init_api3();
|
|
89288
|
+
assignedTaskPresenceFeedDef = {
|
|
89289
|
+
name: "assigned-task-presence",
|
|
89290
|
+
itemKey: (item) => `${item.presenceUpdatedAt}:${item.taskId}:${item.role}`
|
|
89202
89291
|
};
|
|
89203
|
-
|
|
89204
|
-
|
|
89205
|
-
|
|
89206
|
-
|
|
89292
|
+
assignedTaskPresenceSubscribeTarget = {
|
|
89293
|
+
query: api.machines.subscribeAssignedTaskPresenceSince,
|
|
89294
|
+
buildArgs: (args2, afterKey, limit) => ({
|
|
89295
|
+
sessionId: args2.sessionId,
|
|
89296
|
+
machineId: args2.machineId,
|
|
89297
|
+
afterPresenceKey: afterKey ?? undefined,
|
|
89298
|
+
limit
|
|
89299
|
+
}),
|
|
89300
|
+
parsePage: (result) => {
|
|
89301
|
+
const page = result;
|
|
89302
|
+
return {
|
|
89303
|
+
items: page.items,
|
|
89304
|
+
highKey: page.highPresenceKey,
|
|
89305
|
+
hasMore: page.hasMore
|
|
89306
|
+
};
|
|
89207
89307
|
}
|
|
89208
|
-
await hydrateFromReconcile();
|
|
89209
|
-
return opts.snapshot.mergeSignal(signal) ?? opts.snapshot.getBySignal(signal);
|
|
89210
89308
|
};
|
|
89211
|
-
|
|
89212
|
-
|
|
89213
|
-
|
|
89214
|
-
target: opts.target,
|
|
89215
|
-
args: opts.args,
|
|
89216
|
-
buffer: opts.buffer,
|
|
89217
|
-
subscribe: opts.subscribe,
|
|
89218
|
-
initialAfterKey: seedKey,
|
|
89219
|
-
onError: opts.onSubscribeError,
|
|
89220
|
-
onItem: ({ item: signal, ack }) => exports_Effect.gen(function* () {
|
|
89221
|
-
ack();
|
|
89222
|
-
if (opts.isStopped()) {
|
|
89223
|
-
return;
|
|
89224
|
-
}
|
|
89225
|
-
const row = yield* exports_Effect.tryPromise(() => resolveRowForSignal(signal));
|
|
89226
|
-
if (!row) {
|
|
89227
|
-
return;
|
|
89228
|
-
}
|
|
89229
|
-
yield* opts.onSignalRow(row).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89230
|
-
})
|
|
89231
|
-
});
|
|
89232
|
-
const reconcileHandle = yield* runReconcilePollLive({
|
|
89233
|
-
name: `${opts.name}-reconcile`,
|
|
89234
|
-
poll: () => opts.fetchReconcile(),
|
|
89235
|
-
args: undefined,
|
|
89236
|
-
intervalMs: opts.reconcileIntervalMs,
|
|
89237
|
-
onResult: (result) => exports_Effect.gen(function* () {
|
|
89238
|
-
const rows = opts.extractReconcileRows(result);
|
|
89239
|
-
opts.snapshot.replaceAll(rows);
|
|
89240
|
-
yield* opts.onReconcileRows(rows).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89241
|
-
})
|
|
89242
|
-
});
|
|
89243
|
-
return {
|
|
89244
|
-
stop: () => exports_Effect.gen(function* () {
|
|
89245
|
-
yield* signalHandle.stop();
|
|
89246
|
-
yield* reconcileHandle.stop();
|
|
89247
|
-
})
|
|
89309
|
+
ASSIGNED_TASK_PRESENCE_FEED_BUFFER = {
|
|
89310
|
+
maxSize: 200,
|
|
89311
|
+
dedupe: true
|
|
89248
89312
|
};
|
|
89249
89313
|
});
|
|
89250
|
-
var init_dual_channel_feed = __esm(() => {
|
|
89251
|
-
init_esm();
|
|
89252
|
-
init_feed_runtime();
|
|
89253
|
-
});
|
|
89254
89314
|
|
|
89255
89315
|
// src/infrastructure/incremental-sync/feeds/assigned-task-signals.ts
|
|
89256
|
-
var assignedTaskSignalsFeedDef, assignedTaskSignalsSubscribeTarget, ASSIGNED_TASK_SIGNAL_FEED_LIMIT = 50, ASSIGNED_TASK_SIGNAL_FEED_BUFFER
|
|
89316
|
+
var assignedTaskSignalsFeedDef, assignedTaskSignalsSubscribeTarget, ASSIGNED_TASK_SIGNAL_FEED_LIMIT = 50, ASSIGNED_TASK_SIGNAL_FEED_BUFFER;
|
|
89257
89317
|
var init_assigned_task_signals = __esm(() => {
|
|
89258
89318
|
init_api3();
|
|
89259
89319
|
assignedTaskSignalsFeedDef = {
|
|
@@ -89277,16 +89337,32 @@ var init_assigned_task_signals = __esm(() => {
|
|
|
89277
89337
|
});
|
|
89278
89338
|
|
|
89279
89339
|
// src/commands/machine/daemon-start/task-monitor.ts
|
|
89340
|
+
async function seedSignalCursor(session2) {
|
|
89341
|
+
const seedPage = await session2.backend.query(api.machines.subscribeAssignedTaskSignalsSince, {
|
|
89342
|
+
sessionId: session2.sessionId,
|
|
89343
|
+
machineId: session2.machineId,
|
|
89344
|
+
limit: ASSIGNED_TASK_SIGNAL_FEED_LIMIT
|
|
89345
|
+
});
|
|
89346
|
+
return seedPage?.highKey ?? null;
|
|
89347
|
+
}
|
|
89348
|
+
async function seedPresenceCursor(session2) {
|
|
89349
|
+
const seedPage = await session2.backend.query(api.machines.subscribeAssignedTaskPresenceSince, {
|
|
89350
|
+
sessionId: session2.sessionId,
|
|
89351
|
+
machineId: session2.machineId,
|
|
89352
|
+
limit: ASSIGNED_TASK_PRESENCE_FEED_LIMIT
|
|
89353
|
+
});
|
|
89354
|
+
return seedPage?.highPresenceKey ?? null;
|
|
89355
|
+
}
|
|
89280
89356
|
function resolveTaskWantResume(task) {
|
|
89281
|
-
return
|
|
89357
|
+
return sessionAugmentationToWantResume(resolveSessionAugmentationForRole(task.taskContent ?? "", task.agentConfig.role));
|
|
89282
89358
|
}
|
|
89283
89359
|
function buildCliNudgeLogLine(task) {
|
|
89284
89360
|
const { chatroomId, agentConfig } = task;
|
|
89285
89361
|
const { role } = agentConfig;
|
|
89286
89362
|
const lastSeenAction = task.participant?.lastSeenAction ?? "unknown";
|
|
89287
|
-
const
|
|
89363
|
+
const augmentationMode = resolveSessionAugmentationForRole(task.taskContent ?? "", role);
|
|
89288
89364
|
const wantResume = resolveTaskWantResume(task);
|
|
89289
|
-
return `[TaskMonitor] nudging ${role}@${chatroomId} — pending task ${task.taskId}, lastSeenAction=${lastSeenAction},
|
|
89365
|
+
return `[TaskMonitor] nudging ${role}@${chatroomId} — pending task ${task.taskId}, lastSeenAction=${lastSeenAction}, session_augmentation=${augmentationMode}, wantResume=${wantResume}`;
|
|
89290
89366
|
}
|
|
89291
89367
|
function resolveTaskRunnerContextFromFull(task) {
|
|
89292
89368
|
const { chatroomId, agentConfig } = task;
|
|
@@ -89302,11 +89378,12 @@ function resolveTaskRunnerContextFromFull(task) {
|
|
|
89302
89378
|
wantResume: resolveTaskWantResume(task)
|
|
89303
89379
|
};
|
|
89304
89380
|
}
|
|
89305
|
-
function executeCliNudge(task, runtime4, effectContext2, agentMgr) {
|
|
89381
|
+
function executeCliNudge(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
89306
89382
|
const ctx = resolveTaskRunnerContextFromFull(task);
|
|
89307
89383
|
if (!ctx)
|
|
89308
89384
|
return;
|
|
89309
89385
|
const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
|
|
89386
|
+
const augmentationMode = resolveSessionAugmentationForRole(task.taskContent ?? "", role);
|
|
89310
89387
|
exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
|
|
89311
89388
|
yield* agentMgr.stop({ chatroomId, role, reason: "platform.task_monitor_nudge" });
|
|
89312
89389
|
yield* agentMgr.ensureRunning({
|
|
@@ -89318,6 +89395,20 @@ function executeCliNudge(task, runtime4, effectContext2, agentMgr) {
|
|
|
89318
89395
|
reason: "platform.task_monitor_nudge",
|
|
89319
89396
|
wantResume
|
|
89320
89397
|
});
|
|
89398
|
+
if (roleSupportsSessionAugmentation(role)) {
|
|
89399
|
+
yield* exports_Effect.tryPromise({
|
|
89400
|
+
try: () => sessionDeps.backend.mutation(api.machines.emitSessionAugmented, {
|
|
89401
|
+
sessionId: sessionDeps.sessionId,
|
|
89402
|
+
machineId,
|
|
89403
|
+
chatroomId,
|
|
89404
|
+
role,
|
|
89405
|
+
taskId: task.taskId,
|
|
89406
|
+
mode: augmentationMode,
|
|
89407
|
+
newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode)
|
|
89408
|
+
}),
|
|
89409
|
+
catch: (err) => err
|
|
89410
|
+
}).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89411
|
+
}
|
|
89321
89412
|
}).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] nudge failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
|
|
89322
89413
|
}
|
|
89323
89414
|
function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
|
|
@@ -89347,16 +89438,16 @@ async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
|
|
|
89347
89438
|
});
|
|
89348
89439
|
return result;
|
|
89349
89440
|
}
|
|
89350
|
-
function runCliNudgeEffect(task, runtime4, effectContext2, agentMgr) {
|
|
89441
|
+
function runCliNudgeEffect(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
89351
89442
|
console.log(buildCliNudgeLogLine(task));
|
|
89352
|
-
executeCliNudge(task, runtime4, effectContext2, agentMgr);
|
|
89443
|
+
executeCliNudge(task, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
89353
89444
|
}
|
|
89354
89445
|
async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
89355
89446
|
for (const row of listTasksReadyForNudge(tasks, now, cooldown)) {
|
|
89356
89447
|
const full = await fetchTaskForAction(sessionDeps, machineId, row);
|
|
89357
89448
|
if (!full)
|
|
89358
89449
|
continue;
|
|
89359
|
-
runCliNudgeEffect(full, runtime4, effectContext2, agentMgr);
|
|
89450
|
+
runCliNudgeEffect(full, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
89360
89451
|
}
|
|
89361
89452
|
}
|
|
89362
89453
|
async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
|
|
@@ -89384,7 +89475,7 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
|
|
|
89384
89475
|
sessionDeps,
|
|
89385
89476
|
machineId
|
|
89386
89477
|
});
|
|
89387
|
-
if (pass === "
|
|
89478
|
+
if (pass === "presence") {
|
|
89388
89479
|
await nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
|
|
89389
89480
|
}
|
|
89390
89481
|
}
|
|
@@ -89415,12 +89506,22 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
|
89415
89506
|
monitorPassInFlight = false;
|
|
89416
89507
|
});
|
|
89417
89508
|
};
|
|
89418
|
-
|
|
89509
|
+
yield* exports_Effect.tryPromise(() => session2.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
|
|
89419
89510
|
sessionId: session2.sessionId,
|
|
89420
89511
|
machineId: session2.machineId
|
|
89421
|
-
});
|
|
89422
|
-
const
|
|
89423
|
-
|
|
89512
|
+
})).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89513
|
+
const hydrate = yield* exports_Effect.tryPromise(() => session2.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
|
|
89514
|
+
sessionId: session2.sessionId,
|
|
89515
|
+
machineId: session2.machineId
|
|
89516
|
+
})).pipe(exports_Effect.orElseSucceed(() => ({ tasks: [] })));
|
|
89517
|
+
const hydrateTasks = hydrate.tasks ?? [];
|
|
89518
|
+
snapshot.replaceAll(hydrateTasks);
|
|
89519
|
+
if (hydrateTasks.length > 0) {
|
|
89520
|
+
yield* exports_Effect.tryPromise(() => processTasksUpdate(hydrateTasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, "presence")).pipe(exports_Effect.catchAll(() => exports_Effect.void));
|
|
89521
|
+
}
|
|
89522
|
+
const signalSeedKey = yield* exports_Effect.tryPromise(() => seedSignalCursor(session2)).pipe(exports_Effect.orElseSucceed(() => null));
|
|
89523
|
+
const presenceSeedKey = yield* exports_Effect.tryPromise(() => seedPresenceCursor(session2)).pipe(exports_Effect.orElseSucceed(() => null));
|
|
89524
|
+
const signalHandle = yield* runIncrementalSubscribeLive({
|
|
89424
89525
|
wsClient: wsClient2,
|
|
89425
89526
|
def: assignedTaskSignalsFeedDef,
|
|
89426
89527
|
target: assignedTaskSignalsSubscribeTarget,
|
|
@@ -89430,44 +89531,64 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
|
|
|
89430
89531
|
},
|
|
89431
89532
|
buffer: ASSIGNED_TASK_SIGNAL_FEED_BUFFER,
|
|
89432
89533
|
subscribe: { limit: ASSIGNED_TASK_SIGNAL_FEED_LIMIT },
|
|
89433
|
-
|
|
89434
|
-
|
|
89435
|
-
|
|
89436
|
-
|
|
89437
|
-
|
|
89438
|
-
|
|
89534
|
+
initialAfterKey: signalSeedKey,
|
|
89535
|
+
onError: (err) => console.warn(`[${formatTimestamp()}] ⚠️ Task signal subscription error: ${getErrorMessage(err)}`),
|
|
89536
|
+
onItem: ({ item: signal, ack }) => exports_Effect.gen(function* () {
|
|
89537
|
+
ack();
|
|
89538
|
+
if (stopped)
|
|
89539
|
+
return;
|
|
89540
|
+
const row = snapshot.mergeSignal(signal);
|
|
89541
|
+
if (!row)
|
|
89542
|
+
return;
|
|
89543
|
+
yield* exports_Effect.sync(() => {
|
|
89544
|
+
runMonitorPass([row], "signal");
|
|
89545
|
+
});
|
|
89546
|
+
})
|
|
89547
|
+
});
|
|
89548
|
+
const presenceHandle = yield* runIncrementalSubscribeLive({
|
|
89549
|
+
wsClient: wsClient2,
|
|
89550
|
+
def: assignedTaskPresenceFeedDef,
|
|
89551
|
+
target: assignedTaskPresenceSubscribeTarget,
|
|
89552
|
+
args: {
|
|
89553
|
+
sessionId: session2.sessionId,
|
|
89554
|
+
machineId: session2.machineId
|
|
89555
|
+
},
|
|
89556
|
+
buffer: ASSIGNED_TASK_PRESENCE_FEED_BUFFER,
|
|
89557
|
+
subscribe: { limit: ASSIGNED_TASK_PRESENCE_FEED_LIMIT },
|
|
89558
|
+
initialAfterKey: presenceSeedKey,
|
|
89559
|
+
onError: (err) => console.warn(`[${formatTimestamp()}] ⚠️ Task presence subscription error: ${getErrorMessage(err)}`),
|
|
89560
|
+
onItem: ({ item: presence, ack }) => exports_Effect.gen(function* () {
|
|
89561
|
+
ack();
|
|
89562
|
+
if (stopped)
|
|
89563
|
+
return;
|
|
89564
|
+
const row = snapshot.mergePresence(presence);
|
|
89565
|
+
if (!row)
|
|
89566
|
+
return;
|
|
89567
|
+
yield* exports_Effect.sync(() => {
|
|
89568
|
+
runMonitorPass([row], "presence");
|
|
89439
89569
|
});
|
|
89440
|
-
return seedPage?.highKey ?? null;
|
|
89441
|
-
},
|
|
89442
|
-
fetchReconcile: () => queryReconcileSnapshots(),
|
|
89443
|
-
extractReconcileRows: (result) => result?.tasks ?? [],
|
|
89444
|
-
reconcileIntervalMs: ASSIGNED_TASK_RECONCILE_INTERVAL_MS,
|
|
89445
|
-
isStopped: () => stopped,
|
|
89446
|
-
onSubscribeError: (err) => console.warn(`[${formatTimestamp()}] ⚠️ Task signal subscription error: ${getErrorMessage(err)}`),
|
|
89447
|
-
onSignalRow: (row) => exports_Effect.sync(() => {
|
|
89448
|
-
runMonitorPass([row], "signal");
|
|
89449
|
-
}),
|
|
89450
|
-
onReconcileRows: (tasks) => exports_Effect.sync(() => {
|
|
89451
|
-
runMonitorPass([...tasks], "reconcile");
|
|
89452
89570
|
})
|
|
89453
89571
|
});
|
|
89454
89572
|
return {
|
|
89455
89573
|
stop() {
|
|
89456
89574
|
stopped = true;
|
|
89457
|
-
exports_Effect.runPromise(
|
|
89575
|
+
exports_Effect.runPromise(signalHandle.stop());
|
|
89576
|
+
exports_Effect.runPromise(presenceHandle.stop());
|
|
89458
89577
|
console.log(`[${formatTimestamp()}] \uD83D\uDCCB Task-monitor stopped`);
|
|
89459
89578
|
}
|
|
89460
89579
|
};
|
|
89461
89580
|
});
|
|
89462
89581
|
var init_task_monitor = __esm(() => {
|
|
89463
|
-
|
|
89582
|
+
init_team_agent_settings();
|
|
89583
|
+
init_parse_session_augmentation();
|
|
89464
89584
|
init_esm();
|
|
89465
89585
|
init_daemon_services();
|
|
89466
89586
|
init_native_task_delivery_coordinator();
|
|
89467
89587
|
init_task_monitor_logic();
|
|
89468
89588
|
init_task_monitor_snapshot();
|
|
89469
89589
|
init_api3();
|
|
89470
|
-
|
|
89590
|
+
init_feed_runtime();
|
|
89591
|
+
init_assigned_task_presence();
|
|
89471
89592
|
init_assigned_task_signals();
|
|
89472
89593
|
init_convex_error();
|
|
89473
89594
|
});
|
|
@@ -90975,4 +91096,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
90975
91096
|
});
|
|
90976
91097
|
program2.parse();
|
|
90977
91098
|
|
|
90978
|
-
//# debugId=
|
|
91099
|
+
//# debugId=9DA8A47CE355B57D64756E2164756E21
|