@sema-agent/client-core 0.12.1 → 0.13.0
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 +15 -2
- package/dist/abortableSleep.d.ts +29 -0
- package/dist/abortableSleep.js +43 -0
- package/dist/adapt/arms.d.ts +58 -0
- package/dist/adapt/arms.js +613 -0
- package/dist/adapt/ids.d.ts +22 -0
- package/dist/adapt/ids.js +34 -0
- package/dist/adapt/instanceLedger.d.ts +36 -0
- package/dist/adapt/instanceLedger.js +50 -0
- package/dist/adapt/panelTasks.d.ts +54 -0
- package/dist/adapt/panelTasks.js +193 -0
- package/dist/adapt/textStream.d.ts +49 -0
- package/dist/adapt/textStream.js +141 -0
- package/dist/adapt/toolCards.d.ts +65 -0
- package/dist/adapt/toolCards.js +100 -0
- package/dist/adapt/turnFlags.d.ts +33 -0
- package/dist/adapt/turnFlags.js +55 -0
- package/dist/adapt/wireShapes.d.ts +93 -0
- package/dist/adapt/wireShapes.js +167 -0
- package/dist/adapt.d.ts +32 -59
- package/dist/adapt.js +78 -1206
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +55 -13
- package/dist/adapter/downstream/eventToSdkMessage.js +166 -106
- package/dist/adapter/downstream/terminalToSdkResult.js +149 -160
- package/dist/adapter/downstream/turnUsageToModelUsage.d.ts +36 -0
- package/dist/adapter/downstream/turnUsageToModelUsage.js +34 -6
- package/dist/adapter/runStream.d.ts +29 -4
- package/dist/adapter/runStream.js +129 -13
- package/dist/adapter/types.d.ts +2 -2
- package/dist/agentSession/backgroundView.js +4 -15
- package/dist/agentsWireCaps.d.ts +10 -6
- package/dist/agentsWireCaps.js +21 -7
- package/dist/argvFlagValue.d.ts +41 -0
- package/dist/argvFlagValue.js +69 -0
- package/dist/attachmentsWireCaps.d.ts +3 -2
- package/dist/attachmentsWireCaps.js +5 -3
- package/dist/classifierVerdictWire.d.ts +8 -0
- package/dist/classifierVerdictWire.js +8 -0
- package/dist/cloudConfigWireCaps.d.ts +28 -1
- package/dist/cloudConfigWireCaps.js +51 -11
- package/dist/controlRouter.d.ts +14 -8
- package/dist/controlRouter.js +15 -21
- package/dist/detachWire.d.ts +15 -5
- package/dist/detachWire.js +17 -7
- package/dist/effortWire.d.ts +0 -21
- package/dist/effortWire.js +6 -20
- package/dist/engineInlineTaskStats.d.ts +12 -6
- package/dist/engineWireSdk.d.ts +12 -0
- package/dist/env/localeGeo.js +2 -1
- package/dist/envFlag.d.ts +39 -0
- package/dist/envFlag.js +51 -0
- package/dist/finalVerifyWire.d.ts +7 -5
- package/dist/finalVerifyWire.js +6 -5
- package/dist/fleet/fleetLedger.d.ts +32 -9
- package/dist/fleet/fleetLedger.js +119 -34
- package/dist/fleet/fleetProjection.d.ts +44 -6
- package/dist/fleet/fleetProjection.js +52 -10
- package/dist/fleetAgentPanelProjection.d.ts +18 -1
- package/dist/fleetAgentPanelProjection.js +61 -14
- package/dist/forkWireCaps.d.ts +2 -1
- package/dist/forkWireCaps.js +5 -11
- package/dist/goalStopHook.d.ts +142 -0
- package/dist/goalStopHook.js +258 -0
- package/dist/headlessPermissionModeWire.d.ts +10 -0
- package/dist/headlessPermissionModeWire.js +24 -21
- package/dist/headlessReconnectWire.d.ts +7 -1
- package/dist/headlessReconnectWire.js +20 -2
- package/dist/hitl/approvalsFeed.js +31 -8
- package/dist/hitl/askGateWire.d.ts +27 -96
- package/dist/hitl/askGateWire.js +69 -546
- package/dist/hitl/frameRouter.d.ts +86 -0
- package/dist/hitl/frameRouter.js +342 -0
- package/dist/hitl/gateLedger.d.ts +107 -0
- package/dist/hitl/gateLedger.js +113 -0
- package/dist/hitl/hitlBridge.d.ts +75 -15
- package/dist/hitl/hitlBridge.js +94 -22
- package/dist/hitl/hitlHostSurface.d.ts +49 -0
- package/dist/hitl/hitlHostSurface.js +155 -0
- package/dist/hitl/parkResolver.d.ts +74 -0
- package/dist/hitl/parkResolver.js +241 -0
- package/dist/hitl/planReviewWire.d.ts +60 -2
- package/dist/hitl/planReviewWire.js +152 -74
- package/dist/hitl/toolApprovalWire.d.ts +67 -4
- package/dist/hitl/toolApprovalWire.js +119 -31
- package/dist/hooksWireCaps.d.ts +1 -82
- package/dist/hooksWireCaps.js +34 -235
- package/dist/host.d.ts +16 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +15 -1
- package/dist/interactiveToolsWire.d.ts +15 -4
- package/dist/interactiveToolsWire.js +24 -26
- package/dist/limitsWire.js +7 -40
- package/dist/liveInitToolFace.d.ts +51 -6
- package/dist/liveQuestionStore.d.ts +5 -6
- package/dist/model/providerPresets.js +11 -1
- package/dist/notifications.d.ts +48 -2
- package/dist/notifications.js +223 -46
- package/dist/retainBackgroundWireCaps.d.ts +3 -2
- package/dist/retainBackgroundWireCaps.js +5 -9
- package/dist/sandboxWire.d.ts +9 -31
- package/dist/sandboxWire.js +51 -50
- package/dist/scenarioWire.d.ts +1 -1
- package/dist/scenarioWire.js +25 -36
- package/dist/seam.d.ts +23 -6
- package/dist/seam.js +40 -30
- package/dist/seatContract.d.ts +369 -83
- package/dist/seatContract.js +585 -198
- package/dist/selfOrchestrationWireCaps.d.ts +6 -5
- package/dist/selfOrchestrationWireCaps.js +8 -12
- package/dist/sessionSlot.d.ts +8 -0
- package/dist/sessionSlot.js +1 -0
- package/dist/steering.js +2 -2
- package/dist/subagent/engineTaskHandleWire.d.ts +3 -0
- package/dist/subagent/engineTaskHandleWire.js +17 -2
- package/dist/subagentContentStore.d.ts +5 -5
- package/dist/toolResult.d.ts +89 -8
- package/dist/toolResult.js +99 -30
- package/dist/typePins.d.ts +17 -0
- package/dist/typePins.js +1 -0
- package/dist/ultracodeWireCaps.js +5 -6
- package/dist/unrefTimer.d.ts +19 -0
- package/dist/unrefTimer.js +5 -0
- package/dist/workflow.d.ts +3 -2
- package/dist/workflow.js +3 -2
- package/dist/workflowClient.d.ts +7 -0
- package/dist/workflowClient.js +47 -12
- package/package.json +3 -3
package/dist/sandboxWire.d.ts
CHANGED
|
@@ -1,29 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* src/sema/sandboxWire.ts — [686]② `--sandbox` TRI-STATE flag (clay 拍, 2026-07-13): the CLI face of the
|
|
3
|
-
* per-task SANDBOX IMAGE PROFILE the server already ships end-to-end (`TaskRequest.sandboxImageProfile`
|
|
4
|
-
* per-task binding + the model-facing `SelectEnvironment` tool + the `GET /v1/images` catalog).
|
|
5
|
-
*
|
|
6
|
-
* TRI-STATE (clay 口径):
|
|
7
|
-
* a) DEFAULT (no flag) → NO `sandboxImageProfile` on the POST body — the worker's default image runs.
|
|
8
|
-
* b) `--sandbox <profile>` → EXPLICIT: stamp `sandboxImageProfile` (SDK types.ts:115 → service
|
|
9
|
-
* main.ts:2316 resolves profile→digest FAIL-CLOSED with the caller's principal — we only ever send the
|
|
10
|
-
* PROFILE, never a digest). Vocabulary = the live catalog (`sema cloud images list` / GET /v1/images) —
|
|
11
|
-
* the shell does NOT pre-validate against it (fail-closed admission is the server's job; a typo comes
|
|
12
|
-
* back as an honest 404, mapped to a hint by sandboxDegradeHint below).
|
|
13
|
-
* c) `--sandbox auto` → ADVISORY: the submit carries NO profile; instead the FIRST live turn's
|
|
14
|
-
* objective is prefixed with an advisory block asking the model to drive the `SelectEnvironment` tool
|
|
15
|
-
* itself (list → pick → report `Sandbox: <profile> — <reason>` in its reply, so the choice + reason are
|
|
16
|
-
* visible on the run card and correctable by the user). NOT a hard route — server keeps zero new
|
|
17
|
-
* endpoints; the tool's session binding takes effect from the NEXT task boundary ([440] F3 contract).
|
|
18
|
-
*
|
|
19
|
-
* LANE HONESTY (诚实不撒谎 UI, [686] constraint): the profile only works on the k8s sandbox lane — an
|
|
20
|
-
* e2b/host-lane worker (including the local TOC self-spawned engine) 400s the submit honestly
|
|
21
|
-
* (service main.ts:2323 "sandboxImageProfile is only supported on the k8s sandbox backend"). The shell does
|
|
22
|
-
* NOT pre-judge the lane (no caps sniffing before submit — per [686]: "不预判 lane,收到 400 再提示");
|
|
23
|
-
* it maps the server's honest reject into a degradation hint (sandboxDegradeHint) rendered on the error row.
|
|
24
|
-
* So on the local self-spawned engine `--sandbox <profile>` = a LOUD per-turn failure with an actionable
|
|
25
|
-
* hint — never a silent ignore (silently dropping the user's explicit environment choice would be lying).
|
|
26
|
-
*/
|
|
27
1
|
export type SandboxSelection = {
|
|
28
2
|
mode: 'default';
|
|
29
3
|
} | {
|
|
@@ -45,7 +19,7 @@ export type SandboxParseResult = {
|
|
|
45
19
|
* Missing value / flag-shaped value / empty / over-long ⇒ fail-LOUD parse error (never a silent default —
|
|
46
20
|
* a mis-typed environment choice must not quietly run on the wrong image).
|
|
47
21
|
*/
|
|
48
|
-
export declare function parseSandboxArgv(argv: string[]): SandboxParseResult;
|
|
22
|
+
export declare function parseSandboxArgv(argv: readonly string[]): SandboxParseResult;
|
|
49
23
|
/** The request-body stamp for a selection: EXPLICIT ⇒ `{sandboxImageProfile}`, default/auto ⇒ nothing
|
|
50
24
|
* (auto is advisory-by-prompt — the submit itself never carries a profile, per clay's c) 口径). */
|
|
51
25
|
export declare function sandboxRequestFields(sel: SandboxSelection | undefined): {
|
|
@@ -65,11 +39,15 @@ export declare function sandboxRequestFields(sel: SandboxSelection | undefined):
|
|
|
65
39
|
export declare const AUTO_SANDBOX_ADVISORY: string;
|
|
66
40
|
/** Prefix an objective with the auto-select advisory (one-shot — the caller owns the latch). */
|
|
67
41
|
export declare function wrapObjectiveWithAutoSandboxAdvisory(objective: string): string;
|
|
42
|
+
export declare const SANDBOX_K8S_ONLY_400_ANCHOR = "only supported on the k8s sandbox backend";
|
|
43
|
+
export declare const SANDBOX_NO_IMAGE_INDEX_400_ANCHOR = "requires the image index";
|
|
44
|
+
export declare const SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR = "no published sandbox image for profile";
|
|
45
|
+
export declare const SANDBOX_CASCADE_CONFLICT_400_ANCHOR = "not supported together with cascade/verify";
|
|
68
46
|
/**
|
|
69
47
|
* Map a submit failure → the sandbox DEGRADATION HINT, or undefined when the error is not sandbox-shaped.
|
|
70
|
-
* Keys on the server's honest reject texts (
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
48
|
+
* Keys on the server's honest reject texts (the four `SANDBOX_*_ANCHOR` constants above) — status+substring,
|
|
49
|
+
* the same recognize-by-wire-shape idiom the quota/scenario copy modules use. The caller renders it under
|
|
50
|
+
* the raw "API Error: …" row (original message preserved — the hint supplements, never masks, the server's
|
|
51
|
+
* own words).
|
|
74
52
|
*/
|
|
75
53
|
export declare function sandboxDegradeHint(err: unknown): string | undefined;
|
package/dist/sandboxWire.js
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
* So on the local self-spawned engine `--sandbox <profile>` = a LOUD per-turn failure with an actionable
|
|
25
25
|
* hint — never a silent ignore (silently dropping the user's explicit environment choice would be lying).
|
|
26
26
|
*/
|
|
27
|
+
import { lastFlagValue } from './argvFlagValue.js';
|
|
27
28
|
/** Mirror of the server's own body validation (server.ts:4651): non-empty, ≤128 chars. Validating locally
|
|
28
29
|
* just converts a guaranteed 400 into an immediate CLI error — same rule, earlier and cheaper. */
|
|
29
30
|
const MAX_PROFILE_LEN = 128;
|
|
@@ -38,49 +39,38 @@ const USAGE_HINT = "sema: --sandbox expects a profile name or 'auto'.\n" +
|
|
|
38
39
|
* a mis-typed environment choice must not quietly run on the wrong image).
|
|
39
40
|
*/
|
|
40
41
|
export function parseSandboxArgv(argv) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// consumed the prompt as the profile, then died on an unrelated "Input must be provided…"
|
|
66
|
-
// error. Profile names never contain whitespace; a value that does is almost certainly the
|
|
67
|
-
// user's prompt — say exactly that instead of silently mis-parsing.
|
|
68
|
-
if (/\s/.test(v)) {
|
|
69
|
-
return {
|
|
70
|
-
ok: false,
|
|
71
|
-
error: `Invalid sandbox profile "${v}". Profile names cannot contain spaces — if you meant it as the prompt, ` +
|
|
72
|
-
`pass --sandbox a profile name (or 'auto') first, or omit --sandbox to use the worker default image.\n` +
|
|
73
|
-
USAGE_HINT,
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
if (v.length > MAX_PROFILE_LEN) {
|
|
77
|
-
return {
|
|
78
|
-
ok: false,
|
|
79
|
-
error: `sema: --sandbox profile must be at most ${MAX_PROFILE_LEN} characters (same rule the server enforces).`,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
sel = v === 'auto' ? { mode: 'auto' } : { mode: 'explicit', profile: v };
|
|
42
|
+
// REF-CC-143(dup-07)收编:extraction 改吃共用 lastFlagValue(argvFlagValue.ts)——scan-all-then-
|
|
43
|
+
// validate-once, matching this module's own documented "Repeated flag ⇒ LAST wins" contract (the
|
|
44
|
+
// former per-occurrence eager-validate loop actually violated that contract: an earlier INVALID
|
|
45
|
+
// occurrence overridden by a later VALID one used to fail-loud on the earlier one instead of
|
|
46
|
+
// honoring the later value — fixed as a side effect of the consolidation, not a logic rewrite).
|
|
47
|
+
const flag = lastFlagValue(argv, '--sandbox');
|
|
48
|
+
if (!flag.present)
|
|
49
|
+
return { ok: true, sel: { mode: 'default' } };
|
|
50
|
+
if (flag.raw === undefined)
|
|
51
|
+
return { ok: false, error: USAGE_HINT };
|
|
52
|
+
const v = flag.raw.trim();
|
|
53
|
+
if (v.length === 0)
|
|
54
|
+
return { ok: false, error: USAGE_HINT };
|
|
55
|
+
// audit #17: a bare `--sandbox` EATS the following positional — `-p --sandbox 'say hi'`
|
|
56
|
+
// consumed the prompt as the profile, then died on an unrelated "Input must be provided…"
|
|
57
|
+
// error. Profile names never contain whitespace; a value that does is almost certainly the
|
|
58
|
+
// user's prompt — say exactly that instead of silently mis-parsing.
|
|
59
|
+
if (/\s/.test(v)) {
|
|
60
|
+
return {
|
|
61
|
+
ok: false,
|
|
62
|
+
error: `Invalid sandbox profile "${v}". Profile names cannot contain spaces — if you meant it as the prompt, ` +
|
|
63
|
+
`pass --sandbox a profile name (or 'auto') first, or omit --sandbox to use the worker default image.\n` +
|
|
64
|
+
USAGE_HINT,
|
|
65
|
+
};
|
|
83
66
|
}
|
|
67
|
+
if (v.length > MAX_PROFILE_LEN) {
|
|
68
|
+
return {
|
|
69
|
+
ok: false,
|
|
70
|
+
error: `sema: --sandbox profile must be at most ${MAX_PROFILE_LEN} characters (same rule the server enforces).`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const sel = v === 'auto' ? { mode: 'auto' } : { mode: 'explicit', profile: v };
|
|
84
74
|
return { ok: true, sel };
|
|
85
75
|
}
|
|
86
76
|
/** The request-body stamp for a selection: EXPLICIT ⇒ `{sandboxImageProfile}`, default/auto ⇒ nothing
|
|
@@ -108,30 +98,41 @@ export const AUTO_SANDBOX_ADVISORY = '<sandbox-auto-select>\n' +
|
|
|
108
98
|
export function wrapObjectiveWithAutoSandboxAdvisory(objective) {
|
|
109
99
|
return `${AUTO_SANDBOX_ADVISORY}\n\n${objective}`;
|
|
110
100
|
}
|
|
101
|
+
// ── REF-CC-124(域词表-03,P3 wave1 卡C-argv):四条拒绝 hint 判别锚常量化 ─────────────────────────
|
|
102
|
+
// ALLOW 登记(与 detachWire.DETACH_DURABLE_OFF_400_ANCHOR 同形):这四条锚的是**另一个仓**
|
|
103
|
+
// (ai-agent-service)当下的拒绝原文(main.ts SelectEnvironment 校验分支 / per-task-image.ts 镜像
|
|
104
|
+
// 索引缺席分支 / server.ts submit 校验分支)——只留文件名+分支语义,不锚外仓行号(它们会腐烂,
|
|
105
|
+
// wave1 回炉 advisory 修:server 改字即静默失效,失效方向只丢 hint、不误伤,是本族里后果最轻的
|
|
106
|
+
// 一处,故过渡期常量化而非阻断发车)。
|
|
107
|
+
// 候 server 5.0.0 errorCode 换轨,#117(上游到货后这四条整族改吃 errorCode,判别不再靠字符串锚)。
|
|
108
|
+
export const SANDBOX_K8S_ONLY_400_ANCHOR = 'only supported on the k8s sandbox backend';
|
|
109
|
+
export const SANDBOX_NO_IMAGE_INDEX_400_ANCHOR = 'requires the image index';
|
|
110
|
+
export const SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR = 'no published sandbox image for profile';
|
|
111
|
+
export const SANDBOX_CASCADE_CONFLICT_400_ANCHOR = 'not supported together with cascade/verify';
|
|
111
112
|
/**
|
|
112
113
|
* Map a submit failure → the sandbox DEGRADATION HINT, or undefined when the error is not sandbox-shaped.
|
|
113
|
-
* Keys on the server's honest reject texts (
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
114
|
+
* Keys on the server's honest reject texts (the four `SANDBOX_*_ANCHOR` constants above) — status+substring,
|
|
115
|
+
* the same recognize-by-wire-shape idiom the quota/scenario copy modules use. The caller renders it under
|
|
116
|
+
* the raw "API Error: …" row (original message preserved — the hint supplements, never masks, the server's
|
|
117
|
+
* own words).
|
|
117
118
|
*/
|
|
118
119
|
export function sandboxDegradeHint(err) {
|
|
119
120
|
const e = err;
|
|
120
121
|
if (typeof e?.status !== 'number' || typeof e?.message !== 'string')
|
|
121
122
|
return undefined;
|
|
122
123
|
const msg = e.message;
|
|
123
|
-
if (e.status === 400 && msg.includes(
|
|
124
|
+
if (e.status === 400 && msg.includes(SANDBOX_K8S_ONLY_400_ANCHOR)) {
|
|
124
125
|
return ('--sandbox <profile> only applies on k8s-lane workers; this engine runs a host/e2b sandbox lane, so the request was honestly rejected.\n' +
|
|
125
126
|
'Re-run without --sandbox (worker default image), or point the shell at a k8s-lane worker (sema cloud engine connect <url>).');
|
|
126
127
|
}
|
|
127
|
-
if (e.status === 400 && msg.includes(
|
|
128
|
+
if (e.status === 400 && msg.includes(SANDBOX_NO_IMAGE_INDEX_400_ANCHOR)) {
|
|
128
129
|
return ('This worker has no sandbox image index configured (sema-registry backend absent), so per-task profiles cannot resolve.\n' +
|
|
129
130
|
'Re-run without --sandbox, or use a worker with the image index enabled.');
|
|
130
131
|
}
|
|
131
|
-
if (e.status === 404 && msg.includes(
|
|
132
|
+
if (e.status === 404 && msg.includes(SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR)) {
|
|
132
133
|
return 'No published image matches that profile for your principal. List what you can use: sema cloud images list';
|
|
133
134
|
}
|
|
134
|
-
if (e.status === 400 && msg.includes(
|
|
135
|
+
if (e.status === 400 && msg.includes(SANDBOX_CASCADE_CONFLICT_400_ANCHOR)) {
|
|
135
136
|
return '--sandbox cannot combine with cascade/verify submits in v1 (the per-task image would not bind to the sub-runs). Drop one of the two.';
|
|
136
137
|
}
|
|
137
138
|
return undefined;
|
package/dist/scenarioWire.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export type ScenarioParseResult = {
|
|
|
47
47
|
* fail-LOUD parse error (never a silent default — a mis-typed routing choice must not quietly run on
|
|
48
48
|
* the wrong tool surface; same stance as `--sandbox`).
|
|
49
49
|
*/
|
|
50
|
-
export declare function parseScenarioArgv(argv: string[]): ScenarioParseResult;
|
|
50
|
+
export declare function parseScenarioArgv(argv: readonly string[]): ScenarioParseResult;
|
|
51
51
|
/**
|
|
52
52
|
* The settings-lane default (`SEMA_HEADLESS_SCENARIO`). FAIL-SOFT on a bad value (stderr warning +
|
|
53
53
|
* no stamp): a settings-file typo must not hard-brick every headless run the way an explicit flag
|
package/dist/scenarioWire.js
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* deliberately NOT reused here: it selects offline mock transcripts, not live engine routing.
|
|
30
30
|
*/
|
|
31
31
|
import { hostEnv } from './hostEnv.js';
|
|
32
|
+
import { lastFlagValue } from './argvFlagValue.js';
|
|
32
33
|
/** Mirror of the server's scenario NAME shape (ai-agent-service scenarios.ts:318). */
|
|
33
34
|
export const SCENARIO_NAME_RE = /^[a-z][a-z0-9-]{1,31}$/;
|
|
34
35
|
/** Settings-lane env knob (settings.json `env` block → 1a-envseed → process.env). */
|
|
@@ -45,43 +46,31 @@ const USAGE_HINT = "sema: --scenario expects a scenario name (lowercase letters/
|
|
|
45
46
|
* the wrong tool surface; same stance as `--sandbox`).
|
|
46
47
|
*/
|
|
47
48
|
export function parseScenarioArgv(argv) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
const v = raw.trim();
|
|
69
|
-
// sandboxWire audit #17 lesson: a bare `--scenario` EATS the following positional — a value with
|
|
70
|
-
// whitespace is almost certainly the user's prompt; say exactly that instead of mis-parsing.
|
|
71
|
-
if (/\s/.test(v)) {
|
|
72
|
-
return {
|
|
73
|
-
ok: false,
|
|
74
|
-
error: `sema: --scenario got "${v.length > 48 ? `${v.slice(0, 48)}…` : v}" — that looks like your prompt, not a scenario name.\n` +
|
|
75
|
-
'Put the flag AFTER the value form (--scenario=<name>) or keep the name and prompt as separate tokens.\n' +
|
|
76
|
-
USAGE_HINT,
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
if (!SCENARIO_NAME_RE.test(v)) {
|
|
80
|
-
return { ok: false, error: USAGE_HINT };
|
|
81
|
-
}
|
|
82
|
-
scenario = v;
|
|
49
|
+
// REF-CC-143(dup-07)收编:extraction 改吃共用 lastFlagValue(argvFlagValue.ts)——scan-all-then-
|
|
50
|
+
// validate-once, matching this function's own documented "Repeated flag ⇒ LAST wins" contract (the
|
|
51
|
+
// former per-occurrence eager-validate loop actually violated that contract the same way sandboxWire's
|
|
52
|
+
// did: an earlier INVALID occurrence overridden by a later VALID one used to fail-loud on the earlier
|
|
53
|
+
// one instead of honoring the later value — fixed as a side effect of the consolidation).
|
|
54
|
+
const flag = lastFlagValue(argv, '--scenario');
|
|
55
|
+
if (!flag.present)
|
|
56
|
+
return { ok: true };
|
|
57
|
+
if (flag.raw === undefined)
|
|
58
|
+
return { ok: false, error: USAGE_HINT };
|
|
59
|
+
const v = flag.raw.trim();
|
|
60
|
+
// sandboxWire audit #17 lesson: a bare `--scenario` EATS the following positional — a value with
|
|
61
|
+
// whitespace is almost certainly the user's prompt; say exactly that instead of mis-parsing.
|
|
62
|
+
if (/\s/.test(v)) {
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
error: `sema: --scenario got "${v.length > 48 ? `${v.slice(0, 48)}…` : v}" — that looks like your prompt, not a scenario name.\n` +
|
|
66
|
+
'Put the flag AFTER the value form (--scenario=<name>) or keep the name and prompt as separate tokens.\n' +
|
|
67
|
+
USAGE_HINT,
|
|
68
|
+
};
|
|
83
69
|
}
|
|
84
|
-
|
|
70
|
+
if (!SCENARIO_NAME_RE.test(v)) {
|
|
71
|
+
return { ok: false, error: USAGE_HINT };
|
|
72
|
+
}
|
|
73
|
+
return { ok: true, scenario: v };
|
|
85
74
|
}
|
|
86
75
|
/**
|
|
87
76
|
* The settings-lane default (`SEMA_HEADLESS_SCENARIO`). FAIL-SOFT on a bad value (stderr warning +
|
package/dist/seam.d.ts
CHANGED
|
@@ -22,6 +22,25 @@ export interface AbortSignalLike {
|
|
|
22
22
|
export type TimerHandle = unknown;
|
|
23
23
|
/** `ctx.log` 的级别词表(cli utils/debug logForDebugging 的等价面)。 */
|
|
24
24
|
export type AdapterLogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
25
|
+
/**
|
|
26
|
+
* TYPESHAPE-13:inline task tick 的形状——本文件(seam.ts,ChromeEvent 的 `inline_task_stats`/
|
|
27
|
+
* `op:'tick'` 臂内嵌套 `stats` 字段)与 `engineInlineTaskStats.ts`(`publishEngineInlineTaskTick`
|
|
28
|
+
* 的 `tick` 形参)两处逐字相同的形状,抽成具名类型两处共用——漏改一处(比如只给这里加
|
|
29
|
+
* `currentToolName?`)时,两侧编译仍全绿但字段会被静默丢弃,B4 命名 DU 豁免只护直接成员形状,
|
|
30
|
+
* 不护这种嵌套字段。
|
|
31
|
+
*
|
|
32
|
+
* 🔴 [P1 回炉,opus advisory⑤] 定义搬到这里(此前在 `engineInlineTaskStats.ts` 反向 import 进
|
|
33
|
+
* seam.ts):seam.ts 是本包基础词表模块,`engineInlineTaskStats.ts` 改前是零 import 文件——原先
|
|
34
|
+
* 由「零 import 的边缘文件」定义、被「基础词表模块」反向导入,层级是倒的。现在改为
|
|
35
|
+
* `engineInlineTaskStats.ts` 从这里 `import type`,方向回正;`index.ts` 的 barrel 不重复导出
|
|
36
|
+
* (只有这里 `export`,避免两处 `export *` 撞同名)。
|
|
37
|
+
*/
|
|
38
|
+
export interface InlineTaskTick {
|
|
39
|
+
toolUses: number;
|
|
40
|
+
totalTokens: number;
|
|
41
|
+
durationMs: number;
|
|
42
|
+
currentAction?: string;
|
|
43
|
+
}
|
|
25
44
|
/**
|
|
26
45
|
* 宿主注入的适配上下文(时钟/铸号可测,B 形跨端确定性)。
|
|
27
46
|
*
|
|
@@ -234,12 +253,7 @@ export type ChromeEvent = {
|
|
|
234
253
|
op: 'tick';
|
|
235
254
|
/** 委派 tool_use id(渲染面订阅键)。 */
|
|
236
255
|
cardId: string;
|
|
237
|
-
stats:
|
|
238
|
-
toolUses: number;
|
|
239
|
-
totalTokens: number;
|
|
240
|
-
durationMs: number;
|
|
241
|
-
currentAction?: string;
|
|
242
|
-
};
|
|
256
|
+
stats: InlineTaskTick;
|
|
243
257
|
} | {
|
|
244
258
|
kind: 'inline_task_stats';
|
|
245
259
|
laneProof: LaneProof;
|
|
@@ -368,6 +382,9 @@ export type ChromeArmKind = ChromeEvent['kind'];
|
|
|
368
382
|
* `required` 判据:**不实现会让已发生的行为丢失**(转录/模型输入/hook/去重)⇒ true;
|
|
369
383
|
* 只影响可选装饰(spinner 计量、活体预览、chips)⇒ false。
|
|
370
384
|
* `duty` = 一句话义务(完整义务在上方每臂的注释里,那里是真源)。
|
|
385
|
+
*
|
|
386
|
+
* 数组形对外形状不变(消费方逐字沿用 `CHROME_ARMS.map/find/filter`)——真源是上面
|
|
387
|
+
* {@link CHROME_ARM_TABLE},本表只是它的 `Object.entries` 派生投影。
|
|
371
388
|
*/
|
|
372
389
|
export declare const CHROME_ARMS: readonly {
|
|
373
390
|
kind: ChromeArmKind;
|
package/dist/seam.js
CHANGED
|
@@ -1,46 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* chrome
|
|
3
|
-
*
|
|
4
|
-
* 用途:任何宿主(TUI / web / 桌面)在自检里遍历本表,对 `required:true` 的臂断言"我实现了消费口"。
|
|
5
|
-
* 不实现 = 该 UI 面在那个宿主上是**哑的**(不是报错,是静默没有)—— 这正是多端最容易漏的一类,
|
|
6
|
-
* 所以把义务做成**数据**而不是散落在注释里。
|
|
2
|
+
* chrome 臂**覆盖率断言出口**的编译期底座(REF-CC-154,midband-02,gate)。
|
|
7
3
|
*
|
|
8
|
-
* `
|
|
9
|
-
*
|
|
10
|
-
* `
|
|
4
|
+
* 🔴 为什么是 `Record<ChromeArmKind, …>` 不是数组字面量:此前 `CHROME_ARMS` 直接手写成数组,
|
|
5
|
+
* `ChromeEvent` 新增一个判别值时,漏补这张表**编译期零信号**——18 个判别值与表项手数对齐纯靠
|
|
6
|
+
* 人工核对。`Record` 强制**每个** `ChromeArmKind` 成员都有一条目,少一个 = tsc 报错,新臂想不进表
|
|
7
|
+
* 都不行(§B5「union 加成员必须打红全部消费 switch」的同族纪律)。
|
|
11
8
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
{
|
|
26
|
-
kind: 'workflow_notification_enqueue',
|
|
9
|
+
const CHROME_ARM_TABLE = {
|
|
10
|
+
retry_status: { required: false, duty: '渲/清 spinner 的重试覆盖层' },
|
|
11
|
+
panel_task: { required: true, duty: 'publishEngineAgentPanelEvent(event) 原样转发' },
|
|
12
|
+
bgshell_settle: { required: true, duty: '后台 shell 面板行落终态(含 outputPath)' },
|
|
13
|
+
bgshell_register: { required: true, duty: '后台 shell 面板行建行 + 登记「句柄→宿主 run」' },
|
|
14
|
+
tasks_expand: { required: false, duty: '展开 ctrl+t 任务面板' },
|
|
15
|
+
thinking_activity: { required: false, duty: '开/收活体 "∴ Thinking…" 行' },
|
|
16
|
+
request_start: { required: false, duty: 'spinner 置 requesting 态' },
|
|
17
|
+
stream_delta: { required: false, duty: '渲活体预览 + 推进 responseLength' },
|
|
18
|
+
response_metrics: { required: false, duty: '驱动 responseLength reducer(ttft/对账)' },
|
|
19
|
+
attachment: { required: false, duty: '渲 attachment 行(必须带 default 臂)' },
|
|
20
|
+
notification_terminal: { required: false, duty: '可选 UI 提示(记账已由库自持)' },
|
|
21
|
+
subagent_lifecycle: { required: true, duty: 'fire SubagentStart/Stop hooks(去重已由库解)' },
|
|
22
|
+
workflow_notification_enqueue: {
|
|
27
23
|
required: true,
|
|
28
24
|
// 门/notified 记账/cardEnqueued 记号三件已由库在发臂前做完 ⇒ 宿主只投递,且必须用**裸入队**口。
|
|
29
25
|
duty: 'message 裸入完成通知队列(不要用自带去重门的老函数),idle 时喂模型;门与两条记号归库',
|
|
30
26
|
},
|
|
31
|
-
{
|
|
32
|
-
kind: 'task_ledger_sync',
|
|
27
|
+
task_ledger_sync: {
|
|
33
28
|
required: true,
|
|
34
29
|
// 🔴 **两个 source 都要接**(B6 核实:同一张任务卡实测出两条)——`tool_use` 是卡刚开时的
|
|
35
30
|
// 乐观建行(旧引擎只有它),`structured` 是引擎回来的权威全量态(带真实 id/状态)。
|
|
36
31
|
// 只接前者 ⇒ 引擎真实 id 永不回填;只接后者 ⇒ 面板要等工具跑完才出现。幂等键 = toolUseId。
|
|
37
32
|
duty: '按 toolUseId 幂等落 TaskCreate/TaskUpdate —— source 的 tool_use(乐观建行)与 structured(权威全量态)两条都要接',
|
|
38
33
|
},
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
inline_task_stats: { required: true, duty: 'tick/settle/settle_all 转发给 engineInlineTaskStats' },
|
|
35
|
+
prompt_suggestions: { required: false, duty: '推 composer 上方 chips(绝不回喂模型)' },
|
|
36
|
+
last_turn_usage: { required: true, duty: '落最近一次 turn 真 usage(statusline 回落源)' },
|
|
37
|
+
plan_review_park: { required: true, duty: '弹 plan 审批卡(fail-soft,不挡后续终态帧)' },
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* chrome 臂**覆盖率断言出口**(§8-1 裁决的一半:client-core 定接口不定实现)。
|
|
41
|
+
*
|
|
42
|
+
* 用途:任何宿主(TUI / web / 桌面)在自检里遍历本表,对 `required:true` 的臂断言"我实现了消费口"。
|
|
43
|
+
* 不实现 = 该 UI 面在那个宿主上是**哑的**(不是报错,是静默没有)—— 这正是多端最容易漏的一类,
|
|
44
|
+
* 所以把义务做成**数据**而不是散落在注释里。
|
|
45
|
+
*
|
|
46
|
+
* `required` 判据:**不实现会让已发生的行为丢失**(转录/模型输入/hook/去重)⇒ true;
|
|
47
|
+
* 只影响可选装饰(spinner 计量、活体预览、chips)⇒ false。
|
|
48
|
+
* `duty` = 一句话义务(完整义务在上方每臂的注释里,那里是真源)。
|
|
49
|
+
*
|
|
50
|
+
* 数组形对外形状不变(消费方逐字沿用 `CHROME_ARMS.map/find/filter`)——真源是上面
|
|
51
|
+
* {@link CHROME_ARM_TABLE},本表只是它的 `Object.entries` 派生投影。
|
|
52
|
+
*/
|
|
53
|
+
export const CHROME_ARMS = Object.entries(CHROME_ARM_TABLE).map(([kind, d]) => ({ kind, required: d.required, duty: d.duty }));
|
|
44
54
|
/**
|
|
45
55
|
* transcript id 确定性派生([1653] 定案):稳定键优先序 = 帧 id > seq > toolCallId;
|
|
46
56
|
* 全缺才用 ctx.uuid()。同流重放 ⇒ 同 id 序列(往返守卫钉此不变量)。
|