opencode-auto-resume 1.0.19 → 1.0.20
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 +81 -32
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12583,9 +12583,9 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12583
12583
|
return;
|
|
12584
12584
|
}
|
|
12585
12585
|
w.continuing = true;
|
|
12586
|
+
let agent;
|
|
12587
|
+
let model;
|
|
12586
12588
|
try {
|
|
12587
|
-
let agent2;
|
|
12588
|
-
let model2;
|
|
12589
12589
|
const msgResp = await ctx.client.session.messages({ path: { id: sid } });
|
|
12590
12590
|
const msgs = extractMessages(msgResp);
|
|
12591
12591
|
for (let i = msgs.length - 1;i >= 0; i--) {
|
|
@@ -12594,11 +12594,11 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12594
12594
|
if (role === "user") {
|
|
12595
12595
|
const rawAgent = msg.agent;
|
|
12596
12596
|
if (typeof rawAgent === "string") {
|
|
12597
|
-
|
|
12597
|
+
agent = rawAgent;
|
|
12598
12598
|
} else {
|
|
12599
12599
|
const fallbackAgent = msg.info?.agent;
|
|
12600
12600
|
if (typeof fallbackAgent === "string") {
|
|
12601
|
-
|
|
12601
|
+
agent = fallbackAgent;
|
|
12602
12602
|
}
|
|
12603
12603
|
}
|
|
12604
12604
|
let rawModel = msg.model;
|
|
@@ -12606,7 +12606,7 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12606
12606
|
rawModel = msg.info?.model;
|
|
12607
12607
|
}
|
|
12608
12608
|
if (rawModel && typeof rawModel.providerID === "string" && typeof rawModel.modelID === "string") {
|
|
12609
|
-
|
|
12609
|
+
model = {
|
|
12610
12610
|
providerID: rawModel.providerID,
|
|
12611
12611
|
modelID: rawModel.modelID
|
|
12612
12612
|
};
|
|
@@ -12618,11 +12618,11 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12618
12618
|
path: { id: sid },
|
|
12619
12619
|
body: {
|
|
12620
12620
|
parts: [{ type: "text", text }],
|
|
12621
|
-
agent
|
|
12622
|
-
model
|
|
12621
|
+
agent,
|
|
12622
|
+
model
|
|
12623
12623
|
}
|
|
12624
12624
|
});
|
|
12625
|
-
await log("debug", `${short(sid)} - prompt sent with agent: ${
|
|
12625
|
+
await log("debug", `${short(sid)} - prompt sent with agent: ${agent ?? "(default)"}, model: ${model ? `${model.providerID}/${model.modelID}` : "(default)"}`);
|
|
12626
12626
|
recordContinue(sid);
|
|
12627
12627
|
w.lastRetryAt = Date.now();
|
|
12628
12628
|
} catch (err) {
|
|
@@ -12679,6 +12679,46 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12679
12679
|
return false;
|
|
12680
12680
|
}
|
|
12681
12681
|
}
|
|
12682
|
+
async function hasBusySubagents(parentSid) {
|
|
12683
|
+
try {
|
|
12684
|
+
const response = await ctx.client.session.list();
|
|
12685
|
+
const allSessions = extractMessages(response);
|
|
12686
|
+
for (const s of allSessions) {
|
|
12687
|
+
const sId = s.id;
|
|
12688
|
+
if (!sId || sId === parentSid)
|
|
12689
|
+
continue;
|
|
12690
|
+
const status = s.status;
|
|
12691
|
+
if (status === "busy")
|
|
12692
|
+
return true;
|
|
12693
|
+
}
|
|
12694
|
+
return false;
|
|
12695
|
+
} catch (err) {
|
|
12696
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
12697
|
+
await log("debug", `hasBusySubagents failed for ${short(parentSid)}: ${errMsg}`);
|
|
12698
|
+
return false;
|
|
12699
|
+
}
|
|
12700
|
+
}
|
|
12701
|
+
async function checkSessionHasActiveTool(sid) {
|
|
12702
|
+
try {
|
|
12703
|
+
const response = await ctx.client.session.messages({ path: { id: sid } });
|
|
12704
|
+
const messages = extractMessages(response);
|
|
12705
|
+
const lastMsg = messages[messages.length - 1];
|
|
12706
|
+
if (!lastMsg)
|
|
12707
|
+
return false;
|
|
12708
|
+
const rawRole = lastMsg?.role ?? lastMsg?.info?.role;
|
|
12709
|
+
if (rawRole !== "assistant")
|
|
12710
|
+
return false;
|
|
12711
|
+
const toolCall = lastMsg.toolCall;
|
|
12712
|
+
const toolCalls = lastMsg.tool_calls;
|
|
12713
|
+
const parts = lastMsg.parts;
|
|
12714
|
+
const hasToolCall = toolCall !== undefined || (toolCalls?.length ?? 0) > 0 || (parts?.some((p) => p.type === "tool-call" || p.type === "tool_use") ?? false);
|
|
12715
|
+
return hasToolCall;
|
|
12716
|
+
} catch (err) {
|
|
12717
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
12718
|
+
await log("debug", `checkSessionHasActiveTool failed for ${short(sid)}: ${errMsg}`);
|
|
12719
|
+
return false;
|
|
12720
|
+
}
|
|
12721
|
+
}
|
|
12682
12722
|
async function checkSubagentStatus(parentSid) {
|
|
12683
12723
|
try {
|
|
12684
12724
|
const response = await ctx.client.session.list();
|
|
@@ -12698,10 +12738,15 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12698
12738
|
const rawRole = lastMsg?.role ?? lastMsg?.info?.role;
|
|
12699
12739
|
if (lastMsg && rawRole === "assistant" && (("error" in lastMsg) || lastMsg.info && ("error" in lastMsg.info))) {
|
|
12700
12740
|
await log("debug", `Subagent ${short(sId)} appears crashed`);
|
|
12701
|
-
return "crashed";
|
|
12741
|
+
return { status: "crashed" };
|
|
12702
12742
|
}
|
|
12703
12743
|
const msgTime = lastMsg?.time?.created ?? lastMsg?.time;
|
|
12704
|
-
|
|
12744
|
+
if (!msgTime)
|
|
12745
|
+
continue;
|
|
12746
|
+
const toolCall = lastMsg.toolCall;
|
|
12747
|
+
const toolCalls = lastMsg.tool_calls;
|
|
12748
|
+
const parts = lastMsg.parts;
|
|
12749
|
+
const hasToolCall = toolCall !== undefined || (toolCalls?.length ?? 0) > 0 || (parts?.some((p) => p.type === "tool-call") ?? false);
|
|
12705
12750
|
const isStuck = hasToolCall ? now - msgTime > SUBAGENT_STUCK_MS * 3 : now - msgTime > SUBAGENT_STUCK_MS;
|
|
12706
12751
|
if (isStuck) {
|
|
12707
12752
|
await log("debug", `Subagent ${short(sId)} stuck - no new text in >${hasToolCall ? 3 : 1}min`);
|
|
@@ -12770,10 +12815,10 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12770
12815
|
}
|
|
12771
12816
|
return false;
|
|
12772
12817
|
}
|
|
12773
|
-
function trackToolCall(w,
|
|
12818
|
+
function trackToolCall(w, toolName) {
|
|
12774
12819
|
const now = Date.now();
|
|
12775
12820
|
w.recentToolCalls = w.recentToolCalls.filter((call) => now - call.at < 120000);
|
|
12776
|
-
w.recentToolCalls.push({ toolName
|
|
12821
|
+
w.recentToolCalls.push({ toolName, at: now });
|
|
12777
12822
|
const recentTools = w.recentToolCalls.slice(-15).map((call) => call.toolName);
|
|
12778
12823
|
if (recentTools.length < 6)
|
|
12779
12824
|
return false;
|
|
@@ -12816,18 +12861,18 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12816
12861
|
continue;
|
|
12817
12862
|
const toolCall = msg.toolCall;
|
|
12818
12863
|
if (toolCall && typeof toolCall === "object" && "name" in toolCall) {
|
|
12819
|
-
const
|
|
12820
|
-
if (
|
|
12821
|
-
trackToolCall(w,
|
|
12864
|
+
const toolName = toolCall.name;
|
|
12865
|
+
if (toolName) {
|
|
12866
|
+
trackToolCall(w, toolName);
|
|
12822
12867
|
}
|
|
12823
12868
|
}
|
|
12824
12869
|
const toolCalls = msg.tool_calls;
|
|
12825
12870
|
if (toolCalls) {
|
|
12826
12871
|
for (const tc of toolCalls) {
|
|
12827
12872
|
if (typeof tc === "object" && "name" in tc) {
|
|
12828
|
-
const
|
|
12829
|
-
if (
|
|
12830
|
-
trackToolCall(w,
|
|
12873
|
+
const toolName = tc.name;
|
|
12874
|
+
if (toolName) {
|
|
12875
|
+
trackToolCall(w, toolName);
|
|
12831
12876
|
}
|
|
12832
12877
|
}
|
|
12833
12878
|
}
|
|
@@ -12847,14 +12892,15 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12847
12892
|
isReasoning = true;
|
|
12848
12893
|
} else if (partType === "tool_use") {
|
|
12849
12894
|
isToolUse = true;
|
|
12850
|
-
const
|
|
12851
|
-
text = `tool_use: ${
|
|
12895
|
+
const toolName = part.name ?? "unknown";
|
|
12896
|
+
text = `tool_use: ${toolName}`;
|
|
12852
12897
|
} else {
|
|
12853
12898
|
continue;
|
|
12854
12899
|
}
|
|
12855
12900
|
allAssistantText += text + `
|
|
12856
12901
|
`;
|
|
12857
12902
|
if (isToolUse) {
|
|
12903
|
+
const toolName = part.name ?? "unknown";
|
|
12858
12904
|
const isLoop = trackToolCall(w, toolName);
|
|
12859
12905
|
if (isLoop && w.toolLoopAttempts < 2) {
|
|
12860
12906
|
w.toolLoopAttempts++;
|
|
@@ -12880,8 +12926,8 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
12880
12926
|
if (containsToolCallAsText(text)) {
|
|
12881
12927
|
const toolMatch = text.match(/<function=([a-zA-Z_]+)/) || text.match(/<invoke\s+name=([a-zA-Z_]+)/) || text.match(/"name":\s*"([a-zA-Z_]+)/);
|
|
12882
12928
|
if (toolMatch) {
|
|
12883
|
-
const
|
|
12884
|
-
const isLoop = trackToolCall(w,
|
|
12929
|
+
const toolName = toolMatch[1] || "unknown";
|
|
12930
|
+
const isLoop = trackToolCall(w, toolName);
|
|
12885
12931
|
if (isLoop && w.toolLoopAttempts < 2) {
|
|
12886
12932
|
w.toolLoopAttempts++;
|
|
12887
12933
|
const loopCandidate = {
|
|
@@ -13117,8 +13163,13 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13117
13163
|
tryAbortAndResume(sid, w);
|
|
13118
13164
|
}
|
|
13119
13165
|
} else if (subStatus.status === "idle") {
|
|
13120
|
-
|
|
13121
|
-
|
|
13166
|
+
const hasBusySub = await hasBusySubagents(sid);
|
|
13167
|
+
if (hasBusySub) {
|
|
13168
|
+
await log("debug", `Subagents exist but not busy yet, waiting for startup...`);
|
|
13169
|
+
} else {
|
|
13170
|
+
await log("info", `Parent ${short(sid)} stuck with no active subagents. Triggering abort+resume.`);
|
|
13171
|
+
tryAbortAndResume(sid, w);
|
|
13172
|
+
}
|
|
13122
13173
|
} else {
|
|
13123
13174
|
await log("debug", `Subagent still running, waiting...`);
|
|
13124
13175
|
}
|
|
@@ -13137,6 +13188,12 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13137
13188
|
continue;
|
|
13138
13189
|
w.lastSubagentCheckAt = now;
|
|
13139
13190
|
if (w.lastActivityAt > 0 && now - w.lastActivityAt > subagentWaitMs) {
|
|
13191
|
+
const hasActiveTool = await checkSessionHasActiveTool(sid);
|
|
13192
|
+
if (hasActiveTool) {
|
|
13193
|
+
await log("debug", `Parent ${short(sid)} has active tool call, skipping abort check`);
|
|
13194
|
+
w.lastSubagentCheckAt = now;
|
|
13195
|
+
continue;
|
|
13196
|
+
}
|
|
13140
13197
|
const subStatus = await checkSubagentStatus(sid);
|
|
13141
13198
|
if (subStatus.status === "idle" || subStatus.status === "unknown") {
|
|
13142
13199
|
await log("info", `Parent ${short(sid)} stuck with no active subagents. Triggering abort+resume.`);
|
|
@@ -13365,14 +13422,6 @@ var AutoResumePlugin = async (ctx, options) => {
|
|
|
13365
13422
|
},
|
|
13366
13423
|
config: async () => {
|
|
13367
13424
|
log("info", `opencode-auto-resume config OK`);
|
|
13368
|
-
if (ctx.ui && typeof ctx.ui.toast === "function") {
|
|
13369
|
-
ctx.ui.toast({
|
|
13370
|
-
title: "Auto-Resume Plugin",
|
|
13371
|
-
message: `Loaded with ${chunkTimeoutMs}ms timeout, ${loopMaxContinues} loop attempts`,
|
|
13372
|
-
variant: "success",
|
|
13373
|
-
duration: 5000
|
|
13374
|
-
});
|
|
13375
|
-
}
|
|
13376
13425
|
},
|
|
13377
13426
|
tool: {
|
|
13378
13427
|
task_complete: taskCompleteTool
|
package/package.json
CHANGED