devez-vibe 1.9.58 → 1.9.59
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/bin/dvz.exe +0 -0
- package/bridge/claude-agent-sdk-bridge.mjs +59 -22
- package/package.json +1 -1
package/bin/dvz.exe
CHANGED
|
Binary file
|
|
@@ -2686,8 +2686,9 @@ function resumeBackgroundSubagent(session, toolUseId, pending, result) {
|
|
|
2686
2686
|
if (existing) return true;
|
|
2687
2687
|
const known = session.knownSubagents.get(taskId);
|
|
2688
2688
|
const input = pending?.input || {};
|
|
2689
|
+
// 끝난 줄과 같은 id로 돌아와야 호스트가 같은 작업의 idle 줄과 실행 줄을 함께 세우지 않는다.
|
|
2689
2690
|
const running = {
|
|
2690
|
-
id: toolUseId,
|
|
2691
|
+
id: known?.rowId || toolUseId,
|
|
2691
2692
|
toolUseId,
|
|
2692
2693
|
taskId,
|
|
2693
2694
|
background: true,
|
|
@@ -2697,8 +2698,9 @@ function resumeBackgroundSubagent(session, toolUseId, pending, result) {
|
|
|
2697
2698
|
startedAt: Date.now(),
|
|
2698
2699
|
lastSeenAt: Date.now(),
|
|
2699
2700
|
};
|
|
2700
|
-
session.subagents.set(
|
|
2701
|
+
session.subagents.set(running.id, running);
|
|
2701
2702
|
session.knownSubagents.set(taskId, {
|
|
2703
|
+
rowId: running.id,
|
|
2702
2704
|
name: running.name,
|
|
2703
2705
|
description: running.description,
|
|
2704
2706
|
backgroundTask: false,
|
|
@@ -2777,6 +2779,8 @@ function upsertStructuredSubagent(session, message) {
|
|
|
2777
2779
|
}
|
|
2778
2780
|
if (toolUseId) running.toolUseId = toolUseId;
|
|
2779
2781
|
if (taskId) running.taskId = taskId;
|
|
2782
|
+
const runId = firstLine(message.run_id || "", 80);
|
|
2783
|
+
if (runId && !isLateRun(running, runId)) running.runId = runId;
|
|
2780
2784
|
// 스크립트 Monitor는 local_bash 작업으로 와서 스냅숏 이름이 Bash가 된다.
|
|
2781
2785
|
if (session.tools?.get(toolUseId)?.name === "Monitor") running.name = "Monitor";
|
|
2782
2786
|
const parentTaskId = firstLine(message.parent_task_id || "", 80);
|
|
@@ -2786,10 +2790,12 @@ function upsertStructuredSubagent(session, message) {
|
|
|
2786
2790
|
if (subagentType || isSubagentTaskType(message.task_type)) running.backgroundTask = false;
|
|
2787
2791
|
running.lastSeenAt = Date.now();
|
|
2788
2792
|
if (running.taskId) {
|
|
2793
|
+
const known = session.knownSubagents.get(running.taskId);
|
|
2789
2794
|
session.knownSubagents.set(running.taskId, {
|
|
2790
2795
|
rowId: running.id,
|
|
2791
2796
|
name: running.name,
|
|
2792
|
-
|
|
2797
|
+
// 진행 요약으로 바뀐 설명이 아니라 호출 설명을 기억해, 다시 실행된 줄이 그 설명으로 돌아오게 한다.
|
|
2798
|
+
description: known?.description || running.description,
|
|
2793
2799
|
backgroundTask: running.backgroundTask === true,
|
|
2794
2800
|
});
|
|
2795
2801
|
}
|
|
@@ -2800,6 +2806,12 @@ function hasLiveChildren(session, taskId) {
|
|
|
2800
2806
|
return !!taskId && [...session.subagents.values()].some((agent) => agent.parentTaskId === taskId);
|
|
2801
2807
|
}
|
|
2802
2808
|
|
|
2809
|
+
// 같은 작업의 실행 id는 열린 순서대로 문자열 정렬된다. 지금 행보다 앞선 실행의
|
|
2810
|
+
// 통지는 늦게 도착한 것이라 새 실행의 행을 지우면 안 된다.
|
|
2811
|
+
function isLateRun(running, runId) {
|
|
2812
|
+
return Boolean(runId && running.runId && runId < running.runId);
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2803
2815
|
function finishStructuredSubagent(session, message) {
|
|
2804
2816
|
const taskId = firstLine(message.task_id || "", 80);
|
|
2805
2817
|
const toolUseId = firstLine(message.tool_use_id || "", 80);
|
|
@@ -2814,7 +2826,8 @@ function finishStructuredSubagent(session, message) {
|
|
|
2814
2826
|
|| (taskId && findSubagent(session, taskId));
|
|
2815
2827
|
if (!running) return wasHidden;
|
|
2816
2828
|
// 자기 백그라운드 명령을 기다리며 멈춘 에이전트는 그 명령이 끝나면 다시 돌므로 행을 남긴다.
|
|
2817
|
-
if (hasLiveChildren(session, running.taskId)
|
|
2829
|
+
if (hasLiveChildren(session, running.taskId)
|
|
2830
|
+
|| isLateRun(running, firstLine(message.run_id || "", 80))) return true;
|
|
2818
2831
|
session.subagents.delete(running.id);
|
|
2819
2832
|
emitSubagents(session);
|
|
2820
2833
|
return true;
|
|
@@ -3129,6 +3142,7 @@ function taskNotifications(message) {
|
|
|
3129
3142
|
toolUseId: notificationTag(body, "tool-use-id"),
|
|
3130
3143
|
status: notificationTag(body, "status"),
|
|
3131
3144
|
summary: notificationTag(body, "summary"),
|
|
3145
|
+
runId: firstLine(message.origin?.runId || "", 80),
|
|
3132
3146
|
});
|
|
3133
3147
|
}
|
|
3134
3148
|
return notifications;
|
|
@@ -3156,7 +3170,8 @@ function finishNotifiedSubagents(session, notifications) {
|
|
|
3156
3170
|
.find((agent) => agent.background && agent.name === name);
|
|
3157
3171
|
}
|
|
3158
3172
|
}
|
|
3159
|
-
if (!running)
|
|
3173
|
+
if (!running || isLateRun(running, notification.runId)
|
|
3174
|
+
|| hasLiveChildren(session, running.taskId)) continue;
|
|
3160
3175
|
session.subagents.delete(running.id);
|
|
3161
3176
|
emitSubagents(session);
|
|
3162
3177
|
}
|
|
@@ -6010,8 +6025,10 @@ async function runSelfTest() {
|
|
|
6010
6025
|
message: { content: [{ type: "tool_result", tool_use_id: "toolu_2", content: "resumed" }] },
|
|
6011
6026
|
tool_use_result: { success: true, resumedAgentId: "agent-1" },
|
|
6012
6027
|
});
|
|
6013
|
-
|
|
6014
|
-
|
|
6028
|
+
// 재개된 줄은 끝난 줄과 같은 id(처음 Agent 호출 id)로 돌아오고, SendMessage 호출 id로도 찾힌다.
|
|
6029
|
+
const resumed = lifecycleSession.subagents.get("toolu_1");
|
|
6030
|
+
if (!resumed?.background || resumed.taskId !== "agent-1" || resumed.name !== "Explore"
|
|
6031
|
+
|| findSubagent(lifecycleSession, "toolu_2") !== resumed) {
|
|
6015
6032
|
throw new Error(`Claude resumed subagent self-test failed: ${JSON.stringify(resumed)}`);
|
|
6016
6033
|
}
|
|
6017
6034
|
finishTurn(lifecycleSession, null, 1);
|
|
@@ -6161,36 +6178,56 @@ async function runSelfTest() {
|
|
|
6161
6178
|
}
|
|
6162
6179
|
clearSubagents(nestedSession);
|
|
6163
6180
|
// 자기 백그라운드 명령을 기다리며 멈춘 에이전트는 그 명령이 도는 동안 행을 지킨다.
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
subtype: "task_started",
|
|
6167
|
-
task_id: "agent-wait",
|
|
6168
|
-
tool_use_id: "toolu_wait",
|
|
6169
|
-
task_type: "local_agent",
|
|
6170
|
-
subagent_type: "general-purpose",
|
|
6171
|
-
});
|
|
6172
|
-
nestedSession.subagents.get("toolu_wait").background = true;
|
|
6181
|
+
// SDK 순서(접수 결과, task_started, 스냅숏, task_updated·task_notification, 스냅숏,
|
|
6182
|
+
// XML 통지)를 그대로 재생하고, 다시 실행된 뒤 늦게 온 첫 실행 통지도 무시한다.
|
|
6173
6183
|
const waitSnapshot = (tasks) => processSubagentSystemMessage(nestedSession, {
|
|
6174
6184
|
type: "system",
|
|
6175
6185
|
subtype: "background_tasks_changed",
|
|
6176
6186
|
tasks,
|
|
6177
6187
|
});
|
|
6178
|
-
|
|
6179
|
-
processSubagentSystemMessage(nestedSession, {
|
|
6188
|
+
const waitStructured = (subtype, extra) => processSubagentSystemMessage(nestedSession, {
|
|
6180
6189
|
type: "system",
|
|
6181
|
-
subtype
|
|
6190
|
+
subtype,
|
|
6182
6191
|
task_id: "agent-wait",
|
|
6183
|
-
|
|
6192
|
+
...extra,
|
|
6184
6193
|
});
|
|
6194
|
+
const waitXml = (runId) => finishNotifiedSubagents(nestedSession, taskNotifications({
|
|
6195
|
+
origin: { kind: "task-notification", runId },
|
|
6196
|
+
message: { content: [{ type: "text", text: "<task-notification><task-id>agent-wait</task-id><status>completed</status><summary>Agent \"general-purpose\" finished</summary></task-notification>" }] },
|
|
6197
|
+
}));
|
|
6198
|
+
const agentRow = { task_id: "agent-wait", task_type: "local_agent", description: "wait" };
|
|
6199
|
+
const shellRow = { task_id: "shell-wait", task_type: "local_bash", description: "sleep 300", parent_task_id: "agent-wait" };
|
|
6200
|
+
startSubagent(nestedSession, { id: "toolu_wait", input: { description: "대기", subagent_type: "general-purpose" } });
|
|
6201
|
+
keepBackgroundSubagent(nestedSession, "toolu_wait", { isAsync: true, agentId: "agent-wait" });
|
|
6202
|
+
waitStructured("task_started", { tool_use_id: "toolu_wait", task_type: "local_agent", is_backgrounded: true, run_id: "r1" });
|
|
6203
|
+
waitSnapshot([agentRow, shellRow]);
|
|
6204
|
+
waitStructured("task_updated", { patch: { status: "completed" } });
|
|
6205
|
+
waitStructured("task_notification", { status: "completed", run_id: "r1" });
|
|
6206
|
+
waitSnapshot([shellRow]);
|
|
6207
|
+
waitXml("r1");
|
|
6185
6208
|
const waitingKept = nestedSession.subagents.has("toolu_wait");
|
|
6186
6209
|
waitSnapshot([]);
|
|
6187
|
-
|
|
6188
|
-
|
|
6210
|
+
const settledAfterChild = !nestedSession.subagents.has("toolu_wait");
|
|
6211
|
+
waitStructured("task_started", { task_type: "local_agent", is_backgrounded: true, run_id: "r2" });
|
|
6212
|
+
waitXml("r1");
|
|
6213
|
+
const keptAgainstLate = nestedSession.subagents.has("toolu_wait");
|
|
6214
|
+
waitStructured("task_notification", { status: "completed", run_id: "r2" });
|
|
6215
|
+
if (!waitingKept || !settledAfterChild || !keptAgainstLate || nestedSession.subagents.size !== 0) {
|
|
6216
|
+
throw new Error(`Claude waiting subagent self-test failed: ${waitingKept} ${settledAfterChild} ${keptAgainstLate} ${nestedSession.subagents.size}`);
|
|
6189
6217
|
}
|
|
6190
6218
|
clearSubagents(nestedSession);
|
|
6191
6219
|
// 끝난 뒤 SDK가 같은 작업을 다시 돌리면 설명 없는 새 줄이 아니라 같은 줄로 돌아온다.
|
|
6192
6220
|
startSubagent(nestedSession, { id: "toolu_again", input: { description: "3분 대기", subagent_type: "general-purpose" } });
|
|
6193
6221
|
keepBackgroundSubagent(nestedSession, "toolu_again", { isAsync: true, agentId: "agent-again" });
|
|
6222
|
+
// 진행 요약이 설명을 바꿔도 다시 실행된 줄은 호출 설명으로 돌아온다.
|
|
6223
|
+
for (let tick = 0; tick < 2; tick += 1) {
|
|
6224
|
+
processSubagentSystemMessage(nestedSession, {
|
|
6225
|
+
type: "system",
|
|
6226
|
+
subtype: "task_progress",
|
|
6227
|
+
task_id: "agent-again",
|
|
6228
|
+
summary: "로그를 살피는 중",
|
|
6229
|
+
});
|
|
6230
|
+
}
|
|
6194
6231
|
waitSnapshot([]);
|
|
6195
6232
|
processSubagentSystemMessage(nestedSession, {
|
|
6196
6233
|
type: "system",
|