@sema-agent/client-core 0.83.6 → 0.84.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.
Files changed (38) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/README.md +10 -10
  3. package/dist/adapt/wireShapes.js +3 -2
  4. package/dist/adapter/activeRunSelfHeal.js +7 -7
  5. package/dist/adapter/downstream/eventToSdkMessage.js +6 -2
  6. package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
  7. package/dist/adapter/downstream/wiringManifestView.js +1 -0
  8. package/dist/agentSession/engineAgentRegistryRead.d.ts +18 -0
  9. package/dist/agentSession/engineAgentRegistryRead.js +167 -0
  10. package/dist/agentsWireCaps.js +2 -1
  11. package/dist/attachmentsWireCaps.js +2 -2
  12. package/dist/controlRouter.js +1 -1
  13. package/dist/engineAgentAbsence.d.ts +37 -0
  14. package/dist/engineAgentAbsence.js +142 -0
  15. package/dist/engineErrorCodes.js +6 -5
  16. package/dist/engineNoticeCodes.d.ts +17 -0
  17. package/dist/engineNoticeCodes.js +45 -0
  18. package/dist/fleet/fleetProjection.js +3 -2
  19. package/dist/frozenSet.d.ts +1 -0
  20. package/dist/frozenSet.js +20 -0
  21. package/dist/handsSeam.d.ts +3 -0
  22. package/dist/handsSeam.js +19 -0
  23. package/dist/index.d.ts +23 -13
  24. package/dist/index.js +12 -13
  25. package/dist/model/catalogLoader.js +3 -3
  26. package/dist/model/tierVocabulary.js +1 -1
  27. package/dist/request/taskRequest.js +15 -5
  28. package/dist/rewindWireCaps.d.ts +0 -1
  29. package/dist/seam.d.ts +2 -1
  30. package/dist/seatContract.js +2 -2
  31. package/dist/toolResult.js +2 -6
  32. package/dist/toolRoster.d.ts +16 -0
  33. package/dist/toolRoster.js +46 -5
  34. package/dist/wireErrorTriage.js +1 -11
  35. package/dist/workflowClient.js +4 -3
  36. package/dist/workflowMonitor.d.ts +1 -1
  37. package/docs/INTEGRATION-CLIENTS.md +248 -29
  38. package/package.json +3 -3
package/dist/index.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  export * from './seam.js';
2
2
  export * from './workflow.js';
3
- export * from './notifications.js';
3
+ export { _resetEngineTaskNotificationForTest, _resetNotificationQueuePortForTest, _setWatcherTimingForTest, _tickWatchOnceForTest, classifyHookFailureFrame, classifyHookNoticeFrame, deriveNotificationResidualLines, dropQueuedNotificationsForRun, enqueueBgChildNotification, enqueueEngineWorkflowNotification, enqueuePlanReviewOutcome, HOOK_NOTICE_WARN_PREFIX, hookNoticeLastCheckText, installBgTaskStatusProbe, installNotificationQueuePort, installWorkflowStatusProbe, isEngineWorkflowNotified, isHookNoticeFrame, isOwnWorkflowRun, isTaskNotificationObjective, isWorkflowCompletionCardEnqueued, listOwnWorkflowRuns, markEngineWorkflowNotified, normalizeTaskNotification, noteOwnWorkflowRun, noteWorkflowCompletionCardEnqueued, notificationDropCounters, notificationQueuePortMisses, outstandingAbandonedCount, outstandingBgTaskPrompt, outstandingDeliverableWorkflowCount, outstandingWorkflowCount, parseTranscriptNotificationSeeds, registerOutstandingBgTask, registerOutstandingWorkflowRun, renderTaskNotificationXml, splitApiErrorSupplement, subscribeOutstandingWorkflows, taskNotificationDedupKey, taskNotificationDedupKeyFromWire, taskNotificationDeliverySupplement, } from './notifications.js';
4
+ export type { EngineWorkflowCompletion, GoalHookNotice, HookEntryType, HookFailureNotice, HookFailureReason, HookFailureVerdict, HookNoticeReason, HookNoticeVerdict, HookNoticeWire, NotificationDropCounters, NotificationQueuePort, QueuedCommandLike, TaskNotificationFields, TranscriptNotificationSeeds, } from './notifications.js';
4
5
  export * from './peerFrames.js';
5
6
  export * from './steering.js';
6
- export * from './diagnostics.js';
7
+ export type { DiagnosticsAttachment, } from './diagnostics.js';
7
8
  export * from './retryStatus.js';
8
9
  export * from './sessionMemoryStatus.js';
9
10
  export * from './memorySpecWire.js';
@@ -12,11 +13,13 @@ export * from './adapt/textSegmentAuthority.js';
12
13
  export * from './engineHttpTools.js';
13
14
  export * from './sdkWireTransit.js';
14
15
  export { SEMA_SEGMENT_ID_KEY } from './adapt/textStream.js';
15
- export * from './subagentContentStore.js';
16
+ export { __resetSubagentContentStoreConfigForTests, __resetSubagentOwnerLedgerForTests, clearSubagentContent, coerceOutput, configureSubagentContentStore, getBgParentRun, getBgParentRunOwner, getBgTerminalFacts, getSubagentContentSnapshot, isOwnEngineRun, parentToolCallIdOf, planSubagentViewSlots, publishSubagentContentEvent, pushSubagentLocalEcho, recordBgParentRun, recordBgTerminalFacts, recordOwnEngineRun, recordSubagentOwner, recordSubagentOwnerFromProgress, registerSubagentAlias, settleSubagentContent, SUBAGENT_CONTENT_STORE_DEFAULTS, subagentContentStoreConfig, subagentOwnerSessionConflicts, subscribeSubagentContent, } from './subagentContentStore.js';
17
+ export type { BgTerminalFacts, SubagentContentEvent, SubagentContentItem, SubagentContentSnapshot, SubagentContentStoreConfig, SubagentOwnerRecord, SubagentOwnerSessionConflict, SubagentViewSlot, } from './subagentContentStore.js';
16
18
  export * from './engineAgentPanelStore.js';
17
19
  export * from './engineAgentAbsence.js';
18
20
  export * from './fleetAgentPanelProjection.js';
19
- export * from './liveQuestionStore.js';
21
+ export { _resetLiveQuestionStore, hasLocalQuestionResponder, hasQuestionOverlay, hasQuestionOverlayFor, onQuestionFrame, onQuestionFrameFor, publishQuestionFrame, publishQuestionFrameFor, registerLocalQuestionResponder, respondToQuestion, setQuestionRespond, } from './liveQuestionStore.js';
22
+ export type { AskQuestion, AskQuestionOption, QuestionAnswer, QuestionFrame, } from './liveQuestionStore.js';
20
23
  export * from './engineInlineTaskStats.js';
21
24
  export * from './printToolResultFrame.js';
22
25
  export * from './engineCapsCache.js';
