@sema-agent/client-core 0.82.7 → 0.83.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/CHANGELOG.md +97 -0
- package/README.md +15 -7
- package/dist/adapt/arms.d.ts +3 -2
- package/dist/adapt/arms.js +17 -11
- package/dist/adapt/ids.js +12 -8
- package/dist/adapt/textStream.d.ts +3 -2
- package/dist/adapt/toolCards.d.ts +2 -3
- package/dist/adapt/toolCards.js +1 -1
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +13 -6
- package/dist/adapter/activeRunSelfHeal.js +34 -17
- package/dist/adapter/downstream/eventToSdkMessage.js +1 -1
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -4
- package/dist/adapter/downstream/terminalToSdkResult.js +46 -8
- package/dist/adapter/runStream.js +25 -8
- package/dist/clientSlice.d.ts +0 -5
- package/dist/displayUntrusted.d.ts +24 -0
- package/dist/displayUntrusted.js +1437 -0
- package/dist/engineNoticeCodes.js +4 -0
- package/dist/fleet/fleetRowAgentType.d.ts +0 -1
- package/dist/fleet/fleetRowAgentType.js +0 -3
- package/dist/fleetTaskDesc.js +3 -3
- package/dist/gateVocabulary.js +1 -1
- package/dist/hitl/approvalDecisionNoteAudit.js +4 -2
- package/dist/hitl/approvalResolution.js +2 -0
- package/dist/hitl/frameRouter.d.ts +3 -2
- package/dist/hitl/sessionPolicyDeliverable.d.ts +14 -0
- package/dist/hitl/sessionPolicyDeliverable.js +80 -0
- package/dist/hitl/toolApprovalWire.d.ts +1 -0
- package/dist/hitl/toolApprovalWire.js +56 -10
- package/dist/hooksWireCaps.d.ts +6 -1
- package/dist/hooksWireCaps.js +220 -13
- package/dist/host.d.ts +25 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/liveInitToolFace.d.ts +4 -2
- package/dist/liveInitToolFace.js +2 -2
- package/dist/model/catalogLoader.d.ts +1 -6
- package/dist/panelRunningHistory.d.ts +3 -2
- package/dist/peerFrames.d.ts +0 -1
- package/dist/peerFrames.js +2 -1
- package/dist/pluginHooksWire.d.ts +92 -0
- package/dist/pluginHooksWire.js +429 -0
- package/dist/printInitToolFace.js +1 -1
- package/dist/request/printNotification.js +26 -26
- package/dist/seam.d.ts +8 -2
- package/dist/seam.js +18 -7
- package/dist/subagent/engineSubagentResume.js +2 -1
- package/dist/systemReminderTag.d.ts +0 -1
- package/dist/systemReminderTag.js +0 -3
- package/dist/toolResult.js +1 -0
- package/dist/uuidV5.d.ts +3 -0
- package/dist/uuidV5.js +178 -0
- package/dist/webSearchWireCaps.d.ts +0 -3
- package/dist/webSearchWireCaps.js +21 -51
- package/dist/wireFailureShape.d.ts +2 -1
- package/docs/INTEGRATION-CLIENTS.md +794 -13
- package/package.json +2 -2
|
@@ -10,18 +10,17 @@ export type ToolResultOwner = 'leader' | 'subagent';
|
|
|
10
10
|
export declare function toolResultOutcomeOf(toolName: string, end: ToolEndPayload | undefined, rawInput: PendingToolUse['rawInput'], owner: ToolResultOwner, ledgerTier?: (isError: boolean) => RichToolUseResult | null): ToolResultOutcome;
|
|
11
11
|
export interface ToolResultEnvelopeKeys {
|
|
12
12
|
readonly tool_use_result?: ToolResultBody['toolUseResult'];
|
|
13
|
-
readonly toolUseResult?: ToolResultBody['toolUseResult'];
|
|
14
13
|
readonly _sema_degraded?: ToolResultBody['degraded'];
|
|
15
14
|
}
|
|
16
15
|
export declare function toolResultEnvelopeParts(o: ToolResultOutcome): ToolResultEnvelopeKeys;
|
|
17
|
-
|
|
16
|
+
interface PendingToolUse {
|
|
18
17
|
id: string;
|
|
19
18
|
name: string;
|
|
20
19
|
rawInput: unknown;
|
|
21
20
|
eventId?: string;
|
|
22
21
|
parentToolCallId?: string;
|
|
23
22
|
}
|
|
24
|
-
|
|
23
|
+
interface ToolEndPayload {
|
|
25
24
|
output?: unknown;
|
|
26
25
|
structured?: unknown;
|
|
27
26
|
truncated?: boolean;
|
package/dist/adapt/toolCards.js
CHANGED
|
@@ -4,7 +4,7 @@ import { chrome, mainLane, transcript } from './ids.js';
|
|
|
4
4
|
import { flattenWireOutput } from './wireShapes.js';
|
|
5
5
|
import { isCcToolDenialKind } from '../gateVocabulary.js';
|
|
6
6
|
function toolUseResultParts(v) {
|
|
7
|
-
return v !== undefined ? { tool_use_result: v
|
|
7
|
+
return v !== undefined ? { tool_use_result: v } : {};
|
|
8
8
|
}
|
|
9
9
|
export function toolResultOutcomeOf(toolName, end, rawInput, owner, ledgerTier) {
|
|
10
10
|
const isError = end?.isError ?? false;
|
package/dist/adapt.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare const ADAPTER_COVERAGE: {
|
|
|
14
14
|
readonly b5: readonly ["B 层 structuredToToolUseResult 14 case(ask-user-question/bash/edit/create/update/text/grep/glob/notebook-edit/cron-create/cron-delete/cron-list/agent/task-output)+ workflow-run 登记副作用", "D 层 wireOutputToBody 3 臂(bash / taskoutput / 泛化);structured 白名单在场时 T11+T14 正则退位,缺席保回落", "E 层 4 臂:#117a bg Bash 回执 + #158 Monitor 回执(同臂按工具名分,registration.source 判别;判定在库→chrome bgshell_register)· TodoWrite oldTodos 富卡 · ReportFindings 按名认领 · Remember→memory_saved 系统消息", "tool_end_result → user tool_result 正常路径(卡本体);result 与 turn 末两处开卡兜底关闭(abort 不兜底,cli 同)", "task/task-list structured → chrome task_ledger_sync{source:\"structured\"}(判定归一在库、落盘留宿主)", "T7 诚实缺席(§8-4:不搬 mock 合成器,改 degraded 标记)· T20 diff hunks 进包(src/diff/patch.ts)"];
|
|
15
15
|
readonly todo: readonly ["T13 的 **D 层** 半场(taskoutput block content)未随 structured 退位:退位会改 block content 形状(cli 那里是裸对象 = 件1 隐患),属行为面改动,无真实需求驱动 ⇒ 见 DIVERGENCE-8", "macrotask 让渡(cli 在提交前让出宏任务给 Ink;宿主渲染策略,不进库)"];
|
|
16
16
|
};
|
|
17
|
-
export declare const ADAPTER_DIVERGENCES: readonly [string, string, string, string, string, string, string, string, string, string];
|
|
17
|
+
export declare const ADAPTER_DIVERGENCES: readonly [string, string, string, string, string, string, string, string, string, string, string, string];
|
|
18
18
|
export interface WireToCcAdapterWithLedger extends WireToCcAdapter {
|
|
19
19
|
exportLedger(): AdapterLedgerState & Record<string, unknown>;
|
|
20
20
|
importLedger(state: Partial<AdapterLedgerState> | Record<string, unknown>): number;
|
package/dist/adapt.js
CHANGED
|
@@ -69,7 +69,7 @@ export const ADAPTER_DIVERGENCES = [
|
|
|
69
69
|
'DIVERGENCE-1:`user` 帧透传——cli 的 switch 无 user 臂(default 丢弃),adapt 原样透传。' +
|
|
70
70
|
'现役 wire 不产 user 帧(eventToSdkMessage 无该出口),故对真流是惰性的;保留是为了 desktop 重放存量转录。',
|
|
71
71
|
'DIVERGENCE-2:transcript uuid 取值形——cli 铸随机 v4 / 原样透传帧 uuid,adapt 一律走 ' +
|
|
72
|
-
'deriveTranscriptId(
|
|
72
|
+
'deriveTranscriptId(由稳定键确定性派生的 UUID 形,同一稳定键恒得同一值)。差分守卫按「别名结构」比对(同一侧内的复用/区分关系),不比字面值。',
|
|
73
73
|
'DIVERGENCE-3:合并节流的**分片边界**不比对——cli 用 Date.now() 真时钟,adapt 用 ctx.now();' +
|
|
74
74
|
'且 B3 起节拍可由宿主 `ctx.coalesceIntervalMs` 覆盖(缺席=cli 同值 100ms)。' +
|
|
75
75
|
'守卫比对的是 chrome 增量按 channel 拼接后的全文与顺序(语义不变量),不是 chunk 切分。',
|
|
@@ -101,11 +101,18 @@ export const ADAPTER_DIVERGENCES = [
|
|
|
101
101
|
'(框架里的尾换行等是渲染副产物)。T13/T24 的 **B 层**半场同款惰性退位(structured 带齐 ' +
|
|
102
102
|
'status+content 就根本不解模型面文本);T13 的 **D 层** block-content 半场本批**未**退位 —— ' +
|
|
103
103
|
'那一步会改 block content 形状(cli 在这里是裸对象,件1 隐患),无真实需求驱动,如实留白。',
|
|
104
|
-
'DIVERGENCE-9(B5):`tool_result` 消息的 uuid —— cli 在缺 `eventId` 时铸随机 v4
|
|
105
|
-
'
|
|
106
|
-
'DIVERGENCE-10(0.81.0
|
|
107
|
-
'CC 内部转录面驼峰 `toolUseResult`
|
|
108
|
-
'
|
|
104
|
+
'DIVERGENCE-9(B5):`tool_result` 消息的 uuid —— cli 在缺 `eventId` 时铸随机 v4,本包由 toolUseId ' +
|
|
105
|
+
'确定性派生 UUID 形(DIVERGENCE-2 同族:同流重放 ⇒ 同 id 序列,[1653])。守卫按别名结构比,不比字面。',
|
|
106
|
+
'DIVERGENCE-10(0.81.0 起,0.83.0 定形,CC-131):`tool_result` 消息上本包只铸 SDK 面键 `tool_use_result` ' +
|
|
107
|
+
'(0.81.0–0.82.x 曾与 CC 内部转录面驼峰 `toolUseResult` 同引用并铸,0.83.0 删驼峰);cli 侧仍带驼峰 —— 所钉的本包' +
|
|
108
|
+
'旧版本两键同铸,升级后在转录入口从 `tool_use_result` 同值起别名。守卫在两键同在场且同引用时略过驼峰键、' +
|
|
109
|
+
'按 snake 比(两侧对称);cli 侧不再带驼峰后本条自然零触发 ⇒ 自退役。',
|
|
110
|
+
'DIVERGENCE-11(0.83.0,C-R103):system 转录行的到达时戳 —— 本包只给 user / assistant 行补 `timestamp`' +
|
|
111
|
+
'(agent-types 只在这两臂声明),system 行不补(入参自带的照旧原样过境);壳的接收口给每条转录行补到达时刻(只补缺席)。' +
|
|
112
|
+
'守卫在逐字比对前只从壳侧 system 行上去掉这一位;本包侧 system 行若带 `timestamp`,照样判不等。',
|
|
113
|
+
'DIVERGENCE-12(0.83.0,C-R103):记忆写入 —— 本包发 chrome `memory_saved` 臂(`notes` = 笔记原文,`id` 由这次写入的 wire ' +
|
|
114
|
+
'稳定键派生),转录面零行;壳侧是一条 system/memory_saved 转录行(`writtenPaths` 装同一份笔记)。守卫把壳侧这类行移出逐字比对,' +
|
|
115
|
+
'改比:事件 `notes` ⇔ 行 `writtenPaths` 逐项相等、位置相等(之前已覆盖转录行的条数);`id` 不与旧行 uuid 比(本版不承诺相等)。',
|
|
109
116
|
];
|
|
110
117
|
class WireToCcAdapterImpl {
|
|
111
118
|
ledger = createAdapterInstanceLedger();
|
|
@@ -631,35 +631,52 @@ export function activeRunSelfHealRow(outcome, signal, copy, origin, follow) {
|
|
|
631
631
|
return base + governanceOriginClause(signal);
|
|
632
632
|
}
|
|
633
633
|
}
|
|
634
|
+
const INJECTED_LEAD = 'A follow-up message sema sent on its own (not one you typed)';
|
|
634
635
|
function injectedSubmissionRow(outcome, following = false) {
|
|
635
|
-
const
|
|
636
|
+
const lead = INJECTED_LEAD;
|
|
637
|
+
const id = 'taskId' in outcome && outcome.taskId ? ` (id ${outcome.taskId})` : '';
|
|
636
638
|
if (outcome.kind === 'running-steer-failed') {
|
|
637
639
|
return outcome.delivery === 'unknown'
|
|
638
|
-
?
|
|
639
|
-
`(${outcome.detail}) — that
|
|
640
|
-
`
|
|
641
|
-
:
|
|
642
|
-
`
|
|
640
|
+
? `${lead} was passed to the reply already in progress${id}, but its delivery could not be confirmed ` +
|
|
641
|
+
`(${outcome.detail}) — that reply may or may not have received it. sema did not retry, because sending it twice ` +
|
|
642
|
+
`is not safe; watch that reply for what it does next.`
|
|
643
|
+
: `${lead} was not delivered: passing it to the reply already in progress${id} was refused (${outcome.detail}). ` +
|
|
644
|
+
`sema did not retry, so the model has not seen it.`;
|
|
643
645
|
}
|
|
644
646
|
if ((outcome.kind === 'ask-reopen-failed' || outcome.kind === 'plan-review-reopen-failed') && outcome.decisionInFlight === true) {
|
|
645
|
-
return (
|
|
646
|
-
`is still on its way
|
|
647
|
+
return (`${lead} was not delivered: this session is still busy with an earlier reply${id}, and your answer to the decision ` +
|
|
648
|
+
`it is waiting on is still on its way. sema did not retry, so the model has not seen it.`);
|
|
649
|
+
}
|
|
650
|
+
if (outcome.kind === 'running-steered' && outcome.delivery === 'queued') {
|
|
651
|
+
const queuedOn = `${lead} is queued on an earlier reply${id} that is paused waiting for a decision`;
|
|
652
|
+
if (outcome.reopened !== null && reopenDelivered(outcome.reopened)) {
|
|
653
|
+
return `${queuedOn}; sema has shown that decision card, and the message is picked up once you answer it.`;
|
|
654
|
+
}
|
|
655
|
+
if (reopenRefusedForDecisionInFlight(outcome.reopened)) {
|
|
656
|
+
return `${queuedOn}; your answer to it is still on its way, and the message is picked up once that answer is applied.`;
|
|
657
|
+
}
|
|
658
|
+
return `${queuedOn} sema could not show here; the message is picked up only once that decision is made.`;
|
|
659
|
+
}
|
|
660
|
+
if (outcome.kind === 'running-steered' && outcome.delivery === 'parked_for_wake') {
|
|
661
|
+
return (`${lead} has not reached the model: the earlier reply${id} had already finished, so the message was set aside on it ` +
|
|
662
|
+
`instead of starting a new reply, and sema did not retry it.`);
|
|
647
663
|
}
|
|
648
664
|
switch (selfHealSubmissionDisposition(outcome)) {
|
|
649
665
|
case 'held-for-decision':
|
|
650
|
-
return (
|
|
651
|
-
`
|
|
666
|
+
return (`${lead} is on hold: this session is busy with an earlier reply${id} that is waiting on a decision. ` +
|
|
667
|
+
`sema kept the message queued and will send it after you answer the open card.`);
|
|
652
668
|
case 'resending':
|
|
653
|
-
return
|
|
669
|
+
return (`${lead} was held back because this session was busy with an earlier reply${id}; the session is free again, ` +
|
|
670
|
+
`so sema is sending the message now — nothing for you to do.`);
|
|
654
671
|
case 'handed-off':
|
|
655
672
|
return following
|
|
656
|
-
?
|
|
657
|
-
`
|
|
658
|
-
:
|
|
659
|
-
`
|
|
673
|
+
? `${lead} was passed to the reply already in progress${id} instead of starting a new one. ` +
|
|
674
|
+
`sema is following that reply and will show whatever it asks for next; nothing for you to do now.`
|
|
675
|
+
: `${lead} was passed to the reply already in progress${id} instead of starting a new one — ` +
|
|
676
|
+
`watch that reply for what it does with it.`;
|
|
660
677
|
case 'not-delivered':
|
|
661
|
-
return (
|
|
662
|
-
`
|
|
678
|
+
return (`${lead} was not delivered: this session was still busy with an earlier reply${id}, and there was no open card ` +
|
|
679
|
+
`you could answer to free it. sema did not retry, so the model has not seen it.`);
|
|
663
680
|
}
|
|
664
681
|
}
|
|
665
682
|
function decisionInFlightRow(parkedOn) {
|
|
@@ -161,7 +161,7 @@ export function eventToSdkMessage(ev, ctx) {
|
|
|
161
161
|
: {}),
|
|
162
162
|
...(freedTokens !== undefined ? { _sema_freed_tokens: freedTokens } : {}),
|
|
163
163
|
},
|
|
164
|
-
...(Array.isArray(attachedFiles) && attachedFiles.length > 0 ? { attachedFiles } : {}),
|
|
164
|
+
...(Array.isArray(attachedFiles) && attachedFiles.length > 0 ? { _sema_attached_files: attachedFiles } : {}),
|
|
165
165
|
})));
|
|
166
166
|
}
|
|
167
167
|
case 'tool_end': {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentEvent, DeniedBy, TaskStats } from '@sema-agent/sdk';
|
|
2
2
|
import { type CcToolDenialKind } from '../../gateVocabulary.js';
|
|
3
3
|
import { type SDKMessage, type EmitContext } from '../types.js';
|
|
4
|
+
import type { TerminalReason } from '@sema-agent/agent-types';
|
|
4
5
|
import { type SemaModelUsage } from './turnUsageToModelUsage.js';
|
|
5
6
|
export interface SemaFlatUsage {
|
|
6
7
|
readonly inputTokens: number;
|
|
@@ -90,15 +91,12 @@ export declare function subagentUsageIsPartial(row: {
|
|
|
90
91
|
} | null | undefined, opts?: {
|
|
91
92
|
readonly tablePartial?: boolean;
|
|
92
93
|
}): boolean;
|
|
93
|
-
export interface SemaNestedUsageByTask {
|
|
94
|
-
readonly rows: Readonly<Record<string, SemaSubagentUsageRow>>;
|
|
95
|
-
readonly partial: boolean;
|
|
96
|
-
}
|
|
97
94
|
export interface SemaTerminalModelUsage extends SemaModelUsage {
|
|
98
95
|
readonly _sema_total_input_tokens?: number;
|
|
99
96
|
readonly _sema_usage_basis?: string;
|
|
100
97
|
readonly _sema_cache_write_tokens_long?: number;
|
|
101
98
|
}
|
|
99
|
+
export declare function terminalReasonForResult(msg: SDKMessage): TerminalReason | undefined;
|
|
102
100
|
export declare function doneToSdkResult(ev: Extract<AgentEvent, {
|
|
103
101
|
type: 'done';
|
|
104
102
|
}>, ctx: EmitContext, observed?: TerminalStreamObserved): SDKMessage;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { isCcToolDenialKind, isCcToolDenialKindADenial, isGateDeniedByWord } from '../../gateVocabulary.js';
|
|
2
2
|
import { stamp } from '../types.js';
|
|
3
3
|
import { putOwnKey } from '../../ownKey.js';
|
|
4
|
+
import { REDACTION_MARKER_PREFIX, washCredentials } from '../../displayUntrusted.js';
|
|
4
5
|
import { readEffectiveReasoning, readEffectiveMemoryScopes } from '../../effectiveFacts.js';
|
|
5
6
|
import { isReviewPark, readRunTerminal, runTerminalCode, runTerminalGateToolName, } from '../../runTerminal.js';
|
|
6
7
|
import { toCcModelUsage } from './turnUsageToModelUsage.js';
|
|
@@ -30,7 +31,6 @@ function nonEmptyStr(v) {
|
|
|
30
31
|
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
31
32
|
}
|
|
32
33
|
export const TOOL_INPUT_JOIN_MAX_CALLS = 4096;
|
|
33
|
-
const REDACTION_TOKEN_PREFIX = '\u00abredacted';
|
|
34
34
|
function isTransportPlaceholderLeaf(v) {
|
|
35
35
|
return v === '[circular]' || v === '[depth-limit]';
|
|
36
36
|
}
|
|
@@ -46,7 +46,7 @@ function joinableToolInput(args) {
|
|
|
46
46
|
if (++nodes > TOOL_INPUT_SCAN_MAX_NODES || depth > TOOL_INPUT_SCAN_MAX_DEPTH)
|
|
47
47
|
return undefined;
|
|
48
48
|
if (typeof v === 'string') {
|
|
49
|
-
if (v.includes(
|
|
49
|
+
if (v.includes(REDACTION_MARKER_PREFIX) || isTransportPlaceholderLeaf(v))
|
|
50
50
|
return undefined;
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
@@ -413,6 +413,41 @@ function subtypeForErrorCode(code) {
|
|
|
413
413
|
return 'error_max_structured_output_retries';
|
|
414
414
|
return 'error_during_execution';
|
|
415
415
|
}
|
|
416
|
+
function terminalReasonOf(subtype, isError) {
|
|
417
|
+
switch (subtype) {
|
|
418
|
+
case 'success':
|
|
419
|
+
return isError === false ? 'completed' : undefined;
|
|
420
|
+
case 'error_max_turns':
|
|
421
|
+
return 'max_turns';
|
|
422
|
+
case 'error_max_budget_usd':
|
|
423
|
+
return 'budget_exhausted';
|
|
424
|
+
case 'error_max_structured_output_retries':
|
|
425
|
+
return 'structured_output_retry_exhausted';
|
|
426
|
+
default:
|
|
427
|
+
return undefined;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
function terminalReasonParts(subtype, isError) {
|
|
431
|
+
const reason = terminalReasonOf(subtype, isError);
|
|
432
|
+
return reason !== undefined ? { terminal_reason: reason } : {};
|
|
433
|
+
}
|
|
434
|
+
export function terminalReasonForResult(msg) {
|
|
435
|
+
try {
|
|
436
|
+
const m = msg;
|
|
437
|
+
if (typeof m !== 'object' || m === null || Array.isArray(m))
|
|
438
|
+
return undefined;
|
|
439
|
+
const rec = m;
|
|
440
|
+
if (rec.type !== 'result')
|
|
441
|
+
return undefined;
|
|
442
|
+
return terminalReasonOf(rec.subtype, rec.is_error);
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
return undefined;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
function selectedModelParts(model) {
|
|
449
|
+
return typeof model === 'string' && model.length > 0 ? { _sema_selected_model: model } : {};
|
|
450
|
+
}
|
|
416
451
|
function salvagedTextOf(r) {
|
|
417
452
|
const salvagedOutput = r.salvagedOutput;
|
|
418
453
|
return typeof r.result === 'string' && r.result.trim().length > 0
|
|
@@ -448,10 +483,12 @@ function errorResult(ctx, parts) {
|
|
|
448
483
|
...costFactParts(parts.stats, parts.observed),
|
|
449
484
|
...reemitEffectiveFacts(parts.facts),
|
|
450
485
|
...nestedUsageByTaskParts(parts.stats, parts.observed?.nestedUsageByTask),
|
|
451
|
-
errors:
|
|
452
|
-
...(parts.
|
|
453
|
-
...(parts.
|
|
454
|
-
...(parts.
|
|
486
|
+
errors: parts.errors.map(washCredentials),
|
|
487
|
+
...terminalReasonParts(parts.subtype, true),
|
|
488
|
+
...(parts.errorCode !== undefined && parts.errorCode.length > 0 ? { _sema_error_code: parts.errorCode } : {}),
|
|
489
|
+
...(parts.degraded !== undefined ? { _sema_model_degraded: parts.degraded } : {}),
|
|
490
|
+
...selectedModelParts(parts.model),
|
|
491
|
+
...(parts.salvagedResult !== undefined ? { _sema_salvaged_result: parts.salvagedResult } : {}),
|
|
455
492
|
...(parts.outcomeUnknown === true ? { _sema_outcome: 'unknown' } : {}),
|
|
456
493
|
});
|
|
457
494
|
}
|
|
@@ -556,16 +593,17 @@ export function doneToSdkResult(ev, ctx, observed) {
|
|
|
556
593
|
num_turns: stats?.turns ?? 0,
|
|
557
594
|
result: r.result ?? '',
|
|
558
595
|
...structuredOutputParts(r),
|
|
559
|
-
...(degraded !== undefined ? { degraded } : {}),
|
|
596
|
+
...(degraded !== undefined ? { _sema_model_degraded: degraded } : {}),
|
|
560
597
|
stop_reason: null,
|
|
561
598
|
total_cost_usd: costOrNull(stats),
|
|
562
599
|
usage: flattenUsage(stats),
|
|
563
600
|
modelUsage: modelUsageFor(stats, r.model),
|
|
564
601
|
...permissionDenialParts(stats, observed),
|
|
602
|
+
...terminalReasonParts('success', false),
|
|
565
603
|
...costFactParts(stats, observed),
|
|
566
604
|
...effectiveFactParts(rec),
|
|
567
605
|
...nestedUsageByTaskParts(stats, observed?.nestedUsageByTask),
|
|
568
|
-
...(
|
|
606
|
+
...selectedModelParts(r.model),
|
|
569
607
|
});
|
|
570
608
|
}
|
|
571
609
|
export function failedToSdkResult(ev, ctx, observed) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { eventSeq, } from './types.js';
|
|
1
|
+
import { eventSeq, stamp, } from './types.js';
|
|
2
2
|
import { eventToSdkMessage, turnEndUsage } from './downstream/eventToSdkMessage.js';
|
|
3
3
|
import { turnUsageToModelUsage } from './downstream/turnUsageToModelUsage.js';
|
|
4
4
|
import { readRunCostFacts, terminalToSdkResult, TOOL_INPUT_JOIN_MAX_CALLS } from './downstream/terminalToSdkResult.js';
|
|
5
5
|
import { coerceOutput, publishSubagentContentEvent } from '../subagentContentStore.js';
|
|
6
6
|
import { ACTIVE_RUN_BUSY_ERROR_CODE, OUTPUT_INVALID, isLimitsExceededCode } from '../engineErrorCodes.js';
|
|
7
7
|
import { isReviewPark, readRunTerminal, runTerminalCode } from '../runTerminal.js';
|
|
8
|
+
import { washCredentials } from '../displayUntrusted.js';
|
|
8
9
|
import { ccToolDenialKindForToolEnd, gateDeniedBy, gateOutcomeOf } from '../gateOutcome.js';
|
|
9
10
|
import { isCcToolDenialKind, isCcToolDenialKindADenial, isGateDeniedByWord } from '../gateVocabulary.js';
|
|
10
11
|
const mainLane = () => ({ lane: 'main' });
|
|
@@ -97,14 +98,14 @@ export function isModelOutputErrorRowText(text) {
|
|
|
97
98
|
}
|
|
98
99
|
export const OUTCOME_UNKNOWN_ROW_PREFIX = 'Outcome unknown';
|
|
99
100
|
function syntheticTerminalRow(ctx, text) {
|
|
100
|
-
return {
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
return stamp(ctx, {
|
|
102
|
+
uuid: undefined,
|
|
103
|
+
session_id: undefined,
|
|
103
104
|
type: 'assistant',
|
|
104
|
-
message: { role: 'assistant', model: '<synthetic>', content: [{ type: 'text', text }] },
|
|
105
|
+
message: { role: 'assistant', model: '<synthetic>', content: [{ type: 'text', text: washCredentials(text) }] },
|
|
105
106
|
parent_tool_use_id: null,
|
|
106
|
-
|
|
107
|
-
};
|
|
107
|
+
_sema_api_error_message: true,
|
|
108
|
+
});
|
|
108
109
|
}
|
|
109
110
|
export function isOutcomeUnknownRowText(text) {
|
|
110
111
|
return text.trimStart().startsWith(`${OUTCOME_UNKNOWN_ROW_PREFIX}:`);
|
|
@@ -158,6 +159,21 @@ export function _resetDroppedFrameReportForTest() {
|
|
|
158
159
|
export function _droppedFrameMemoSizeForTest() {
|
|
159
160
|
return reportedDroppedTypes.size;
|
|
160
161
|
}
|
|
162
|
+
function withStringFailureFields(ev) {
|
|
163
|
+
if (ev.type !== 'failed')
|
|
164
|
+
return ev;
|
|
165
|
+
const got = ev;
|
|
166
|
+
const badMessage = got.errorMessage !== undefined && typeof got.errorMessage !== 'string';
|
|
167
|
+
const badCode = got.errorCode !== undefined && typeof got.errorCode !== 'string';
|
|
168
|
+
if (!badMessage && !badCode)
|
|
169
|
+
return ev;
|
|
170
|
+
const { errorMessage, errorCode, ...rest } = ev;
|
|
171
|
+
return {
|
|
172
|
+
...rest,
|
|
173
|
+
...(badMessage ? {} : { errorMessage }),
|
|
174
|
+
...(badCode ? {} : { errorCode }),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
161
177
|
let inFlightTurns = 0;
|
|
162
178
|
export function isRunStreamActive() {
|
|
163
179
|
return inFlightTurns > 0;
|
|
@@ -199,7 +215,8 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
199
215
|
return false;
|
|
200
216
|
}
|
|
201
217
|
};
|
|
202
|
-
for await (const
|
|
218
|
+
for await (const rawEv of events) {
|
|
219
|
+
const ev = withStringFailureFields(rawEv);
|
|
203
220
|
if (ev.type === 'tool_end' && ev.isError !== true)
|
|
204
221
|
successfulToolEndObserved = true;
|
|
205
222
|
const seq = eventSeq(ev);
|
package/dist/clientSlice.d.ts
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const REDACTION_MARKER_PREFIX = "\u00ABredacted";
|
|
2
|
+
export declare function looksLikeKnownSecret(s: string): boolean;
|
|
3
|
+
export declare function washCredentials(text: string): string;
|
|
4
|
+
export type DisplayMark = 'escape' | 'dot' | 'space';
|
|
5
|
+
export interface DisplayFace {
|
|
6
|
+
readonly unsafe: RegExp | null;
|
|
7
|
+
readonly fold: boolean;
|
|
8
|
+
readonly mark: DisplayMark;
|
|
9
|
+
}
|
|
10
|
+
export declare const LEGACY_ESCAPE_FACE: DisplayFace;
|
|
11
|
+
export declare const LEGACY_LABEL_FACE: DisplayFace;
|
|
12
|
+
export declare const LEGACY_NAME_FACE: DisplayFace;
|
|
13
|
+
export declare function applyDisplayFace(text: string, face: DisplayFace): string;
|
|
14
|
+
export interface DisplayUntrustedOptions {
|
|
15
|
+
readonly credentialUrls?: boolean;
|
|
16
|
+
readonly credentialWords?: boolean;
|
|
17
|
+
readonly controls?: boolean;
|
|
18
|
+
readonly bidi?: boolean;
|
|
19
|
+
readonly foldLines?: boolean;
|
|
20
|
+
readonly keepLayout?: boolean;
|
|
21
|
+
readonly mark?: DisplayMark;
|
|
22
|
+
readonly max?: number;
|
|
23
|
+
}
|
|
24
|
+
export declare function displayUntrusted(text: string, opts?: DisplayUntrustedOptions): string;
|