agent-dealer 1.2.7 → 1.2.9
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/bundle/server/dist/adapters/agent-deck-bind.js +16 -6
- package/bundle/server/dist/adapters/agent-deck-bind.test.js +74 -0
- package/bundle/server/dist/adapters/agent-health.js +14 -3
- package/bundle/server/dist/adapters/github.js +84 -5
- package/bundle/server/dist/adapters/github.test.js +83 -1
- package/bundle/server/dist/adapters/muse-capability.js +443 -24
- package/bundle/server/dist/adapters/muse-capability.test.js +469 -25
- package/bundle/server/dist/adapters/muse-visual-qa.js +114 -0
- package/bundle/server/dist/adapters/muse-visual-qa.test.js +68 -0
- package/bundle/server/dist/adapters/worktree-deps.js +96 -0
- package/bundle/server/dist/adapters/worktree-deps.test.js +144 -0
- package/bundle/server/dist/capacity/muse-probe.js +56 -9
- package/bundle/server/dist/capacity/muse-probe.test.js +188 -1
- package/bundle/server/dist/coordinator/admission.js +14 -1
- package/bundle/server/dist/coordinator/admission.test.js +197 -4
- package/bundle/server/dist/coordinator/auto-merge.integration.test.js +276 -0
- package/bundle/server/dist/coordinator/auto-merge.js +244 -4
- package/bundle/server/dist/coordinator/checks-wait-config.js +19 -0
- package/bundle/server/dist/coordinator/commands.js +284 -23
- package/bundle/server/dist/coordinator/commands.test.js +47 -0
- package/bundle/server/dist/coordinator/deck-outage.integration.test.js +4 -2
- package/bundle/server/dist/coordinator/developer-effect.js +224 -4
- package/bundle/server/dist/coordinator/developer-effect.test.js +288 -3
- package/bundle/server/dist/coordinator/execution-report.js +6 -0
- package/bundle/server/dist/coordinator/execution-report.test.js +7 -0
- package/bundle/server/dist/coordinator/failure-cause.js +64 -1
- package/bundle/server/dist/coordinator/failure-cause.test.js +92 -1
- package/bundle/server/dist/coordinator/failure-reason.js +7 -0
- package/bundle/server/dist/coordinator/failure-reason.test.js +14 -0
- package/bundle/server/dist/coordinator/human-resolution.js +36 -1
- package/bundle/server/dist/coordinator/human-resolution.test.js +33 -0
- package/bundle/server/dist/coordinator/merge-conflict-sync.js +647 -0
- package/bundle/server/dist/coordinator/merge-conflict-sync.test.js +121 -0
- package/bundle/server/dist/coordinator/muse-developer.integration.test.js +9 -4
- package/bundle/server/dist/coordinator/muse-spawn.js +122 -29
- package/bundle/server/dist/coordinator/muse-spawn.test.js +210 -0
- package/bundle/server/dist/coordinator/operator-criteria.js +168 -0
- package/bundle/server/dist/coordinator/operator-criteria.test.js +78 -0
- package/bundle/server/dist/coordinator/operator-verification.integration.test.js +347 -0
- package/bundle/server/dist/coordinator/playbook-feedback.js +693 -0
- package/bundle/server/dist/coordinator/playbook-feedback.test.js +702 -0
- package/bundle/server/dist/coordinator/projection.js +10 -4
- package/bundle/server/dist/coordinator/projection.test.js +13 -0
- package/bundle/server/dist/coordinator/prompts-execution-contract.test.js +107 -0
- package/bundle/server/dist/coordinator/prompts.js +211 -2
- package/bundle/server/dist/coordinator/prompts.test.js +231 -0
- package/bundle/server/dist/coordinator/recovery.js +57 -3
- package/bundle/server/dist/coordinator/recovery.test.js +67 -8
- package/bundle/server/dist/coordinator/reflect-trigger.js +33 -169
- package/bundle/server/dist/coordinator/reflect-trigger.test.js +149 -200
- package/bundle/server/dist/coordinator/repair-cycle.integration.test.js +1 -0
- package/bundle/server/dist/coordinator/reviewer-effect.js +16 -1
- package/bundle/server/dist/coordinator/reviewer-result.js +6 -0
- package/bundle/server/dist/coordinator/routing.js +45 -6
- package/bundle/server/dist/coordinator/routing.test.js +76 -15
- package/bundle/server/dist/coordinator/session-timeouts.js +30 -0
- package/bundle/server/dist/coordinator/usage-cap-defer.js +61 -0
- package/bundle/server/dist/coordinator/usage-cap.integration.test.js +1 -1
- package/bundle/server/dist/coordinator/worker-loop.js +18 -4
- package/bundle/server/dist/db/ci-attempts-migration.test.js +70 -0
- package/bundle/server/dist/db/index.js +18 -0
- package/bundle/server/dist/db/schema.sql +5 -0
- package/bundle/server/dist/docs-execution-analysis.test.js +1 -0
- package/bundle/server/dist/repository/artifacts-for-issue.js +3 -3
- package/bundle/server/dist/repository/human-actions.js +14 -0
- package/bundle/server/dist/repository/issues.js +67 -6
- package/bundle/server/dist/repository/work-items.js +7 -0
- package/bundle/server/dist/repository/worker-sessions.js +51 -2
- package/bundle/server/dist/routes/human-actions.js +10 -8
- package/bundle/server/dist/routes/issues-execution-contract.test.js +321 -0
- package/bundle/server/dist/routes/issues.js +19 -2
- package/bundle/server/dist/runners/muse-code-args.js +25 -0
- package/bundle/server/dist/runners/muse-code-args.test.js +30 -0
- package/bundle/server/dist/runners/muse-code-jsonl.js +106 -11
- package/bundle/server/dist/runners/muse-config-core.js +18 -1
- package/bundle/server/dist/runners/muse-config.test.js +37 -0
- package/bundle/server/dist/runners/muse-serve-session.js +5 -0
- package/bundle/server/dist/runners/spawn-cli.js +116 -0
- package/bundle/server/dist/runners/spawn-cli.test.js +124 -0
- package/bundle/server/package.json +2 -2
- package/bundle/server/static-ui/assets/index-CU6fNntg.js +64 -0
- package/bundle/server/static-ui/assets/{index-DyAJNyfV.css → index-K_YcYkQU.css} +1 -1
- package/bundle/server/static-ui/index.html +2 -2
- package/bundle/shared/dist/execution-analysis.d.ts +22 -22
- package/bundle/shared/dist/execution-contract.d.ts +117 -0
- package/bundle/shared/dist/execution-contract.js +307 -0
- package/bundle/shared/dist/execution-contract.test.d.ts +2 -0
- package/bundle/shared/dist/execution-contract.test.js +499 -0
- package/bundle/shared/dist/execution-report.d.ts +9 -9
- package/bundle/shared/dist/execution-report.js +2 -0
- package/bundle/shared/dist/failure-cause.d.ts +4 -4
- package/bundle/shared/dist/failure-cause.js +2 -0
- package/bundle/shared/dist/human-actions.d.ts +4 -4
- package/bundle/shared/dist/human-actions.js +17 -0
- package/bundle/shared/dist/index.d.ts +85 -84
- package/bundle/shared/dist/index.js +3 -0
- package/bundle/shared/dist/issues.d.ts +176 -16
- package/bundle/shared/dist/issues.js +22 -0
- package/bundle/shared/dist/issues.test.js +3 -0
- package/bundle/shared/dist/outbound-draft.d.ts +12 -12
- package/bundle/shared/dist/worker-sessions.d.ts +10 -0
- package/bundle/shared/dist/worker-sessions.js +8 -0
- package/bundle/shared/dist/worker-sessions.test.js +1 -0
- package/bundle/shared/dist/workflow.d.ts +4 -4
- package/bundle/shared/dist/workflow.js +16 -0
- package/bundle/shared/dist/workflow.test.js +3 -0
- package/bundle/shared/package.json +1 -1
- package/dist/action.js +4 -1
- package/dist/action.test.js +42 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/bundle/server/static-ui/assets/index-yLyxRd-7.js +0 -64
|
@@ -1,198 +1,62 @@
|
|
|
1
|
-
import { parseProfileSnapshot, parseStringList } from "@agent-dealer/shared";
|
|
2
|
-
import { randomUUID } from "node:crypto";
|
|
3
1
|
import { checkAgentDeckHealth } from "../adapters/agent-deck.js";
|
|
4
2
|
import { callDeckTool } from "../adapters/reflect-authority.js";
|
|
5
3
|
import { getIssue } from "../repository/issues.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { listWorkflowEventsForIssue } from "../repository/workflow-events.js";
|
|
9
|
-
import { listWorkerSessionsForIssue } from "../repository/worker-sessions.js";
|
|
10
|
-
import { createIssueArtifact, latestIssueArtifact } from "../repository/artifacts.js";
|
|
11
|
-
import { listArtifactsForIssueByKind } from "../repository/artifacts-for-issue.js";
|
|
4
|
+
import { createIssueArtifact } from "../repository/artifacts.js";
|
|
5
|
+
import { collectPlaybookUseReceiptsForIssue, latestReceiptErrors, reportDeckFailureSignals, } from "./playbook-feedback.js";
|
|
12
6
|
import { getHumanAction, resolveHumanAction, } from "../repository/human-actions.js";
|
|
13
|
-
const REFLECT_TOOL_TIMEOUT_MS = 15_000;
|
|
14
|
-
/**
|
|
15
|
-
* Reflect targets the deck the developer actually ran with (frozen snapshot). Playbook
|
|
16
|
-
* ids are no longer on the snapshot (NOT-149) — only dead legacy agent columns still
|
|
17
|
-
* carry them for in-flight profiles. New agents with an empty legacy list skip reflect
|
|
18
|
-
* until a follow-up discovers playbooks dynamically from the Deck.
|
|
19
|
-
*/
|
|
20
|
-
function resolveReflectTargets(issue) {
|
|
21
|
-
const developerSessions = listWorkerSessionsForIssue(issue.id).filter((s) => s.role === "developer");
|
|
22
|
-
const finalSession = developerSessions[developerSessions.length - 1] ?? null;
|
|
23
|
-
const snapshot = finalSession ? parseProfileSnapshot(finalSession.profileSnapshotJson) : null;
|
|
24
|
-
const developerAgent = issue.developerAgentId ? getAgent(issue.developerAgentId) : null;
|
|
25
|
-
const deckId = snapshot?.deckId ?? developerAgent?.deckId ?? null;
|
|
26
|
-
if (!developerAgent)
|
|
27
|
-
return { deckId, playbookIds: [] };
|
|
28
|
-
const fromList = parseStringList(developerAgent.playbookIdsJson);
|
|
29
|
-
if (fromList.length)
|
|
30
|
-
return { deckId, playbookIds: fromList };
|
|
31
|
-
return { deckId, playbookIds: developerAgent.playbookId ? [developerAgent.playbookId] : [] };
|
|
32
|
-
}
|
|
33
7
|
const defaultDeps = {
|
|
34
8
|
checkHealth: checkAgentDeckHealth,
|
|
35
9
|
callTool: callDeckTool,
|
|
36
10
|
};
|
|
37
|
-
function readConclusionExcerpt(issueId) {
|
|
38
|
-
const artifact = latestIssueArtifact(issueId, "implementation_conclusion");
|
|
39
|
-
if (!artifact?.contentJson)
|
|
40
|
-
return null;
|
|
41
|
-
try {
|
|
42
|
-
const text = JSON.parse(artifact.contentJson).text?.trim();
|
|
43
|
-
if (!text)
|
|
44
|
-
return null;
|
|
45
|
-
return text.length > 800 ? `${text.slice(0, 800)}…` : text;
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function reviewRoundCount(issueId) {
|
|
52
|
-
const verdicts = listWorkflowEventsForIssue(issueId)
|
|
53
|
-
.filter((e) => e.type === "review.submitted")
|
|
54
|
-
.map((e) => {
|
|
55
|
-
try {
|
|
56
|
-
return JSON.parse(e.payloadJson ?? "{}").verdict ?? "unknown";
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return "unknown";
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
return { rounds: verdicts.length, verdicts };
|
|
63
|
-
}
|
|
64
|
-
function buildRationale(issueId) {
|
|
65
|
-
const issue = getIssue(issueId);
|
|
66
|
-
const findings = listFindingsForIssue(issueId);
|
|
67
|
-
const resolved = findings.filter((f) => f.status === "resolved").length;
|
|
68
|
-
const recurring = findings.filter((f) => f.status === "recurring").length;
|
|
69
|
-
const { rounds, verdicts } = reviewRoundCount(issueId);
|
|
70
|
-
const conclusion = readConclusionExcerpt(issueId);
|
|
71
|
-
const parts = [
|
|
72
|
-
`Issue "${issue.title}" completed after ${rounds} review round(s)${verdicts.length ? ` (${verdicts.join(" → ")})` : ""}.`,
|
|
73
|
-
`${findings.length} finding(s) tracked across rounds (${resolved} resolved, ${recurring} recurring).`,
|
|
74
|
-
];
|
|
75
|
-
if (conclusion)
|
|
76
|
-
parts.push(`Final implementation conclusion: ${conclusion}`);
|
|
77
|
-
return parts.join(" ");
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Playbook ids this issue already has a `playbook_patch` artifact for, from any earlier
|
|
81
|
-
* reflect attempt (i.e. a prior attempt that parked partway through, before a `retry`).
|
|
82
|
-
* The retry loop skips these instead of re-proposing — otherwise a park on playbook N
|
|
83
|
-
* after playbooks `1..N-1` already succeeded would duplicate their Notes items on retry
|
|
84
|
-
* (PR #21 review finding #1). Reflect fires at most once per issue outside of retries, so
|
|
85
|
-
* every artifact this finds genuinely belongs to this same reflection, never a later
|
|
86
|
-
* unrelated one.
|
|
87
|
-
*
|
|
88
|
-
* NOT-96: queries `playbook_patch` rows by kind directly rather than scanning the
|
|
89
|
-
* newest-first, all-kinds `listArtifactsForIssue` window — on an artifact-heavy issue an
|
|
90
|
-
* older `playbook_patch` could otherwise fall outside that window and get re-proposed.
|
|
91
|
-
*/
|
|
92
|
-
function alreadyProposedPlaybookIds(issueId) {
|
|
93
|
-
const ids = new Set();
|
|
94
|
-
for (const artifact of listArtifactsForIssueByKind(issueId, "playbook_patch")) {
|
|
95
|
-
try {
|
|
96
|
-
const playbookId = JSON.parse(artifact.contentJson ?? "{}").playbookId;
|
|
97
|
-
if (playbookId)
|
|
98
|
-
ids.add(playbookId);
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// malformed content — nothing to skip on its account
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return ids;
|
|
105
|
-
}
|
|
106
|
-
function recordStatus(issueId, content) {
|
|
107
|
-
createIssueArtifact({ issueId, kind: "reflect_status", author: "system", content });
|
|
108
|
-
}
|
|
109
11
|
/**
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
* human-action resolution.
|
|
12
|
+
* Records completion evidence for a terminal issue: actual-use receipts for every
|
|
13
|
+
* terminal worker session, then one idempotent `signal_only` Deck report per
|
|
14
|
+
* failure/correction trigger. Never throws — every failure mode is recorded as a
|
|
15
|
+
* `reflect_status`/`playbook_use_receipt` artifact, never as an exception that would
|
|
16
|
+
* undo the already-committed human-action resolution.
|
|
115
17
|
*/
|
|
116
18
|
export async function triggerIssueReflect(issueId, deps = defaultDeps) {
|
|
117
19
|
const issue = getIssue(issueId);
|
|
118
20
|
if (!issue)
|
|
119
21
|
return "skipped";
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
let anySucceeded = false;
|
|
132
|
-
let anyFailed = false;
|
|
133
|
-
for (const playbookId of playbookIds) {
|
|
134
|
-
if (alreadyProposed.has(playbookId)) {
|
|
135
|
-
// A prior attempt for this issue already proposed this playbook's patch — a retry
|
|
136
|
-
// must not duplicate it (PR #21 review finding #1).
|
|
137
|
-
anySucceeded = true;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
const playbook = await deps.callTool({
|
|
141
|
-
deckId,
|
|
142
|
-
toolName: "get_playbook",
|
|
143
|
-
arguments: { playbook_id: playbookId },
|
|
144
|
-
timeoutMs: REFLECT_TOOL_TIMEOUT_MS,
|
|
145
|
-
});
|
|
146
|
-
if (!playbook.ok) {
|
|
147
|
-
recordStatus(issueId, { status: "failed", attemptId, error: playbook.reason });
|
|
148
|
-
anyFailed = true;
|
|
149
|
-
continue;
|
|
150
|
-
}
|
|
151
|
-
const proposed = await deps.callTool({
|
|
152
|
-
deckId,
|
|
153
|
-
toolName: "propose_playbook_patch",
|
|
154
|
-
arguments: {
|
|
155
|
-
kind: "update",
|
|
156
|
-
playbook_id: playbookId,
|
|
157
|
-
ops: [{ op: "add_item", section: "Notes", text: rationale }],
|
|
158
|
-
rationale,
|
|
159
|
-
},
|
|
160
|
-
timeoutMs: REFLECT_TOOL_TIMEOUT_MS,
|
|
161
|
-
});
|
|
162
|
-
if (!proposed.ok) {
|
|
163
|
-
recordStatus(issueId, { status: "failed", attemptId, error: proposed.reason });
|
|
164
|
-
anyFailed = true;
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
22
|
+
const receipts = await collectPlaybookUseReceiptsForIssue(issueId, deps);
|
|
23
|
+
const signals = await reportDeckFailureSignals(issueId, deps);
|
|
24
|
+
// Incomplete receipt collection is a visible issue-level status even when no
|
|
25
|
+
// signal candidate exists — otherwise missing evidence leaves no trace. The reason
|
|
26
|
+
// names the actual receipt errors (Deck offline vs. malformed correlation
|
|
27
|
+
// response), never a blanket "offline". Collection resumes the next time issue
|
|
28
|
+
// reflection runs — a later instance-completing trigger re-attempts every session
|
|
29
|
+
// still missing a receipt — or via an explicit reflection retry. Never changes
|
|
30
|
+
// the issue outcome.
|
|
31
|
+
if (receipts.errors > 0) {
|
|
32
|
+
const details = latestReceiptErrors(issueId);
|
|
167
33
|
createIssueArtifact({
|
|
168
34
|
issueId,
|
|
169
|
-
kind: "
|
|
35
|
+
kind: "reflect_status",
|
|
170
36
|
author: "system",
|
|
171
37
|
content: {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
38
|
+
status: "failed",
|
|
39
|
+
reason: details.length > 0
|
|
40
|
+
? `playbook-use receipt collection incomplete — retried on the next reflection trigger: ${details.join("; ")}`
|
|
41
|
+
: "playbook-use receipt collection incomplete — retried on the next reflection trigger",
|
|
42
|
+
pendingReceipts: receipts.pending,
|
|
177
43
|
},
|
|
178
44
|
});
|
|
179
|
-
anySucceeded = true;
|
|
180
45
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return anySucceeded ? "triggered" : "failed";
|
|
46
|
+
if (receipts.collected > 0 || signals.sent.length > 0)
|
|
47
|
+
return "triggered";
|
|
48
|
+
if (receipts.errors > 0 || signals.error)
|
|
49
|
+
return "failed";
|
|
50
|
+
return "skipped";
|
|
187
51
|
}
|
|
188
52
|
/**
|
|
189
53
|
* Resolves an open `reflection_interaction_required` action. Deliberately bypasses
|
|
190
54
|
* `resolveHumanActionAndAdvance`'s workflow state machine entirely (commands.ts) — that
|
|
191
55
|
* machine requires an active workflow instance to advance, but this action is raised
|
|
192
|
-
* against an issue that is already
|
|
193
|
-
* never reopen the issue or enqueue developer/reviewer work (NOT-94). `retry`
|
|
194
|
-
* brand new correlated
|
|
195
|
-
* further Deck call.
|
|
56
|
+
* against an issue that is already terminal with no active instance, and resolving it
|
|
57
|
+
* must never reopen the issue or enqueue developer/reviewer work (NOT-94). `retry`
|
|
58
|
+
* starts a brand new correlated evidence-collection attempt with its own new authority;
|
|
59
|
+
* `dismiss` makes no further Deck call.
|
|
196
60
|
*/
|
|
197
61
|
export function resolveReflectionInteractionAction(actionId, resolvedBy, choice, deps = defaultDeps) {
|
|
198
62
|
const action = getHumanAction(actionId);
|