@@ -67,7 +70,8 @@ export * from './sseIdleTriage.js';
67
70
  export * from './engineWireSdk.js';
68
71
  export * from './classifierVerdictWire.js';
69
72
  export { stripSystemReminderBlocks, unwrapSystemReminder } from './systemReminderTag.js';
70
- export * from './engineErrorCodes.js';
73
+ export { ACTIVE_RUN_BUSY_ERROR_CODE, asModelFallbackReason, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_LIMIT_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_MEMORY_PROJECT_KEY_SPELLING, CONFIG_MEMORY_WRITE_SCOPE_MISMATCH, CONFIG_REFUSAL_CODES, CONFIG_STRATEGY_FIND_LIMIT_INVALID, CONFIG_STRATEGY_MAX_SIZE_INVALID, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, DELEGATION_CAP_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, delegationCapDispositionOf, DRAINING_ERROR_CODE, ENGINE_STOP_REASONS, engineStopReasonToCc, ENV_LIFETIME_EXPIRED, GATE_PARKED_ERROR_CODE, isConfigRefusalCode, isDelegationCapCode, isInterruptedToolEndCode, isLimitsExceededCode, isRewindFamilyCode, isWorkflowParkRefusalCode, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, MCP_SERVER_REVOKED, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, OUTPUT_INVALID, RESUME_AT_ERROR_CODE_PREFIX, RESUME_CONTEXT_UNAVAILABLE, RESUME_ENV_FAILED, RESUME_PLACEMENT_MISMATCH, RESUME_POLICY_FOLD_CODE, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, RESUME_TOOL_CONTRACT_MISMATCH, RESUME_TOOL_UNAVAILABLE, RESUME_USAGE_WINDOW_EXHAUSTED, REWIND_ERROR_CODE_PREFIXES, SCENARIO_NOT_ALLOWED_ERROR_CODE, STOP_CONFLICT_CODES, STREAM_MAX_DURATION, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, USAGE_WINDOW_EXHAUSTED, WORKFLOW_PARK_REFUSAL_CODES, } from './engineErrorCodes.js';
74
+ export type { DelegationCapDisposition, ModelFallbackReason, } from './engineErrorCodes.js';
71
75
  export * from './agentsWireCaps.js';
72
76
  export * from './attachmentsWireCaps.js';
73
77
  export * from './clientContextWireCaps.js';
@@ -115,20 +119,23 @@ export * from './limitsWire.js';
115
119
  export * from './interactiveToolsWire.js';
116
120
  export * from './headlessPermissionModeWire.js';
117
121
  export * from './headlessReconnectWire.js';
118
- export * from './fleet/fleetProjection.js';
122
+ export { coerceTaskStatus, coerceWorkflowStatus, CONTROL_TOOL_VERBS, FLEET_TASK_ROW_KEYS_NOT_PROJECTED, FLEET_TASK_ROW_WIRE_KEYS, FLEET_TASK_VIEW_KEYS, FLEET_WORKFLOW_ROW_KEYS_NOT_PROJECTED, FLEET_WORKFLOW_ROW_WIRE_KEYS, FLEET_WORKFLOW_VIEW_KEYS, projectDescription, projectTasks, projectWorkflows, TERMINAL_FLEET_TASK_STATUSES, wireResumable, wireRowUsage, } from './fleet/fleetProjection.js';
123
+ export type { FleetRowUsage, FleetTaskStatus, FleetTaskView, FleetWorkflowView, NotProjectedEntry, ProjectTasksOptions, } from './fleet/fleetProjection.js';
119
124
  export * from './fleet/fleetLedger.js';
120
125
  export * from './fleet/workflowSizeWarning.js';
121
126
  export * from './subagent/engineDelegatedPrompt.js';
122
127
  export * from './subagent/engineRowStopGate.js';
123
128
  export * from './subagent/engineSubagentOutput.js';
124
129
  export * from './subagent/engineSubagentSteer.js';
125
- export * from './subagent/engineSubagentResume.js';
130
+ export { __resetRetainWithoutWakeWarningForTests, auditRetainWithoutWake, classifySubagentResumeFailure, resolveOwnerRunId, resolveSubagentContinueTarget, resolveSubagentResumeContext, resumeSettledSubagent, SUBAGENT_RESUME_CAP, subagentResumeAvailable, } from './subagent/engineSubagentResume.js';
131
+ export type { RetainWithoutWakeInput, RetainWithoutWakeVerdict, SubagentOwnerContext, SubagentResumeContext, SubagentResumeFacade, SubagentResumeFailureKind, SubagentResumeFailureVerdict, SubagentResumeOutcome, } from './subagent/engineSubagentResume.js';
126
132
  export * from './subagent/engineTaskHandleWire.js';
127
133
  export * from './subagent/engineCompactWire.js';
128
134
  export * from './subagent/engineSubagentTail.js';
129
- export * from './subagent/subagentOwnerAbsence.js';
135
+ export { __resetBgOwnerAbsenceForTests, } from './subagent/subagentOwnerAbsence.js';
130
136
  export * from './engineSessionParam.js';
131
- export * from './engineWireTarget.js';
137
+ export { engineWireTarget, engineWireTargetFor, installEngineWireTarget, installEngineWireTargetFor, } from './engineWireTarget.js';
138
+ export type { EngineWireTarget, } from './engineWireTarget.js';
132
139
  export * from './principalWire.js';
133
140
  export * from './wireErrorTriage.js';
134
141
  export * from './resumeRefusalCopy.js';
