@resolveio/server-lib 22.3.98 → 22.3.99
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/package.json +1 -1
- package/public_api.d.ts +1 -0
- package/public_api.js +1 -0
- package/public_api.js.map +1 -1
- package/util/ai-qa-policy.js +3 -1
- package/util/ai-qa-policy.js.map +1 -1
- package/util/ai-runner-qa-auth.js +3 -1
- package/util/ai-runner-qa-auth.js.map +1 -1
- package/util/ai-runner-qa-tools.js +10 -4
- package/util/ai-runner-qa-tools.js.map +1 -1
- package/util/support-runner-v5.d.ts +145 -0
- package/util/support-runner-v5.js +295 -0
- package/util/support-runner-v5.js.map +1 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
export type ResolveIOSupportV5StepType = 'compile_check' | 'startup_check' | 'live_seed' | 'auth_bootstrap' | 'route_probe' | 'qa_row' | 'build_repair' | 'qa_retest' | 'pr_review' | 'artifact_package' | 'cleanup';
|
|
2
|
+
export type ResolveIOSupportV5Outcome = 'pass' | 'needs_repair' | 'retry_same_step' | 'park_manual' | 'budget_stop' | 'infra_retry' | 'ready_for_merge';
|
|
3
|
+
export type ResolveIOSupportV5Lane = 'build' | 'qa' | 'review' | 'supervisor';
|
|
4
|
+
export interface ResolveIOSupportV5Budget {
|
|
5
|
+
maxPromptTokensPerNonInitialStep: number;
|
|
6
|
+
maxLoopsPerTicket: number;
|
|
7
|
+
maxRepeatedNoProgress: number;
|
|
8
|
+
maxRuntimeMinutesPerLoop: number;
|
|
9
|
+
totalPromptTokenEstimate: number;
|
|
10
|
+
totalRuntimeMs: number;
|
|
11
|
+
loopCount: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ResolveIOSupportV5LaneMemory {
|
|
14
|
+
lane: ResolveIOSupportV5Lane;
|
|
15
|
+
model: string;
|
|
16
|
+
threadKey: string;
|
|
17
|
+
scopeSummary: string;
|
|
18
|
+
activeBlocker: string;
|
|
19
|
+
activeQaRow?: {
|
|
20
|
+
index?: number;
|
|
21
|
+
workflow?: string;
|
|
22
|
+
route?: string;
|
|
23
|
+
assertion?: string;
|
|
24
|
+
status?: string;
|
|
25
|
+
};
|
|
26
|
+
changedFiles: string[];
|
|
27
|
+
artifactPaths: string[];
|
|
28
|
+
latestPromptTokenEstimate?: number;
|
|
29
|
+
updatedAt: string;
|
|
30
|
+
}
|
|
31
|
+
export interface ResolveIOSupportV5SupervisorState {
|
|
32
|
+
version: 'v5';
|
|
33
|
+
status: 'active' | 'parked' | 'complete';
|
|
34
|
+
currentGoal: string;
|
|
35
|
+
approvedScope: string;
|
|
36
|
+
prBranch: string;
|
|
37
|
+
activeStep: ResolveIOSupportV5StepType;
|
|
38
|
+
activeBlocker: string;
|
|
39
|
+
lastGoodCheckpoint: string;
|
|
40
|
+
currentQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
41
|
+
processLease?: {
|
|
42
|
+
runId?: string;
|
|
43
|
+
token?: string;
|
|
44
|
+
generation?: number;
|
|
45
|
+
workspace?: string;
|
|
46
|
+
lane?: string;
|
|
47
|
+
};
|
|
48
|
+
artifactLinks: string[];
|
|
49
|
+
noEmailUnlessApproved: boolean;
|
|
50
|
+
updatedAt: string;
|
|
51
|
+
}
|
|
52
|
+
export interface ResolveIOSupportV5StepRecord {
|
|
53
|
+
stepType: ResolveIOSupportV5StepType;
|
|
54
|
+
outcome: ResolveIOSupportV5Outcome;
|
|
55
|
+
lane: ResolveIOSupportV5Lane;
|
|
56
|
+
model?: string;
|
|
57
|
+
threadKey?: string;
|
|
58
|
+
promptTokenEstimate?: number;
|
|
59
|
+
runtimeMs?: number;
|
|
60
|
+
summary: string;
|
|
61
|
+
blocker?: string;
|
|
62
|
+
changedFiles?: string[];
|
|
63
|
+
artifactPaths?: string[];
|
|
64
|
+
recordedAt: string;
|
|
65
|
+
}
|
|
66
|
+
export interface ResolveIOSupportV5RunnerIncident {
|
|
67
|
+
incidentClass: string;
|
|
68
|
+
summary: string;
|
|
69
|
+
stepType?: ResolveIOSupportV5StepType;
|
|
70
|
+
blockerFingerprint?: string;
|
|
71
|
+
artifactPaths?: string[];
|
|
72
|
+
recordedAt: string;
|
|
73
|
+
}
|
|
74
|
+
export interface ResolveIOSupportV5StateBundle {
|
|
75
|
+
supportWorkflowVersion: 'v5';
|
|
76
|
+
supportV5SupervisorState: ResolveIOSupportV5SupervisorState;
|
|
77
|
+
supportV5LaneMemory: {
|
|
78
|
+
build: ResolveIOSupportV5LaneMemory;
|
|
79
|
+
qa: ResolveIOSupportV5LaneMemory;
|
|
80
|
+
};
|
|
81
|
+
supportV5StepHistory: ResolveIOSupportV5StepRecord[];
|
|
82
|
+
supportV5Budget: ResolveIOSupportV5Budget;
|
|
83
|
+
supportV5RunnerIncidents: ResolveIOSupportV5RunnerIncident[];
|
|
84
|
+
}
|
|
85
|
+
export interface ResolveIOSupportV5InitializeInput {
|
|
86
|
+
jobId: string;
|
|
87
|
+
ticketId?: string;
|
|
88
|
+
ticketNumber?: string;
|
|
89
|
+
title?: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
approvedScopeRequirements?: string[];
|
|
92
|
+
approvedScopeHours?: number | null;
|
|
93
|
+
prBranch?: string;
|
|
94
|
+
buildThreadKey?: string;
|
|
95
|
+
qaThreadKey?: string;
|
|
96
|
+
processLease?: ResolveIOSupportV5SupervisorState['processLease'];
|
|
97
|
+
now?: Date | string;
|
|
98
|
+
existing?: Partial<ResolveIOSupportV5StateBundle>;
|
|
99
|
+
}
|
|
100
|
+
export interface ResolveIOSupportV5StepInput {
|
|
101
|
+
stepType: ResolveIOSupportV5StepType;
|
|
102
|
+
outcome: ResolveIOSupportV5Outcome;
|
|
103
|
+
lane: ResolveIOSupportV5Lane;
|
|
104
|
+
model?: string;
|
|
105
|
+
threadKey?: string;
|
|
106
|
+
promptTokenEstimate?: number;
|
|
107
|
+
runtimeMs?: number;
|
|
108
|
+
summary?: string;
|
|
109
|
+
blocker?: string;
|
|
110
|
+
changedFiles?: string[];
|
|
111
|
+
artifactPaths?: string[];
|
|
112
|
+
activeQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
113
|
+
now?: Date | string;
|
|
114
|
+
}
|
|
115
|
+
export interface ResolveIOSupportV5ContinuationDecision {
|
|
116
|
+
action: 'continue' | 'park';
|
|
117
|
+
reason: string;
|
|
118
|
+
nextStep: ResolveIOSupportV5StepType;
|
|
119
|
+
repeatedNoProgressCount: number;
|
|
120
|
+
budgetExceeded: boolean;
|
|
121
|
+
}
|
|
122
|
+
export declare function fingerprintResolveIOSupportV5Blocker(value: any): string;
|
|
123
|
+
export declare function buildResolveIOSupportV5Budget(existing?: Partial<ResolveIOSupportV5Budget>): ResolveIOSupportV5Budget;
|
|
124
|
+
export declare function initializeResolveIOSupportV5State(input: ResolveIOSupportV5InitializeInput): ResolveIOSupportV5StateBundle;
|
|
125
|
+
export declare function recordResolveIOSupportV5Step(bundle: ResolveIOSupportV5StateBundle, step: ResolveIOSupportV5StepInput): ResolveIOSupportV5StateBundle;
|
|
126
|
+
export declare function decideResolveIOSupportV5Continuation(bundle: ResolveIOSupportV5StateBundle): ResolveIOSupportV5ContinuationDecision;
|
|
127
|
+
export declare function buildResolveIOSupportV5DiagnoseFirstPrompt(lines: {
|
|
128
|
+
goal?: string;
|
|
129
|
+
approvedScope?: string[];
|
|
130
|
+
activeStep?: ResolveIOSupportV5StepType;
|
|
131
|
+
activeBlocker?: string;
|
|
132
|
+
lane?: ResolveIOSupportV5Lane;
|
|
133
|
+
laneSummary?: string;
|
|
134
|
+
currentQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];
|
|
135
|
+
artifactPaths?: string[];
|
|
136
|
+
changedFiles?: string[];
|
|
137
|
+
}): string[];
|
|
138
|
+
export declare function buildResolveIOSupportV5Incident(input: {
|
|
139
|
+
incidentClass: string;
|
|
140
|
+
summary: string;
|
|
141
|
+
stepType?: ResolveIOSupportV5StepType;
|
|
142
|
+
blocker?: string;
|
|
143
|
+
artifactPaths?: string[];
|
|
144
|
+
now?: Date | string;
|
|
145
|
+
}): ResolveIOSupportV5RunnerIncident;
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __values = (this && this.__values) || function(o) {
|
|
14
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
15
|
+
if (m) return m.call(o);
|
|
16
|
+
if (o && typeof o.length === "number") return {
|
|
17
|
+
next: function () {
|
|
18
|
+
if (o && i >= o.length) o = void 0;
|
|
19
|
+
return { value: o && o[i++], done: !o };
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
23
|
+
};
|
|
24
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
25
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
26
|
+
if (!m) return o;
|
|
27
|
+
var i = m.call(o), r, ar = [], e;
|
|
28
|
+
try {
|
|
29
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
30
|
+
}
|
|
31
|
+
catch (error) { e = { error: error }; }
|
|
32
|
+
finally {
|
|
33
|
+
try {
|
|
34
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
35
|
+
}
|
|
36
|
+
finally { if (e) throw e.error; }
|
|
37
|
+
}
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
41
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
42
|
+
if (ar || !(i in from)) {
|
|
43
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
44
|
+
ar[i] = from[i];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.fingerprintResolveIOSupportV5Blocker = fingerprintResolveIOSupportV5Blocker;
|
|
51
|
+
exports.buildResolveIOSupportV5Budget = buildResolveIOSupportV5Budget;
|
|
52
|
+
exports.initializeResolveIOSupportV5State = initializeResolveIOSupportV5State;
|
|
53
|
+
exports.recordResolveIOSupportV5Step = recordResolveIOSupportV5Step;
|
|
54
|
+
exports.decideResolveIOSupportV5Continuation = decideResolveIOSupportV5Continuation;
|
|
55
|
+
exports.buildResolveIOSupportV5DiagnoseFirstPrompt = buildResolveIOSupportV5DiagnoseFirstPrompt;
|
|
56
|
+
exports.buildResolveIOSupportV5Incident = buildResolveIOSupportV5Incident;
|
|
57
|
+
function isoNow(value) {
|
|
58
|
+
if (value instanceof Date) {
|
|
59
|
+
return value.toISOString();
|
|
60
|
+
}
|
|
61
|
+
var parsed = value ? new Date(value) : new Date();
|
|
62
|
+
if (Number.isFinite(parsed.getTime())) {
|
|
63
|
+
return parsed.toISOString();
|
|
64
|
+
}
|
|
65
|
+
return new Date().toISOString();
|
|
66
|
+
}
|
|
67
|
+
function cleanText(value, max) {
|
|
68
|
+
if (max === void 0) { max = 2000; }
|
|
69
|
+
return String(value || '').replace(/\s+/g, ' ').trim().slice(0, max);
|
|
70
|
+
}
|
|
71
|
+
function cleanList(values, limit, max) {
|
|
72
|
+
var e_1, _a;
|
|
73
|
+
if (limit === void 0) { limit = 20; }
|
|
74
|
+
if (max === void 0) { max = 500; }
|
|
75
|
+
if (!Array.isArray(values)) {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
var result = [];
|
|
79
|
+
try {
|
|
80
|
+
for (var values_1 = __values(values), values_1_1 = values_1.next(); !values_1_1.done; values_1_1 = values_1.next()) {
|
|
81
|
+
var value = values_1_1.value;
|
|
82
|
+
var normalized = cleanText(value, max);
|
|
83
|
+
if (normalized && !result.includes(normalized)) {
|
|
84
|
+
result.push(normalized);
|
|
85
|
+
}
|
|
86
|
+
if (result.length >= limit) {
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
92
|
+
finally {
|
|
93
|
+
try {
|
|
94
|
+
if (values_1_1 && !values_1_1.done && (_a = values_1.return)) _a.call(values_1);
|
|
95
|
+
}
|
|
96
|
+
finally { if (e_1) throw e_1.error; }
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
function fingerprintResolveIOSupportV5Blocker(value) {
|
|
101
|
+
var text = cleanText(value, 4000)
|
|
102
|
+
.toLowerCase()
|
|
103
|
+
.replace(/[a-f0-9]{16,}/g, '<id>')
|
|
104
|
+
.replace(/\b\d{2,}\b/g, '<n>')
|
|
105
|
+
.replace(/\bline\s+<n>\b/g, 'line <n>');
|
|
106
|
+
var hash = 0;
|
|
107
|
+
for (var index = 0; index < text.length; index += 1) {
|
|
108
|
+
hash = ((hash << 5) - hash + text.charCodeAt(index)) | 0;
|
|
109
|
+
}
|
|
110
|
+
return "v5-".concat(Math.abs(hash).toString(36));
|
|
111
|
+
}
|
|
112
|
+
function buildResolveIOSupportV5Budget(existing) {
|
|
113
|
+
return {
|
|
114
|
+
maxPromptTokensPerNonInitialStep: Number((existing === null || existing === void 0 ? void 0 : existing.maxPromptTokensPerNonInitialStep) || 4000),
|
|
115
|
+
maxLoopsPerTicket: Number((existing === null || existing === void 0 ? void 0 : existing.maxLoopsPerTicket) || 24),
|
|
116
|
+
maxRepeatedNoProgress: Number((existing === null || existing === void 0 ? void 0 : existing.maxRepeatedNoProgress) || 2),
|
|
117
|
+
maxRuntimeMinutesPerLoop: Number((existing === null || existing === void 0 ? void 0 : existing.maxRuntimeMinutesPerLoop) || 15),
|
|
118
|
+
totalPromptTokenEstimate: Number((existing === null || existing === void 0 ? void 0 : existing.totalPromptTokenEstimate) || 0),
|
|
119
|
+
totalRuntimeMs: Number((existing === null || existing === void 0 ? void 0 : existing.totalRuntimeMs) || 0),
|
|
120
|
+
loopCount: Number((existing === null || existing === void 0 ? void 0 : existing.loopCount) || 0)
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function initializeResolveIOSupportV5State(input) {
|
|
124
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
125
|
+
var now = isoNow(input.now);
|
|
126
|
+
var existing = input.existing || {};
|
|
127
|
+
var existingSupervisor = existing.supportV5SupervisorState;
|
|
128
|
+
var existingLaneMemory = existing.supportV5LaneMemory || {};
|
|
129
|
+
var scope = cleanList(input.approvedScopeRequirements, 24, 240).join(' | ')
|
|
130
|
+
|| cleanText(input.description, 1000)
|
|
131
|
+
|| cleanText(input.title, 300);
|
|
132
|
+
var ticketLabel = cleanText(input.ticketNumber || input.ticketId || input.jobId, 120);
|
|
133
|
+
var buildThreadKey = cleanText(input.buildThreadKey || ((_a = existingLaneMemory.build) === null || _a === void 0 ? void 0 : _a.threadKey) || "support:".concat(input.ticketId || input.jobId, ":job:").concat(input.jobId, ":build"), 240);
|
|
134
|
+
var qaThreadKey = cleanText(input.qaThreadKey || ((_b = existingLaneMemory.qa) === null || _b === void 0 ? void 0 : _b.threadKey) || "support:".concat(input.ticketId || input.jobId, ":job:").concat(input.jobId, ":qa"), 240);
|
|
135
|
+
var budget = buildResolveIOSupportV5Budget(existing.supportV5Budget);
|
|
136
|
+
return {
|
|
137
|
+
supportWorkflowVersion: 'v5',
|
|
138
|
+
supportV5SupervisorState: {
|
|
139
|
+
version: 'v5',
|
|
140
|
+
status: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.status) || 'active',
|
|
141
|
+
currentGoal: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.currentGoal) || "Resolve support ticket ".concat(ticketLabel),
|
|
142
|
+
approvedScope: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.approvedScope) || scope,
|
|
143
|
+
prBranch: cleanText(input.prBranch || (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.prBranch) || '', 240),
|
|
144
|
+
activeStep: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.activeStep) || 'compile_check',
|
|
145
|
+
activeBlocker: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.activeBlocker) || '',
|
|
146
|
+
lastGoodCheckpoint: (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.lastGoodCheckpoint) || 'v5_initialized',
|
|
147
|
+
currentQaRow: existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.currentQaRow,
|
|
148
|
+
processLease: input.processLease || (existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.processLease),
|
|
149
|
+
artifactLinks: cleanList(existingSupervisor === null || existingSupervisor === void 0 ? void 0 : existingSupervisor.artifactLinks, 40, 500),
|
|
150
|
+
noEmailUnlessApproved: true,
|
|
151
|
+
updatedAt: now
|
|
152
|
+
},
|
|
153
|
+
supportV5LaneMemory: {
|
|
154
|
+
build: {
|
|
155
|
+
lane: 'build',
|
|
156
|
+
model: ((_c = existingLaneMemory.build) === null || _c === void 0 ? void 0 : _c.model) || 'gpt-5.3-codex',
|
|
157
|
+
threadKey: buildThreadKey,
|
|
158
|
+
scopeSummary: ((_d = existingLaneMemory.build) === null || _d === void 0 ? void 0 : _d.scopeSummary) || scope,
|
|
159
|
+
activeBlocker: ((_e = existingLaneMemory.build) === null || _e === void 0 ? void 0 : _e.activeBlocker) || '',
|
|
160
|
+
activeQaRow: (_f = existingLaneMemory.build) === null || _f === void 0 ? void 0 : _f.activeQaRow,
|
|
161
|
+
changedFiles: cleanList((_g = existingLaneMemory.build) === null || _g === void 0 ? void 0 : _g.changedFiles, 80, 500),
|
|
162
|
+
artifactPaths: cleanList((_h = existingLaneMemory.build) === null || _h === void 0 ? void 0 : _h.artifactPaths, 80, 500),
|
|
163
|
+
latestPromptTokenEstimate: Number(((_j = existingLaneMemory.build) === null || _j === void 0 ? void 0 : _j.latestPromptTokenEstimate) || 0) || undefined,
|
|
164
|
+
updatedAt: ((_k = existingLaneMemory.build) === null || _k === void 0 ? void 0 : _k.updatedAt) || now
|
|
165
|
+
},
|
|
166
|
+
qa: {
|
|
167
|
+
lane: 'qa',
|
|
168
|
+
model: ((_l = existingLaneMemory.qa) === null || _l === void 0 ? void 0 : _l.model) || 'gpt-5.4-mini',
|
|
169
|
+
threadKey: qaThreadKey,
|
|
170
|
+
scopeSummary: ((_m = existingLaneMemory.qa) === null || _m === void 0 ? void 0 : _m.scopeSummary) || scope,
|
|
171
|
+
activeBlocker: ((_o = existingLaneMemory.qa) === null || _o === void 0 ? void 0 : _o.activeBlocker) || '',
|
|
172
|
+
activeQaRow: (_p = existingLaneMemory.qa) === null || _p === void 0 ? void 0 : _p.activeQaRow,
|
|
173
|
+
changedFiles: cleanList((_q = existingLaneMemory.qa) === null || _q === void 0 ? void 0 : _q.changedFiles, 80, 500),
|
|
174
|
+
artifactPaths: cleanList((_r = existingLaneMemory.qa) === null || _r === void 0 ? void 0 : _r.artifactPaths, 80, 500),
|
|
175
|
+
latestPromptTokenEstimate: Number(((_s = existingLaneMemory.qa) === null || _s === void 0 ? void 0 : _s.latestPromptTokenEstimate) || 0) || undefined,
|
|
176
|
+
updatedAt: ((_t = existingLaneMemory.qa) === null || _t === void 0 ? void 0 : _t.updatedAt) || now
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
supportV5StepHistory: Array.isArray(existing.supportV5StepHistory)
|
|
180
|
+
? existing.supportV5StepHistory.slice(-80)
|
|
181
|
+
: [],
|
|
182
|
+
supportV5Budget: budget,
|
|
183
|
+
supportV5RunnerIncidents: Array.isArray(existing.supportV5RunnerIncidents)
|
|
184
|
+
? existing.supportV5RunnerIncidents.slice(-80)
|
|
185
|
+
: []
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function recordResolveIOSupportV5Step(bundle, step) {
|
|
189
|
+
var _a, _b;
|
|
190
|
+
var now = isoNow(step.now);
|
|
191
|
+
var promptTokens = Math.max(0, Number(step.promptTokenEstimate || 0) || 0);
|
|
192
|
+
var runtimeMs = Math.max(0, Number(step.runtimeMs || 0) || 0);
|
|
193
|
+
var record = {
|
|
194
|
+
stepType: step.stepType,
|
|
195
|
+
outcome: step.outcome,
|
|
196
|
+
lane: step.lane,
|
|
197
|
+
model: cleanText(step.model, 80),
|
|
198
|
+
threadKey: cleanText(step.threadKey, 240),
|
|
199
|
+
promptTokenEstimate: promptTokens || undefined,
|
|
200
|
+
runtimeMs: runtimeMs || undefined,
|
|
201
|
+
summary: cleanText(step.summary || step.blocker || step.outcome, 1200),
|
|
202
|
+
blocker: cleanText(step.blocker, 1200),
|
|
203
|
+
changedFiles: cleanList(step.changedFiles, 80, 500),
|
|
204
|
+
artifactPaths: cleanList(step.artifactPaths, 80, 500),
|
|
205
|
+
recordedAt: now
|
|
206
|
+
};
|
|
207
|
+
var laneMemory = __assign({}, bundle.supportV5LaneMemory);
|
|
208
|
+
if (step.lane === 'build' || step.lane === 'qa') {
|
|
209
|
+
var previous = laneMemory[step.lane];
|
|
210
|
+
laneMemory[step.lane] = __assign(__assign({}, previous), { activeBlocker: record.blocker || previous.activeBlocker || '', activeQaRow: step.activeQaRow || previous.activeQaRow, changedFiles: ((_a = record.changedFiles) === null || _a === void 0 ? void 0 : _a.length) ? record.changedFiles : previous.changedFiles, artifactPaths: ((_b = record.artifactPaths) === null || _b === void 0 ? void 0 : _b.length) ? record.artifactPaths : previous.artifactPaths, latestPromptTokenEstimate: promptTokens || previous.latestPromptTokenEstimate, updatedAt: now });
|
|
211
|
+
}
|
|
212
|
+
var supervisor = __assign(__assign({}, bundle.supportV5SupervisorState), { status: step.outcome === 'ready_for_merge' ? 'complete' : (step.outcome === 'park_manual' || step.outcome === 'budget_stop' ? 'parked' : 'active'), activeStep: step.stepType, activeBlocker: record.blocker || '', currentQaRow: step.activeQaRow || bundle.supportV5SupervisorState.currentQaRow, lastGoodCheckpoint: step.outcome === 'pass' || step.outcome === 'ready_for_merge'
|
|
213
|
+
? step.stepType
|
|
214
|
+
: bundle.supportV5SupervisorState.lastGoodCheckpoint, artifactLinks: Array.from(new Set(__spreadArray(__spreadArray([], __read(bundle.supportV5SupervisorState.artifactLinks), false), __read((record.artifactPaths || [])), false))).slice(-80), updatedAt: now });
|
|
215
|
+
return __assign(__assign({}, bundle), { supportV5SupervisorState: supervisor, supportV5LaneMemory: laneMemory, supportV5StepHistory: __spreadArray(__spreadArray([], __read(bundle.supportV5StepHistory), false), [record], false).slice(-100), supportV5Budget: __assign(__assign({}, bundle.supportV5Budget), { totalPromptTokenEstimate: bundle.supportV5Budget.totalPromptTokenEstimate + promptTokens, totalRuntimeMs: bundle.supportV5Budget.totalRuntimeMs + runtimeMs, loopCount: bundle.supportV5Budget.loopCount + 1 }) });
|
|
216
|
+
}
|
|
217
|
+
function decideResolveIOSupportV5Continuation(bundle) {
|
|
218
|
+
var history = bundle.supportV5StepHistory || [];
|
|
219
|
+
var budget = buildResolveIOSupportV5Budget(bundle.supportV5Budget);
|
|
220
|
+
var last = history[history.length - 1];
|
|
221
|
+
var blockerFingerprint = fingerprintResolveIOSupportV5Blocker((last === null || last === void 0 ? void 0 : last.blocker) || (last === null || last === void 0 ? void 0 : last.summary) || '');
|
|
222
|
+
var repeatedNoProgressCount = 0;
|
|
223
|
+
for (var index = history.length - 1; index >= 0; index -= 1) {
|
|
224
|
+
var item = history[index];
|
|
225
|
+
if (item.outcome === 'pass' || item.outcome === 'ready_for_merge') {
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
if (item.stepType !== (last === null || last === void 0 ? void 0 : last.stepType)) {
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
if (fingerprintResolveIOSupportV5Blocker(item.blocker || item.summary || '') === blockerFingerprint) {
|
|
232
|
+
repeatedNoProgressCount += 1;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
var budgetExceeded = budget.loopCount >= budget.maxLoopsPerTicket
|
|
236
|
+
|| ((last === null || last === void 0 ? void 0 : last.promptTokenEstimate) || 0) > budget.maxPromptTokensPerNonInitialStep * 2;
|
|
237
|
+
if (budgetExceeded) {
|
|
238
|
+
return {
|
|
239
|
+
action: 'park',
|
|
240
|
+
reason: 'support_v5_budget_guard',
|
|
241
|
+
nextStep: (last === null || last === void 0 ? void 0 : last.stepType) || 'cleanup',
|
|
242
|
+
repeatedNoProgressCount: repeatedNoProgressCount,
|
|
243
|
+
budgetExceeded: budgetExceeded
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
if (repeatedNoProgressCount > budget.maxRepeatedNoProgress) {
|
|
247
|
+
return {
|
|
248
|
+
action: 'park',
|
|
249
|
+
reason: 'support_v5_repeated_no_progress',
|
|
250
|
+
nextStep: (last === null || last === void 0 ? void 0 : last.stepType) || 'cleanup',
|
|
251
|
+
repeatedNoProgressCount: repeatedNoProgressCount,
|
|
252
|
+
budgetExceeded: budgetExceeded
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
action: 'continue',
|
|
257
|
+
reason: 'support_v5_continue',
|
|
258
|
+
nextStep: (last === null || last === void 0 ? void 0 : last.stepType) || bundle.supportV5SupervisorState.activeStep,
|
|
259
|
+
repeatedNoProgressCount: repeatedNoProgressCount,
|
|
260
|
+
budgetExceeded: false
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
function buildResolveIOSupportV5DiagnoseFirstPrompt(lines) {
|
|
264
|
+
var _a, _b;
|
|
265
|
+
return [
|
|
266
|
+
'Support Runner V5 contract: act like a guarded autonomous engineer, not a gate checklist.',
|
|
267
|
+
'Start with Diagnose First: observed evidence, likely cause, smallest next action, and expected proof.',
|
|
268
|
+
'Use compact lane memory and current artifacts before asking for broad ticket context.',
|
|
269
|
+
'Do not send customer email. Do not write production data. Do not spawn duplicate build, QA, server, client, Mongo, browser, or Codex processes.',
|
|
270
|
+
'If repairing, inspect logs/artifacts/source/diff first; make the smallest code or localhost-data change, then run the smallest self-gate.',
|
|
271
|
+
'If QA fails, retest the failed row before advancing; if the same blocker repeats without new proof, park with the exact blocker.',
|
|
272
|
+
lines.goal ? "Goal: ".concat(cleanText(lines.goal, 500)) : '',
|
|
273
|
+
cleanList(lines.approvedScope, 12, 240).length ? "Approved scope: ".concat(cleanList(lines.approvedScope, 12, 240).join(' | ')) : '',
|
|
274
|
+
lines.activeStep ? "Active step: ".concat(lines.activeStep) : '',
|
|
275
|
+
lines.lane ? "Lane: ".concat(lines.lane) : '',
|
|
276
|
+
lines.laneSummary ? "Lane memory: ".concat(cleanText(lines.laneSummary, 700)) : '',
|
|
277
|
+
lines.activeBlocker ? "Active blocker: ".concat(cleanText(lines.activeBlocker, 800)) : '',
|
|
278
|
+
((_a = lines.currentQaRow) === null || _a === void 0 ? void 0 : _a.workflow) ? "Current QA row: ".concat(cleanText(lines.currentQaRow.workflow, 300)) : '',
|
|
279
|
+
((_b = lines.currentQaRow) === null || _b === void 0 ? void 0 : _b.route) ? "Current QA route: ".concat(cleanText(lines.currentQaRow.route, 300)) : '',
|
|
280
|
+
cleanList(lines.changedFiles, 12, 200).length ? "Changed files: ".concat(cleanList(lines.changedFiles, 12, 200).join(', ')) : '',
|
|
281
|
+
cleanList(lines.artifactPaths, 12, 240).length ? "Artifacts: ".concat(cleanList(lines.artifactPaths, 12, 240).join(', ')) : ''
|
|
282
|
+
].filter(Boolean);
|
|
283
|
+
}
|
|
284
|
+
function buildResolveIOSupportV5Incident(input) {
|
|
285
|
+
return {
|
|
286
|
+
incidentClass: cleanText(input.incidentClass, 120) || 'support_v5_runner_incident',
|
|
287
|
+
summary: cleanText(input.summary, 1200),
|
|
288
|
+
stepType: input.stepType,
|
|
289
|
+
blockerFingerprint: input.blocker ? fingerprintResolveIOSupportV5Blocker(input.blocker) : undefined,
|
|
290
|
+
artifactPaths: cleanList(input.artifactPaths, 40, 500),
|
|
291
|
+
recordedAt: isoNow(input.now)
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
//# sourceMappingURL=support-runner-v5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/support-runner-v5.ts"],"names":[],"mappings":"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","file":"support-runner-v5.js","sourcesContent":["export type ResolveIOSupportV5StepType =\n\t| 'compile_check'\n\t| 'startup_check'\n\t| 'live_seed'\n\t| 'auth_bootstrap'\n\t| 'route_probe'\n\t| 'qa_row'\n\t| 'build_repair'\n\t| 'qa_retest'\n\t| 'pr_review'\n\t| 'artifact_package'\n\t| 'cleanup';\n\nexport type ResolveIOSupportV5Outcome =\n\t| 'pass'\n\t| 'needs_repair'\n\t| 'retry_same_step'\n\t| 'park_manual'\n\t| 'budget_stop'\n\t| 'infra_retry'\n\t| 'ready_for_merge';\n\nexport type ResolveIOSupportV5Lane = 'build' | 'qa' | 'review' | 'supervisor';\n\nexport interface ResolveIOSupportV5Budget {\n\tmaxPromptTokensPerNonInitialStep: number;\n\tmaxLoopsPerTicket: number;\n\tmaxRepeatedNoProgress: number;\n\tmaxRuntimeMinutesPerLoop: number;\n\ttotalPromptTokenEstimate: number;\n\ttotalRuntimeMs: number;\n\tloopCount: number;\n}\n\nexport interface ResolveIOSupportV5LaneMemory {\n\tlane: ResolveIOSupportV5Lane;\n\tmodel: string;\n\tthreadKey: string;\n\tscopeSummary: string;\n\tactiveBlocker: string;\n\tactiveQaRow?: {\n\t\tindex?: number;\n\t\tworkflow?: string;\n\t\troute?: string;\n\t\tassertion?: string;\n\t\tstatus?: string;\n\t};\n\tchangedFiles: string[];\n\tartifactPaths: string[];\n\tlatestPromptTokenEstimate?: number;\n\tupdatedAt: string;\n}\n\nexport interface ResolveIOSupportV5SupervisorState {\n\tversion: 'v5';\n\tstatus: 'active' | 'parked' | 'complete';\n\tcurrentGoal: string;\n\tapprovedScope: string;\n\tprBranch: string;\n\tactiveStep: ResolveIOSupportV5StepType;\n\tactiveBlocker: string;\n\tlastGoodCheckpoint: string;\n\tcurrentQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];\n\tprocessLease?: {\n\t\trunId?: string;\n\t\ttoken?: string;\n\t\tgeneration?: number;\n\t\tworkspace?: string;\n\t\tlane?: string;\n\t};\n\tartifactLinks: string[];\n\tnoEmailUnlessApproved: boolean;\n\tupdatedAt: string;\n}\n\nexport interface ResolveIOSupportV5StepRecord {\n\tstepType: ResolveIOSupportV5StepType;\n\toutcome: ResolveIOSupportV5Outcome;\n\tlane: ResolveIOSupportV5Lane;\n\tmodel?: string;\n\tthreadKey?: string;\n\tpromptTokenEstimate?: number;\n\truntimeMs?: number;\n\tsummary: string;\n\tblocker?: string;\n\tchangedFiles?: string[];\n\tartifactPaths?: string[];\n\trecordedAt: string;\n}\n\nexport interface ResolveIOSupportV5RunnerIncident {\n\tincidentClass: string;\n\tsummary: string;\n\tstepType?: ResolveIOSupportV5StepType;\n\tblockerFingerprint?: string;\n\tartifactPaths?: string[];\n\trecordedAt: string;\n}\n\nexport interface ResolveIOSupportV5StateBundle {\n\tsupportWorkflowVersion: 'v5';\n\tsupportV5SupervisorState: ResolveIOSupportV5SupervisorState;\n\tsupportV5LaneMemory: {\n\t\tbuild: ResolveIOSupportV5LaneMemory;\n\t\tqa: ResolveIOSupportV5LaneMemory;\n\t};\n\tsupportV5StepHistory: ResolveIOSupportV5StepRecord[];\n\tsupportV5Budget: ResolveIOSupportV5Budget;\n\tsupportV5RunnerIncidents: ResolveIOSupportV5RunnerIncident[];\n}\n\nexport interface ResolveIOSupportV5InitializeInput {\n\tjobId: string;\n\tticketId?: string;\n\tticketNumber?: string;\n\ttitle?: string;\n\tdescription?: string;\n\tapprovedScopeRequirements?: string[];\n\tapprovedScopeHours?: number | null;\n\tprBranch?: string;\n\tbuildThreadKey?: string;\n\tqaThreadKey?: string;\n\tprocessLease?: ResolveIOSupportV5SupervisorState['processLease'];\n\tnow?: Date | string;\n\texisting?: Partial<ResolveIOSupportV5StateBundle>;\n}\n\nexport interface ResolveIOSupportV5StepInput {\n\tstepType: ResolveIOSupportV5StepType;\n\toutcome: ResolveIOSupportV5Outcome;\n\tlane: ResolveIOSupportV5Lane;\n\tmodel?: string;\n\tthreadKey?: string;\n\tpromptTokenEstimate?: number;\n\truntimeMs?: number;\n\tsummary?: string;\n\tblocker?: string;\n\tchangedFiles?: string[];\n\tartifactPaths?: string[];\n\tactiveQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];\n\tnow?: Date | string;\n}\n\nexport interface ResolveIOSupportV5ContinuationDecision {\n\taction: 'continue' | 'park';\n\treason: string;\n\tnextStep: ResolveIOSupportV5StepType;\n\trepeatedNoProgressCount: number;\n\tbudgetExceeded: boolean;\n}\n\nfunction isoNow(value?: Date | string): string {\n\tif (value instanceof Date) {\n\t\treturn value.toISOString();\n\t}\n\tconst parsed = value ? new Date(value) : new Date();\n\tif (Number.isFinite(parsed.getTime())) {\n\t\treturn parsed.toISOString();\n\t}\n\treturn new Date().toISOString();\n}\n\nfunction cleanText(value: any, max = 2000): string {\n\treturn String(value || '').replace(/\\s+/g, ' ').trim().slice(0, max);\n}\n\nfunction cleanList(values: any, limit = 20, max = 500): string[] {\n\tif (!Array.isArray(values)) {\n\t\treturn [];\n\t}\n\tconst result: string[] = [];\n\tfor (const value of values) {\n\t\tconst normalized = cleanText(value, max);\n\t\tif (normalized && !result.includes(normalized)) {\n\t\t\tresult.push(normalized);\n\t\t}\n\t\tif (result.length >= limit) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function fingerprintResolveIOSupportV5Blocker(value: any): string {\n\tconst text = cleanText(value, 4000)\n\t\t.toLowerCase()\n\t\t.replace(/[a-f0-9]{16,}/g, '<id>')\n\t\t.replace(/\\b\\d{2,}\\b/g, '<n>')\n\t\t.replace(/\\bline\\s+<n>\\b/g, 'line <n>');\n\tlet hash = 0;\n\tfor (let index = 0; index < text.length; index += 1) {\n\t\thash = ((hash << 5) - hash + text.charCodeAt(index)) | 0;\n\t}\n\treturn `v5-${Math.abs(hash).toString(36)}`;\n}\n\nexport function buildResolveIOSupportV5Budget(existing?: Partial<ResolveIOSupportV5Budget>): ResolveIOSupportV5Budget {\n\treturn {\n\t\tmaxPromptTokensPerNonInitialStep: Number(existing?.maxPromptTokensPerNonInitialStep || 4000),\n\t\tmaxLoopsPerTicket: Number(existing?.maxLoopsPerTicket || 24),\n\t\tmaxRepeatedNoProgress: Number(existing?.maxRepeatedNoProgress || 2),\n\t\tmaxRuntimeMinutesPerLoop: Number(existing?.maxRuntimeMinutesPerLoop || 15),\n\t\ttotalPromptTokenEstimate: Number(existing?.totalPromptTokenEstimate || 0),\n\t\ttotalRuntimeMs: Number(existing?.totalRuntimeMs || 0),\n\t\tloopCount: Number(existing?.loopCount || 0)\n\t};\n}\n\nexport function initializeResolveIOSupportV5State(input: ResolveIOSupportV5InitializeInput): ResolveIOSupportV5StateBundle {\n\tconst now = isoNow(input.now);\n\tconst existing = input.existing || {};\n\tconst existingSupervisor = existing.supportV5SupervisorState;\n\tconst existingLaneMemory = existing.supportV5LaneMemory || {} as ResolveIOSupportV5StateBundle['supportV5LaneMemory'];\n\tconst scope = cleanList(input.approvedScopeRequirements, 24, 240).join(' | ')\n\t\t|| cleanText(input.description, 1000)\n\t\t|| cleanText(input.title, 300);\n\tconst ticketLabel = cleanText(input.ticketNumber || input.ticketId || input.jobId, 120);\n\tconst buildThreadKey = cleanText(input.buildThreadKey || existingLaneMemory.build?.threadKey || `support:${input.ticketId || input.jobId}:job:${input.jobId}:build`, 240);\n\tconst qaThreadKey = cleanText(input.qaThreadKey || existingLaneMemory.qa?.threadKey || `support:${input.ticketId || input.jobId}:job:${input.jobId}:qa`, 240);\n\tconst budget = buildResolveIOSupportV5Budget(existing.supportV5Budget);\n\treturn {\n\t\tsupportWorkflowVersion: 'v5',\n\t\tsupportV5SupervisorState: {\n\t\t\tversion: 'v5',\n\t\t\tstatus: existingSupervisor?.status || 'active',\n\t\t\tcurrentGoal: existingSupervisor?.currentGoal || `Resolve support ticket ${ticketLabel}`,\n\t\t\tapprovedScope: existingSupervisor?.approvedScope || scope,\n\t\t\tprBranch: cleanText(input.prBranch || existingSupervisor?.prBranch || '', 240),\n\t\t\tactiveStep: existingSupervisor?.activeStep || 'compile_check',\n\t\t\tactiveBlocker: existingSupervisor?.activeBlocker || '',\n\t\t\tlastGoodCheckpoint: existingSupervisor?.lastGoodCheckpoint || 'v5_initialized',\n\t\t\tcurrentQaRow: existingSupervisor?.currentQaRow,\n\t\t\tprocessLease: input.processLease || existingSupervisor?.processLease,\n\t\t\tartifactLinks: cleanList(existingSupervisor?.artifactLinks, 40, 500),\n\t\t\tnoEmailUnlessApproved: true,\n\t\t\tupdatedAt: now\n\t\t},\n\t\tsupportV5LaneMemory: {\n\t\t\tbuild: {\n\t\t\t\tlane: 'build',\n\t\t\t\tmodel: existingLaneMemory.build?.model || 'gpt-5.3-codex',\n\t\t\t\tthreadKey: buildThreadKey,\n\t\t\t\tscopeSummary: existingLaneMemory.build?.scopeSummary || scope,\n\t\t\t\tactiveBlocker: existingLaneMemory.build?.activeBlocker || '',\n\t\t\t\tactiveQaRow: existingLaneMemory.build?.activeQaRow,\n\t\t\t\tchangedFiles: cleanList(existingLaneMemory.build?.changedFiles, 80, 500),\n\t\t\t\tartifactPaths: cleanList(existingLaneMemory.build?.artifactPaths, 80, 500),\n\t\t\t\tlatestPromptTokenEstimate: Number(existingLaneMemory.build?.latestPromptTokenEstimate || 0) || undefined,\n\t\t\t\tupdatedAt: existingLaneMemory.build?.updatedAt || now\n\t\t\t},\n\t\t\tqa: {\n\t\t\t\tlane: 'qa',\n\t\t\t\tmodel: existingLaneMemory.qa?.model || 'gpt-5.4-mini',\n\t\t\t\tthreadKey: qaThreadKey,\n\t\t\t\tscopeSummary: existingLaneMemory.qa?.scopeSummary || scope,\n\t\t\t\tactiveBlocker: existingLaneMemory.qa?.activeBlocker || '',\n\t\t\t\tactiveQaRow: existingLaneMemory.qa?.activeQaRow,\n\t\t\t\tchangedFiles: cleanList(existingLaneMemory.qa?.changedFiles, 80, 500),\n\t\t\t\tartifactPaths: cleanList(existingLaneMemory.qa?.artifactPaths, 80, 500),\n\t\t\t\tlatestPromptTokenEstimate: Number(existingLaneMemory.qa?.latestPromptTokenEstimate || 0) || undefined,\n\t\t\t\tupdatedAt: existingLaneMemory.qa?.updatedAt || now\n\t\t\t}\n\t\t},\n\t\tsupportV5StepHistory: Array.isArray(existing.supportV5StepHistory)\n\t\t\t? existing.supportV5StepHistory.slice(-80)\n\t\t\t: [],\n\t\tsupportV5Budget: budget,\n\t\tsupportV5RunnerIncidents: Array.isArray(existing.supportV5RunnerIncidents)\n\t\t\t? existing.supportV5RunnerIncidents.slice(-80)\n\t\t\t: []\n\t};\n}\n\nexport function recordResolveIOSupportV5Step(\n\tbundle: ResolveIOSupportV5StateBundle,\n\tstep: ResolveIOSupportV5StepInput\n): ResolveIOSupportV5StateBundle {\n\tconst now = isoNow(step.now);\n\tconst promptTokens = Math.max(0, Number(step.promptTokenEstimate || 0) || 0);\n\tconst runtimeMs = Math.max(0, Number(step.runtimeMs || 0) || 0);\n\tconst record: ResolveIOSupportV5StepRecord = {\n\t\tstepType: step.stepType,\n\t\toutcome: step.outcome,\n\t\tlane: step.lane,\n\t\tmodel: cleanText(step.model, 80),\n\t\tthreadKey: cleanText(step.threadKey, 240),\n\t\tpromptTokenEstimate: promptTokens || undefined,\n\t\truntimeMs: runtimeMs || undefined,\n\t\tsummary: cleanText(step.summary || step.blocker || step.outcome, 1200),\n\t\tblocker: cleanText(step.blocker, 1200),\n\t\tchangedFiles: cleanList(step.changedFiles, 80, 500),\n\t\tartifactPaths: cleanList(step.artifactPaths, 80, 500),\n\t\trecordedAt: now\n\t};\n\tconst laneMemory = { ...bundle.supportV5LaneMemory };\n\tif (step.lane === 'build' || step.lane === 'qa') {\n\t\tconst previous = laneMemory[step.lane];\n\t\tlaneMemory[step.lane] = {\n\t\t\t...previous,\n\t\t\tactiveBlocker: record.blocker || previous.activeBlocker || '',\n\t\t\tactiveQaRow: step.activeQaRow || previous.activeQaRow,\n\t\t\tchangedFiles: record.changedFiles?.length ? record.changedFiles : previous.changedFiles,\n\t\t\tartifactPaths: record.artifactPaths?.length ? record.artifactPaths : previous.artifactPaths,\n\t\t\tlatestPromptTokenEstimate: promptTokens || previous.latestPromptTokenEstimate,\n\t\t\tupdatedAt: now\n\t\t};\n\t}\n\tconst supervisor = {\n\t\t...bundle.supportV5SupervisorState,\n\t\tstatus: step.outcome === 'ready_for_merge' ? 'complete' as const : (step.outcome === 'park_manual' || step.outcome === 'budget_stop' ? 'parked' as const : 'active' as const),\n\t\tactiveStep: step.stepType,\n\t\tactiveBlocker: record.blocker || '',\n\t\tcurrentQaRow: step.activeQaRow || bundle.supportV5SupervisorState.currentQaRow,\n\t\tlastGoodCheckpoint: step.outcome === 'pass' || step.outcome === 'ready_for_merge'\n\t\t\t? step.stepType\n\t\t\t: bundle.supportV5SupervisorState.lastGoodCheckpoint,\n\t\tartifactLinks: Array.from(new Set([\n\t\t\t...bundle.supportV5SupervisorState.artifactLinks,\n\t\t\t...(record.artifactPaths || [])\n\t\t])).slice(-80),\n\t\tupdatedAt: now\n\t};\n\treturn {\n\t\t...bundle,\n\t\tsupportV5SupervisorState: supervisor,\n\t\tsupportV5LaneMemory: laneMemory,\n\t\tsupportV5StepHistory: [...bundle.supportV5StepHistory, record].slice(-100),\n\t\tsupportV5Budget: {\n\t\t\t...bundle.supportV5Budget,\n\t\t\ttotalPromptTokenEstimate: bundle.supportV5Budget.totalPromptTokenEstimate + promptTokens,\n\t\t\ttotalRuntimeMs: bundle.supportV5Budget.totalRuntimeMs + runtimeMs,\n\t\t\tloopCount: bundle.supportV5Budget.loopCount + 1\n\t\t}\n\t};\n}\n\nexport function decideResolveIOSupportV5Continuation(bundle: ResolveIOSupportV5StateBundle): ResolveIOSupportV5ContinuationDecision {\n\tconst history = bundle.supportV5StepHistory || [];\n\tconst budget = buildResolveIOSupportV5Budget(bundle.supportV5Budget);\n\tconst last = history[history.length - 1];\n\tconst blockerFingerprint = fingerprintResolveIOSupportV5Blocker(last?.blocker || last?.summary || '');\n\tlet repeatedNoProgressCount = 0;\n\tfor (let index = history.length - 1; index >= 0; index -= 1) {\n\t\tconst item = history[index];\n\t\tif (item.outcome === 'pass' || item.outcome === 'ready_for_merge') {\n\t\t\tbreak;\n\t\t}\n\t\tif (item.stepType !== last?.stepType) {\n\t\t\tbreak;\n\t\t}\n\t\tif (fingerprintResolveIOSupportV5Blocker(item.blocker || item.summary || '') === blockerFingerprint) {\n\t\t\trepeatedNoProgressCount += 1;\n\t\t}\n\t}\n\tconst budgetExceeded = budget.loopCount >= budget.maxLoopsPerTicket\n\t\t|| (last?.promptTokenEstimate || 0) > budget.maxPromptTokensPerNonInitialStep * 2;\n\tif (budgetExceeded) {\n\t\treturn {\n\t\t\taction: 'park',\n\t\t\treason: 'support_v5_budget_guard',\n\t\t\tnextStep: last?.stepType || 'cleanup',\n\t\t\trepeatedNoProgressCount,\n\t\t\tbudgetExceeded\n\t\t};\n\t}\n\tif (repeatedNoProgressCount > budget.maxRepeatedNoProgress) {\n\t\treturn {\n\t\t\taction: 'park',\n\t\t\treason: 'support_v5_repeated_no_progress',\n\t\t\tnextStep: last?.stepType || 'cleanup',\n\t\t\trepeatedNoProgressCount,\n\t\t\tbudgetExceeded\n\t\t};\n\t}\n\treturn {\n\t\taction: 'continue',\n\t\treason: 'support_v5_continue',\n\t\tnextStep: last?.stepType || bundle.supportV5SupervisorState.activeStep,\n\t\trepeatedNoProgressCount,\n\t\tbudgetExceeded: false\n\t};\n}\n\nexport function buildResolveIOSupportV5DiagnoseFirstPrompt(lines: {\n\tgoal?: string;\n\tapprovedScope?: string[];\n\tactiveStep?: ResolveIOSupportV5StepType;\n\tactiveBlocker?: string;\n\tlane?: ResolveIOSupportV5Lane;\n\tlaneSummary?: string;\n\tcurrentQaRow?: ResolveIOSupportV5LaneMemory['activeQaRow'];\n\tartifactPaths?: string[];\n\tchangedFiles?: string[];\n}): string[] {\n\treturn [\n\t\t'Support Runner V5 contract: act like a guarded autonomous engineer, not a gate checklist.',\n\t\t'Start with Diagnose First: observed evidence, likely cause, smallest next action, and expected proof.',\n\t\t'Use compact lane memory and current artifacts before asking for broad ticket context.',\n\t\t'Do not send customer email. Do not write production data. Do not spawn duplicate build, QA, server, client, Mongo, browser, or Codex processes.',\n\t\t'If repairing, inspect logs/artifacts/source/diff first; make the smallest code or localhost-data change, then run the smallest self-gate.',\n\t\t'If QA fails, retest the failed row before advancing; if the same blocker repeats without new proof, park with the exact blocker.',\n\t\tlines.goal ? `Goal: ${cleanText(lines.goal, 500)}` : '',\n\t\tcleanList(lines.approvedScope, 12, 240).length ? `Approved scope: ${cleanList(lines.approvedScope, 12, 240).join(' | ')}` : '',\n\t\tlines.activeStep ? `Active step: ${lines.activeStep}` : '',\n\t\tlines.lane ? `Lane: ${lines.lane}` : '',\n\t\tlines.laneSummary ? `Lane memory: ${cleanText(lines.laneSummary, 700)}` : '',\n\t\tlines.activeBlocker ? `Active blocker: ${cleanText(lines.activeBlocker, 800)}` : '',\n\t\tlines.currentQaRow?.workflow ? `Current QA row: ${cleanText(lines.currentQaRow.workflow, 300)}` : '',\n\t\tlines.currentQaRow?.route ? `Current QA route: ${cleanText(lines.currentQaRow.route, 300)}` : '',\n\t\tcleanList(lines.changedFiles, 12, 200).length ? `Changed files: ${cleanList(lines.changedFiles, 12, 200).join(', ')}` : '',\n\t\tcleanList(lines.artifactPaths, 12, 240).length ? `Artifacts: ${cleanList(lines.artifactPaths, 12, 240).join(', ')}` : ''\n\t].filter(Boolean);\n}\n\nexport function buildResolveIOSupportV5Incident(input: {\n\tincidentClass: string;\n\tsummary: string;\n\tstepType?: ResolveIOSupportV5StepType;\n\tblocker?: string;\n\tartifactPaths?: string[];\n\tnow?: Date | string;\n}): ResolveIOSupportV5RunnerIncident {\n\treturn {\n\t\tincidentClass: cleanText(input.incidentClass, 120) || 'support_v5_runner_incident',\n\t\tsummary: cleanText(input.summary, 1200),\n\t\tstepType: input.stepType,\n\t\tblockerFingerprint: input.blocker ? fingerprintResolveIOSupportV5Blocker(input.blocker) : undefined,\n\t\tartifactPaths: cleanList(input.artifactPaths, 40, 500),\n\t\trecordedAt: isoNow(input.now)\n\t};\n}\n"]}
|