@sema-agent/client-core 0.12.0 → 0.12.1

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 CHANGED
@@ -23,7 +23,7 @@ Renamed from **`@sema-agent/wire-cc-adapter`** (0.1.x, deprecated — see *Migra
23
23
 
24
24
  ## Scope
25
25
 
26
- **Version:** 0.11.23
26
+ **Version:** 0.12.1
27
27
 
28
28
  - **Today** — the adapter seam, the whole `adapt()` pipeline (all 14 A-layer arms plus the
29
29
  B/D/E tool-card layers), the notification/caps/model families, the adapter kernel (stream driver
@@ -217,6 +217,7 @@ itself (FAILED names + skipped names + arithmetic reconciliation). All-SKIP repo
217
217
  | `scripts/run-background-view-test.mjs` | `createBackgroundView` lifecycle: polling/notify pairing, per-source degrade (`501 → not-configured` vs `unavailable`), the capabilities `scheduler` probe, and dispose really aborting the in-flight fleet snapshot (pure projection lives in the pure suite's W-A segment) |
218
218
  | `scripts/run-fleet-view-keys-test.mjs` | The fleet projection views, **both directions**: `FleetTaskView`/`FleetWorkflowView` ⇄ their key lists (compile-pinned) ⇄ what a maximal/minimal row really projects, plus a wire-key coverage ledger (every `FleetTaskRow` key is either projected or carries a written reason why not) and a drift ledger against the shell's render contract. A one-directional assignability check is blind to optional keys — which is how `startedAt` was silently dropped |
219
219
  | `scripts/run-usage-verbatim-channel-test.mjs` | The two complementary usage disciplines (core 3.0.0 metering semantics): the CC `ModelUsage` mirror stays pure (five pinned keys, `totalInputTokens` has no seat), while the sema-owned channel forwards the engine `turn_end.usage` object **verbatim** (six keys, incl. `totalInputTokens`) via `last_turn_usage.engineUsage` / `handle.latestEngineUsage` — honest absence on pre-3.0.0 engines, no fabricated zeros |
220
+ | `scripts/run-plan-review-decide-verify-test.mjs` | `decidePlanReview`'s post-decide honesty ([2315]/[2316], engine RB-471 family): a 2xx from the decide endpoint is **not** a terminal — the wire re-pulls the task status and words the outcome by the real shape (still-locked / legal new gate / genuinely left park / unverified), never claiming success it hasn't earned. Driven against a real fake-engine HTTP server through the shipped dist |
220
221
  | `scripts/run-public-surface-test.mjs` | The outward promises: the npm export surface baseline, the peer floor witness, and this README's claims |
221
222
 
222
223
  Each suite carries a floor that only moves up — a refactor that stops executing a group of
@@ -119,7 +119,48 @@ export async function decidePlanReview(taskId, decision) {
119
119
  try {
120
120
  const body = await client.assistant.planReview(taskId, { decision });
121
121
  hostLog('debug', `planReviewWire: ${decision} → ok ${JSON.stringify(body).slice(0, 200)}`);
122
- outcome = `The plan was ${decision === 'approve' ? 'approved and the parked task resumed to completion' : 'rejected (plan discarded)'} final status: ${body?.status ?? 'unknown'}.`;
122
+ // [2315]/[2316](#109,2026-08-02):decide **2xx 不当终态** —— test 黑盒实测 reject 9/9
123
+ // 返回 200 而会话仍锁在同一 gate(core RB-471:重开兜底对 reject 腿恒真误触发)。这里回拉
124
+ // 一次任务状态,按真形分三路措辞;根因归 core/server,本腿是「对外动作回读验证」在产品面的
125
+ // 同款,上游修后仍有价值(approve 合法推进新 gate 的形也靠它说真话)。
126
+ // 回拉用**短超时**独立 client(15s):verify 腿挂住不该占用 decide 的 6h 宽预算。
127
+ let postStatus;
128
+ try {
129
+ const probe = makeEngineWireClient({
130
+ baseUrl: cfg.baseUrl,
131
+ ...(cfg.token ? { token: cfg.token } : {}),
132
+ principal: cfg.principal,
133
+ timeoutMs: 15_000,
134
+ });
135
+ const post = probe ? (await probe.runs.get(taskId)) : null;
136
+ postStatus = typeof post?.status === 'string' ? post.status : undefined;
137
+ }
138
+ catch (e) {
139
+ hostLog('debug', `planReviewWire: post-decide status re-pull failed (fail-soft): ${String(e)}`);
140
+ }
141
+ // 回拉失败时回落 decide 200 体自带的 status(次级来源;两者都缺=unverified,措辞如实降级)。
142
+ const effective = postStatus ?? (typeof body?.status === 'string' ? body.status : undefined);
143
+ if (effective === 'needs_review') {
144
+ // 决定没生效,仍锁原 gate。不渲「已处理」;真出路只有 approve 或 cancel(下一次提交撞 409
145
+ // 时 activeRunSelfHeal 会把审批卡重开——这里不自动重弹卡,避免「刚拒绝又弹卡」的突袭感,
146
+ // 决定权经卡的重开路径还给用户)。
147
+ outcome =
148
+ `The plan_review ${decision} returned HTTP 200 but the session is STILL locked on the same review gate ` +
149
+ `(post-decide status: needs_review). The decision did NOT take effect (known engine issue, RB-471 family). ` +
150
+ `Tell the user plainly that the ${decision} did not go through; the reliable exits today are approving the plan or cancelling the task.`;
151
+ }
152
+ else if (effective === 'suspended') {
153
+ // 合法推进到新 gate(test [2315] ②形):不是「完成」,如实说下一张审批卡会跟上。
154
+ outcome =
155
+ `The plan was ${decision === 'approve' ? 'approved' : 'rejected'} and the task advanced to a NEW approval gate ` +
156
+ `(post-decide status: suspended) — the next approval card will surface it; this is not a completion yet.`;
157
+ }
158
+ else if (effective !== undefined) {
159
+ outcome = `The plan was ${decision === 'approve' ? 'approved and the parked task resumed to completion' : 'rejected (plan discarded)'} — final status: ${effective} (post-decide re-checked: task left the review gate).`;
160
+ }
161
+ else {
162
+ outcome = `The plan was ${decision === 'approve' ? 'approved and the parked task resumed to completion' : 'rejected (plan discarded)'} — final status: unknown (post-decide verification unavailable; treat as unconfirmed).`;
163
+ }
123
164
  }
124
165
  catch (e) {
125
166
  // APIError 判型走 status duck-check(sseIdleTriage 同款纪律:双包时 instanceof 会分叉)。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/client-core",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Client-side session runtime shared by every sema human client (TUI / web / desktop): sema wire frames (AgentEvent) -> CC session vocabulary (SDKMessage) with dual-plane output (transcript/chrome), deterministic transcript ids, lane discipline as a type, and the notification/dedup ledgers. Every CC-skin shape is collected here so the wire itself stays neutral. Blackboard [1832] design axioms; [1651]/[1652]/[1653] signed seam design. Renamed from @sema-agent/wire-cc-adapter (0.1.x).",
5
5
  "license": "MIT",
6
6
  "type": "module",