@@ -143,20 +150,21 @@ export { ENGINE_FIRED_HOOK_EVENTS, PLUGIN_HOOK_DISPOSITIONS, PLUGIN_HOOK_REASONS
143
150
  export * from './liveInitToolFace.js';
144
151
  export * from './printInitToolFace.js';
145
152
  export * from './model/providerPresets.js';
146
- export * from './hitl/hitlBridge.js';
153
+ export { __setDecideTimeoutRetryBudgetForTests, backendDeny, DecideTransportRetryExhaustedError, findPendingForTask, HitlBridge, HitlSafetyError, isPlanReviewModeAfter, makeHitlCanUseTool, PLAN_REVIEW_MODE_AFTER_WORDS, readDecideCurrentPending, readWireErrorCode, } from './hitl/hitlBridge.js';
154
+ export type { ActiveGate, ApprovalsResourceLike, AskAnswer, AssistantResourceLike, DecideOperationEnd, DecideOperationEvent, DecideOperationIdentity, DecideOperationObserver, DecideOperationSpan, DecideOperationStart, FindPendingOutcome, GateCurrentPending, GatePrompt, HitlBackendDenyDecision, HitlBridgeOptions, HitlCanUseToolFn, HitlClientLike, HitlDecideDenyOutcome, HitlFailureStage, HitlPermissionDecisionLike, HitlSafetyCode, PlanReviewModeAfter, PlanReviewOutcome, } from './hitl/hitlBridge.js';
147
155
  export * from './hitl/suspendedReopen.js';
148
156
  export * from './hitl/approvalOutcomeNote.js';
149
157
  export * from './hitl/approvalResolution.js';
150
158
  export { toolEndOutputText, ENGINE_ABORT_TOOL_RESULT } from './hitl/frameRouter.js';
151
- export { isAskTool } from './hitl/frameRouter.js';
152
- export * from './hitl/hitlHostSurface.js';
159
+ export { _resetHitlHostSurfaceForTest, CANCEL_DENY_BUDGET_MS, CANCEL_DENY_WARN_TEXT, EDIT_NOT_FORWARDED_WARN_TEXT, EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT, hitlHostSurfaceFor, hitlHostSurfaceMisses, hitlHostSurfaceMissesFor, installHitlHostSurface, installHitlHostSurfaceFor, observeCancelByDeny, REMEMBER_NOT_APPLIED_WARN_TEXT, RULE_NOT_SENT_REJECTED_WARN_TEXT, RULE_NOT_SENT_WARN_TEXT, surfaceEditRefusedOnBlindAsk, surfaceForCurrentSession, surfaceRememberNotApplied, } from './hitl/hitlHostSurface.js';
160
+ export type { ClassifierDenyContext, HitlHostSurface, HitlNotice, } from './hitl/hitlHostSurface.js';
153
161
  export * from './hitl/toolApprovalWire.js';
154
162
  export * from './hitl/editedRuleTextPrecheck.js';
155
163
  export * from './coreValuePorts.js';
156
164
  export * from './hitl/askGateWire.js';
157
165
  export * from './hitl/planReviewWire.js';
158
166
  export { PLAN_REVIEW_QUESTION_ID_PREFIX, REOPEN_ID_TAIL, approvalCallKey, askGateQuestionId, planReviewQuestionId, liveFrameCallKey, armedKeyFromQuestionId, } from './hitl/gateIdentity.js';
159
- export * from './hitl/armedGateRegistry.js';
167
+ export { _resetArmedGateRegistryForTest, _setGateArmedWaitMsForTest, clearArmedGate, gateArmedWaitMs, notePlanReviewAnswered, onGateArmed, planReviewArmedKey, registerArmedGate, registerArmedGateFor, registerArmedGateFromQuestionId, waitForGateArmed, wasGateArmed, wasGateArmedFor, } from './hitl/armedGateRegistry.js';
160
168
  export * from './hitl/parkOwnership.js';
161
169
  export * from './hitl/parkRowBirthWait.js';
162
170
  export * from './hitl/approvalDecisionNoteAudit.js';
@@ -176,6 +184,8 @@ export * from './request/printNotification.js';
176
184
  export * from './seatContract.js';
177
185
  export * from './agentSession/contract.js';
178
186
  export * from './agentSession/backgroundView.js';
187
+ export { readEngineAgentRegistry, isEngineAgentRegistryListingSuperseded } from './agentSession/engineAgentRegistryRead.js';
188
+ export type { EngineAgentRegistryClient } from './agentSession/engineAgentRegistryRead.js';
179
189
  export * from './model/catalog.js';
180
190
  export * from './model/catalogLoader.js';
181
191
  export * from './model/providerAuth.js';
package/dist/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  export * from './seam.js';
2
2
  export * from './workflow.js';
3
- export * from './notifications.js';
3
+ export { _resetEngineTaskNotificationForTest, _resetNotificationQueuePortForTest, _setWatcherTimingForTest, _tickWatchOnceForTest, classifyHookFailureFrame, classifyHookNoticeFrame, deriveNotificationResidualLines, dropQueuedNotificationsForRun, enqueueBgChildNotification, enqueueEngineWorkflowNotification, enqueuePlanReviewOutcome, HOOK_NOTICE_WARN_PREFIX, hookNoticeLastCheckText, installBgTaskStatusProbe, installNotificationQueuePort, installWorkflowStatusProbe, isEngineWorkflowNotified, isHookNoticeFrame, isOwnWorkflowRun, isTaskNotificationObjective, isWorkflowCompletionCardEnqueued, listOwnWorkflowRuns, markEngineWorkflowNotified, normalizeTaskNotification, noteOwnWorkflowRun, noteWorkflowCompletionCardEnqueued, notificationDropCounters, notificationQueuePortMisses, outstandingAbandonedCount, outstandingBgTaskPrompt, outstandingDeliverableWorkflowCount, outstandingWorkflowCount, parseTranscriptNotificationSeeds, registerOutstandingBgTask, registerOutstandingWorkflowRun, renderTaskNotificationXml, splitApiErrorSupplement, subscribeOutstandingWorkflows, taskNotificationDedupKey, taskNotificationDedupKeyFromWire, taskNotificationDeliverySupplement, } from './notifications.js';
4
4
  export * from './peerFrames.js';
5
5
  export * from './steering.js';
6
- export * from './diagnostics.js';
7
6
  export * from './retryStatus.js';
8
7
  export * from './sessionMemoryStatus.js';
9
8
  export * from './memorySpecWire.js';
@@ -12,11 +11,11 @@ export * from './adapt/textSegmentAuthority.js';
12
11
  export * from './engineHttpTools.js';
13
12
  export * from './sdkWireTransit.js';
14
13
  export { SEMA_SEGMENT_ID_KEY } from './adapt/textStream.js';
15
- export * from './subagentContentStore.js';
14
+ export { __resetSubagentContentStoreConfigForTests, __resetSubagentOwnerLedgerForTests, clearSubagentContent, coerceOutput, configureSubagentContentStore, getBgParentRun, getBgParentRunOwner, getBgTerminalFacts, getSubagentContentSnapshot, isOwnEngineRun, parentToolCallIdOf, planSubagentViewSlots, publishSubagentContentEvent, pushSubagentLocalEcho, recordBgParentRun, recordBgTerminalFacts, recordOwnEngineRun, recordSubagentOwner, recordSubagentOwnerFromProgress, registerSubagentAlias, settleSubagentContent, SUBAGENT_CONTENT_STORE_DEFAULTS, subagentContentStoreConfig, subagentOwnerSessionConflicts, subscribeSubagentContent, } from './subagentContentStore.js';
16
15
  export * from './engineAgentPanelStore.js';
17
16
  export * from './engineAgentAbsence.js';
18
17
  export * from './fleetAgentPanelProjection.js';
19
- export * from './liveQuestionStore.js';
18
+ export { _resetLiveQuestionStore, hasLocalQuestionResponder, hasQuestionOverlay, hasQuestionOverlayFor, onQuestionFrame, onQuestionFrameFor, publishQuestionFrame, publishQuestionFrameFor, registerLocalQuestionResponder, respondToQuestion, setQuestionRespond, } from './liveQuestionStore.js';
20
19
  export * from './engineInlineTaskStats.js';
21
20
  export * from './printToolResultFrame.js';
22
21
  export * from './engineCapsCache.js';
@@ -65,7 +64,7 @@ export * from './sseIdleTriage.js';
65
64
  export * from './engineWireSdk.js';
66
65
  export * from './classifierVerdictWire.js';
67
66
  export { stripSystemReminderBlocks, unwrapSystemReminder } from './systemReminderTag.js';
68
- export * from './engineErrorCodes.js';
67
+ export { ACTIVE_RUN_BUSY_ERROR_CODE, asModelFallbackReason, CAPABILITY_SELF_ORCHESTRATION_REQUIRED, CONFIG_DELEGATION_ENTRY_CAPS, CONFIG_LIMIT_INVALID, CONFIG_LIMIT_UNKNOWN_KEY, CONFIG_MEMORY_PROJECT_KEY_SPELLING, CONFIG_MEMORY_WRITE_SCOPE_MISMATCH, CONFIG_REFUSAL_CODES, CONFIG_STRATEGY_FIND_LIMIT_INVALID, CONFIG_STRATEGY_MAX_SIZE_INVALID, DECIDE_WORKFLOW_HOST_UNKNOWN, DECIDE_WORKFLOW_LANE_CODES, DECIDE_WORKFLOW_REMEMBER_UNSUPPORTED, DELEGATION_CAP_CODES, DELEGATION_CONCURRENCY_CAP, DELEGATION_SESSION_CAP, delegationCapDispositionOf, DRAINING_ERROR_CODE, ENGINE_STOP_REASONS, engineStopReasonToCc, ENV_LIFETIME_EXPIRED, GATE_PARKED_ERROR_CODE, isConfigRefusalCode, isDelegationCapCode, isInterruptedToolEndCode, isLimitsExceededCode, isRewindFamilyCode, isWorkflowParkRefusalCode, LIMITS_MAX_COST_EXCEEDED, LIMITS_MAX_TOKENS_EXCEEDED, LIMITS_MAX_TURNS_EXCEEDED, LIMITS_MAX_WALLTIME_EXCEEDED, MCP_SERVER_REVOKED, MODEL_FALLBACK_INHERIT_NO_TIER_BINDING, OUTPUT_INVALID, RESUME_AT_ERROR_CODE_PREFIX, RESUME_CONTEXT_UNAVAILABLE, RESUME_ENV_FAILED, RESUME_PLACEMENT_MISMATCH, RESUME_POLICY_FOLD_CODE, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_RETRY_LATER_CODES, RESUME_TOOL_CONTRACT_MISMATCH, RESUME_TOOL_UNAVAILABLE, RESUME_USAGE_WINDOW_EXHAUSTED, REWIND_ERROR_CODE_PREFIXES, SCENARIO_NOT_ALLOWED_ERROR_CODE, STOP_CONFLICT_CODES, STREAM_MAX_DURATION, TOOL_END_INTERRUPTED_NEVER_STARTED, TOOL_END_INTERRUPTED_OUTCOME_UNKNOWN, USAGE_WINDOW_EXHAUSTED, WORKFLOW_PARK_REFUSAL_CODES, } from './engineErrorCodes.js';
69
68
  export * from './agentsWireCaps.js';
70
69
  export * from './attachmentsWireCaps.js';
71
70
  export * from './clientContextWireCaps.js';
@@ -112,20 +111,20 @@ export * from './limitsWire.js';
112
111
  export * from './interactiveToolsWire.js';
113
112
  export * from './headlessPermissionModeWire.js';
114
113
  export * from './headlessReconnectWire.js';
115
- export * from './fleet/fleetProjection.js';
114
+ export { coerceTaskStatus, coerceWorkflowStatus, CONTROL_TOOL_VERBS, FLEET_TASK_ROW_KEYS_NOT_PROJECTED, FLEET_TASK_ROW_WIRE_KEYS, FLEET_TASK_VIEW_KEYS, FLEET_WORKFLOW_ROW_KEYS_NOT_PROJECTED, FLEET_WORKFLOW_ROW_WIRE_KEYS, FLEET_WORKFLOW_VIEW_KEYS, projectDescription, projectTasks, projectWorkflows, TERMINAL_FLEET_TASK_STATUSES, wireResumable, wireRowUsage, } from './fleet/fleetProjection.js';
116
115
  export * from './fleet/fleetLedger.js';
117
116
  export * from './fleet/workflowSizeWarning.js';
118
117
  export * from './subagent/engineDelegatedPrompt.js';
119
118
  export * from './subagent/engineRowStopGate.js';
120
119
  export * from './subagent/engineSubagentOutput.js';
121
120
  export * from './subagent/engineSubagentSteer.js';
122
- export * from './subagent/engineSubagentResume.js';
121
+ export { __resetRetainWithoutWakeWarningForTests, auditRetainWithoutWake, classifySubagentResumeFailure, resolveOwnerRunId, resolveSubagentContinueTarget, resolveSubagentResumeContext, resumeSettledSubagent, SUBAGENT_RESUME_CAP, subagentResumeAvailable, } from './subagent/engineSubagentResume.js';
123
122
  export * from './subagent/engineTaskHandleWire.js';
124
123
  export * from './subagent/engineCompactWire.js';
125
124
  export * from './subagent/engineSubagentTail.js';
126
- export * from './subagent/subagentOwnerAbsence.js';
125
+ export { __resetBgOwnerAbsenceForTests, } from './subagent/subagentOwnerAbsence.js';
127
126
  export * from './engineSessionParam.js';
128
- export * from './engineWireTarget.js';
127
+ export { engineWireTarget, engineWireTargetFor, installEngineWireTarget, installEngineWireTargetFor, } from './engineWireTarget.js';
129
128
  export * from './principalWire.js';
130
129
  export * from './wireErrorTriage.js';
131
130
  export * from './resumeRefusalCopy.js';
@@ -140,20 +139,19 @@ export { ENGINE_FIRED_HOOK_EVENTS, PLUGIN_HOOK_DISPOSITIONS, PLUGIN_HOOK_REASONS
140
139
  export * from './liveInitToolFace.js';
141
140
  export * from './printInitToolFace.js';
142
141
  export * from './model/providerPresets.js';
143
- export * from './hitl/hitlBridge.js';
142
+ export { __setDecideTimeoutRetryBudgetForTests, backendDeny, DecideTransportRetryExhaustedError, findPendingForTask, HitlBridge, HitlSafetyError, isPlanReviewModeAfter, makeHitlCanUseTool, PLAN_REVIEW_MODE_AFTER_WORDS, readDecideCurrentPending, readWireErrorCode, } from './hitl/hitlBridge.js';
144
143
  export * from './hitl/suspendedReopen.js';
145
144
  export * from './hitl/approvalOutcomeNote.js';
146
145
  export * from './hitl/approvalResolution.js';
147
146
  export { toolEndOutputText, ENGINE_ABORT_TOOL_RESULT } from './hitl/frameRouter.js';
148
- export { isAskTool } from './hitl/frameRouter.js';
149
- export * from './hitl/hitlHostSurface.js';
147
+ export { _resetHitlHostSurfaceForTest, CANCEL_DENY_BUDGET_MS, CANCEL_DENY_WARN_TEXT, EDIT_NOT_FORWARDED_WARN_TEXT, EDIT_REFUSED_ON_BLIND_ASK_WARN_TEXT, hitlHostSurfaceFor, hitlHostSurfaceMisses, hitlHostSurfaceMissesFor, installHitlHostSurface, installHitlHostSurfaceFor, observeCancelByDeny, REMEMBER_NOT_APPLIED_WARN_TEXT, RULE_NOT_SENT_REJECTED_WARN_TEXT, RULE_NOT_SENT_WARN_TEXT, surfaceEditRefusedOnBlindAsk, surfaceForCurrentSession, surfaceRememberNotApplied, } from './hitl/hitlHostSurface.js';
150
148
  export * from './hitl/toolApprovalWire.js';
151
149
  export * from './hitl/editedRuleTextPrecheck.js';
152
150
  export * from './coreValuePorts.js';
153
151
  export * from './hitl/askGateWire.js';
154
152
  export * from './hitl/planReviewWire.js';
155
153
  export { PLAN_REVIEW_QUESTION_ID_PREFIX, REOPEN_ID_TAIL, approvalCallKey, askGateQuestionId, planReviewQuestionId, liveFrameCallKey, armedKeyFromQuestionId, } from './hitl/gateIdentity.js';
156
- export * from './hitl/armedGateRegistry.js';
154
+ export { _resetArmedGateRegistryForTest, _setGateArmedWaitMsForTest, clearArmedGate, gateArmedWaitMs, notePlanReviewAnswered, onGateArmed, planReviewArmedKey, registerArmedGate, registerArmedGateFor, registerArmedGateFromQuestionId, waitForGateArmed, wasGateArmed, wasGateArmedFor, } from './hitl/armedGateRegistry.js';
157
155
  export * from './hitl/parkOwnership.js';
158
156
  export * from './hitl/parkRowBirthWait.js';
159
157
  export * from './hitl/approvalDecisionNoteAudit.js';
@@ -173,6 +171,7 @@ export * from './request/printNotification.js';
173
171
  export * from './seatContract.js';
174
172
  export * from './agentSession/contract.js';
175
173
  export * from './agentSession/backgroundView.js';
174
+ export { readEngineAgentRegistry, isEngineAgentRegistryListingSuperseded } from './agentSession/engineAgentRegistryRead.js';
176
175
  export * from './model/catalog.js';
177
176
  export * from './model/catalogLoader.js';
178
177
  export * from './model/providerAuth.js';
@@ -1,10 +1,10 @@
1
1
  import { hostEnv } from '../hostEnv.js';
2
2
  import { resolveModelCatalog, } from './catalog.js';
3
- export const DEFAULT_CATALOG_SOURCES = [
3
+ export const DEFAULT_CATALOG_SOURCES = Object.freeze([
4
4
  'https://raw.githubusercontent.com/sema-agent/sema-model-catalog/main/dist/catalog.json',
5
5
  'https://cdn.jsdelivr.net/gh/sema-agent/sema-model-catalog@main/dist/catalog.json',
6
- ];
7
- export const CATALOG_DEFAULT_HOSTS = ['raw.githubusercontent.com', 'cdn.jsdelivr.net'];
6
+ ]);
7
+ export const CATALOG_DEFAULT_HOSTS = Object.freeze(['raw.githubusercontent.com', 'cdn.jsdelivr.net']);
8
8
  export const CATALOG_SOURCES_ENV = 'SEMA_CATALOG_SOURCES';
9
9
  const DEFAULT_CATALOG_TIMEOUT_MS = 3500;
10
10
  const CATALOG_CACHE_RELATIVE_PATH = 'cache/model-catalog.json';
@@ -1,4 +1,4 @@
1
- export const TIER_ORDER = ['ultra', 'max', 'pro', 'flash', 'lite'];
1
+ export const TIER_ORDER = Object.freeze(['ultra', 'max', 'pro', 'flash', 'lite']);
2
2
  export const SURFACED_TIERS = ['max', 'pro', 'flash', 'lite'];
3
3
  export const CC_TIER_ALIASES = {
4
4
  fable: 'max',
@@ -39,11 +39,11 @@ export const REQUEST_FIELD_MATRIX = [
39
39
  { field: 'reasoningEffort', lanes: ['interactive', 'print', 'utility'], live: false, why: '思考档位(sdk `TaskRequest.reasoningEffort` 七词闭集;上游对表外词 400 响亮拒 ⇒ 本层不预铸第二判官)。档位是请求级的位、与车道无关:交互面 = `/effort` 拨盘,无人值守面 = 档位旗。🔴 端交的必须是**档位词**:「思考 token 数」今天没有上游对位(见 `UPSTREAM_ABSENT_REQUEST_INTENTS` 的 `maxThinkingTokens`),别把一个数字折成档位词发出去', whyUtilityLane: '有座:side-channel 该用显式低档(省钱省时);与 model 同一条理由 —— 本车道上这两位都由壳显式给,不跟用户会话的拨盘走' },
40
40
  { field: 'model', lanes: ['interactive', 'print', 'utility'], live: false, why: '模型选择(sdk `TaskRequest.model`;交互面 = `/model` 中途换模型的拨盘,无人值守面 = 模型旗 / 部署缺省那一路,side-channel 面 = 壳显式挑的那一只)。三条车道都有来源、都是提交面。🔴 0.79.0 改口:修前「print 的模型走另一条路」这句理由被用户面实测证伪 —— 无人值守车道传了模型名却整键不上请求体,于是同一个坏名字在交互态被引擎 400 点名、在无人值守态却安静换成部署缺省并在首帧回显一个没生效的名字。一个**选择**类声明被静默丢掉,后果与收紧类声明被静默丢掉同形(端不读回执就以为生效)—— 与 `excludeTools` 补 print 座同律。本层原样透传、不预判模型名(名字的合法性归引擎,本层不铸第二判官)', whyUtilityLane: '有座:side-channel 显式挑便宜的那只模型(不跟用户会话的 `/model` 拨盘走)' },
41
41
  { field: 'images', lanes: ['interactive'], live: false, why: '贴图提交是交互动作,`-p` 的 stdin 没有图片块', whyUtilityLane: '无座:贴图是交互动作,side-channel 的提交体里没有图片块' },
42
- { field: 'resumeAt/resumeAtMode/restoreFiles/rewindFiles/rewindFilesTo', lanes: ['interactive'], live: false, why: 'E18 `/rewind` 是交互命令;五键同生同灭(CC-145:core 6.0.0 起 both 臂发 restoreFiles,退役键 rewindFiles 只为旧读者留座不再铸;resumeAtMode 是 both/conversation 两臂恒带的排他截语义位)', whyUtilityLane: '无座:回退是交互命令,而 side-channel 是一次性的独立会话,没有可回退的历史' },
42
+ { field: 'resumeAt/resumeAtMode/restoreFiles/rewindFilesTo', lanes: ['interactive'], live: false, why: 'E18 `/rewind` 是交互命令;四键同生同灭(CC-145:core 6.0.0 起 both 臂发 restoreFiles;CC-223 起退役键 rewindFiles 不再有座 —— 交它按表外子键响亮拒;resumeAtMode 是 both/conversation 两臂恒带的排他截语义位)', whyUtilityLane: '无座:回退是交互命令,而 side-channel 是一次性的独立会话,没有可回退的历史' },
43
43
  { field: 'clientContext', lanes: ['interactive'], live: false, why: 'IANA 时区 + 可选邮箱 → core 本地化 `# Environment` 的 today;print 同样跑在用户机器上,缺席让引擎误标 (UTC)', gap: true, whyUtilityLane: '无座:本地化 today 的用途在用户会话的环境段,而 side-channel 的系统提示由壳整段给出 —— 这一列我判不准要不要(与本行 `gap` 同一条待办:要补先单独立项)' },
44
44
  { field: 'scratchpadDir', lanes: ['interactive'], live: true, why: '[816]③ per-session 暂存目录;print 也有 session,缺席让 `-p` 的工具写不进 exemptDir', gap: true, whyUtilityLane: '无座:per-session 暂存目录是给**工具**写的,零工具面上没人写' },
45
45
  ];
46
- export const LIVE_DEFAULT_FIELDS = [
46
+ export const LIVE_DEFAULT_FIELDS = Object.freeze([
47
47
  'cwd',
48
48
  'additionalDirectories',
49
49
  'additionalReadDirectories',
@@ -54,7 +54,7 @@ export const LIVE_DEFAULT_FIELDS = [
54
54
  'suggestNextPrompts',
55
55
  'compactionModel',
56
56
  'sessionId(三态解析)',
57
- ];
57
+ ]);
58
58
  export const TASK_REQUEST_OMISSION_CAUSES = Object.freeze([
59
59
  'upstream_absent',
60
60
  'other_channel',
@@ -125,7 +125,7 @@ const INPUT_KEY_ROUTES = {
125
125
  memoryCapture: row('memoryCapture'),
126
126
  memory: row('memory'),
127
127
  approverPosture: row('approverPosture'),
128
- rewind: row('resumeAt/resumeAtMode/restoreFiles/rewindFiles/rewindFilesTo'),
128
+ rewind: row('resumeAt/resumeAtMode/restoreFiles/rewindFilesTo'),
129
129
  repo: row('repo'),
130
130
  council: row('council'),
131
131
  debate: row('debate'),
@@ -585,11 +585,12 @@ export function assembleTaskRequest(input, lane) {
585
585
  refuseBadMaxTokens(maxTokensIn);
586
586
  refuseBadOutputRetries(outputRetriesIn);
587
587
  const rewindRoute = INPUT_KEY_ROUTES.rewind;
588
+ const RETIRED_REWIND_FILES_KEY = 'rewindFiles';
588
589
  const REWIND_KEYS = rewindRoute.via === 'matrix' ? rewindRoute.field.split('/') : [];
589
590
  const rewindIn = i.rewind;
590
591
  if (present(rewindIn) && (typeof rewindIn !== 'object' || Array.isArray(rewindIn))) {
591
592
  throw new TypeError(`buildTaskRequest: rewind 只接受对象或缺席(undefined/null)—— 收到 ${coarseShape(rewindIn)}。` +
592
- '它是五个具名请求键(resumeAt / resumeAtMode / restoreFiles / rewindFiles / rewindFilesTo)的合写位,不是任意展开口。错误文本只报形状,不回显值。');
593
+ '它是四个具名请求键(resumeAt / resumeAtMode / restoreFiles / rewindFilesTo)的合写位,不是任意展开口。错误文本只报形状,不回显值。');
593
594
  }
594
595
  const rewindObj = present(rewindIn) ? rewindIn : {};
595
596
  const rewindWire = {};
@@ -632,14 +633,23 @@ export function assembleTaskRequest(input, lane) {
632
633
  continue;
633
634
  unknownKeys.push(`settings.${sub}`);
634
635
  }
636
+ let retiredRewindFiles = false;
635
637
  for (const sub of Object.keys(rewindObj)) {
636
638
  if (REWIND_KEYS.includes(sub))
637
639
  continue;
638
640
  const stray = rewindObj[sub];
639
641
  if (!present(stray))
640
642
  continue;
643
+ if (sub === RETIRED_REWIND_FILES_KEY)
644
+ retiredRewindFiles = true;
641
645
  unknownKeys.push(`rewind.${sub}`);
642
646
  }
647
+ if (retiredRewindFiles) {
648
+ throw new TypeError('buildTaskRequest: "rewind.rewindFiles" 是退役键(引擎 core 6.0.0 起退役:「逐轮捕获」那一义被引擎忽略 —— 文件首触追踪恒开,' +
649
+ '无需请求;「回退时一并还原文件」那一义被引擎拒收、改名为 restoreFiles)。本包在装配前拒:在场即拒,true / false 同判。' +
650
+ '处置:删掉这个键;要在回退会话时一并还原文件,改交 ' +
651
+ 'rewind.restoreFiles: true(必须与 rewind.resumeAt 同交);只还原文件、不动会话,交 rewind.rewindFilesTo。错误文本只报键名,不回显值。');
652
+ }
643
653
  if (unknownKeys.length > 0) {
644
654
  const shown = unknownKeys.slice(0, MAX_UNKNOWN_KEYS_SHOWN).map(keyForDisplay).join(', ');
645
655
  const more = unknownKeys.length > MAX_UNKNOWN_KEYS_SHOWN ? ` 等共 ${unknownKeys.length} 个` : '';
@@ -2,7 +2,6 @@ export interface SeamRewindSpec {
2
2
  resumeAt?: string;
3
3
  resumeAtMode?: 'at' | 'before';
4
4
  restoreFiles?: boolean;
5
- rewindFiles?: boolean;
6
5
  rewindFilesTo?: string;
7
6
  }
8
7
  export type RewindMode = 'both' | 'conversation' | 'code';
package/dist/seam.d.ts CHANGED
@@ -2,7 +2,7 @@ import type { ModelUsage, SDKMessage } from '@sema-agent/agent-types';
2
2
  import type { EngineTurnUsage } from './adapter/downstream/turnUsageToModelUsage.js';
3
3
  import type { RunCostReconcile } from './adapter/downstream/terminalToSdkResult.js';
4
4
  import type { WiringManifestAutoMode, WiringManifestModelGate, WiringManifestMcpEntryView, WiringManifestHookEntryView, WiringManifestLspSeamView, WiringManifestWriteProtectionView, WiringManifestAutoConsolidationView, WiringManifestReadDenyView, ContextUsageSectionView, PromptManifestSectionView, PromptManifestBlockView, PromptManifestToolView } from './adapter/downstream/eventToSdkMessage.js';
5
- import type { ToolRosterView, ToolRosterDeltaView } from './toolRoster.js';
5
+ import type { ToolRosterView, ToolRosterDeltaView, WiringManifestHandsView } from './toolRoster.js';
6
6
  export interface AbortSignalLike {
7
7
  readonly aborted: boolean;
8
8
  }
@@ -162,6 +162,7 @@ export interface WiringManifestChromeEvent {
162
162
  writeProtection?: WiringManifestWriteProtectionView;
163
163
  autoConsolidation?: WiringManifestAutoConsolidationView;
164
164
  readDeny?: WiringManifestReadDenyView;
165
+ hands?: WiringManifestHandsView;
165
166
  eventId?: string;
166
167
  }
167
168
  export interface TextSegmentCommittedRow {
@@ -12,13 +12,13 @@ const isObject = (v) => typeof v === "object" && v !== null;
12
12
  const isAbsent = (v) => typeof v === "undefined";
13
13
  const optionalString = (v) => isAbsent(v) || typeof v === "string";
14
14
  const inTuple = (tuple, v) => tuple.includes(v);
15
- export const TOOL_PERMISSION_REQUEST_ID_DOMAINS = [
15
+ export const TOOL_PERMISSION_REQUEST_ID_DOMAINS = Object.freeze([
16
16
  "live:",
17
17
  "durable:",
18
18
  "question:",
19
19
  "elicit:",
20
20
  "plan:",
21
- ];
21
+ ]);
22
22
  export function toolPermissionRequestIdDomain(requestId) {
23
23
  if (typeof requestId !== "string")
24
24
  return undefined;
@@ -2,7 +2,8 @@ import { convertLeadingTabsToSpaces, getPatchFromContents } from './diff/patch.j
2
2
  import { markEngineWorkflowNotified, registerOutstandingBgTask, registerOutstandingWorkflowRun, } from './notifications.js';
3
3
  import { parseWorkflowPollEnvelope, projectWorkflowTaskOutput } from './workflow.js';
4
4
  import { asModelFallbackReason } from './engineErrorCodes.js';
5
- export const STRUCTURED_DETAIL_TYPES = new Set([
5
+ import { frozenSet } from './frozenSet.js';
6
+ export const STRUCTURED_DETAIL_TYPES = frozenSet([
6
7
  'edit',
7
8
  'create',
8
9
  'update',
@@ -58,13 +59,8 @@ export function structuredDetailType(structured) {
58
59
  const MAX_STRUCTURED_FIELD_CHARS = 1_000_000;
59
60
  const WF_TERMINAL_STATUSES = new Set([
60
61
  'completed',
61
- 'done',
62
62
  'failed',
63
- 'stopped',
64
- 'interrupted',
65
- 'error',
66
63
  'cancelled',
67
- 'canceled',
68
64
  ]);
69
65
  export const PROTOCOL_MARKERS = {
70
66
  bashHead: /^exit code: (-?\d+)(?: \(([^)\n]*)\))?\n(--- stdout ---\n)?/,
@@ -63,6 +63,22 @@ export type HandsMountedReading = {
63
63
  why: 'no-manifest' | 'no-roster' | 'roster-unreadable' | 'mount-condition-absent';
64
64
  };
65
65
  export declare function handsMountedFromManifest(manifest: unknown): HandsMountedReading;
66
+ export interface WiringManifestHandsView {
67
+ mounted: boolean;
68
+ reason?: string;
69
+ }
70
+ export type HandsSeamReading = {
71
+ kind: 'not_reported';
72
+ } | {
73
+ kind: 'mounted';
74
+ } | {
75
+ kind: 'not_mounted';
76
+ reason?: string;
77
+ };
78
+ export declare function handsSeamReadingOf(view: {
79
+ readonly hands?: WiringManifestHandsView;
80
+ } | null | undefined): HandsSeamReading;
81
+ export declare function handsSeamDetail(reading: HandsSeamReading): string;
66
82
  export declare function handsMountedDetail(reading: HandsMountedReading): string;
67
83
  export declare function toolRosterNames(roster: ToolRosterView | undefined): readonly string[];
68
84
  export interface ToolShim {
@@ -1,3 +1,5 @@
1
+ import { displayUntrusted } from './displayUntrusted.js';
2
+ import { HANDS_REASON_NO_EXECUTION_ENV, projectHandsSection } from './handsSeam.js';
1
3
  const str = (v) => typeof v === 'string' && v.length > 0 ? v : undefined;
2
4
  const strArr = (v) => Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined;
3
5
  const obj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) ? v : undefined;
@@ -135,14 +137,51 @@ export function handsMountedFromManifest(manifest) {
135
137
  const rows = roster.entries.filter((e) => e.mountedBy === 'hands').length;
136
138
  return rows > 0 ? { kind: 'mounted', rows } : { kind: 'not-mounted' };
137
139
  }
138
- export function handsMountedDetail(reading) {
139
- switch (reading.kind) {
140
+ export function handsSeamReadingOf(view) {
141
+ const seam = typeof view === 'object' && view !== null ? projectHandsSection(view) : undefined;
142
+ if (seam === undefined)
143
+ return { kind: 'not_reported' };
144
+ if (seam.mounted)
145
+ return { kind: 'mounted' };
146
+ return seam.reason !== undefined ? { kind: 'not_mounted', reason: seam.reason } : { kind: 'not_mounted' };
147
+ }
148
+ const HANDS_NONE_STEM = 'this leg of the run was assembled with NO built-in file-and-shell tools';
149
+ const HANDS_NONE_TAIL = "so on this leg the model had no tool of the engine's own for editing files or running commands (tools mounted by other conditions, such as external servers, and sub-runs delegated to other legs are not covered by this reading)";
150
+ const HANDS_REASON_DISPLAY_MAX = 64;
151
+ const HANDS_NOT_REPORTED_SENTENCE = 'whether this leg has built-in file-and-shell tools is not stated here — the engine did not report its hands seam (older engines and servers, and the static half of a manifest, never do); the tool roster may still answer it';
152
+ export function handsSeamDetail(reading) {
153
+ const kind = typeof reading === 'object' && reading !== null ? reading.kind : undefined;
154
+ switch (kind) {
140
155
  case 'mounted':
141
- return `this run was assembled with file-and-shell tools mounted (${reading.rows} of them)`;
156
+ return 'this leg of the run was assembled with its built-in file tools mounted — the engine says so; whether a shell is reachable is answered by the tool roster, not by this statement';
157
+ case 'not_mounted': {
158
+ const raw = reading.reason;
159
+ const reason = typeof raw === 'string' && raw.length > 0 ? raw : undefined;
160
+ const why = reason === undefined
161
+ ? 'the engine states it mounted no hands on this leg (it gave no reason)'
162
+ : reason === HANDS_REASON_NO_EXECUTION_ENV
163
+ ? 'the engine states it mounted no hands on this leg because no execution environment was supplied'
164
+ : `the engine states it mounted no hands on this leg (reason: ${displayUntrusted(reason, { max: HANDS_REASON_DISPLAY_MAX })}, a word this build does not know)`;
165
+ return `${HANDS_NONE_STEM} — ${why}, ${HANDS_NONE_TAIL}`;
166
+ }
167
+ default:
168
+ return HANDS_NOT_REPORTED_SENTENCE;
169
+ }
170
+ }
171
+ export function handsMountedDetail(reading) {
172
+ const r = reading;
173
+ const kind = typeof r === 'object' && r !== null ? r.kind : undefined;
174
+ switch (kind) {
175
+ case 'mounted': {
176
+ const rows = r.rows;
177
+ if (typeof rows === 'number' && Number.isInteger(rows) && rows > 0)
178
+ return `this run was assembled with file-and-shell tools mounted (${rows} of them)`;
179
+ return HANDS_NOT_REPORTED_SENTENCE;
180
+ }
142
181
  case 'not-mounted':
143
- return 'this leg of the run was assembled with NO built-in file-and-shell tools — the engine reports a roster and not one row was mounted by that condition, so on this leg the model had no tool of the engine\'s own for editing files or running commands (tools mounted by other conditions, such as external servers, and sub-runs delegated to other legs are not covered by this reading)';
182
+ return `${HANDS_NONE_STEM} — the engine reports a roster and not one row was mounted by that condition, ${HANDS_NONE_TAIL}`;
144
183
  case 'unknown':
145
- switch (reading.why) {
184
+ switch (r.why) {
146
185
  case 'no-manifest':
147
186
  return 'whether this run has file-and-shell tools is unknown — no assembly manifest was observed for it';
148
187
  case 'no-roster':
@@ -152,7 +191,9 @@ export function handsMountedDetail(reading) {
152
191
  case 'mount-condition-absent':
153
192
  return 'whether this run has file-and-shell tools is unknown — this engine does not report which condition mounted each tool, so an empty count here would be a fact about the reader, not about the run';
154
193
  }
194
+ return HANDS_NOT_REPORTED_SENTENCE;
155
195
  }
196
+ return HANDS_NOT_REPORTED_SENTENCE;
156
197
  }
157
198
  export function toolRosterNames(roster) {
158
199
  return roster?.entries.map((e) => e.name) ?? [];
@@ -45,10 +45,6 @@ export function isPreStreamDrainingReject(err) {
45
45
  const e = err;
46
46
  return typeof e?.status === 'number' && e.status === 503 && e.errorCode === DRAINING_ERROR_CODE;
47
47
  }
48
- const RESUME_AT_TEXT_COMPAT = [
49
- { status: 404, marker: `(${RESUME_AT_ERROR_CODE_PREFIX}unknown_event)` },
50
- { status: 422, marker: `(${RESUME_AT_ERROR_CODE_PREFIX}no_session)` },
51
- ];
52
48
  export function effectiveWireErrorCode(err) {
53
49
  if (typeof err !== 'object' || err === null)
54
50
  return undefined;
@@ -75,14 +71,8 @@ export function corruptStoredRowContent(where) {
75
71
  return `The engine could not read a stored record this session needs in order to continue. The unreadable row is ${capForDisplay(where, 200)}; whoever operates this engine has to repair or remove that row before this session can continue.`;
76
72
  }
77
73
  export function isResumeAtRejection(err) {
78
- const e = err;
79
74
  const code = effectiveWireErrorCode(err);
80
- if (code !== undefined && code.startsWith(RESUME_AT_ERROR_CODE_PREFIX))
81
- return true;
82
- const marker = RESUME_AT_TEXT_COMPAT.find((c) => c.status === e?.status)?.marker;
83
- if (marker === undefined)
84
- return false;
85
- return [e?.message, e?.errorMessage].some((t) => typeof t === 'string' && t.endsWith(marker));
75
+ return code !== undefined && code.startsWith(RESUME_AT_ERROR_CODE_PREFIX);
86
76
  }
87
77
  export function drainingRetryDelayMs(err, attempt, opts) {
88
78
  const ra = err?.retryAfterMs;
@@ -240,7 +240,8 @@ function synthPhaseStatus(runStatus, agents) {
240
240
  }
241
241
  export function projectWorkflowRun(run) {
242
242
  const parks = readWorkflowParks(run);
243
- const agents = (run.agents ?? []).map((r, i) => projectAgent(r, i));
243
+ const agentsKnown = Array.isArray(run.agents);
244
+ const agents = (agentsKnown ? run.agents : []).map((r, i) => projectAgent(r, i));
244
245
  const phases = projectPhases(run, agents);
245
246
  const validTokens = (v) => typeof v === 'number' && Number.isInteger(v) && v >= 0 ? v : undefined;
246
247
  const ownTokens = validTokens(run.stats?.tokens);
@@ -265,7 +266,7 @@ export function projectWorkflowRun(run) {
265
266
  ...(parks !== undefined ? { parks } : {}),
266
267
  ...(readWorkflowResumeAdmissionIncomplete(run) ? { resumeAdmissionIncomplete: true } : {}),
267
268
  script: '',
268
- agentCount: agents.length,
269
+ ...(agentsKnown ? { agentCount: agents.length } : {}),
269
270
  ...(totalTokens !== undefined ? { totalTokens } : {}),
270
271
  phases,
271
272
  };
@@ -814,7 +815,7 @@ export function createLiveWorkflowSource(config) {
814
815
  code = null;
815
816
  lastError = null;
816
817
  if (engineWireDebugEnabled()) {
817
- hostLog('debug', `[sema][workflow][perf] get ${Date.now() - t0}ms first=${first} agents=${current.agentCount} phases=${current.phases.length}`);
818
+ hostLog('debug', `[sema][workflow][perf] get ${Date.now() - t0}ms first=${first} agents=${current.agentCount ?? '?'} phases=${current.phases.length}`);
818
819
  }
819
820
  first = false;
820
821
  notify();
@@ -49,7 +49,7 @@ export interface WorkflowRunState {
49
49
  scriptPath?: string;
50
50
  status: 'running' | 'done' | 'failed' | 'stopped' | 'paused' | 'parked' | 'unknown';
51
51
  cloud?: boolean;
52
- agentCount: number;
52
+ agentCount?: number;
53
53
  totalTokens?: number;
54
54
  phases: WorkflowPhase[];
55
55
  parks?: readonly WorkflowParkRowView[];