@dungle-scrubs/harness-cli-normalizer 0.6.0 → 0.6.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/README.md +33 -6
- package/dist/cli/args.d.ts +9 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +36 -26
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/check.d.ts +14 -0
- package/dist/cli/check.d.ts.map +1 -1
- package/dist/cli/check.js +10 -3
- package/dist/cli/check.js.map +1 -1
- package/dist/cli/config.d.ts +4 -4
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +8 -6
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/exit-codes.d.ts +0 -1
- package/dist/cli/exit-codes.d.ts.map +1 -1
- package/dist/cli/exit-codes.js +0 -1
- package/dist/cli/exit-codes.js.map +1 -1
- package/dist/cli/help.d.ts +2 -2
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +10 -2
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/inspect.d.ts.map +1 -1
- package/dist/cli/inspect.js +84 -265
- package/dist/cli/inspect.js.map +1 -1
- package/dist/cli/plan-turn.d.ts +68 -0
- package/dist/cli/plan-turn.d.ts.map +1 -0
- package/dist/cli/plan-turn.js +268 -0
- package/dist/cli/plan-turn.js.map +1 -0
- package/dist/cli/refuse.d.ts.map +1 -1
- package/dist/cli/refuse.js +2 -1
- package/dist/cli/refuse.js.map +1 -1
- package/dist/cli/resolve-harness.d.ts.map +1 -1
- package/dist/cli/resolve-harness.js +2 -3
- package/dist/cli/resolve-harness.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +33 -367
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/session-json.d.ts +1 -1
- package/dist/cli/session-json.d.ts.map +1 -1
- package/dist/cli/session-json.js +1 -3
- package/dist/cli/session-json.js.map +1 -1
- package/dist/cli/session.d.ts.map +1 -1
- package/dist/cli/session.js +35 -43
- package/dist/cli/session.js.map +1 -1
- package/dist/cli/skills-root.d.ts +1 -1
- package/dist/cli/skills-root.d.ts.map +1 -1
- package/dist/cli/skills-root.js +1 -1
- package/dist/cli/skills-root.js.map +1 -1
- package/dist/execution/decode.d.ts.map +1 -1
- package/dist/execution/decode.js +11 -36
- package/dist/execution/decode.js.map +1 -1
- package/dist/execution/events.d.ts +4 -1
- package/dist/execution/events.d.ts.map +1 -1
- package/dist/execution/events.js.map +1 -1
- package/dist/execution/failure.d.ts +3 -1
- package/dist/execution/failure.d.ts.map +1 -1
- package/dist/execution/failure.js +14 -11
- package/dist/execution/failure.js.map +1 -1
- package/dist/execution/open-session.d.ts +1 -1
- package/dist/execution/open-session.d.ts.map +1 -1
- package/dist/execution/open-session.js +150 -223
- package/dist/execution/open-session.js.map +1 -1
- package/dist/execution/stream-turn.d.ts +9 -14
- package/dist/execution/stream-turn.d.ts.map +1 -1
- package/dist/execution/stream-turn.js +85 -188
- package/dist/execution/stream-turn.js.map +1 -1
- package/dist/execution/supervisor.d.ts +71 -0
- package/dist/execution/supervisor.d.ts.map +1 -0
- package/dist/execution/supervisor.js +127 -0
- package/dist/execution/supervisor.js.map +1 -0
- package/dist/interpretation/argv.d.ts +39 -12
- package/dist/interpretation/argv.d.ts.map +1 -1
- package/dist/interpretation/argv.js +28 -20
- package/dist/interpretation/argv.js.map +1 -1
- package/dist/interpretation/content.d.ts +10 -1
- package/dist/interpretation/content.d.ts.map +1 -1
- package/dist/interpretation/content.js +20 -11
- package/dist/interpretation/content.js.map +1 -1
- package/dist/interpretation/hints.d.ts +1 -1
- package/dist/interpretation/hints.d.ts.map +1 -1
- package/dist/interpretation/hints.js +10 -11
- package/dist/interpretation/hints.js.map +1 -1
- package/dist/interpretation/index.d.ts +0 -1
- package/dist/interpretation/index.d.ts.map +1 -1
- package/dist/interpretation/index.js +0 -1
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/isolation.d.ts +10 -0
- package/dist/interpretation/isolation.d.ts.map +1 -0
- package/dist/interpretation/isolation.js +30 -0
- package/dist/interpretation/isolation.js.map +1 -0
- package/dist/interpretation/limits.d.ts +2 -5
- package/dist/interpretation/limits.d.ts.map +1 -1
- package/dist/interpretation/limits.js +8 -62
- package/dist/interpretation/limits.js.map +1 -1
- package/dist/interpretation/question.d.ts +27 -0
- package/dist/interpretation/question.d.ts.map +1 -1
- package/dist/interpretation/question.js +28 -0
- package/dist/interpretation/question.js.map +1 -1
- package/dist/interpretation/refusal.d.ts +10 -5
- package/dist/interpretation/refusal.d.ts.map +1 -1
- package/dist/interpretation/refusal.js +24 -15
- package/dist/interpretation/refusal.js.map +1 -1
- package/dist/interpretation/resolve-options.d.ts +36 -2
- package/dist/interpretation/resolve-options.d.ts.map +1 -1
- package/dist/interpretation/resolve-options.js +53 -22
- package/dist/interpretation/resolve-options.js.map +1 -1
- package/dist/interpretation/session-input.d.ts +44 -1
- package/dist/interpretation/session-input.d.ts.map +1 -1
- package/dist/interpretation/session-input.js +59 -4
- package/dist/interpretation/session-input.js.map +1 -1
- package/dist/interpretation/shape.d.ts +1 -0
- package/dist/interpretation/shape.d.ts.map +1 -1
- package/dist/interpretation/shape.js +10 -0
- package/dist/interpretation/shape.js.map +1 -1
- package/dist/interpretation/skills-selection.d.ts +25 -33
- package/dist/interpretation/skills-selection.d.ts.map +1 -1
- package/dist/interpretation/skills-selection.js +41 -48
- package/dist/interpretation/skills-selection.js.map +1 -1
- package/dist/interpretation/support.d.ts.map +1 -1
- package/dist/interpretation/support.js +25 -8
- package/dist/interpretation/support.js.map +1 -1
- package/dist/interpretation/tool-selection.d.ts +7 -6
- package/dist/interpretation/tool-selection.d.ts.map +1 -1
- package/dist/interpretation/tool-selection.js +54 -116
- package/dist/interpretation/tool-selection.js.map +1 -1
- package/dist/interpretation/tool-vocabulary.d.ts +31 -12
- package/dist/interpretation/tool-vocabulary.d.ts.map +1 -1
- package/dist/interpretation/tool-vocabulary.js +19 -41
- package/dist/interpretation/tool-vocabulary.js.map +1 -1
- package/dist/interpretation/turn-options.d.ts +4 -0
- package/dist/interpretation/turn-options.d.ts.map +1 -1
- package/dist/interpretation/turn-options.js +107 -241
- package/dist/interpretation/turn-options.js.map +1 -1
- package/dist/interpretation/vocabulary.d.ts +8 -6
- package/dist/interpretation/vocabulary.d.ts.map +1 -1
- package/dist/interpretation/vocabulary.js +22 -9
- package/dist/interpretation/vocabulary.js.map +1 -1
- package/dist/knowledge/claude-code.d.ts +3 -1
- package/dist/knowledge/claude-code.d.ts.map +1 -1
- package/dist/knowledge/claude-code.js +17 -4
- package/dist/knowledge/claude-code.js.map +1 -1
- package/dist/knowledge/codex.d.ts.map +1 -1
- package/dist/knowledge/codex.js +31 -7
- package/dist/knowledge/codex.js.map +1 -1
- package/dist/knowledge/descriptor.d.ts +67 -36
- package/dist/knowledge/descriptor.d.ts.map +1 -1
- package/dist/knowledge/descriptor.js +50 -15
- package/dist/knowledge/descriptor.js.map +1 -1
- package/dist/knowledge/matchers.d.ts +12 -0
- package/dist/knowledge/matchers.d.ts.map +1 -1
- package/dist/knowledge/matchers.js +34 -0
- package/dist/knowledge/matchers.js.map +1 -1
- package/dist/knowledge/muse.d.ts.map +1 -1
- package/dist/knowledge/muse.js +13 -6
- package/dist/knowledge/muse.js.map +1 -1
- package/dist/knowledge/overrides.d.ts.map +1 -1
- package/dist/knowledge/overrides.js +9 -20
- package/dist/knowledge/overrides.js.map +1 -1
- package/dist/knowledge/pi.d.ts.map +1 -1
- package/dist/knowledge/pi.js +8 -6
- package/dist/knowledge/pi.js.map +1 -1
- package/dist/knowledge/profile.d.ts +1 -0
- package/dist/knowledge/profile.d.ts.map +1 -1
- package/dist/knowledge/profile.js +1 -0
- package/dist/knowledge/profile.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/args.ts +39 -27
- package/src/cli/check.ts +10 -3
- package/src/cli/config.ts +14 -11
- package/src/cli/exit-codes.ts +0 -2
- package/src/cli/help.ts +10 -2
- package/src/cli/index.ts +3 -1
- package/src/cli/inspect.ts +88 -269
- package/src/cli/plan-turn.ts +350 -0
- package/src/cli/refuse.ts +2 -1
- package/src/cli/resolve-harness.ts +4 -5
- package/src/cli/run.ts +36 -399
- package/src/cli/session-json.ts +1 -6
- package/src/cli/session.ts +51 -44
- package/src/cli/skills-root.ts +1 -4
- package/src/execution/decode.ts +10 -36
- package/src/execution/events.ts +4 -1
- package/src/execution/failure.ts +18 -11
- package/src/execution/open-session.ts +154 -228
- package/src/execution/stream-turn.ts +90 -193
- package/src/execution/supervisor.ts +199 -0
- package/src/interpretation/argv.ts +65 -34
- package/src/interpretation/content.ts +30 -13
- package/src/interpretation/hints.ts +2 -12
- package/src/interpretation/index.ts +0 -1
- package/src/interpretation/isolation.ts +39 -0
- package/src/interpretation/limits.ts +14 -75
- package/src/interpretation/question.ts +46 -0
- package/src/interpretation/refusal.ts +28 -18
- package/src/interpretation/resolve-options.ts +98 -33
- package/src/interpretation/session-input.ts +88 -5
- package/src/interpretation/shape.ts +10 -0
- package/src/interpretation/skills-selection.ts +70 -74
- package/src/interpretation/support.ts +21 -6
- package/src/interpretation/tool-selection.ts +67 -122
- package/src/interpretation/tool-vocabulary.ts +48 -53
- package/src/interpretation/turn-options.ts +125 -220
- package/src/interpretation/vocabulary.ts +15 -10
- package/src/knowledge/claude-code.ts +17 -4
- package/src/knowledge/codex.ts +31 -7
- package/src/knowledge/descriptor.ts +106 -49
- package/src/knowledge/matchers.ts +35 -0
- package/src/knowledge/muse.ts +13 -6
- package/src/knowledge/overrides.ts +17 -32
- package/src/knowledge/pi.ts +8 -6
- package/src/knowledge/profile.ts +1 -0
- package/dist/interpretation/dimensions.d.ts +0 -11
- package/dist/interpretation/dimensions.d.ts.map +0 -1
- package/dist/interpretation/dimensions.js +0 -4
- package/dist/interpretation/dimensions.js.map +0 -1
- package/src/interpretation/dimensions.ts +0 -14
package/src/cli/session.ts
CHANGED
|
@@ -2,7 +2,14 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
3
|
import { nodeRunnerDeps } from "../execution/node-deps.js";
|
|
4
4
|
import { CLOSE_GRACE_MS, openSession } from "../execution/open-session.js";
|
|
5
|
+
import {
|
|
6
|
+
composeAnswer,
|
|
7
|
+
isQuestionMode,
|
|
8
|
+
QUESTION_MODES,
|
|
9
|
+
type QuestionMode,
|
|
10
|
+
} from "../interpretation/question.js";
|
|
5
11
|
import { ArgvRefusalError } from "../interpretation/refusal.js";
|
|
12
|
+
import type { BehaviorTier } from "../interpretation/resolve-options.js";
|
|
6
13
|
import type { HarnessDescriptor } from "../knowledge/descriptor.js";
|
|
7
14
|
import { defaultDescriptors } from "../knowledge/overrides.js";
|
|
8
15
|
import { createRenderState, renderEvent } from "./render.js";
|
|
@@ -22,7 +29,7 @@ export const session = async (harnessName: string, rawArgs: string[]): Promise<v
|
|
|
22
29
|
.map((d) => d.name);
|
|
23
30
|
const err = new ArgvRefusalError({
|
|
24
31
|
issue: "no-session-mode",
|
|
25
|
-
harness:
|
|
32
|
+
harness: h.name,
|
|
26
33
|
supported,
|
|
27
34
|
detail: `session mode is available on ${supported.join(", ")}; ${harnessName} declares no persistent headless session`,
|
|
28
35
|
});
|
|
@@ -37,7 +44,7 @@ export const session = async (harnessName: string, rawArgs: string[]): Promise<v
|
|
|
37
44
|
return;
|
|
38
45
|
}
|
|
39
46
|
|
|
40
|
-
const { parseCommonFlags } = await import("./args.js");
|
|
47
|
+
const { parseCommonFlags, resumeIdOf } = await import("./args.js");
|
|
41
48
|
let parsed: ReturnType<typeof parseCommonFlags>;
|
|
42
49
|
try {
|
|
43
50
|
parsed = parseCommonFlags(rawArgs);
|
|
@@ -57,23 +64,34 @@ export const session = async (harnessName: string, rawArgs: string[]): Promise<v
|
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
const values = parsed.values as Record<string, unknown>;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
67
|
+
if (values.isolation !== undefined) {
|
|
68
|
+
const { refuse, refusalOf } = await import("./refuse.js");
|
|
69
|
+
refuse(
|
|
70
|
+
refusalOf(
|
|
71
|
+
new ArgvRefusalError({
|
|
72
|
+
harness: h.name,
|
|
73
|
+
message: "isolation is available only for a fresh hcn run",
|
|
74
|
+
issue: "invalid-option-value",
|
|
75
|
+
option: "isolation",
|
|
76
|
+
supported: ["hcn run --isolation tool-free"],
|
|
77
|
+
}),
|
|
78
|
+
),
|
|
79
|
+
jsonMode,
|
|
80
|
+
"closed",
|
|
81
|
+
);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// --resume and --session-id are aliases for one concept; the one check
|
|
85
|
+
// every command calls decides whether both were given.
|
|
86
|
+
let resumeId: string | undefined;
|
|
87
|
+
try {
|
|
88
|
+
resumeId = resumeIdOf(values);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
if (!(err instanceof ArgvRefusalError)) throw err;
|
|
91
|
+
const { refusalOf, refuse } = await import("./refuse.js");
|
|
92
|
+
refuse(refusalOf(err), jsonMode, "closed");
|
|
73
93
|
return;
|
|
74
94
|
}
|
|
75
|
-
const resumeId =
|
|
76
|
-
(values.resume as string | undefined) ?? (values["session-id"] as string | undefined);
|
|
77
95
|
// The two flags are aliases for "use this session". Whether that means
|
|
78
96
|
// RESUME is decided by the store, not by which spelling was typed: an id
|
|
79
97
|
// that exists is resumed (resumeFlag rendered), an id that does not exist
|
|
@@ -107,18 +125,18 @@ export const session = async (harnessName: string, rawArgs: string[]): Promise<v
|
|
|
107
125
|
const provider = values.provider as string | undefined;
|
|
108
126
|
const effort = values.effort as string | undefined;
|
|
109
127
|
|
|
110
|
-
// question mode
|
|
128
|
+
// question mode: the arg is validated through the one predicate, then
|
|
129
|
+
// precedence resolves through the one owner (RFC-02 change 6).
|
|
111
130
|
const rawArgMode = values.questions !== undefined ? String(values.questions) : undefined;
|
|
112
|
-
if (rawArgMode !== undefined && !
|
|
131
|
+
if (rawArgMode !== undefined && !isQuestionMode(rawArgMode)) {
|
|
113
132
|
const { refuse, refusalOf } = await import("./refuse.js");
|
|
114
|
-
const { ArgvRefusalError } = await import("../interpretation/refusal.js");
|
|
115
133
|
refuse(
|
|
116
134
|
refusalOf(
|
|
117
135
|
new ArgvRefusalError({
|
|
118
136
|
issue: "invalid-option-value",
|
|
119
137
|
harness: h.name,
|
|
120
138
|
option: "questions",
|
|
121
|
-
supported: [
|
|
139
|
+
supported: [...QUESTION_MODES],
|
|
122
140
|
detail: rawArgMode,
|
|
123
141
|
}),
|
|
124
142
|
),
|
|
@@ -127,27 +145,19 @@ export const session = async (harnessName: string, rawArgs: string[]): Promise<v
|
|
|
127
145
|
);
|
|
128
146
|
return;
|
|
129
147
|
}
|
|
130
|
-
let questionMode:
|
|
131
|
-
let questionTier:
|
|
148
|
+
let questionMode: QuestionMode;
|
|
149
|
+
let questionTier: BehaviorTier;
|
|
132
150
|
try {
|
|
133
151
|
const { loadUserConfig, loadProjectConfig } = await import("./config.js");
|
|
134
|
-
const
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
questionTier = "project-config";
|
|
144
|
-
} else if (userMode !== undefined) {
|
|
145
|
-
questionMode = userMode as import("../interpretation/question.js").QuestionMode;
|
|
146
|
-
questionTier = "user-config";
|
|
147
|
-
} else {
|
|
148
|
-
questionMode = "ask";
|
|
149
|
-
questionTier = "default";
|
|
150
|
-
}
|
|
152
|
+
const { resolveBehavior } = await import("../interpretation/resolve-options.js");
|
|
153
|
+
const behavior = resolveBehavior(
|
|
154
|
+
{
|
|
155
|
+
questions: rawArgMode !== undefined && isQuestionMode(rawArgMode) ? rawArgMode : undefined,
|
|
156
|
+
},
|
|
157
|
+
{ user: loadUserConfig()?.config, project: loadProjectConfig()?.config },
|
|
158
|
+
);
|
|
159
|
+
questionMode = behavior.questions.value;
|
|
160
|
+
questionTier = behavior.questions.tier;
|
|
151
161
|
} catch (configErr) {
|
|
152
162
|
process.stderr.write(`config error: ${(configErr as Error).message}\n`);
|
|
153
163
|
if (jsonMode) {
|
|
@@ -382,10 +392,7 @@ export const session = async (harnessName: string, rawArgs: string[]): Promise<v
|
|
|
382
392
|
answer = a;
|
|
383
393
|
}
|
|
384
394
|
}
|
|
385
|
-
handle.send({
|
|
386
|
-
id: `you-${++sendCount}`,
|
|
387
|
-
text: `The user answered the question: "${q.question}" with: ${answer}. Continue accordingly.`,
|
|
388
|
-
});
|
|
395
|
+
handle.send({ id: `you-${++sendCount}`, text: composeAnswer(q.question, answer) });
|
|
389
396
|
// Drain the answer turn BEFORE prompting again - the pump's
|
|
390
397
|
// backpressure stalls the harness until the turn iterable is
|
|
391
398
|
// consumed (verified live: menu answered, you-prompt rendered, no
|
package/src/cli/skills-root.ts
CHANGED
|
@@ -31,10 +31,7 @@ export const listKnownSkills = (): string[] => {
|
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
export const resolveSkillNames = (
|
|
35
|
-
names: readonly string[],
|
|
36
|
-
harness: HarnessName = "claude",
|
|
37
|
-
): string[] => {
|
|
34
|
+
export const resolveSkillNames = (names: readonly string[], harness: HarnessName): string[] => {
|
|
38
35
|
const root = skillsRoot();
|
|
39
36
|
const known = new Set(listKnownSkills());
|
|
40
37
|
const unknown = names.filter((n) => !known.has(n));
|
package/src/execution/decode.ts
CHANGED
|
@@ -10,7 +10,7 @@ import { decodeIdentity } from "../interpretation/identity.js";
|
|
|
10
10
|
import { detectLimitInLine } from "../interpretation/limits.js";
|
|
11
11
|
import type { HarnessDescriptor, StreamingGranularity } from "../knowledge/descriptor.js";
|
|
12
12
|
import type { HarnessEvent } from "./events.js";
|
|
13
|
-
import { failureFromBudget } from "./failure.js";
|
|
13
|
+
import { failureFromBudget, failureFromLimit } from "./failure.js";
|
|
14
14
|
|
|
15
15
|
export interface DecodeState {
|
|
16
16
|
lastSeenId: string | null;
|
|
@@ -99,47 +99,21 @@ export const decodeParsed = (
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
// Content (message/token/tool/error/budget) is per-harness;
|
|
103
|
-
// above is descriptor-driven. contentEventsOf dispatches by
|
|
104
|
-
// name. budget
|
|
102
|
+
// Content (message/token/tool/error/budget/limit) is per-harness;
|
|
103
|
+
// identity above is descriptor-driven. contentEventsOf dispatches by
|
|
104
|
+
// harness name inside interpretation. budget and limit are not
|
|
105
|
+
// HarnessEvent kinds of their own here: both become failures.
|
|
105
106
|
for (const content of contentEventsOf(h.name, raw)) {
|
|
106
107
|
if (content.kind === "budget") {
|
|
107
108
|
events.push({ kind: "failure", ...failureFromBudget(content.detail) });
|
|
109
|
+
} else if (content.kind === "limit") {
|
|
110
|
+
events.push({
|
|
111
|
+
kind: "failure",
|
|
112
|
+
...failureFromLimit(content.code, content.detail, content.resetsAt),
|
|
113
|
+
});
|
|
108
114
|
} else {
|
|
109
115
|
events.push(content);
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
|
-
|
|
113
|
-
// claude's rate_limit_event: only non-"allowed" statuses are failures.
|
|
114
|
-
// overageStatus is deliberately not classified - it is a separate
|
|
115
|
-
// billing signal, not a rate limit.
|
|
116
|
-
if (h.name === "claude" && typeof (raw as Record<string, unknown>).type === "string") {
|
|
117
|
-
const rec = raw as Record<string, unknown>;
|
|
118
|
-
if (rec.type === "rate_limit_event") {
|
|
119
|
-
const info = rec.rate_limit_info as Record<string, unknown> | undefined;
|
|
120
|
-
const status = info?.status as string | undefined;
|
|
121
|
-
if (status !== undefined && status !== "allowed") {
|
|
122
|
-
const rawResets = info?.resetsAt;
|
|
123
|
-
let resetsAt: number | undefined;
|
|
124
|
-
if (typeof rawResets === "number" && Number.isFinite(rawResets) && rawResets > 0) {
|
|
125
|
-
// Arithmetic conversion: resetsAt is seconds, we need milliseconds. No wall clock read.
|
|
126
|
-
resetsAt = rawResets * 1000;
|
|
127
|
-
if (!Number.isFinite(resetsAt) || resetsAt <= 0) resetsAt = undefined;
|
|
128
|
-
}
|
|
129
|
-
// Push a failure event directly - this is a structured record, not a wall scan
|
|
130
|
-
const failure: import("./failure.js").FailureSummary = {
|
|
131
|
-
class: "rate-limit",
|
|
132
|
-
retryable: true,
|
|
133
|
-
message: `Rate limit hit (rate_limit_event status=${status}) - retry after backoff or route to another provider`,
|
|
134
|
-
code: "rate-limit" as const,
|
|
135
|
-
...(resetsAt !== undefined ? { resetsAt } : {}),
|
|
136
|
-
};
|
|
137
|
-
events.push({
|
|
138
|
-
kind: "failure",
|
|
139
|
-
...failure,
|
|
140
|
-
} as unknown as import("./events.js").HarnessEvent);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
118
|
return events;
|
|
145
119
|
};
|
package/src/execution/events.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* concatenate both.
|
|
16
16
|
*/
|
|
17
17
|
import type { CapabilityResult } from "../interpretation/capabilities.js";
|
|
18
|
+
import type { QuestionMode } from "../interpretation/question.js";
|
|
18
19
|
import type { LimitCode } from "../knowledge/descriptor.js";
|
|
19
20
|
import type { FailureSummary } from "./failure.js";
|
|
20
21
|
|
|
@@ -29,7 +30,9 @@ export type ExitCause =
|
|
|
29
30
|
* SUCCESSFUL turn (process exit 0); the caller resumes with the answer. */
|
|
30
31
|
| "awaiting-input";
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
/** The question mode the turn ran under - the one vocabulary question.ts
|
|
34
|
+
* owns, recorded on done per RFC-01. */
|
|
35
|
+
export type EscalationMode = QuestionMode;
|
|
33
36
|
export type EscalationDetection = "block" | "malformed" | "none";
|
|
34
37
|
export interface EscalationRecord {
|
|
35
38
|
readonly mode: EscalationMode;
|
package/src/execution/failure.ts
CHANGED
|
@@ -103,7 +103,7 @@ const messageFor = (cls: FailureClass, detail?: string): string => {
|
|
|
103
103
|
}; /** D11: the run outlived its caller-set wall-clock budget. */
|
|
104
104
|
export const failureFromTimeout = (): FailureSummary => ({
|
|
105
105
|
class: "timeout",
|
|
106
|
-
retryable:
|
|
106
|
+
retryable: retryableOf("timeout"),
|
|
107
107
|
message: messageFor("timeout"),
|
|
108
108
|
});
|
|
109
109
|
|
|
@@ -114,7 +114,7 @@ export const failureFromNative = (
|
|
|
114
114
|
stderrTail: readonly string[],
|
|
115
115
|
): FailureSummary => ({
|
|
116
116
|
class: "native",
|
|
117
|
-
retryable:
|
|
117
|
+
retryable: retryableOf("native"),
|
|
118
118
|
message: messageFor(
|
|
119
119
|
"native",
|
|
120
120
|
stderrTail.slice(-3).join(" | ").slice(0, 512) || `exit ${nativeExitCode}`,
|
|
@@ -122,7 +122,13 @@ export const failureFromNative = (
|
|
|
122
122
|
nativeExitCode: nativeExitCode ?? undefined,
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
/** A limit, from a wall phrasing (detail defaults to the code) or from a
|
|
126
|
+
* structured record that names its status and, sometimes, a reset time. */
|
|
127
|
+
export const failureFromLimit = (
|
|
128
|
+
code: LimitCode,
|
|
129
|
+
detail: string = code,
|
|
130
|
+
resetsAt?: number,
|
|
131
|
+
): FailureSummary => {
|
|
126
132
|
const cls: FailureClass =
|
|
127
133
|
code === "rate-limit"
|
|
128
134
|
? "rate-limit"
|
|
@@ -132,14 +138,15 @@ export const failureFromLimit = (code: LimitCode): FailureSummary => {
|
|
|
132
138
|
return {
|
|
133
139
|
class: cls,
|
|
134
140
|
retryable: retryableOf(cls),
|
|
135
|
-
message: messageFor(cls,
|
|
136
|
-
code
|
|
141
|
+
message: messageFor(cls, detail),
|
|
142
|
+
code,
|
|
143
|
+
...(resetsAt !== undefined ? { resetsAt } : {}),
|
|
137
144
|
};
|
|
138
145
|
};
|
|
139
146
|
|
|
140
147
|
export const failureFromAuth = (kind: AuthFailureKind): FailureSummary => ({
|
|
141
148
|
class: "auth",
|
|
142
|
-
retryable:
|
|
149
|
+
retryable: retryableOf("auth"),
|
|
143
150
|
message: messageFor("auth", kind),
|
|
144
151
|
authKind: kind,
|
|
145
152
|
});
|
|
@@ -157,25 +164,25 @@ export const failureFromTerminalError = (h: HarnessDescriptor, message: string):
|
|
|
157
164
|
|
|
158
165
|
export const failureFromTask = (detail?: string): FailureSummary => ({
|
|
159
166
|
class: "task",
|
|
160
|
-
retryable:
|
|
167
|
+
retryable: retryableOf("task"),
|
|
161
168
|
message: messageFor("task", detail),
|
|
162
169
|
});
|
|
163
170
|
|
|
164
171
|
export const failureFromBudget = (detail?: string): FailureSummary => ({
|
|
165
172
|
class: "budget",
|
|
166
|
-
retryable:
|
|
173
|
+
retryable: retryableOf("budget"),
|
|
167
174
|
message: messageFor("budget", detail),
|
|
168
175
|
});
|
|
169
176
|
|
|
170
177
|
export const failureFromTransport = (detail?: string): FailureSummary => ({
|
|
171
178
|
class: "transport",
|
|
172
|
-
retryable:
|
|
179
|
+
retryable: retryableOf("transport"),
|
|
173
180
|
message: messageFor("transport", detail),
|
|
174
181
|
});
|
|
175
182
|
|
|
176
183
|
export const failureFromUnavailable = (detail?: string): FailureSummary => ({
|
|
177
184
|
class: "unavailable",
|
|
178
|
-
retryable:
|
|
185
|
+
retryable: retryableOf("unavailable"),
|
|
179
186
|
message: messageFor("unavailable", detail),
|
|
180
187
|
});
|
|
181
188
|
|
|
@@ -189,7 +196,7 @@ export const failureFromRejected = (opts: {
|
|
|
189
196
|
detail?: string;
|
|
190
197
|
}): FailureSummary => ({
|
|
191
198
|
class: "rejected",
|
|
192
|
-
retryable:
|
|
199
|
+
retryable: retryableOf("rejected"),
|
|
193
200
|
// D8: hint first, support list second - prose order matches the
|
|
194
201
|
// structured fields so an agent scanning the message hits the
|
|
195
202
|
// stay-on-harness suggestion before the switch temptation.
|