@sema-agent/client-core 0.91.0 → 0.93.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/CHANGELOG.md +351 -0
- package/README.md +51 -34
- package/dist/adapt/arms.js +6 -12
- package/dist/adapt/panelTasks.d.ts +0 -2
- package/dist/adapt/panelTasks.js +6 -26
- package/dist/adapt/toolCards.js +6 -4
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +3 -3
- package/dist/adapter/activeRunSelfHeal.d.ts +0 -2
- package/dist/adapter/activeRunSelfHeal.js +5 -27
- package/dist/adapter/downstream/terminalToSdkResult.js +16 -7
- package/dist/adapter/runStream.js +6 -2
- package/dist/agentsWireCaps.js +1 -1
- package/dist/approvalDecidedByCapability.d.ts +16 -0
- package/dist/approvalDecidedByCapability.js +47 -0
- package/dist/approvalsStreamLiveCapability.js +3 -3
- package/dist/askSurvivesStandingAnswer.d.ts +4 -1
- package/dist/askSurvivesStandingAnswer.js +13 -0
- package/dist/autoModeUnavailable.js +3 -2
- package/dist/centerWiringCapability.js +1 -1
- package/dist/cloudConfigWireCaps.js +10 -9
- package/dist/compensations.js +7 -7
- package/dist/controlRouter.d.ts +23 -23
- package/dist/controlRouter.js +114 -49
- package/dist/coreValuePorts.d.ts +4 -2
- package/dist/coreValuePorts.js +5 -0
- package/dist/decideFailureNote.js +4 -2
- package/dist/decideReceipt.d.ts +11 -0
- package/dist/decideReceipt.js +95 -9
- package/dist/detachWire.d.ts +2 -14
- package/dist/detachWire.js +1 -47
- package/dist/deviceExecutorManagementCapability.d.ts +6 -2
- package/dist/deviceExecutorManagementCapability.js +61 -15
- package/dist/displayUntrusted.js +2 -1
- package/dist/effectiveFacts.d.ts +14 -4
- package/dist/effectiveFacts.js +45 -5
- package/dist/engineAgentAbsence.js +2 -1
- package/dist/engineCapReader.js +16 -10
- package/dist/engineCapsCache.d.ts +2 -0
- package/dist/engineCapsCache.js +13 -2
- package/dist/engineConfigDrift.d.ts +20 -0
- package/dist/engineConfigDrift.js +54 -0
- package/dist/engineErrorCodes.d.ts +17 -0
- package/dist/engineErrorCodes.js +45 -0
- package/dist/engineInlineTaskStats.d.ts +1 -0
- package/dist/engineNoticeCodes.d.ts +16 -2
- package/dist/engineNoticeCodes.js +71 -0
- package/dist/engineWireFor.d.ts +22 -0
- package/dist/engineWireFor.js +154 -9
- package/dist/engineWireSdk.d.ts +0 -1
- package/dist/engineWireSdk.js +0 -3
- package/dist/executionLaneCapability.js +4 -2
- package/dist/fileHistoryCaptureCapability.d.ts +1 -1
- package/dist/fileHistoryCaptureCapability.js +1 -6
- package/dist/fileHistoryLegNotice.d.ts +1 -1
- package/dist/fileHistoryLegNotice.js +1 -6
- package/dist/gateOutcome.js +2 -17
- package/dist/gateVocabulary.d.ts +2 -8
- package/dist/gateVocabulary.js +6 -32
- package/dist/generated/engineFactTables.d.ts +17 -1
- package/dist/generated/engineFactTables.js +91 -0
- package/dist/generated/engineNoticeTables.d.ts +1 -1
- package/dist/generated/engineNoticeTables.js +4 -1
- package/dist/generated/settingsSchemaTables.d.ts +8 -0
- package/dist/generated/settingsSchemaTables.js +40 -0
- package/dist/goalStopHook.d.ts +1 -8
- package/dist/goalStopHook.js +2 -58
- package/dist/headlessPermissionModeWire.d.ts +3 -2
- package/dist/headlessPermissionModeWire.js +46 -5
- package/dist/hitl/allowRuleShadow.d.ts +21 -0
- package/dist/hitl/allowRuleShadow.js +167 -0
- package/dist/hitl/askClassPair.d.ts +14 -0
- package/dist/hitl/askClassPair.js +42 -0
- package/dist/hitl/askGateWire.js +1 -0
- package/dist/hitl/askParkRowRouting.js +2 -2
- package/dist/hitl/askSurvivesPosture.d.ts +5 -0
- package/dist/hitl/askSurvivesPosture.js +17 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +21 -0
- package/dist/hitl/automaticAnswerVerdict.js +143 -0
- package/dist/hitl/crashConverged.d.ts +1 -0
- package/dist/hitl/crashConverged.js +1 -1
- package/dist/hitl/frameRouter.d.ts +2 -0
- package/dist/hitl/frameRouter.js +73 -16
- package/dist/hitl/gateLedger.d.ts +7 -0
- package/dist/hitl/gateLedger.js +37 -5
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +6 -1
- package/dist/hitl/hitlHostSurface.d.ts +5 -2
- package/dist/hitl/hitlHostSurface.js +25 -3
- package/dist/hitl/livePendingAsk.js +24 -5
- package/dist/hitl/parkResolver.js +24 -4
- package/dist/hitl/persistedRulesWire.d.ts +4 -1
- package/dist/hitl/persistedRulesWire.js +38 -19
- package/dist/hitl/planReviewWire.d.ts +0 -2
- package/dist/hitl/planReviewWire.js +3 -20
- package/dist/hitl/replayedApproval.d.ts +21 -0
- package/dist/hitl/replayedApproval.js +89 -0
- package/dist/hitl/sessionPolicyDeliverable.js +20 -2
- package/dist/hitl/sessionPolicyWire.d.ts +10 -0
- package/dist/hitl/sessionPolicyWire.js +19 -6
- package/dist/hitl/toolApprovalWire.d.ts +27 -7
- package/dist/hitl/toolApprovalWire.js +153 -94
- package/dist/hookMatcherVerdict.js +2 -1
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +1 -1
- package/dist/humanTurn.js +3 -4
- package/dist/index.d.ts +21 -6
- package/dist/index.js +17 -4
- package/dist/inheritEnvWire.d.ts +1 -4
- package/dist/inheritEnvWire.js +3 -22
- package/dist/limitsWire.d.ts +0 -6
- package/dist/limitsWire.js +0 -38
- package/dist/mcpLiveness.js +2 -1
- package/dist/mcpProbeCapability.js +1 -1
- package/dist/mcpProbeWire.js +10 -12
- package/dist/mcpReconnect.d.ts +5 -0
- package/dist/mcpReconnect.js +28 -0
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/memoryVerbsWire.d.ts +1 -1
- package/dist/memoryVerbsWire.js +17 -13
- package/dist/model/catalog.js +2 -1
- package/dist/model/providerPresets.d.ts +3 -1
- package/dist/model/tierVocabulary.d.ts +2 -1
- package/dist/model/tierVocabulary.js +3 -8
- package/dist/ownKey.d.ts +2 -0
- package/dist/ownKey.js +15 -0
- package/dist/peerFrames.js +2 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.d.ts +16 -0
- package/dist/permissionModesCapability.js +71 -0
- package/dist/permissionRuleIssue.js +10 -7
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionWireCaps.d.ts +2 -0
- package/dist/permissionWireCaps.js +8 -1
- package/dist/permissionsAllowGrantCapability.js +7 -2
- package/dist/permissionsDeclaration.d.ts +7 -1
- package/dist/permissionsDeclaration.js +29 -20
- package/dist/pluginHooksWire.js +2 -11
- package/dist/postureKnob.js +1 -1
- package/dist/promptProfileWireCaps.d.ts +2 -1
- package/dist/protocolSegment.d.ts +11 -0
- package/dist/protocolSegment.js +31 -0
- package/dist/readFacePosture.js +1 -1
- package/dist/request/taskRequest.js +1 -15
- package/dist/resumeRefusalCopy.d.ts +1 -0
- package/dist/resumeRefusalCopy.js +26 -3
- package/dist/retryStatus.js +2 -1
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/ruleCompileVerdict.d.ts +2 -0
- package/dist/ruleCompileVerdict.js +13 -0
- package/dist/ruleRemovalConsequence.d.ts +2 -1
- package/dist/runCancelContext.d.ts +12 -0
- package/dist/runCancelContext.js +83 -1
- package/dist/runTerminal.d.ts +16 -0
- package/dist/runTerminal.js +32 -3
- package/dist/seam.d.ts +1 -0
- package/dist/seam.js +1 -1
- package/dist/seatContract.d.ts +2 -1
- package/dist/sessionMemoryStatus.d.ts +2 -4
- package/dist/sessionPolicyCapability.js +1 -1
- package/dist/sessionSyncFileHistoryCapability.d.ts +18 -0
- package/dist/sessionSyncFileHistoryCapability.js +50 -0
- package/dist/skillToolListsCapability.d.ts +18 -0
- package/dist/skillToolListsCapability.js +50 -0
- package/dist/sqlEngineCapability.js +2 -9
- package/dist/steerPriorityCapability.d.ts +18 -0
- package/dist/steerPriorityCapability.js +80 -0
- package/dist/steerReceipt.d.ts +9 -0
- package/dist/steerReceipt.js +25 -0
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/engineSubagentSteer.js +2 -9
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +15 -5
- package/dist/taskRequestWords.d.ts +4 -2
- package/dist/taskRequestWords.js +1 -1
- package/dist/toolHistoryBadTurn.js +1 -2
- package/dist/toolResult.d.ts +10 -1
- package/dist/toolResult.js +80 -6
- package/dist/types/engineState.d.ts +2 -12
- package/dist/userInvokedSkillsCapability.d.ts +18 -0
- package/dist/userInvokedSkillsCapability.js +50 -0
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/webSearchWireCaps.d.ts +1 -1
- package/dist/webSearchWireCaps.js +40 -2
- package/dist/wireFailureShape.d.ts +2 -0
- package/dist/wireFailureShape.js +6 -2
- package/dist/wireRefusalCopy.d.ts +9 -3
- package/dist/wireRefusalCopy.js +41 -4
- package/dist/workflowsJournalCapability.d.ts +18 -0
- package/dist/workflowsJournalCapability.js +50 -0
- package/dist/writeProtectionCapability.d.ts +2 -4
- package/dist/writeProtectionCapability.js +1 -1
- package/docs/INTEGRATION-CLIENTS.md +1516 -18
- package/package.json +2 -2
package/dist/adapt/arms.js
CHANGED
|
@@ -8,7 +8,7 @@ import { projectDiagnosticsFrame } from '../diagnostics.js';
|
|
|
8
8
|
import { recordEngineToolLabel } from '../engineToolLabelStore.js';
|
|
9
9
|
import { registerSubagentAlias, registerSubagentContentAlias } from '../subagentContentStore.js';
|
|
10
10
|
import { readAsyncLaunchedAgentReceipt } from '../toolResult.js';
|
|
11
|
-
import {
|
|
11
|
+
import { recordWorkflowAgentTaskId } from '../workflow.js';
|
|
12
12
|
import { isTerminalStatus } from '../runTerminal.js';
|
|
13
13
|
import { readToolHistoryMismatchKey } from '../toolHistoryMismatch.js';
|
|
14
14
|
import { readProviderRejectionResendKey } from '../providerRejection.js';
|
|
@@ -578,9 +578,7 @@ const taskProgressArm = function* (m, { ctx, cards, panel, inst }) {
|
|
|
578
578
|
const explicitParentRaw = m.parentToolCallId;
|
|
579
579
|
const explicitParent = typeof explicitParentRaw === 'string' ? explicitParentRaw : undefined;
|
|
580
580
|
const workflowRunId = typeof m.workflowRunId === 'string' ? m.workflowRunId : undefined;
|
|
581
|
-
if (workflowRunId !== undefined
|
|
582
|
-
isWorkflowAgentTaskId(taskId) ||
|
|
583
|
-
(explicitParent !== undefined && inst.isWorkflowCard(explicitParent))) {
|
|
581
|
+
if (workflowRunId !== undefined) {
|
|
584
582
|
recordWorkflowAgentTaskId(taskId);
|
|
585
583
|
if (workflowRunId !== undefined && explicitParent !== undefined && inst.isWorkflowCard(explicitParent))
|
|
586
584
|
noteOwnWorkflowRun(workflowRunId);
|
|
@@ -588,19 +586,13 @@ const taskProgressArm = function* (m, { ctx, cards, panel, inst }) {
|
|
|
588
586
|
t: ctx.now(),
|
|
589
587
|
taskId,
|
|
590
588
|
lane: 'workflow',
|
|
591
|
-
via: workflowRunId
|
|
592
|
-
? 'workflowRunId'
|
|
593
|
-
: isWorkflowAgentTaskId(taskId)
|
|
594
|
-
? 'wa-id'
|
|
595
|
-
: 'workflow-card-parent',
|
|
589
|
+
via: 'workflowRunId',
|
|
596
590
|
}));
|
|
597
591
|
return;
|
|
598
592
|
}
|
|
599
593
|
if (explicitParent !== undefined)
|
|
600
594
|
registerSubagentAlias(explicitParent, taskId);
|
|
601
|
-
const cardId =
|
|
602
|
-
? undefined
|
|
603
|
-
: panel.bind(taskId, explicitParent);
|
|
595
|
+
const cardId = panel.bind(taskId, explicitParent);
|
|
604
596
|
const usage = (m.usage ?? {});
|
|
605
597
|
ctx.probe?.('tick', JSON.stringify({
|
|
606
598
|
t: ctx.now(),
|
|
@@ -612,6 +604,7 @@ const taskProgressArm = function* (m, { ctx, cards, panel, inst }) {
|
|
|
612
604
|
toolUses: usage.toolUses ?? null,
|
|
613
605
|
}));
|
|
614
606
|
const currentAction = typeof m.currentAction === 'string' && m.currentAction.length > 0 ? m.currentAction : undefined;
|
|
607
|
+
const model = typeof m.model === 'string' && m.model.length > 0 ? m.model : undefined;
|
|
615
608
|
const spawnName = m.spawnName;
|
|
616
609
|
if (cardId !== undefined) {
|
|
617
610
|
yield chrome({
|
|
@@ -624,6 +617,7 @@ const taskProgressArm = function* (m, { ctx, cards, panel, inst }) {
|
|
|
624
617
|
totalTokens: typeof usage.totalTokens === 'number' ? usage.totalTokens : 0,
|
|
625
618
|
durationMs: typeof usage.durationMs === 'number' ? usage.durationMs : 0,
|
|
626
619
|
...(currentAction !== undefined ? { currentAction } : {}),
|
|
620
|
+
...(model !== undefined ? { model } : {}),
|
|
627
621
|
},
|
|
628
622
|
});
|
|
629
623
|
}
|
|
@@ -3,9 +3,7 @@ import type { AdapterInstanceLedger } from './instanceLedger.js';
|
|
|
3
3
|
import type { OpenCardView } from './toolCards.js';
|
|
4
4
|
export interface PanelTaskLedger {
|
|
5
5
|
bind(taskId: string, parentToolCallId?: string): string | undefined;
|
|
6
|
-
unboundCandidates(): number;
|
|
7
6
|
laneOf(taskId: string): LaneProof;
|
|
8
|
-
isBound(taskId: string): boolean;
|
|
9
7
|
isLiveBound(taskId: string): boolean;
|
|
10
8
|
isLive(taskId: string): boolean;
|
|
11
9
|
markLive(taskId: string): void;
|
package/dist/adapt/panelTasks.js
CHANGED
|
@@ -21,44 +21,24 @@ export function createPanelTaskLedger(ctx, cards, inst) {
|
|
|
21
21
|
};
|
|
22
22
|
return {
|
|
23
23
|
laneOf,
|
|
24
|
-
isBound: (taskId) => taskCardBinding.has(taskId),
|
|
25
24
|
isLiveBound: (taskId) => liveBoundPanelTasks.has(taskId),
|
|
26
25
|
bind(taskId, parentToolCallId) {
|
|
27
26
|
const existing = taskCardBinding.get(taskId);
|
|
28
27
|
if (existing !== undefined)
|
|
29
28
|
return existing;
|
|
30
|
-
|
|
31
|
-
if (parentToolCallId !== undefined) {
|
|
32
|
-
const named = cards.peek(parentToolCallId);
|
|
33
|
-
if (named !== undefined && !SUBAGENT_TOOL_NAMES.has(named.name))
|
|
34
|
-
return undefined;
|
|
35
|
-
target = parentToolCallId;
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
for (const [id, p] of cards.entries()) {
|
|
39
|
-
if (!boundToolCalls.has(id) && SUBAGENT_TOOL_NAMES.has(p.name)) {
|
|
40
|
-
target = id;
|
|
41
|
-
break;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (target === undefined)
|
|
29
|
+
if (parentToolCallId === undefined)
|
|
46
30
|
return undefined;
|
|
31
|
+
const named = cards.peek(parentToolCallId);
|
|
32
|
+
if (named !== undefined && !SUBAGENT_TOOL_NAMES.has(named.name))
|
|
33
|
+
return undefined;
|
|
34
|
+
const target = parentToolCallId;
|
|
47
35
|
taskCardBinding.set(taskId, target);
|
|
48
36
|
boundToolCalls.add(target);
|
|
49
37
|
if (cards.has(target))
|
|
50
38
|
liveBoundPanelTasks.add(taskId);
|
|
51
|
-
ctx.probe?.('bind', `bind ${taskId} -> ${target} via
|
|
39
|
+
ctx.probe?.('bind', `bind ${taskId} -> ${target} via=explicit`);
|
|
52
40
|
return target;
|
|
53
41
|
},
|
|
54
|
-
unboundCandidates() {
|
|
55
|
-
let n = 0;
|
|
56
|
-
for (const [id, p] of cards.entries()) {
|
|
57
|
-
if (!boundToolCalls.has(id) && SUBAGENT_TOOL_NAMES.has(p.name))
|
|
58
|
-
n++;
|
|
59
|
-
}
|
|
60
|
-
return n;
|
|
61
|
-
},
|
|
62
42
|
isLive: (taskId) => livePanelTasks.has(taskId),
|
|
63
43
|
markLive: (taskId) => {
|
|
64
44
|
livePanelTasks.add(taskId);
|
package/dist/adapt/toolCards.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { deriveTranscriptId } from '../seam.js';
|
|
2
|
-
import { degradedToolResultBody, detectEngineBgShellReceipt, reportFindingsToolUseResult, structuredToToolUseResult, todoWriteToolUseResult, wireOutputToBody, } from '../toolResult.js';
|
|
2
|
+
import { degradedToolResultBody, detectEngineBgShellDetach, detectEngineBgShellReceipt, reportFindingsToolUseResult, structuredToToolUseResult, todoWriteToolUseResult, wireOutputToBody, } from '../toolResult.js';
|
|
3
3
|
import { chrome, mainLane, transcript } from './ids.js';
|
|
4
4
|
import { flattenWireOutput } from './wireShapes.js';
|
|
5
5
|
import { isCcToolDenialKind } from '../gateVocabulary.js';
|
|
@@ -34,9 +34,11 @@ export function createToolCardLedger(ctx, idOf) {
|
|
|
34
34
|
let lastLiveTodos = [];
|
|
35
35
|
function* buildToolResult(p, end) {
|
|
36
36
|
const isError = end?.isError ?? false;
|
|
37
|
-
if ((p.name === 'Bash' || p.name === 'Monitor') && !isError
|
|
38
|
-
const
|
|
39
|
-
|
|
37
|
+
if ((p.name === 'Bash' || p.name === 'Monitor') && !isError) {
|
|
38
|
+
const outputText = end?.output !== undefined ? flattenWireOutput(end.output) : undefined;
|
|
39
|
+
const reg = detectEngineBgShellDetach(p.name, p.rawInput, end?.structured, outputText) ??
|
|
40
|
+
detectEngineBgShellReceipt(p.name, p.rawInput, outputText, end?.structured);
|
|
41
|
+
if (reg !== null) {
|
|
40
42
|
yield chrome({ kind: 'bgshell_register', laneProof: mainLane(), taskId: reg.taskId, registration: reg });
|
|
41
43
|
}
|
|
42
44
|
}
|
package/dist/adapt.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare const ADAPTER_COVERAGE: {
|
|
|
11
11
|
readonly transcriptKinds: readonly ["assistant_text", "assistant_thinking", "assistant_tool_use", "user_tool_result_decision", "user_task_notification", "system_passthrough"];
|
|
12
12
|
readonly b3: readonly ["T38 三清第三清 + T57 第五处断闸:prompt_suggestions(turn 开场作废 + 子流断闸)", "T40 IDLE-FLUSH 1.5s 竞速(需 ctx.setTimer;缺席=不启用)", "T58 手动 iterator 的 finally cleanup(early break/throw 都要关上游生成器)", "T59 abort 半场(ctx.signal;中断后不产终答)", "T60 无 result 收尾腿(泄尾增量 → 清 liveness → 尾思考 → 尾文本段)"];
|
|
13
13
|
readonly b4: readonly ["A 层第 14 臂 task_progress:workflow lane 三级门 + 判据④ belt 回植 + C1 alias + bindTaskCard(显式父/FIFO/含糊即 unbound)+ inline stats + T50 双形读 + SubagentStart + #6 resident 台账 + 面板 tick", "settlePanelTasks 三处 sweep 全接线(tool_end 显式关卡带报告 / result 防御 sweep / turn 末 + abort sweep)", "P0-2 tool label 侧信道(sanitizeToolUseBlock 摘 label + engineToolLabelStore 登记;0.5.0 真缺口,label 会随 tool_use block 落转录 → /compact 直发 provider 400)", "task_notification 的两件宿主义务收回库内自持:dropQueuedNotificationsForRun + clearEnginePanelTaskResident;stop hook 的 if-started 门由库解", "T8 flattenWireOutput 提为独立导出(A 层 settle 报告与 B 层卡体同一份)"];
|
|
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)"];
|
|
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)+ CC-331 交出后台的 Bash(结构化 detached 位同形登记,一张卡至多一条;结构化位自述登记失败时两臂都不铸)· 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
17
|
export declare const ADAPTER_DIVERGENCES: readonly [string, string, string, string, string, string, string, string, string, string, string, string];
|
package/dist/adapt.js
CHANGED
|
@@ -55,7 +55,7 @@ export const ADAPTER_COVERAGE = {
|
|
|
55
55
|
b5: [
|
|
56
56
|
'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 登记副作用',
|
|
57
57
|
'D 层 wireOutputToBody 3 臂(bash / taskoutput / 泛化);structured 白名单在场时 T11+T14 正则退位,缺席保回落',
|
|
58
|
-
'E 层 4 臂:#117a bg Bash 回执 + #158 Monitor 回执(同臂按工具名分,registration.source 判别;判定在库→chrome bgshell_register)· TodoWrite oldTodos 富卡 · ReportFindings 按名认领 · Remember→memory_saved 系统消息',
|
|
58
|
+
'E 层 4 臂:#117a bg Bash 回执 + #158 Monitor 回执(同臂按工具名分,registration.source 判别;判定在库→chrome bgshell_register)+ CC-331 交出后台的 Bash(结构化 detached 位同形登记,一张卡至多一条;结构化位自述登记失败时两臂都不铸)· TodoWrite oldTodos 富卡 · ReportFindings 按名认领 · Remember→memory_saved 系统消息',
|
|
59
59
|
'tool_end_result → user tool_result 正常路径(卡本体);result 与 turn 末两处开卡兜底关闭(abort 不兜底,cli 同)',
|
|
60
60
|
'task/task-list structured → chrome task_ledger_sync{source:"structured"}(判定归一在库、落盘留宿主)',
|
|
61
61
|
'T7 诚实缺席(§8-4:不搬 mock 合成器,改 degraded 标记)· T20 diff hunks 进包(src/diff/patch.ts)',
|
|
@@ -107,10 +107,10 @@ export const ADAPTER_DIVERGENCES = [
|
|
|
107
107
|
'(0.81.0–0.82.x 曾与 CC 内部转录面驼峰 `toolUseResult` 同引用并铸,0.83.0 删驼峰);cli 侧仍带驼峰 —— 所钉的本包' +
|
|
108
108
|
'旧版本两键同铸,升级后在转录入口从 `tool_use_result` 同值起别名。守卫在两键同在场且同引用时略过驼峰键、' +
|
|
109
109
|
'按 snake 比(两侧对称);cli 侧不再带驼峰后本条自然零触发 ⇒ 自退役。',
|
|
110
|
-
'DIVERGENCE-11(0.83.0
|
|
110
|
+
'DIVERGENCE-11(0.83.0):system 转录行的到达时戳 —— 本包只给 user / assistant 行补 `timestamp`' +
|
|
111
111
|
'(agent-types 只在这两臂声明),system 行不补(入参自带的照旧原样过境);壳的接收口给每条转录行补到达时刻(只补缺席)。' +
|
|
112
112
|
'守卫在逐字比对前只从壳侧 system 行上去掉这一位;本包侧 system 行若带 `timestamp`,照样判不等。',
|
|
113
|
-
'DIVERGENCE-12(0.83.0
|
|
113
|
+
'DIVERGENCE-12(0.83.0):记忆写入 —— 本包发 chrome `memory_saved` 臂(`notes` = 笔记原文,`id` 由这次写入的 wire ' +
|
|
114
114
|
'稳定键派生),转录面零行;壳侧是一条 system/memory_saved 转录行(`writtenPaths` 装同一份笔记)。守卫把壳侧这类行移出逐字比对,' +
|
|
115
115
|
'改比:事件 `notes` ⇔ 行 `writtenPaths` 逐项相等、位置相等(之前已覆盖转录行的条数);`id` 不与旧行 uuid 比(本版不承诺相等)。',
|
|
116
116
|
];
|
|
@@ -192,8 +192,6 @@ export interface SelfHealFollowDeclaration {
|
|
|
192
192
|
}
|
|
193
193
|
export declare function readCancelRequested(body: unknown): boolean | undefined;
|
|
194
194
|
export declare function atMostOnceFailureClass(e: unknown): 'rejected' | 'unknown';
|
|
195
|
-
export declare function readSteerDelivery(receipt: unknown): string | null;
|
|
196
|
-
export declare function readSteerReceiptStatus(receipt: unknown): string | null;
|
|
197
195
|
export declare function clearRunningChoiceOffer(taskId: string, sessionId?: string): void;
|
|
198
196
|
export declare function __resetRunningChoiceLedgerForTests(): void;
|
|
199
197
|
export interface ClaimReleaseVerdict {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { abortableSleep } from '../abortableSleep.js';
|
|
2
2
|
import { corruptStoredRowContent, corruptStoredRowWhere, effectiveWireErrorCode } from '../wireErrorTriage.js';
|
|
3
|
-
import { steeringRefusedBeforeEngine, steeringStatusIs4xx } from '../controlRouter.js';
|
|
3
|
+
import { steerBodyOf, steeringRefusedBeforeEngine, steeringStatusIs4xx, UNOBSERVED_STEER_PRIORITY } from '../controlRouter.js';
|
|
4
|
+
import { readSteerReceipt } from '../steerReceipt.js';
|
|
4
5
|
export const PLAN_REVIEW_GATE_KIND = 'plan_review';
|
|
5
6
|
export const PLAN_REVIEW_GATE_KINDS = Object.freeze([PLAN_REVIEW_GATE_KIND, 'dry_run_review']);
|
|
6
7
|
export const ASK_PARK_GATE_KINDS = Object.freeze(['human', 'irreversible_ask', 'policy_ask', 'tool_approval']);
|
|
@@ -265,28 +266,6 @@ export function atMostOnceFailureClass(e) {
|
|
|
265
266
|
return 'rejected';
|
|
266
267
|
return typeof e === 'object' && e !== null && steeringRefusedBeforeEngine(e) !== undefined ? 'rejected' : 'unknown';
|
|
267
268
|
}
|
|
268
|
-
export function readSteerDelivery(receipt) {
|
|
269
|
-
try {
|
|
270
|
-
if (typeof receipt !== 'object' || receipt === null || !('delivery' in receipt))
|
|
271
|
-
return null;
|
|
272
|
-
const d = receipt.delivery;
|
|
273
|
-
return typeof d === 'string' && d.length > 0 ? d : null;
|
|
274
|
-
}
|
|
275
|
-
catch {
|
|
276
|
-
return null;
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
export function readSteerReceiptStatus(receipt) {
|
|
280
|
-
try {
|
|
281
|
-
if (typeof receipt !== 'object' || receipt === null || !('status' in receipt))
|
|
282
|
-
return null;
|
|
283
|
-
const s = receipt.status;
|
|
284
|
-
return typeof s === 'string' && s.length > 0 ? s : null;
|
|
285
|
-
}
|
|
286
|
-
catch {
|
|
287
|
-
return null;
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
269
|
const CANCEL_RELEASE_WAIT_MS = 10_000;
|
|
291
270
|
const RUNNING_LIVENESS_RECHECK_TIMEOUT_MS = 4_000;
|
|
292
271
|
const runningChoiceDeclined = new Set();
|
|
@@ -772,9 +751,8 @@ async function runningChoiceArm(taskId, status, busy, statusFromWire, runs, deps
|
|
|
772
751
|
}
|
|
773
752
|
if (choice === 'steer' && canSteer && runs?.steer !== undefined) {
|
|
774
753
|
try {
|
|
775
|
-
const receipt = await runs.steer(taskId, { text }, sessionOpts(deps));
|
|
776
|
-
const delivery =
|
|
777
|
-
const receiptStatus = readSteerReceiptStatus(receipt);
|
|
754
|
+
const receipt = await runs.steer(taskId, steerBodyOf({ text }, UNOBSERVED_STEER_PRIORITY), sessionOpts(deps));
|
|
755
|
+
const { delivery, status: receiptStatus } = readSteerReceipt(receipt);
|
|
778
756
|
if (delivery === 'queued') {
|
|
779
757
|
const verdict = receiptStatus !== null && PLAN_REVIEW_STATES.includes(receiptStatus)
|
|
780
758
|
? await planVerdict(taskId, deps)
|
|
@@ -1071,7 +1049,7 @@ function activeRunSelfHealBaseRow(outcome, signal, wayOut, following = false, ke
|
|
|
1071
1049
|
}
|
|
1072
1050
|
case 'running-steer-failed':
|
|
1073
1051
|
if (outcome.delivery === 'rejected') {
|
|
1074
|
-
return (`
|
|
1052
|
+
return (`Handing your message to the running run (run ${outcome.taskId}) was refused: ${outcome.detail}. ` +
|
|
1075
1053
|
`sema did NOT retry it (a steer is not safe to send twice) and it did NOT cancel that run. ` +
|
|
1076
1054
|
`Your message was NOT sent; send it again if you still want it.`);
|
|
1077
1055
|
}
|
|
@@ -7,8 +7,15 @@ import { isReviewPark, readRunTerminal, runTerminalCode, runTerminalGateToolName
|
|
|
7
7
|
import { toCcModelUsage } from './turnUsageToModelUsage.js';
|
|
8
8
|
import { LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, OUTPUT_INVALID, isCorruptSessionCode, isRewindFamilyCode, } from '../../engineErrorCodes.js';
|
|
9
9
|
import { corruptSessionContent } from '../../corruptSessionCopy.js';
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
import { abortCauseNoteOf, readAbortCause } from '../../runCancelContext.js';
|
|
11
|
+
function withTerminalNote(text, code, frame) {
|
|
12
|
+
const withCorrupt = isCorruptSessionCode(code) ? `${text}\n${corruptSessionContent()}` : text;
|
|
13
|
+
const abortNote = abortCauseNoteOf(frame);
|
|
14
|
+
return abortNote === undefined ? withCorrupt : `${withCorrupt}\n${abortNote}`;
|
|
15
|
+
}
|
|
16
|
+
function abortCauseWordOf(frame) {
|
|
17
|
+
const r = readAbortCause(frame);
|
|
18
|
+
return r === undefined ? undefined : r.kind === 'known' ? r.cause : r.word;
|
|
12
19
|
}
|
|
13
20
|
function finiteOr0(v) {
|
|
14
21
|
return typeof v === 'number' && Number.isFinite(v) ? v : 0;
|
|
@@ -500,6 +507,7 @@ function errorResult(ctx, parts) {
|
|
|
500
507
|
...(parts.salvagedResult !== undefined ? { _sema_salvaged_result: parts.salvagedResult } : {}),
|
|
501
508
|
...(parts.outcomeUnknown === true ? { _sema_outcome: 'unknown' } : {}),
|
|
502
509
|
...(parts.parkFailedReason !== undefined ? { _sema_park_failed_reason: washCredentials(parts.parkFailedReason) } : {}),
|
|
510
|
+
...(parts.abortCause !== undefined ? { _sema_abort_cause: parts.abortCause } : {}),
|
|
503
511
|
});
|
|
504
512
|
}
|
|
505
513
|
export function doneToSdkResult(ev, ctx, observed) {
|
|
@@ -516,7 +524,7 @@ export function doneToSdkResult(ev, ctx, observed) {
|
|
|
516
524
|
const degraded = degradedOf(r);
|
|
517
525
|
const parkFailedRaw = ev._sema_park_failed_reason;
|
|
518
526
|
const parkFailedReason = typeof parkFailedRaw === 'string' && parkFailedRaw.length > 0 ? parkFailedRaw : undefined;
|
|
519
|
-
const errorBase = { durationMs, stats, model: r.model, errorCode, degraded, observed, facts: effectiveFactParts(rec), parkFailedReason };
|
|
527
|
+
const errorBase = { durationMs, stats, model: r.model, errorCode, degraded, observed, facts: effectiveFactParts(rec), parkFailedReason, abortCause: abortCauseWordOf(ev) };
|
|
520
528
|
if (terminal?.kind === 'failed') {
|
|
521
529
|
const failedCode = terminal.code;
|
|
522
530
|
const failedMessage = terminal.message;
|
|
@@ -534,9 +542,9 @@ export function doneToSdkResult(ev, ctx, observed) {
|
|
|
534
542
|
...errorBase,
|
|
535
543
|
subtype: failedSubtype,
|
|
536
544
|
errors: [
|
|
537
|
-
|
|
545
|
+
withTerminalNote(isRewindFamilyCode(failedCode) && failedMessage
|
|
538
546
|
? `${failedMessage} (${failedCode})`
|
|
539
|
-
: (failedMessage ?? 'run failed'), failedCode),
|
|
547
|
+
: (failedMessage ?? 'run failed'), failedCode, ev),
|
|
540
548
|
],
|
|
541
549
|
});
|
|
542
550
|
}
|
|
@@ -625,10 +633,11 @@ export function failedToSdkResult(ev, ctx, observed) {
|
|
|
625
633
|
observed,
|
|
626
634
|
durationMs: elapsedMs(ctx),
|
|
627
635
|
errorCode: ev.errorCode,
|
|
636
|
+
abortCause: abortCauseWordOf(ev),
|
|
628
637
|
errors: [
|
|
629
|
-
|
|
638
|
+
withTerminalNote(isRewindFamilyCode(ev.errorCode) && ev.errorMessage
|
|
630
639
|
? `${ev.errorMessage} (${ev.errorCode})`
|
|
631
|
-
: (ev.errorMessage ?? ev.errorCode ?? 'run failed'), ev.errorCode),
|
|
640
|
+
: (ev.errorMessage ?? ev.errorCode ?? 'run failed'), ev.errorCode, ev),
|
|
632
641
|
],
|
|
633
642
|
});
|
|
634
643
|
}
|
|
@@ -5,6 +5,7 @@ import { readRunCostFacts, terminalToSdkResult, TOOL_INPUT_JOIN_MAX_CALLS } from
|
|
|
5
5
|
import { coerceOutput, publishSubagentContentEvent } from '../subagentContentStore.js';
|
|
6
6
|
import { ACTIVE_RUN_BUSY_ERROR_CODE, OUTPUT_INVALID, isCorruptSessionCode, isLimitsExceededCode } from '../engineErrorCodes.js';
|
|
7
7
|
import { corruptSessionContent } from '../corruptSessionCopy.js';
|
|
8
|
+
import { abortCauseNoteOf } from '../runCancelContext.js';
|
|
8
9
|
import { classifyToolHistoryMismatch, noteToolHistoryTerminal, openToolHistoryGeneration, TOOL_HISTORY_REWIND_SENTENCE, toolHistoryMismatchRowKey, toolHistoryRepeatSentence, toolHistoryRewindOffered, } from '../toolHistoryMismatch.js';
|
|
9
10
|
import { isReviewPark, readRunTerminal, runTerminalCode } from '../runTerminal.js';
|
|
10
11
|
import { providerRejectionResend } from '../providerRejection.js';
|
|
@@ -328,8 +329,10 @@ const DROPPED_WHY_SENTENCE = Object.freeze({
|
|
|
328
329
|
'If the engine reuses an id across two DIFFERENT frames (server 7.77.0 does this for `reasoning_end`, fixed upstream in 7.78.1), the second one is lost here — this line is the only trace.',
|
|
329
330
|
turn_end_usage_absent: "the engine declares `turn_end.usage` as always present (core >= 7.17.0), and this frame has none. " +
|
|
330
331
|
'The turn is counted as UNKNOWN spend (the run total is reported as a lower bound), and the frame itself renders NOWHERE.',
|
|
332
|
+
unknown_arm: "this build's projector has no arm for this frame type, so it was dropped — the type is not one this build knows (an engine newer than this client can send such frames). It renders NOWHERE.",
|
|
333
|
+
malformed: "this build's projector has an arm for this frame type, but the frame did not pass that arm's shape check (a field it requires was not usable), so it was dropped. It renders NOWHERE.",
|
|
331
334
|
});
|
|
332
|
-
const DROPPED_WHY_SENTENCE_DEFAULT = "this build's projector has no arm for it (engine newer than the client, or a malformed frame). It renders NOWHERE.";
|
|
335
|
+
const DROPPED_WHY_SENTENCE_DEFAULT = "this build's projector has no arm for it (engine newer than the client, or a malformed frame; this build cannot tell which). It renders NOWHERE.";
|
|
333
336
|
export function droppedWhySentence(why) {
|
|
334
337
|
const row = Object.hasOwn(DROPPED_WHY_SENTENCE, why) ? DROPPED_WHY_SENTENCE[why] : undefined;
|
|
335
338
|
return typeof row === 'string' ? row : DROPPED_WHY_SENTENCE_DEFAULT;
|
|
@@ -660,6 +663,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
660
663
|
const sessionUnreadable = ev.type === 'failed'
|
|
661
664
|
? isCorruptSessionCode(ev.errorCode)
|
|
662
665
|
: doneTerminal?.kind === 'failed' && isCorruptSessionCode(doneTerminal.code);
|
|
666
|
+
const abortNote = abortCauseNoteOf(ev);
|
|
663
667
|
const historyTerminal = apiErrorTerminalOfRowFrame(ev, rowFacts);
|
|
664
668
|
const historyMismatch = classifyToolHistoryMismatch(historyTerminal.carrier);
|
|
665
669
|
const historyEchoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
|
|
@@ -677,7 +681,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
677
681
|
: '';
|
|
678
682
|
const resend = historyTerminal.detail !== undefined ? providerRejectionResend(historyTerminal.detail, historyTerminal.carrier) : undefined;
|
|
679
683
|
const resendLine = resend !== undefined ? `\n${resend.text}` : '';
|
|
680
|
-
yield syntheticTerminalRow(ctx, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend);
|
|
684
|
+
yield syntheticTerminalRow(ctx, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${abortNote !== undefined ? `\n${abortNote}` : ''}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend);
|
|
681
685
|
}
|
|
682
686
|
else {
|
|
683
687
|
const echoedSid = ev.type === 'done' ? engineSessionIdOf(ev.result) : undefined;
|
package/dist/agentsWireCaps.js
CHANGED
|
@@ -249,7 +249,7 @@ async function runPrepare(cfg, projector, probe, generation) {
|
|
|
249
249
|
const [caps, projected] = await Promise.all([probe, projector()]);
|
|
250
250
|
if (caps === false) {
|
|
251
251
|
if (projected.agents && preparedKey === cfg.baseUrl) {
|
|
252
|
-
warnOnce(`agents wire: this engine does not support per-task custom agents (capabilities.taskAgents
|
|
252
|
+
warnOnce(`agents wire: this engine does not support per-task custom agents (capabilities.taskAgents is not true: the engine does not report it, or this deployment turns it off, for example a multi-tenant one; this client cannot tell which) — ${projected.agents.length} custom agent definition(s) will NOT be sent`);
|
|
253
253
|
}
|
|
254
254
|
return;
|
|
255
255
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type ApprovalDecidedByReading = {
|
|
2
|
+
kind: 'unobserved';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'not_reported';
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'present';
|
|
7
|
+
value: true;
|
|
8
|
+
};
|
|
9
|
+
export declare function projectApprovalDecidedByCapability(caps: unknown): ApprovalDecidedByReading | undefined;
|
|
10
|
+
export declare function noteEngineCapsForApprovalDecidedBy(baseUrl: string, caps: unknown, opts?: {
|
|
11
|
+
generation?: number;
|
|
12
|
+
}): void;
|
|
13
|
+
export declare function observedApprovalDecidedBy(baseUrl?: string | undefined): ApprovalDecidedByReading;
|
|
14
|
+
export declare function approvalDecidedByAdmitted(reading: ApprovalDecidedByReading | undefined): boolean;
|
|
15
|
+
export declare function forgetApprovalDecidedByReading(baseUrl: string | undefined): void;
|
|
16
|
+
export declare function __resetApprovalDecidedByReadingsForTests(): void;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
+
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
import { readOwnDataValue } from './ownKey.js';
|
|
4
|
+
export function projectApprovalDecidedByCapability(caps) {
|
|
5
|
+
try {
|
|
6
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
7
|
+
return undefined;
|
|
8
|
+
if (!Object.hasOwn(caps, 'approvalDecidedBy'))
|
|
9
|
+
return { kind: 'not_reported' };
|
|
10
|
+
const v = caps.approvalDecidedBy;
|
|
11
|
+
if (v === undefined)
|
|
12
|
+
return { kind: 'not_reported' };
|
|
13
|
+
return v === true ? { kind: 'present', value: true } : undefined;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const reader = createEngineCapReader({
|
|
20
|
+
name: 'approvalDecidedBy',
|
|
21
|
+
project: projectApprovalDecidedByCapability,
|
|
22
|
+
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
23
|
+
});
|
|
24
|
+
export function noteEngineCapsForApprovalDecidedBy(baseUrl, caps, opts) {
|
|
25
|
+
reader.note(baseUrl, caps, opts);
|
|
26
|
+
}
|
|
27
|
+
export function observedApprovalDecidedBy(baseUrl = engineWireTarget()?.baseUrl) {
|
|
28
|
+
return reader.observed(baseUrl);
|
|
29
|
+
}
|
|
30
|
+
export function approvalDecidedByAdmitted(reading) {
|
|
31
|
+
try {
|
|
32
|
+
if (reading === null || reading === undefined || typeof reading !== 'object' || Array.isArray(reading))
|
|
33
|
+
return false;
|
|
34
|
+
if (readOwnDataValue(reading, 'kind') !== 'present')
|
|
35
|
+
return false;
|
|
36
|
+
return readOwnDataValue(reading, 'value') === true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function forgetApprovalDecidedByReading(baseUrl) {
|
|
43
|
+
reader.forget(baseUrl);
|
|
44
|
+
}
|
|
45
|
+
export function __resetApprovalDecidedByReadingsForTests() {
|
|
46
|
+
reader.__resetForTests();
|
|
47
|
+
}
|
|
@@ -31,13 +31,13 @@ export function livePendingNeedsReconcile(reading) {
|
|
|
31
31
|
export function approvalsStreamLiveDoctorDetail(reading) {
|
|
32
32
|
switch (reading.kind) {
|
|
33
33
|
case 'unobserved':
|
|
34
|
-
return 'live approval push not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
34
|
+
return 'live approval push not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which), so suspended asks are pulled by the reconcile cadence';
|
|
35
35
|
case 'not_reported':
|
|
36
|
-
return 'live approval push not reported by this engine
|
|
36
|
+
return 'live approval push not reported by this engine; this does not say whether it pushes, so suspended asks are pulled by the reconcile cadence';
|
|
37
37
|
case 'present':
|
|
38
38
|
return reading.live
|
|
39
39
|
? 'live approval push on — the engine announces suspended asks on the approvals stream; the reconcile cadence is only a fallback'
|
|
40
|
-
: 'live approval push off on this deployment (no checkpoint store or tool approvals disabled) — suspended asks are only visible through the reconcile cadence, so the client polls for them';
|
|
40
|
+
: 'live approval push off on this deployment (no checkpoint store or tool approvals disabled; the engine reports one bit for both, so this client cannot tell which) — suspended asks are only visible through the reconcile cadence, so the client polls for them';
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
export function forgetApprovalsStreamLiveReading(baseUrl) {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import { type AutomaticAnswerRoad, type AutomaticAnswerUnknownWhy } from './hitl/automaticAnswerVerdict.js';
|
|
2
|
+
export declare const MODE_ARBITRATION: Readonly<Record<"hook" | "write_protection" | "mode" | "rule_unreadable" | "content_question" | "ancestor" | "unverifiable_delete" | "transcript_write" | "org_rule" | "governance_unavailable" | "ask_rule" | "denial_limit_fallback" | "classifier_no_ruling" | "requires_user_interaction" | "operator_forced" | "shell_floor" | "write_protection_unresolved" | "probe" | "tool_marks_mcp" | "tool_marks_a2a" | "policy_rra" | "artifact_shared_read" | "unstated" | "ordinary", import("./generated/engineFactTables.js").CoreModeArbitrationRow>>;
|
|
2
3
|
export type StandingAnswerVerdict = {
|
|
3
4
|
readonly kind: 'must_ask';
|
|
4
5
|
readonly by: string;
|
|
6
|
+
readonly road?: AutomaticAnswerRoad;
|
|
5
7
|
} | {
|
|
6
8
|
readonly kind: 'may_answer';
|
|
7
9
|
} | {
|
|
8
10
|
readonly kind: 'unknown';
|
|
11
|
+
readonly why?: AutomaticAnswerUnknownWhy;
|
|
9
12
|
};
|
|
10
13
|
export declare function askSurvivesStandingAnswer(card: object | null | undefined): StandingAnswerVerdict;
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
import { CORE_MODE_ARBITRATION } from './generated/engineFactTables.js';
|
|
2
|
+
import { automaticAnswerVerdict } from './hitl/automaticAnswerVerdict.js';
|
|
2
3
|
export const MODE_ARBITRATION = CORE_MODE_ARBITRATION;
|
|
3
4
|
const MUST_ASK_MANDATED = Object.freeze({ kind: 'must_ask', by: 'mandated' });
|
|
4
5
|
const MAY_ANSWER = Object.freeze({ kind: 'may_answer' });
|
|
5
6
|
const UNKNOWN = Object.freeze({ kind: 'unknown' });
|
|
6
7
|
export function askSurvivesStandingAnswer(card) {
|
|
8
|
+
const old = legacyStandingAnswerVerdict(card);
|
|
9
|
+
const neu = automaticAnswerVerdict(card, 'standing_rule');
|
|
10
|
+
if (old.kind === 'must_ask' || neu.kind === 'must_ask') {
|
|
11
|
+
const by = old.kind === 'must_ask' ? old.by : neu.kind === 'must_ask' ? (neu.askClass ?? neu.road) : 'mandated';
|
|
12
|
+
const road = neu.kind === 'must_ask' ? neu.road : by === 'mandated' ? 'mandated' : 'ask_class';
|
|
13
|
+
return Object.freeze({ kind: 'must_ask', by, road });
|
|
14
|
+
}
|
|
15
|
+
if (old.kind === 'unknown' || neu.kind === 'unknown')
|
|
16
|
+
return neu.kind === 'unknown' ? Object.freeze({ kind: 'unknown', why: neu.why }) : UNKNOWN;
|
|
17
|
+
return MAY_ANSWER;
|
|
18
|
+
}
|
|
19
|
+
function legacyStandingAnswerVerdict(card) {
|
|
7
20
|
try {
|
|
8
21
|
if (card === null || card === undefined || typeof card !== 'object')
|
|
9
22
|
return UNKNOWN;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import { CORE_AUTO_MODE_UNAVAILABLE_CAUSES, CORE_CLASSIFIER_DENY_CAUSES } from './generated/engineFactTables.js';
|
|
2
|
+
export const CLASSIFIER_DENY_CAUSES = CORE_CLASSIFIER_DENY_CAUSES;
|
|
2
3
|
const DENY_CAUSE_SET = new Set(CLASSIFIER_DENY_CAUSES);
|
|
3
4
|
export function isClassifierDenyCause(v) {
|
|
4
5
|
return typeof v === 'string' && DENY_CAUSE_SET.has(v);
|
|
@@ -26,7 +27,7 @@ function gateRecordOf(v) {
|
|
|
26
27
|
return undefined;
|
|
27
28
|
return g;
|
|
28
29
|
}
|
|
29
|
-
export const AUTO_MODE_UNAVAILABLE_CAUSES =
|
|
30
|
+
export const AUTO_MODE_UNAVAILABLE_CAUSES = CORE_AUTO_MODE_UNAVAILABLE_CAUSES;
|
|
30
31
|
const DENY_CAUSE_SENTENCES = Object.freeze({
|
|
31
32
|
unavailable: 'denied because the auto-mode classifier could not run this round (the call may be retried later)',
|
|
32
33
|
parse_error: 'denied because the auto-mode classifier answered outside its contract (its reply could not be parsed, so the call was blocked)',
|
|
@@ -159,7 +159,7 @@ export function centerWiringDoctorDetail(reading) {
|
|
|
159
159
|
const unobserved = 'center wiring not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it, so whether this engine is connected to a configuration center is unknown';
|
|
160
160
|
const r = guarded(reading);
|
|
161
161
|
if (r?.kind === 'not_reported') {
|
|
162
|
-
return 'center wiring not reported by this engine
|
|
162
|
+
return 'center wiring not reported by this engine; this does not say whether the engine is connected to a configuration center';
|
|
163
163
|
}
|
|
164
164
|
if (r?.kind === 'none') {
|
|
165
165
|
return 'no configuration center on this deployment — the engine runs on its own local configuration; no quota lease or usage reporting goes through a center';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MCP_CAPS } from './mcpWireCaps.js';
|
|
2
2
|
import { toCappedSpec } from './skillsWireCaps.js';
|
|
3
3
|
import { TIER_ORDER } from './model/tierVocabulary.js';
|
|
4
|
+
import { SETTINGS_BUDGET_NUMBER_KEYS, SETTINGS_BUDGET_PER_MODEL_NUMBER_KEYS, SETTINGS_BUDGET_STRING_KEYS, SETTINGS_TIER_GROUP_NAME_RE, } from './generated/settingsSchemaTables.js';
|
|
4
5
|
const asRec = (v) => (typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined);
|
|
5
6
|
const asArr = (v) => (Array.isArray(v) ? v : []);
|
|
6
7
|
const asStr = (v) => (typeof v === 'string' && v.length > 0 ? v : undefined);
|
|
@@ -129,7 +130,7 @@ function withoutRegistryAnnotations(e) {
|
|
|
129
130
|
return out;
|
|
130
131
|
}
|
|
131
132
|
const TIER_WORDS = TIER_ORDER;
|
|
132
|
-
const TIER_GROUP_NAME =
|
|
133
|
+
const TIER_GROUP_NAME = SETTINGS_TIER_GROUP_NAME_RE;
|
|
133
134
|
const setOwn = (o, k, v) => {
|
|
134
135
|
Object.defineProperty(o, k, { value: v, enumerable: true, writable: true, configurable: true });
|
|
135
136
|
};
|
|
@@ -319,9 +320,9 @@ export function cloudRosterNames(rostersValue) {
|
|
|
319
320
|
.map((e) => asStr(asRec(e)?.name))
|
|
320
321
|
.filter((n) => !!n);
|
|
321
322
|
}
|
|
322
|
-
const BUDGET_NUMBER_KEYS =
|
|
323
|
-
const BUDGET_STRING_KEYS =
|
|
324
|
-
const PER_MODEL_NUMBER_KEYS =
|
|
323
|
+
const BUDGET_NUMBER_KEYS = SETTINGS_BUDGET_NUMBER_KEYS;
|
|
324
|
+
const BUDGET_STRING_KEYS = SETTINGS_BUDGET_STRING_KEYS;
|
|
325
|
+
const PER_MODEL_NUMBER_KEYS = SETTINGS_BUDGET_PER_MODEL_NUMBER_KEYS;
|
|
325
326
|
const _budgetKeysCovered = true;
|
|
326
327
|
const _budgetKeysReal = true;
|
|
327
328
|
const _perModelKeysCovered = true;
|
|
@@ -488,6 +489,8 @@ export function projectEffectiveBody(body, skillBodies, env, rostersValue, opts)
|
|
|
488
489
|
}
|
|
489
490
|
const quoted = (s, fallback) => (s === undefined ? fallback : `the "${s}" settings`);
|
|
490
491
|
const listOf = (xs, truncatedFrom) => xs === undefined ? '' : `: ${xs.join(', ')}${truncatedFrom === undefined ? '' : ` (${truncatedFrom} in total)`}`;
|
|
492
|
+
const ENTRY_UNUSABLE_WHY = '(incomplete or invalid settings; this client cannot tell which)';
|
|
493
|
+
const ENTRY_REJECTED = `is in the catalog, but its entry is one the local engine cannot use ${ENTRY_UNUSABLE_WHY}`;
|
|
491
494
|
function warningNotice(w) {
|
|
492
495
|
const where = quoted(w.domain, 'the configuration');
|
|
493
496
|
switch (w.kind) {
|
|
@@ -511,12 +514,10 @@ function warningNotice(w) {
|
|
|
511
514
|
}
|
|
512
515
|
function droppedRefNotice(d) {
|
|
513
516
|
const t = d.target;
|
|
514
|
-
const notServed = d.reason === 'rejected'
|
|
515
|
-
? 'is in the catalog, but its entry is one the local engine cannot use (incomplete or invalid settings)'
|
|
516
|
-
: 'is not in the model catalog served to you';
|
|
517
|
+
const notServed = d.reason === 'rejected' ? ENTRY_REJECTED : 'is not in the model catalog served to you';
|
|
517
518
|
switch (d.key) {
|
|
518
519
|
case 'models':
|
|
519
|
-
return { level: 'warn', text: `cloud config: ${t === undefined ? 'a model entry' : `model "${t}"`}
|
|
520
|
+
return { level: 'warn', text: `cloud config: ${t === undefined ? 'a model entry' : `model "${t}"`} ${ENTRY_REJECTED} — it was left out of the local catalog` };
|
|
520
521
|
case 'default':
|
|
521
522
|
return { level: 'warn', text: `cloud config: ${t === undefined ? 'the default model setting could not be read' : `the default model "${t}" ${notServed}`}, so it was left out — the local engine picks its default from roles and tiers instead` };
|
|
522
523
|
case 'roles':
|
|
@@ -598,7 +599,7 @@ export function cloudEffectiveNotices(p) {
|
|
|
598
599
|
const shown = named.slice(0, 5).join(', ') + (named.length > 5 ? `, +${named.length - 5} more` : '');
|
|
599
600
|
out.push({
|
|
600
601
|
level: 'warn',
|
|
601
|
-
text: `cloud config: none of the model entries served to you${shown !== '' ? ` (${shown})` : ''} is one the local engine can use
|
|
602
|
+
text: `cloud config: none of the model entries served to you${shown !== '' ? ` (${shown})` : ''} is one the local engine can use ${ENTRY_UNUSABLE_WHY} — ` +
|
|
602
603
|
'the catalog is kept as sent, and a locally started engine rejects the cloud model settings: at startup it uses its own environment catalog instead, and on a later refresh it keeps the previous configuration',
|
|
603
604
|
});
|
|
604
605
|
}
|