@sema-agent/client-core 0.100.0 → 0.101.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 +395 -0
- package/README.md +164 -117
- package/dist/adapt/arms.js +51 -16
- package/dist/adapt/textStream.js +7 -4
- package/dist/adapt/toolCards.js +9 -8
- package/dist/adapt.js +7 -1
- package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
- package/dist/adapter/activeRunSelfHeal.js +108 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +33 -12
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
- package/dist/adapter/runStream.d.ts +4 -4
- package/dist/adapter/runStream.js +158 -43
- package/dist/agentsWireCaps.d.ts +2 -7
- package/dist/agentsWireCaps.js +1 -2
- package/dist/approvalDecidedByCapability.js +2 -2
- package/dist/approvalFrameFamilies.d.ts +33 -0
- package/dist/approvalFrameFamilies.js +120 -0
- package/dist/approvalsStreamLiveCapability.js +2 -2
- package/dist/attachmentsWireCaps.js +41 -13
- package/dist/callerCwdCapability.js +2 -2
- package/dist/centerWiringCapability.js +2 -2
- package/dist/clockReading.d.ts +2 -0
- package/dist/clockReading.js +4 -0
- package/dist/cloudConfigWireCaps.d.ts +19 -5
- package/dist/cloudConfigWireCaps.js +193 -56
- package/dist/coreValuePorts.d.ts +12 -2
- package/dist/coreValuePorts.js +9 -0
- package/dist/decideFailureNote.js +5 -3
- package/dist/decideReceipt.js +2 -2
- package/dist/deviceExecutorManagementCapability.js +2 -2
- package/dist/deviceFlowPolling.js +1 -1
- package/dist/disableSkillsWire.d.ts +1 -1
- package/dist/disableSkillsWire.js +4 -3
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +65 -8
- package/dist/engineCapReader.js +1 -1
- package/dist/engineConfigDrift.js +1 -1
- package/dist/engineErrorCodes.d.ts +14 -5
- package/dist/engineErrorCodes.js +27 -6
- package/dist/engineGenerationConvergence.d.ts +39 -0
- package/dist/engineGenerationConvergence.js +95 -0
- package/dist/engineGenerationPort.d.ts +61 -0
- package/dist/engineGenerationPort.js +144 -0
- package/dist/engineHealthFacts.d.ts +23 -0
- package/dist/engineHealthFacts.js +92 -0
- package/dist/engineIdentity.d.ts +4 -0
- package/dist/engineIdentity.js +11 -0
- package/dist/engineNoticeCodes.d.ts +2 -5
- package/dist/engineRowRef.js +3 -0
- package/dist/engineSessionMessages.js +2 -2
- package/dist/engineToolDirectory.js +2 -2
- package/dist/engineWireFor.d.ts +99 -0
- package/dist/engineWireFor.js +248 -6
- package/dist/engineWireTarget.d.ts +1 -0
- package/dist/engineWireTarget.js +8 -0
- package/dist/env/uiLanguage.js +1 -1
- package/dist/errorSupplementRoles.d.ts +3 -0
- package/dist/errorSupplementRoles.js +37 -0
- package/dist/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.js +3 -3
- package/dist/finalVerifyWire.d.ts +6 -3
- package/dist/finalVerifyWire.js +6 -23
- package/dist/flagInput.d.ts +4 -0
- package/dist/flagInput.js +24 -0
- package/dist/fleet/fleetLedger.js +5 -2
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +15 -2
- package/dist/gateVocabulary.js +3 -0
- package/dist/generated/engineFactTables.d.ts +7 -3
- package/dist/generated/engineFactTables.js +52 -0
- package/dist/generated/engineNoticeTables.js +12 -0
- package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
- package/dist/generated/settingsSchemaActiveTiers.js +14 -0
- package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
- package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
- package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
- package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
- package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
- package/dist/generated/settingsSchemaDefaultModel.js +25 -0
- package/dist/generated/settingsSchemaFns.d.ts +54 -0
- package/dist/generated/settingsSchemaFns.js +26 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
- package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
- package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
- package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
- package/dist/generated/settingsSchemaSettingsSources.js +58 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +13 -0
- package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlPattern.js +183 -0
- package/dist/headlessPermissionModeWire.d.ts +18 -2
- package/dist/headlessPermissionModeWire.js +30 -19
- package/dist/hitl/allowRuleShadow.js +7 -5
- package/dist/hitl/approvalCardReading.d.ts +3 -0
- package/dist/hitl/approvalCardReading.js +17 -0
- package/dist/hitl/approvalCompleteParked.js +1 -1
- package/dist/hitl/approvalDelivery.d.ts +87 -0
- package/dist/hitl/approvalDelivery.js +193 -0
- package/dist/hitl/approvalResolution.d.ts +11 -0
- package/dist/hitl/approvalResolution.js +50 -11
- package/dist/hitl/askClassPair.d.ts +6 -0
- package/dist/hitl/askClassPair.js +30 -3
- package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
- package/dist/hitl/askParkAutoReopenBlock.js +117 -0
- package/dist/hitl/askParkRowRouting.js +4 -1
- package/dist/hitl/attributionLadder.d.ts +42 -3
- package/dist/hitl/attributionLadder.js +79 -8
- package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
- package/dist/hitl/automaticAnswerVerdict.js +46 -11
- package/dist/hitl/crashConverged.js +2 -2
- package/dist/hitl/decisionConflict.d.ts +6 -2
- package/dist/hitl/decisionConflict.js +24 -9
- package/dist/hitl/decisionRefusal.d.ts +20 -10
- package/dist/hitl/decisionRefusal.js +99 -54
- package/dist/hitl/decisionSend.d.ts +3 -0
- package/dist/hitl/decisionSend.js +87 -103
- package/dist/hitl/frameRouter.d.ts +1 -0
- package/dist/hitl/frameRouter.js +9 -2
- package/dist/hitl/hitlBridge.d.ts +18 -6
- package/dist/hitl/hitlBridge.js +41 -37
- package/dist/hitl/livePendingAsk.js +4 -3
- package/dist/hitl/noAllowCause.js +1 -1
- package/dist/hitl/parkResolver.js +3 -2
- package/dist/hitl/persistedRulesWire.js +1 -0
- package/dist/hitl/planReviewWire.d.ts +4 -0
- package/dist/hitl/planReviewWire.js +59 -30
- package/dist/hitl/resumeRunningCard.d.ts +3 -2
- package/dist/hitl/resumeRunningCard.js +17 -11
- package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
- package/dist/hitl/sessionPolicyDeliverable.js +62 -29
- package/dist/hitl/sessionPolicyWire.d.ts +13 -3
- package/dist/hitl/sessionPolicyWire.js +81 -16
- package/dist/hitl/standingRows.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +9 -10
- package/dist/hitl/toolApprovalWire.js +72 -54
- package/dist/hookMatcherVerdict.d.ts +2 -0
- package/dist/hookMatcherVerdict.js +12 -0
- package/dist/hooksCompactTransition.d.ts +19 -0
- package/dist/hooksCompactTransition.js +41 -0
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +202 -203
- package/dist/host.d.ts +1 -14
- package/dist/host.js +0 -8
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +1 -1
- package/dist/hostSettingsSource.d.ts +172 -0
- package/dist/hostSettingsSource.js +675 -0
- package/dist/hostTurnSettings.d.ts +73 -17
- package/dist/hostTurnSettings.js +594 -97
- package/dist/httpHookPolicy.d.ts +37 -0
- package/dist/httpHookPolicy.js +176 -0
- package/dist/humanTurn.d.ts +2 -1
- package/dist/humanTurn.js +37 -7
- package/dist/humanTurnRead.js +4 -3
- package/dist/humanTurnSentences.d.ts +10 -0
- package/dist/humanTurnSentences.js +74 -0
- package/dist/i18n/messages.en.d.ts +184 -2
- package/dist/i18n/messages.en.js +187 -5
- package/dist/i18n/messages.zh.js +197 -5
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +69 -15
- package/dist/index.js +45 -13
- package/dist/inheritEnvCapability.d.ts +3 -1
- package/dist/inheritEnvCapability.js +31 -17
- package/dist/inheritEnvWire.d.ts +2 -1
- package/dist/inheritEnvWire.js +11 -5
- package/dist/interactiveToolsWire.d.ts +4 -2
- package/dist/interactiveToolsWire.js +5 -5
- package/dist/jsonFaithful.d.ts +20 -0
- package/dist/jsonFaithful.js +152 -0
- package/dist/limitsWire.d.ts +7 -2
- package/dist/limitsWire.js +19 -13
- package/dist/liveInitToolFace.d.ts +6 -1
- package/dist/liveInitToolFace.js +5 -3
- package/dist/liveModelCatalog.d.ts +22 -0
- package/dist/liveModelCatalog.js +132 -18
- package/dist/mcpPanel.js +1 -1
- package/dist/mcpProbeCapability.js +2 -2
- package/dist/mcpStatusSupersetKeys.d.ts +24 -0
- package/dist/mcpStatusSupersetKeys.js +45 -0
- package/dist/mcpToolToggles.js +2 -1
- package/dist/mcpWireCaps.d.ts +39 -1
- package/dist/mcpWireCaps.js +254 -50
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/model/catalogDefault.d.ts +24 -0
- package/dist/model/catalogDefault.js +4 -0
- package/dist/model/liveCatalogShape.js +5 -4
- package/dist/model/modelsPolicy.js +4 -3
- package/dist/model/onboardJudgement.d.ts +1 -0
- package/dist/model/onboardJudgement.js +1 -1
- package/dist/model/subagentModelWord.js +2 -2
- package/dist/modelCapabilityProbe.js +6 -6
- package/dist/modelIdentityResolvability.d.ts +10 -1
- package/dist/modelIdentityResolvability.js +62 -39
- package/dist/modsKernelIdentity.d.ts +10 -0
- package/dist/modsKernelIdentity.js +103 -0
- package/dist/modsKernelTransit.d.ts +8 -0
- package/dist/modsKernelTransit.js +6 -0
- package/dist/notifications.d.ts +30 -12
- package/dist/notifications.js +241 -53
- package/dist/outputStyleSeatCapability.js +2 -2
- package/dist/ownKey.d.ts +11 -0
- package/dist/ownKey.js +164 -3
- package/dist/panelReduce.js +1 -1
- package/dist/peerFrames.d.ts +1 -1
- package/dist/peerFrames.js +6 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.js +4 -4
- package/dist/permissionRuleIssue.js +2 -0
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionsAllowGrantCapability.js +2 -2
- package/dist/permissionsDeclaration.d.ts +43 -4
- package/dist/permissionsDeclaration.js +102 -35
- package/dist/pluginHooksWire.d.ts +20 -4
- package/dist/pluginHooksWire.js +92 -53
- package/dist/prepareRefusal.d.ts +3 -2
- package/dist/prepareRefusal.js +27 -9
- package/dist/printInitToolFace.js +2 -2
- package/dist/printModelStatus.js +1 -1
- package/dist/projectMemory.d.ts +32 -0
- package/dist/projectMemory.js +70 -0
- package/dist/promptBlockedCopy.d.ts +2 -1
- package/dist/promptBlockedCopy.js +2 -1
- package/dist/promptDelivery.d.ts +23 -3
- package/dist/promptDelivery.js +169 -30
- package/dist/providerRejection.d.ts +19 -1
- package/dist/providerRejection.js +75 -4
- package/dist/queuedDelivery.d.ts +48 -0
- package/dist/queuedDelivery.js +233 -0
- package/dist/reattachWindow.d.ts +94 -0
- package/dist/reattachWindow.js +127 -0
- package/dist/request/printNotification.d.ts +1 -1
- package/dist/request/printNotification.js +5 -1
- package/dist/request/submissionIdentity.d.ts +37 -0
- package/dist/request/submissionIdentity.js +65 -0
- package/dist/request/taskRequest.d.ts +12 -4
- package/dist/request/taskRequest.js +221 -152
- package/dist/resultFrameKeys.d.ts +1 -0
- package/dist/resultFrameKeys.js +4 -1
- package/dist/retryStatus.d.ts +8 -0
- package/dist/retryStatus.js +57 -9
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/rewindEngineAction.d.ts +2 -0
- package/dist/rewindEngineAction.js +23 -1
- package/dist/rowKind.d.ts +36 -0
- package/dist/rowKind.js +97 -0
- package/dist/ruleCompileVerdict.d.ts +18 -0
- package/dist/ruleCompileVerdict.js +67 -2
- package/dist/ruleReadings.d.ts +58 -0
- package/dist/ruleReadings.js +132 -0
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +9 -3
- package/dist/runCancelContext.d.ts +0 -1
- package/dist/runCancelContext.js +1 -2
- package/dist/runTerminal.d.ts +5 -0
- package/dist/runTerminal.js +52 -17
- package/dist/sandboxWire.d.ts +1 -1
- package/dist/sandboxWire.js +4 -6
- package/dist/scenarioRefusal.js +1 -1
- package/dist/scenarioSkills.d.ts +20 -0
- package/dist/scenarioSkills.js +72 -0
- package/dist/scenarioWire.d.ts +5 -2
- package/dist/scenarioWire.js +9 -9
- package/dist/sealedKeyCapability.js +2 -2
- package/dist/seam.d.ts +2 -0
- package/dist/seam.js +2 -2
- package/dist/seatContract.d.ts +46 -1
- package/dist/seatContract.js +49 -19
- package/dist/selfOrchestrationDenial.js +1 -1
- package/dist/sessionPolicyCapability.js +2 -2
- package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
- package/dist/sessionRulesChildrenReadLive.js +5 -0
- package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
- package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
- package/dist/sessionSyncFileHistoryCapability.js +2 -2
- package/dist/settingsCredentialKeyPaths.js +60 -5
- package/dist/settingsHooksSalvage.d.ts +1 -0
- package/dist/settingsHooksSalvage.js +7 -1
- package/dist/settingsLayerAdmission.d.ts +4 -0
- package/dist/settingsLayerAdmission.js +16 -0
- package/dist/skillToolListsCapability.js +6 -5
- package/dist/skillsWireCaps.d.ts +14 -0
- package/dist/skillsWireCaps.js +47 -16
- package/dist/slashCommandGate.d.ts +24 -0
- package/dist/slashCommandGate.js +74 -0
- package/dist/slashCommandTable.d.ts +14 -0
- package/dist/slashCommandTable.js +99 -0
- package/dist/sqlEngineCapability.js +2 -2
- package/dist/steerPriorityCapability.js +2 -2
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/agentStateDetail.js +1 -1
- package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
- package/dist/subagent/engineDelegatedPrompt.js +38 -7
- package/dist/subagent/engineRowStopGate.js +2 -2
- package/dist/subagent/engineSubagentResume.js +3 -3
- package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
- package/dist/subagent/engineTaskHandleWire.js +10 -0
- package/dist/submitFailure.d.ts +8 -0
- package/dist/submitFailure.js +17 -0
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +7 -0
- package/dist/terminationIntent.d.ts +55 -0
- package/dist/terminationIntent.js +352 -0
- package/dist/toolHistoryMismatch.d.ts +8 -0
- package/dist/toolHistoryMismatch.js +37 -6
- package/dist/toolResult.d.ts +13 -3
- package/dist/toolResult.js +158 -9
- package/dist/toolResultContent.d.ts +13 -0
- package/dist/toolResultContent.js +82 -7
- package/dist/toolRoster.d.ts +18 -0
- package/dist/toolRoster.js +64 -0
- package/dist/turnFailurePresentation.js +27 -90
- package/dist/usageLimitAutoResume.d.ts +74 -0
- package/dist/usageLimitAutoResume.js +227 -0
- package/dist/userAttachmentEnvelope.js +1 -1
- package/dist/userAttachmentSeat.js +5 -5
- package/dist/userInvokedSkillsCapability.js +2 -2
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/wireErrorTriage.js +99 -50
- package/dist/wireFailureShape.d.ts +25 -1
- package/dist/wireFailureShape.js +92 -5
- package/dist/wireRefusalCopy.d.ts +24 -1
- package/dist/wireRefusalCopy.js +253 -32
- package/dist/wiringFleetDoctor.d.ts +3 -0
- package/dist/wiringFleetDoctor.js +21 -0
- package/dist/workflow.d.ts +2 -1
- package/dist/workflow.js +38 -1
- package/dist/workflowClient.d.ts +2 -7
- package/dist/workflowsJournalCapability.js +2 -2
- package/dist/writeProtectionCapability.js +2 -2
- package/docs/INTEGRATION-CLIENTS.md +607 -181
- package/package.json +14 -3
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import { appendOwnElement, readOwnDataValue } from '../ownKey.js';
|
|
1
2
|
import { refuseBadDisableSkills, refuseDisableSkillsConflict } from '../disableSkillsWire.js';
|
|
2
3
|
import { ATTACHMENTS_SPEC_KEYS, AttachmentsSpecRefused } from '../attachmentsWireCaps.js';
|
|
3
4
|
import { retiredAttachmentsKeyOf } from '../taskRequestWords.js';
|
|
4
5
|
import { msg, renderMessage } from '../i18n/translate.js';
|
|
6
|
+
import { PROJECT_MEMORY_DISABLED } from '../projectMemory.js';
|
|
7
|
+
import { frameFamiliesJudgementOf } from '../approvalFrameFamilies.js';
|
|
5
8
|
import { outputStyleSeatAdmitted } from '../outputStyleSeatCapability.js';
|
|
6
9
|
import { refuseBadApprovalReach } from '../approvalReachWire.js';
|
|
7
|
-
import { HOST_SUPPLIED_KEYS,
|
|
10
|
+
import { HOST_SUPPLIED_KEYS, UNWIRED_HOST_TURN_SETTINGS, buildHostTurnSettings, hostIntakeSnapshotOf, hostFileHistoryRestoreNotice, hostProjectionNotice, hostTurnSettingsOf, intersectHostHooks, rethrowHostResolvedDeferred, hostSettingsRefusedError, } from '../hostTurnSettings.js';
|
|
11
|
+
import { SUBMISSION_ORIGINS, SUBMISSION_SURFACES, SUBMISSION_TOOLS, submissionAxesOf, } from './submissionIdentity.js';
|
|
12
|
+
import { withAssemblyRefusal } from '../wireFailureShape.js';
|
|
13
|
+
import { isPlainRecord, materializeJsonFaithful, shapeTag } from '../jsonFaithful.js';
|
|
8
14
|
export const REQUEST_FIELD_MATRIX = [
|
|
9
15
|
{ field: 'objective', lanes: ['interactive', 'print', 'utility'], live: false, why: '本 turn 的真实输入,每条车道都必需', whyUtilityLane: '恒座:三条车道都必须带上本次提交的模型面输入' },
|
|
10
16
|
{ field: 'sessionId', lanes: ['interactive', 'print', 'utility'], live: false, why: '单命名空间(TP-A Step 2):壳 id 即引擎 session id;print 在非 live 下保留 mock 常量', whyUtilityLane: '恒座:side-channel 提交走**独立**会话 id(壳另铸一个,绝不复用用户会话那一个 —— 复用会把这次提交的转录混进用户会话)' },
|
|
@@ -18,15 +24,17 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
18
24
|
{ field: 'enableFork', lanes: ['interactive', 'print'], live: true, why: '显式布尔才 stamp([503]② fail-OPEN 教训:off 必须显式)', whyUtilityLane: '无座:分叉是会话面的动作,而 side-channel 提交是一次性的独立会话' },
|
|
19
25
|
{ field: 'attachments', lanes: ['interactive', 'print'], live: true, why: 'design/133 + G1 缺省开的 turn 边界 attachment', whyUtilityLane: '无座:turn 边界的附件配置属用户会话;side-channel 提交不带附件' },
|
|
20
26
|
{ field: 'skills', lanes: ['interactive', 'print'], live: true, why: '本地技能目录投影(布局取 CC 同款);两条车道都由 launchRepl 载入面注入', whyUtilityLane: '无座:技能挂的是工具,与零工具面矛盾' },
|
|
21
|
-
{ field: 'userInvokedSkills', lanes: ['interactive', 'print'], live: true, why: '人用名字点过的技能(sdk `TaskRequest.userInvokedSkills`:非空串数组;这些技能的 allowedTools / disallowedTools 开跑即生效、不出技能卡,只管这一次 run)。两条用户车道都有「人敲 /技能名」的入口 ⇒ 都有座。🔴 放宽方向:值只经片段口给(能力读数 present 才给键);空数组 = 没点名 ⇒ 不 stamp;坏形(不是串数组)装配期响亮拒;名字对不对归引擎判(`config.user_invoked_skill_unknown`)', whyUtilityLane: '无座:技能挂的是工具,与零工具面矛盾(与 skills 一行同理)' },
|
|
27
|
+
{ field: 'userInvokedSkills', lanes: ['interactive', 'print'], live: true, why: '人用名字点过的技能(sdk `TaskRequest.userInvokedSkills`:非空串数组;这些技能的 allowedTools / disallowedTools 开跑即生效、不出技能卡,只管这一次 run)。两条用户车道都有「人敲 /技能名」的入口 ⇒ 都有座。🔴 放宽方向:值只经片段口给(能力读数 present 才给键);空数组 = 没点名 ⇒ 不 stamp;坏形(不是串数组)装配期响亮拒;名字对不对归引擎判(`config.user_invoked_skill_unknown`)', whyUtilityLane: '无座:技能挂的是工具,与零工具面矛盾(与 skills 一行同理)', origins: ['user'], whyOriginLimited: '只给用户所写的提交:点名的技能是用户本人敲名字点的(放宽方向:点名即生效、不出技能卡);注入件与客户端自发的旁路提交不许借用户的点名放宽这一次的工具面' },
|
|
22
28
|
{ field: 'mcpServers', lanes: ['interactive', 'print'], live: true, why: '本地 .mcp.json 投影;service 单用户门决定是否兑现', whyUtilityLane: '无座:MCP 服务挂的是工具,与零工具面矛盾' },
|
|
23
29
|
{ field: 'settings.webSearch', lanes: ['interactive', 'print'], live: true, why: 'SEMA_WEBSEARCH_* / settings.json;per-request 配置赢过部署 env', whyUtilityLane: '无座:联网检索是一只工具,与零工具面矛盾' },
|
|
24
30
|
{ field: 'settings.hooks', lanes: ['interactive', 'print'], live: true, why: '[495]① 用户 settings 文件 hooks 逐字上 wire', whyUtilityLane: '无座:hook 挂在工具门上(零工具面没有门),而且 side-channel 是壳自己的提交,不该继承用户那份 hook 表' },
|
|
31
|
+
{ field: 'settings.approvalFrameFamilies', lanes: ['interactive', 'print'], live: true, why: '这条运行的客户端渲得了哪些审批开卡帧族的**逐运行声明**(服务端提交体 `settings.approvalFrameFamilies`:词数组,值族闭集 tool_approval / approval_request;一条运行只在声明含服务端呈的那一族时才开审批卡,不含 ⇒ 问当场交无人值守政策口、不出卡)。两条用户车道都有审批腿(交互面出卡答人;`-p` 面交宿主的审批口),都得声明;🔴 只在能力读数 confirmed(受理位 `taskSettings.approvalFrameFamilies` 恒真 ∧ 值族位合格)时由装配口自己铸,老服务端(受理位缺席)对表外 settings 子键整条 400', whyUtilityLane: '无座:side-channel 强制零工具面(`excludeAllTools`),没有门控调用、不会问审批 ⇒ 声明没有对象;带上它只会在不认识这一键的老服务端上给这条提交多一种 400' },
|
|
25
32
|
{ field: 'settings.<resolved>', lanes: ['interactive', 'print'], live: true, why: 'settings resolver 的 effective 快照(hooks/env/model + 已解析权限投影)。两条车道同源:交互面 replEntry / print 面 printModeEngine 各跑一遍同一个 resolver,产物经同一个 buildWireSettingsStamp 投影。开放集(子键不可枚举)⇒ unregisteredRequestKeys 放行本车道 settings 的**表外**子键,但表内异车道子键仍点名', whyUtilityLane: '无座:这一位是**开放集 spread**(子键原样即 wire 键),摊开的是用户 settings 的已解析面(权限 / env / 模型)。side-channel 是壳自己的提交:摊上去既无用(零工具面没有工具门求值权限)又把用户的配置面带进了一条他没参与的提交。🔴 无座 ⇒ 本车道整只快照不产。🔴 **本行无座的前提由构造期校验兜住**:剥掉的是用户显式的 deny / ask,所以 `refuseUtilityWithoutToolUnload` 强制这条车道必须带字面 `excludeAllTools: true` —— 否则产出会是一条「既没卸工具、又没带用户 deny」的请求(比无人值守车道同一份输入更宽)' },
|
|
26
33
|
{ field: 'repo', lanes: ['interactive', 'print'], live: true, why: 'scan/code-review 场景的仓库坐标(passthrough;server 是权威校验方,本层不铸第二判官)', whyUtilityLane: '无座:场景键;side-channel 不走场景' },
|
|
27
34
|
{ field: 'memoryCapture', lanes: ['interactive', 'print', 'utility'], live: true, why: '本会话永远不进长期记忆的**声明形**(server §12.4 body 键,单成员闭集 "off");每条车道都是提交面 ⇒ 都能声明。与 memoryWrite:false 不是一个轴(那是「本 run 只读平面」)。⚠️ parked 续跑腿结构性拿不到声明(决策/续跑端点从持久 body 重建 spec),那是引擎侧事实,不是本层的漏', whyUtilityLane: '有座:side-channel 提交是壳自己的一次性问答,**绝不该**进用户的长期记忆 —— 这一位正是那句声明,且它是收紧方向,带上去只会更严' },
|
|
28
35
|
{ field: 'memory', lanes: ['interactive', 'print', 'utility'], live: true, why: '这一次运行不挂记忆面的**请求级**开关(server §12.7 body 键,单成员闭集 "off");每条车道都是提交面 ⇒ 都能声明。与 memoryCapture(采集面)不是一个轴、可并存;与 memoryWrite:false(只读平面)也不是一个轴', whyUtilityLane: '有座:side-channel 提交不需要挂记忆面(不挂记忆段 / 索引 / 三只记忆工具),省 token 且零记忆写入;与 memoryCapture 不是一个轴,两条都带' },
|
|
29
|
-
{ field: 'fileHistory', lanes: ['interactive', 'print'], live: true, why: '「这一次运行别捕获文件历史」的**请求级声明**(server 7.104.0 提交体键,单成员闭集 "disabled";`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs` 同收,子代继承)。两条用户车道都是提交面、都跑在用户的文件上 ⇒ 都能声明;「本会话不捕获」= 每个提交都带(续跑腿重放同一个体)。🔴 只在能力读数 `on-optional` 时发(老 server 对表外键 400)
|
|
36
|
+
{ field: 'fileHistory', lanes: ['interactive', 'print'], live: true, why: '「这一次运行别捕获文件历史」的**请求级声明**(server 7.104.0 提交体键,单成员闭集 "disabled";`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs` 同收,子代继承)。两条用户车道都是提交面、都跑在用户的文件上 ⇒ 都能声明;「本会话不捕获」= 每个提交都带(续跑腿重放同一个体)。🔴 只在能力读数 `on-optional` 时发(老 server 对表外键 400),值由装配产物 `fileHistory` 行铸出(AS-4)。与 rewind 还原键同交 ⇒ 上游 400 `request.field_conflict`', whyUtilityLane: '无座:side-channel 强制零工具面(`excludeAllTools`),不会改任何文件 ⇒ 没有可捕获的东西;带上它只会在不认识这一键的老 server 上给这条提交多一种 400' },
|
|
37
|
+
{ field: 'projectMemory', lanes: ['interactive', 'print', 'utility'], live: true, why: '「这一次运行别读部署的项目上下文(项目指令文件与项目层)」的**请求级声明**(core 7.55.0 `TaskSpec.projectMemory`,单成员闭集 "disabled";子代继承、续跑腿重放同一个体)。三条车道都是提交面、引擎对每一条都会调部署的项目上下文座 ⇒ 都能声明(关闭是收紧方向;不关的车道会把项目指令文件递给模型)。缺席 = 座照常读 = 不带键,本层不铸 "on"。🔴 宿主经见位才发的片段口取值,服务端能力位 `projectMemory` 为真才给键(老服务端对表外顶层键整条 400)', whyUtilityLane: '有座:side-channel 提交虽然零工具面,引擎仍对它调部署的项目上下文座;壳在「不读项目指令文件」的模式(`--safe-mode` / `--bare`)下,这一条旁路提交也不该把项目指令文件带给模型 —— 这一位是收紧方向,带上去只会更严(与 memory / memoryCapture 同理由)' },
|
|
30
38
|
{ field: 'inheritEnv', lanes: ['interactive', 'print'], live: true, why: '模型驱动的宿主 shell「继承多少用户环境」的**请求级声明**(server 7.106.0 提交体键,两词闭集 "all" / "scrub";`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs` 同收,续跑腿重放同判)。两条用户车道都是提交面、都可能在用户机器上跑 shell ⇒ 都能声明。本层两词原样透传、不按车道 / 部署预判(非 host 车道 × "all" 400、托管 × "all" 422 归上游判)。🔴 缺席 = 缺省清洗且清掉本会话上一条声明 ⇒ 要「本会话整份继承」就每个提交都带。🔴 只在服务端版本 ≥ 7.106.0 时发(老 server 对表外键整条 400),值由片段口 `inheritEnvDeclaration` 唯一铸出', whyUtilityLane: '无座:side-channel 强制零工具面(`excludeAllTools`),没有模型驱动的 shell 去继承环境;带上它只会在不认这一键的老服务端上给这条提交多一种 400' },
|
|
31
39
|
{ field: 'requireExistingSession', lanes: ['interactive', 'print'], live: true, why: '「只续已有会话」的**请求级断言**(sdk `TaskRequest.requireExistingSession`):`true` 且会话不在 ⇒ 服务端在任何东西跑起来之前拒(会话不在 / 没给会话 id 两形),而**不是**静默新开一个同 id 的空会话;缺席 / `false` = 历史的「找不到就新开」。两条用户车道都有「续某个会话」的入口 ⇒ 都能声明。本层只认字面 `true`(`false` 与缺席同义、不发);非布尔坏值响亮拒(上游对它 400);`true` 而入参没有可续的会话 id ⇒ 装配期按名响亮拒,不留给上游。上游两形的拒绝经 `requireExistingSessionRefusalFromError` 归成一句', whyUtilityLane: '无座:side-channel 每一次提交都走壳另铸的**独立**会话 id(见 sessionId 那一行),从不续任何已有会话 ⇒「必须已存在」对它没有意义,带上去只会让每一次提交都被拒' },
|
|
32
40
|
{ field: 'disableSkills', lanes: ['interactive', 'print'], live: true, why: '「这一发一只技能都不装」的**请求级声明**(出厂技能、调用方给的技能、子代定义里的技能一个都不进引擎;其余工具照挂 —— 与 excludeAllTools 是两件事,两键同带各自生效)。两条用户车道都是提交面 ⇒ 都能声明。本层只认字面 true(false 与缺席同义、不发);非布尔坏值响亮拒(上游对它 400);与非空 skills 或任一非空 agents[].skills 同在 ⇒ 装配期按名响亮拒(上游对这一组合 400),兜底层落 agents 之后同判。🔴 只在能力位读数为真时发(老服务端对表外键整条 400),值由片段口 disableSkillsDeclaration 唯一铸出', whyUtilityLane: '无座:同 skills 一行 —— side-channel 是零工具面,装不装技能都无从谈起' },
|
|
@@ -38,7 +46,7 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
38
46
|
{ field: 'outputRetries', lanes: ['print', 'utility'], live: true, why: '结构化输出的重试轮数(sdk `TaskRequest.outputRetries`;与 `outputSchema` 是**成对旋钮** —— 没有 schema 时引擎忽略它)。🔴 座位集与 `outputSchema` 那一行**逐字相同**:一半有座一半没座 = 端调得动重试轮数却调不动它所服务的约束(同座孪生分开定座,正是「主轴改了、孪生漏了」那一族)。上游接受域很窄(有限、≥1、向下取整、封顶 10),**表外一律整键省略**并回落引擎缺省 ⇒ 本层对坏值**响亮拒**(见 `refuseBadOutputRetries`),但**不预夹** [1,10]:夹是上游的事,本层不铸第二判官', whyUtilityLane: '有座:与 outputSchema 同座孪生 —— side-channel 要机读小答案时,重试轮数是同一个旋钮的另一半' },
|
|
39
47
|
{ field: 'maxCostUsd', lanes: ['print', 'utility'], live: true, why: '花费上限声明(sdk `TaskRequest.maxCostUsd`,请求体**顶层**位;上游向下夹到部署上限 —— 只许要得更少)。与 `limits` 同一条理由只在无人值守车道:交互面由人随时中断。🔴 坏值(非数 / 非有限 / 非正)在本层**响亮拒**:上游对这一位的坏值是安静忽略并回落部署上限,不是 4xx(见 `refuseBadMaxCostUsd`)', whyUtilityLane: '有座:小预算是本车道的定义之一(与 limits 同一条理由);上游向下夹到部署上限,只许要得更少' },
|
|
40
48
|
{ field: 'maxTokens', lanes: ['print', 'utility'], live: true, why: '整任务 token 预算上限声明(sdk `TaskRequest.maxTokens`,请求体**顶层**位,与 `maxCostUsd` 同属上游那一族「调用方要求的上限」:向下夹到部署上限 —— 只许要得更少)。🔴 座位集与 `maxCostUsd` 那一行**逐字相同**:同一条预算轴的两种计价单位,分开定座就是让其中一条静默漂。🔴 坏值(非数 / 非有限 / 非正 / 非整)在本层**响亮拒**:上游对这一位的坏值是安静按「调用方没给」处理并回落部署上限,不是 4xx —— 部署没设上限时这一次运行就没有 token 闸,而声明人不会知道(见 `refuseBadMaxTokens`)', whyUtilityLane: '有座:与 maxCostUsd 同轴孪生 —— 小预算是本车道的定义之一,两种计价单位都该能声明' },
|
|
41
|
-
{ field: 'attachmentIds', lanes: ['interactive'], live: true, why: '附件**字节通道**(uploadAttachment 回执 id;server ≥1.289 绑定会话并把文件物化进 run 的 attachments/)。有上传入口的端才有 id 可引用:web/desktop 有,壳走 images / 本地文件路径,`-p` 车道连 uploadAttachment 都没有 ⇒ print 缺席是**没有来源**,不是漏。🔴 与上面的 `attachments` 同名不同物(那是 turn 边界的配置键),两条永远不许合并', whyUtilityLane: '无座:预上传附件句柄要先有上传入口才有 id 可引用,而 side-channel 没有上传面' },
|
|
49
|
+
{ field: 'attachmentIds', lanes: ['interactive'], live: true, why: '附件**字节通道**(uploadAttachment 回执 id;server ≥1.289 绑定会话并把文件物化进 run 的 attachments/)。有上传入口的端才有 id 可引用:web/desktop 有,壳走 images / 本地文件路径,`-p` 车道连 uploadAttachment 都没有 ⇒ print 缺席是**没有来源**,不是漏。🔴 与上面的 `attachments` 同名不同物(那是 turn 边界的配置键),两条永远不许合并', whyUtilityLane: '无座:预上传附件句柄要先有上传入口才有 id 可引用,而 side-channel 没有上传面', origins: ['user'], whyOriginLimited: '只给用户所写的提交:上传件句柄是用户本人上传、挂在这一条消息上的文件;注入件与客户端自发的旁路提交不带用户的上传件(带上去 = 把用户的文件交给一条不是他写的提交)' },
|
|
42
50
|
{ field: 'excludeTools', lanes: ['interactive', 'print', 'utility'], live: true, why: 'design/161 W3(2026-07-30):真 wire 键(SDK types `excludeTools`)且早在 seatContract `START_SESSION_OPTION_KEYS` 里,却是 desktop 手写 taskReq 的第 9 键、矩阵外——而 stamp 门对未登记键**静默丢弃**,真实危险形=「用户显式排除的工具被静默放回」(权限方向回归,类型层不报)。今天只有 desktop 在发;壳的工具面走 roster/interactiveTools 另一条路。0.77.0 补 print 座(三问:① wire 位与车道无关 —— sdk 具名位、提交体真收 `body.excludeTools`;② 来源 —— print 今天没有排除入口,但这是**收紧方向**的声明,传了只进回执 = 端不读回执就把用户排除的工具放回;③ 口径 —— 仍是 live 门后的位,与交互面同一行)', whyUtilityLane: '有座:逐名排除是卸载声明旁边的第二条收紧声明(两键同带各自生效)。⚠️ 它**不是** excludeAllTools 的降级替身 —— 本车道强制带卸载声明(见 `refuseUtilityWithoutToolUnload`),不认那一键的上游会把整条提交拒掉,那时正解是换车道或不发' },
|
|
43
51
|
{ field: 'allowTools', lanes: ['interactive', 'print'], live: true, why: '引擎的可用性选择器(收紧方向的声明:只给点名的工具;`[]` = 什么都不给,照发)。两条用户车道都是提交面、都有「只给这几只工具」的用户入口(终端 `--tools`)⇒ 都有座;坏形(不是串数组)在装配期响亮拒,不静默删键', whyUtilityLane: '无座:side-channel 恒带 excludeAllTools(零工具面),可用性选择器在零工具面上没有可选的东西' },
|
|
44
52
|
{ field: 'excludeAllTools', lanes: ['interactive', 'print', 'utility'], live: true, why: '0.78.0(sdk 11.x 具名位 `excludeAllTools`,server ≥7.90.0 请求面):整只工具面卸载 —— 调用方工具 / 脚手架 / 手 / MCP / A2A / skills 一个都不挂,终局必然纯文本(wire 上 `wiring_manifest.tools.count === 0`,整条流零 tool_start / tool_end / tool_disclosure)。与 excludeTools 是两种语义、刻意不折叠(`"*"` 是一个合法的工具名,「卸全部」不能写成 `excludeTools:["*"]`);两键同带各自生效。类型只收字面 `true`(server 只把 literal true 写上任务规格,`false` = 替引擎重申它自己的缺省 ⇒ 不发、与缺席同义、不进回执);坏值响亮拒(收紧方向的声明不许被打字错误安静丢掉)。每条车道都是提交面 ⇒ 都能声明。探测靠键闭集、没有能力位:没接线的 server(≤7.89.x)400 `request.body_shape` 并在 `unknownKeys` 里逐字点名,本层不替它猜;A2A 入站面不承载本键(零工具面走 skill 路由)', whyUtilityLane: '有座,而且**本车道强制**:零工具面就是这条车道的定义 —— side-channel 提交整只工具面卸载,终局必然纯文本。🔴 缺这一位(或给 `false`)⇒ 构造期响亮拒(`refuseUtilityWithoutToolUnload`):本车道上一整片「无座」的理由都压在这个前提上,其中 `settings.<resolved>` 那一行剥掉的是用户显式的 deny / ask ——前提不成立时产出会是一条「既没卸工具、又没带用户 deny」的请求' },
|
|
@@ -46,8 +54,8 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
46
54
|
{ field: 'systemPrompt', lanes: ['interactive', 'print', 'utility'], live: false, why: '整段替换系统提示(sdk `TaskRequest.systemPrompt`;上游字符数超限 400 响亮拒,本层原样透传)。三条车道都有来源:交互面 = CC QueryParams.systemPrompt,无人值守面 = `--system-prompt[-file]` 一类旗,side-channel 面 = 壳整段给出的那一份。与追加位 `appendSystemPrompt` 不是一个位(那一位归 live 兜底层,见 `LIVE_DEFAULT_FIELDS`)', whyUtilityLane: '有座:side-channel 提交的系统提示由壳整段给出 —— 它不是用户会话的续谈,不该继承用户那一份' },
|
|
47
55
|
{ field: 'reasoningEffort', lanes: ['interactive', 'print', 'utility'], live: false, why: '思考档位(sdk `TaskRequest.reasoningEffort` 七词闭集;上游对表外词 400 响亮拒 ⇒ 本层不预铸第二判官)。档位是请求级的位、与车道无关:交互面 = `/effort` 拨盘,无人值守面 = 档位旗。🔴 端交的必须是**档位词**:「思考 token 数」今天没有上游对位(见 `UPSTREAM_ABSENT_REQUEST_INTENTS` 的 `maxThinkingTokens`),别把一个数字折成档位词发出去', whyUtilityLane: '有座:side-channel 该用显式低档(省钱省时);与 model 同一条理由 —— 本车道上这两位都由壳显式给,不跟用户会话的拨盘走' },
|
|
48
56
|
{ 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` 拨盘走)' },
|
|
49
|
-
{ field: 'images', lanes: ['interactive', 'print'], live: false, why: '图片输入(sdk `TaskRequest.images`;base64 / url 两形,原样透传)。两条用户车道都是提交面、都有来源:交互面 = 粘贴图与 `@` 图片像素,一次性车道 = 结构化输入里的图片块。张数、单张与合计的座位判定归人类提交装配口 `encodeHumanTurn`(两条车道同一份判定,本表不另判);请求体与图片张数的上限归上游判', whyUtilityLane: '无座:贴图是交互动作,side-channel 的提交体里没有图片块' },
|
|
50
|
-
{ field: 'userAttachments', lanes: ['interactive', 'print'], live: false, why: '请求层附件(sdk `TaskRequest.userAttachments`:挂在这次提交目标上的 `@` 文本类附件条目,引擎铸帧、在第一次模型调用之前判形)。两条用户车道都是提交面、都经同一只装配口 `encodeHumanTurn`(条目只在这台引擎的席位读数判 `yes` 时出;老服务端对这一键 400,所以没有条目就不发);空数组 = 没带附件 ⇒ 整键不 stamp。座位集与 `images` 一行逐字相同', whyUtilityLane: '无座:side-channel 是壳自己的一次性提交,没有用户 `@` 附件' },
|
|
57
|
+
{ field: 'images', lanes: ['interactive', 'print'], live: false, why: '图片输入(sdk `TaskRequest.images`;base64 / url 两形,原样透传)。两条用户车道都是提交面、都有来源:交互面 = 粘贴图与 `@` 图片像素,一次性车道 = 结构化输入里的图片块。张数、单张与合计的座位判定归人类提交装配口 `encodeHumanTurn`(两条车道同一份判定,本表不另判);请求体与图片张数的上限归上游判', whyUtilityLane: '无座:贴图是交互动作,side-channel 的提交体里没有图片块', origins: ['user'], whyOriginLimited: '只给用户所写的提交:图片是用户本人贴进 / 点名进这一条消息的内容;注入件(计划复核结局等)与客户端自发的旁路提交没有用户贴的图片,带上去就是把别处的图片当成这一发的输入' },
|
|
58
|
+
{ field: 'userAttachments', lanes: ['interactive', 'print'], live: false, why: '请求层附件(sdk `TaskRequest.userAttachments`:挂在这次提交目标上的 `@` 文本类附件条目,引擎铸帧、在第一次模型调用之前判形)。两条用户车道都是提交面、都经同一只装配口 `encodeHumanTurn`(条目只在这台引擎的席位读数判 `yes` 时出;老服务端对这一键 400,所以没有条目就不发);空数组 = 没带附件 ⇒ 整键不 stamp。座位集与 `images` 一行逐字相同', whyUtilityLane: '无座:side-channel 是壳自己的一次性提交,没有用户 `@` 附件', origins: ['user'], whyOriginLimited: '只给用户所写的提交:请求层附件是用户本人 `@` 进这一条消息的附件;注入件与客户端自发的旁路提交不带用户的附件' },
|
|
51
59
|
{ 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 是一次性的独立会话,没有可回退的历史' },
|
|
52
60
|
{ field: 'clientContext', lanes: ['interactive'], live: false, why: 'IANA 时区 + 可选邮箱 → core 本地化 `# Environment` 的 today;print 同样跑在用户机器上,缺席让引擎误标 (UTC)', gap: true, whyUtilityLane: '无座:本地化 today 的用途在用户会话的环境段,而 side-channel 的系统提示由壳整段给出 —— 这一列我判不准要不要(与本行 `gap` 同一条待办:要补先单独立项)' },
|
|
53
61
|
{ field: 'scratchpadDir', lanes: ['interactive'], live: true, why: '[816]③ per-session 暂存目录;print 也有 session,缺席让 `-p` 的工具写不进 exemptDir', gap: true, whyUtilityLane: '无座:per-session 暂存目录是给**工具**写的,零工具面上没人写' },
|
|
@@ -70,12 +78,14 @@ export const TASK_REQUEST_OMISSION_CAUSES = Object.freeze([
|
|
|
70
78
|
'upstream_absent',
|
|
71
79
|
'other_channel',
|
|
72
80
|
'off_lane',
|
|
81
|
+
'off_origin',
|
|
73
82
|
'not_live',
|
|
74
83
|
]);
|
|
75
84
|
const TASK_REQUEST_OMISSION_CAUSE_SENTENCES = Object.freeze({
|
|
76
85
|
upstream_absent: 'this build knows the intent but the engine has no request field for it, so nothing was sent and nothing will be until that field exists upstream — retire the knob, or wait for the upstream field',
|
|
77
86
|
other_channel: 'this is a real request field, but the request assembler never sets it — it belongs to the live-defaults layer, so hand the value to that layer instead of to the assembler',
|
|
78
87
|
off_lane: 'this request lane has no seat for the key, so the value was not sent — the lane table records why that lane does not carry it; submit on a lane that seats it, or stop passing it here',
|
|
88
|
+
off_origin: 'the key has a seat on this lane, but not for the origin of this submission, so the value was not sent — the lane table records which origins carry it and why; pass it only on a submission whose origin is listed there, or stop passing it here',
|
|
79
89
|
not_live: 'the key has a seat on this lane but only reaches the wire on a live submission, and this submission was not live — nothing is wrong here: a mock or fixture submission keeps its request shape fixed',
|
|
80
90
|
});
|
|
81
91
|
export function taskRequestOmissionCauseDetail(cause) {
|
|
@@ -98,6 +108,10 @@ const TASK_REQUEST_OMISSION_CAUSE_NOTICE_PARTS = Object.freeze({
|
|
|
98
108
|
lead: 'Not sent with this request',
|
|
99
109
|
reason: 'this kind of request does not carry this setting, so giving it or leaving it out makes no difference to what this request sends',
|
|
100
110
|
},
|
|
111
|
+
off_origin: {
|
|
112
|
+
lead: 'Not sent with this request',
|
|
113
|
+
reason: 'the request was marked as not written by a person (for example an automatic follow-up), and this setting is only sent with requests a person writes themselves',
|
|
114
|
+
},
|
|
101
115
|
not_live: {
|
|
102
116
|
lead: 'Not sent with this request',
|
|
103
117
|
reason: 'the request was marked as not going to a live engine (for example an offline or test run), and this setting is only sent on requests that go to one',
|
|
@@ -169,12 +183,14 @@ const INPUT_KEY_ROUTES = {
|
|
|
169
183
|
},
|
|
170
184
|
memoryCapture: row('memoryCapture'),
|
|
171
185
|
inheritEnv: row('inheritEnv'),
|
|
186
|
+
projectMemory: row('projectMemory'),
|
|
172
187
|
requireExistingSession: row('requireExistingSession'),
|
|
173
188
|
disableSkills: row('disableSkills'),
|
|
174
189
|
rewind: row('resumeAt/resumeAtMode/restoreFiles/rewindFilesTo'),
|
|
175
190
|
repo: row('repo'),
|
|
176
191
|
allowTools: row('allowTools'),
|
|
177
192
|
hostSettings: { via: 'control' },
|
|
193
|
+
approvalFrameFamiliesReading: { via: 'control' },
|
|
178
194
|
settings: { via: 'settings' },
|
|
179
195
|
};
|
|
180
196
|
const HOST_TOP_KEY_ROUTES = {
|
|
@@ -184,15 +200,19 @@ const HOST_TOP_KEY_ROUTES = {
|
|
|
184
200
|
const HOST_TOP_KEYS = Object.freeze(Object.keys(HOST_TOP_KEY_ROUTES));
|
|
185
201
|
const _hostTopKeysPin = [true];
|
|
186
202
|
void _hostTopKeysPin;
|
|
203
|
+
const _projectMemoryWordPin = [true, true];
|
|
204
|
+
void _projectMemoryWordPin;
|
|
187
205
|
const HOST_TOP_ASK_AFTER = 'memoryCapture';
|
|
188
206
|
const HOST_SETTINGS_SUBKEYS = Object.freeze(HOST_SUPPLIED_KEYS.filter((k) => k.startsWith('settings.')).map((k) => k.slice('settings.'.length)));
|
|
189
|
-
const
|
|
207
|
+
const MINTED_SETTINGS_SUBKEYS = Object.freeze(['approvalFrameFamilies']);
|
|
208
|
+
const _hostSubkeysPin = [true, true, true, true];
|
|
190
209
|
void _hostSubkeysPin;
|
|
191
210
|
const SETTINGS_KEY_ROUTES = {
|
|
192
211
|
resolved: row('settings.<resolved>'),
|
|
193
212
|
webSearch: row('settings.webSearch'),
|
|
194
213
|
ultracode: row('settings.ultracode'),
|
|
195
214
|
hooks: row('settings.hooks'),
|
|
215
|
+
approvalFrameFamilies: row('settings.approvalFrameFamilies'),
|
|
196
216
|
outputStyle: { via: 'always' },
|
|
197
217
|
};
|
|
198
218
|
export const UPSTREAM_ABSENT_REQUEST_INTENTS = Object.freeze(Object.entries(INPUT_KEY_ROUTES).flatMap(([key, route]) => route.via === 'fixed' && route.cause === 'upstream_absent' ? [Object.freeze({ key, why: route.why })] : []));
|
|
@@ -226,10 +246,11 @@ const OMISSION_JUDGES = {
|
|
|
226
246
|
upstream_absent: s => s.via === 'fixed' && s.cause === 'upstream_absent',
|
|
227
247
|
other_channel: s => s.via === 'fixed' && s.cause === 'other_channel',
|
|
228
248
|
off_lane: (s, lane) => s.via === 'matrix' && !s.spec.lanes.includes(lane),
|
|
249
|
+
off_origin: (s, _lane, _live, origin) => s.via === 'matrix' && origin !== undefined && s.spec.origins !== undefined && !s.spec.origins.includes(origin),
|
|
229
250
|
not_live: (s, _lane, live) => s.via === 'matrix' && s.spec.live && !live,
|
|
230
251
|
};
|
|
231
|
-
const omissionCauseOf = (s, lane, live) => TASK_REQUEST_OMISSION_CAUSES.find(cause => OMISSION_JUDGES[cause](s, lane, live));
|
|
232
|
-
const hostRefusalNoticeOf = (intake, lane, live) => {
|
|
252
|
+
const omissionCauseOf = (s, lane, live, origin) => TASK_REQUEST_OMISSION_CAUSES.find(cause => OMISSION_JUDGES[cause](s, lane, live, origin));
|
|
253
|
+
const hostRefusalNoticeOf = (intake, lane, live, origin) => {
|
|
233
254
|
const verdictNotice = intake.notice ?? hostProjectionNotice();
|
|
234
255
|
try {
|
|
235
256
|
const refusing = intake.refusingKeys;
|
|
@@ -238,7 +259,7 @@ const hostRefusalNoticeOf = (intake, lane, live) => {
|
|
|
238
259
|
const turnNotices = intake.turnNotices;
|
|
239
260
|
const aligned = turnNotices !== undefined && turnNotices.length === refusing.length;
|
|
240
261
|
for (const [i, key] of refusing.entries()) {
|
|
241
|
-
if (!hostRefuseRowSeated(key, lane, live))
|
|
262
|
+
if (!hostRefuseRowSeated(key, lane, live, origin))
|
|
242
263
|
continue;
|
|
243
264
|
return aligned ? (turnNotices[i] ?? verdictNotice) : verdictNotice;
|
|
244
265
|
}
|
|
@@ -248,10 +269,10 @@ const hostRefusalNoticeOf = (intake, lane, live) => {
|
|
|
248
269
|
return verdictNotice;
|
|
249
270
|
}
|
|
250
271
|
};
|
|
251
|
-
const hostRefuseRowSeated = (key, lane, live) => {
|
|
272
|
+
const hostRefuseRowSeated = (key, lane, live, origin) => {
|
|
252
273
|
if (hasOwn(HOST_TOP_KEY_ROUTES, key)) {
|
|
253
274
|
const top = HOST_TOP_KEY_ROUTES[key];
|
|
254
|
-
return top === undefined || (top.via !== 'matrix' && top.via !== 'fixed') || omissionCauseOf(standingOf(top), lane, live) === undefined;
|
|
275
|
+
return top === undefined || (top.via !== 'matrix' && top.via !== 'fixed') || omissionCauseOf(standingOf(top), lane, live, origin) === undefined;
|
|
255
276
|
}
|
|
256
277
|
if (!key.startsWith('settings.'))
|
|
257
278
|
return true;
|
|
@@ -262,7 +283,7 @@ const hostRefuseRowSeated = (key, lane, live) => {
|
|
|
262
283
|
if (route === undefined || route.via === 'always')
|
|
263
284
|
return true;
|
|
264
285
|
if (route.via === 'matrix' || route.via === 'fixed')
|
|
265
|
-
return omissionCauseOf(standingOf(route), lane, live) === undefined;
|
|
286
|
+
return omissionCauseOf(standingOf(route), lane, live, origin) === undefined;
|
|
266
287
|
return true;
|
|
267
288
|
};
|
|
268
289
|
const REQUEST_LANE_SET = { interactive: true, print: true, utility: true };
|
|
@@ -273,6 +294,60 @@ const refuseBadLane = (lane) => {
|
|
|
273
294
|
throw new TypeError(`buildTaskRequest: 车道实参只接受 ${Object.keys(REQUEST_LANE_SET).map(l => `'${l}'`).join(' / ')} —— 收到 ${coarseShape(lane)}。` +
|
|
274
295
|
'表外的车道词会让车道表里每一行都判「不属于本车道」,请求体只剩 objective 与 sessionId 而没有任何信号,所以在装配前拒。错误文本只报形状,不回显值。');
|
|
275
296
|
};
|
|
297
|
+
const laneAxesOf = (arg, port) => {
|
|
298
|
+
if (typeof arg !== 'object' || arg === null) {
|
|
299
|
+
refuseBadLane(arg);
|
|
300
|
+
return { lane: arg, origin: undefined };
|
|
301
|
+
}
|
|
302
|
+
const axes = submissionAxesOf(arg);
|
|
303
|
+
if (axes !== undefined)
|
|
304
|
+
return axes;
|
|
305
|
+
let shape;
|
|
306
|
+
try {
|
|
307
|
+
shape = coarseShape(arg);
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
shape = 'typeof=object / unreadable';
|
|
311
|
+
}
|
|
312
|
+
const err = new TypeError(renderMessage(msg('config.taskRequest.submissionIdentityMalformed', {
|
|
313
|
+
shape,
|
|
314
|
+
lanes: REQUEST_LANES.join(' / '),
|
|
315
|
+
surfaces: SUBMISSION_SURFACES.join(' / '),
|
|
316
|
+
origins: SUBMISSION_ORIGINS.join(' / '),
|
|
317
|
+
tools: SUBMISSION_TOOLS.join(' / '),
|
|
318
|
+
})));
|
|
319
|
+
throw port === 'assembly' ? withAssemblyRefusal(err, 'input_malformed') : err;
|
|
320
|
+
};
|
|
321
|
+
const originAxisFaultOf = (origins, why, lanes) => {
|
|
322
|
+
if (origins === undefined)
|
|
323
|
+
return '写了 whyOriginLimited 却没写 origins(理由没有对象)';
|
|
324
|
+
if (typeof why !== 'string' || why.length === 0)
|
|
325
|
+
return '写了 origins 却没写 whyOriginLimited(来源受限必须带理由)';
|
|
326
|
+
if (!Array.isArray(origins) || origins.length === 0)
|
|
327
|
+
return 'origins 不是非空数组';
|
|
328
|
+
if (!origins.every((o) => SUBMISSION_ORIGINS.includes(o)) || new Set(origins).size !== origins.length) {
|
|
329
|
+
return 'origins 里有出身闭集外的词或重复词';
|
|
330
|
+
}
|
|
331
|
+
if (origins.length === SUBMISSION_ORIGINS.length)
|
|
332
|
+
return 'origins 是全集(与缺省同义:两种写法说同一件事,删掉这一位)';
|
|
333
|
+
if (!origins.includes('user'))
|
|
334
|
+
return 'origins 不含 user(成因 off_origin 的终端用户句说「这一发被标成不是人写的」,对这一行会是假话;真有这种行时先加成因词与句子)';
|
|
335
|
+
if (!origins.includes('shell') && lanes.includes('utility'))
|
|
336
|
+
return 'origins 排除壳出身却占 utility 座(身份形派生到 utility 必是壳出身,那个座永远到不了)';
|
|
337
|
+
return undefined;
|
|
338
|
+
};
|
|
339
|
+
const refuseOriginAxisDrift = () => {
|
|
340
|
+
for (const r of REQUEST_FIELD_MATRIX) {
|
|
341
|
+
const origins = r.origins;
|
|
342
|
+
const why = r.whyOriginLimited;
|
|
343
|
+
if (origins === undefined && why === undefined)
|
|
344
|
+
continue;
|
|
345
|
+
const fault = originAxisFaultOf(origins, why, r.lanes);
|
|
346
|
+
if (fault === undefined)
|
|
347
|
+
continue;
|
|
348
|
+
throw new Error(`buildTaskRequest: 车道表 REQUEST_FIELD_MATRIX 的「${r.field}」一行来源轴不自洽 —— ${fault}。这是本包内部缺陷,不是调用方入参的问题。`);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
276
351
|
const present = (v) => v !== undefined && v !== null;
|
|
277
352
|
const rewindSubKeys = () => {
|
|
278
353
|
const r = INPUT_KEY_ROUTES.rewind;
|
|
@@ -290,6 +365,7 @@ const VALUE_LEVEL_IN_PLAY = Object.freeze({
|
|
|
290
365
|
memoryCapture: (v) => v === 'off',
|
|
291
366
|
memory: (v) => v === 'off',
|
|
292
367
|
fileHistory: (v) => v === FILE_HISTORY_DISABLED,
|
|
368
|
+
projectMemory: (v) => v === PROJECT_MEMORY_DISABLED,
|
|
293
369
|
requireExistingSession: (v) => v === true,
|
|
294
370
|
disableSkills: (v) => v === true,
|
|
295
371
|
rewind: (v) => typeof v === 'object' && v !== null && rewindSubKeys().some((k) => hasOwn(v, k) && present(v[k])),
|
|
@@ -304,15 +380,16 @@ const snapshotByName = (source, keys, seed = {}) => {
|
|
|
304
380
|
const UNKNOWN_KEY_DISPLAY_MAX = 64;
|
|
305
381
|
const MAX_UNKNOWN_KEYS_SHOWN = 16;
|
|
306
382
|
const keyForDisplay = (k) => k.length > UNKNOWN_KEY_DISPLAY_MAX ? `${JSON.stringify(k.slice(0, UNKNOWN_KEY_DISPLAY_MAX))}(已截短)` : JSON.stringify(k);
|
|
307
|
-
export function taskRequestSeatOf(key,
|
|
308
|
-
|
|
383
|
+
export function taskRequestSeatOf(key, laneOrIdentity) {
|
|
384
|
+
const { lane, origin } = laneAxesOf(laneOrIdentity, 'seat');
|
|
385
|
+
refuseOriginAxisDrift();
|
|
309
386
|
const route = typeof key === 'string' ? routeOfInputKey(key) : undefined;
|
|
310
387
|
if (route === undefined)
|
|
311
388
|
return SEAT_UNKNOWN;
|
|
312
389
|
if (route.via === 'always' || route.via === 'control' || route.via === 'settings')
|
|
313
390
|
return SEATED_UNGATED;
|
|
314
391
|
const standing = standingOf(route);
|
|
315
|
-
const cause = omissionCauseOf(standing, lane, true);
|
|
392
|
+
const cause = omissionCauseOf(standing, lane, true, origin);
|
|
316
393
|
if (cause !== undefined && cause !== 'not_live')
|
|
317
394
|
return Object.freeze({ seat: 'none', cause });
|
|
318
395
|
return standing.via === 'matrix' && standing.spec.live ? SEATED_LIVE_GATED : SEATED_UNGATED;
|
|
@@ -324,99 +401,6 @@ const foreignSettingsSubKeys = (lane) => REQUEST_FIELD_MATRIX.filter(f => f.fiel
|
|
|
324
401
|
const namedSettingsSubKeys = () => REQUEST_FIELD_MATRIX.filter(f => f.field.startsWith('settings.') && f.field !== 'settings.<resolved>').map(f => f.field.slice('settings.'.length));
|
|
325
402
|
const PERMISSION_FACE_KEY = 'permissions';
|
|
326
403
|
const coarseShape = (v) => v === null ? 'typeof=object / null' : Array.isArray(v) ? 'typeof=object / array' : `typeof=${typeof v}`;
|
|
327
|
-
const shapeTag = (v) => {
|
|
328
|
-
try {
|
|
329
|
-
const proto = Object.getPrototypeOf(v);
|
|
330
|
-
const carrier = proto === null
|
|
331
|
-
? 'null-prototype'
|
|
332
|
-
: String(proto?.constructor?.name ?? 'anonymous');
|
|
333
|
-
return `typeof=${typeof v} / ${Object.prototype.toString.call(v)} / prototype=${carrier}`;
|
|
334
|
-
}
|
|
335
|
-
catch {
|
|
336
|
-
return `typeof=${typeof v} / shape=unreadable`;
|
|
337
|
-
}
|
|
338
|
-
};
|
|
339
|
-
const isPlainRecord = (v) => {
|
|
340
|
-
if (typeof v !== 'object' || v === null)
|
|
341
|
-
return false;
|
|
342
|
-
const proto = Object.getPrototypeOf(v);
|
|
343
|
-
if (proto === null)
|
|
344
|
-
return true;
|
|
345
|
-
if (typeof proto !== 'object')
|
|
346
|
-
return false;
|
|
347
|
-
if (!Object.prototype.hasOwnProperty.call(proto, 'constructor'))
|
|
348
|
-
return false;
|
|
349
|
-
const ctor = proto.constructor;
|
|
350
|
-
if (typeof ctor !== 'function')
|
|
351
|
-
return false;
|
|
352
|
-
if (Function.prototype.toString.call(ctor) !== Function.prototype.toString.call(Object))
|
|
353
|
-
return false;
|
|
354
|
-
return ctor.prototype === proto;
|
|
355
|
-
};
|
|
356
|
-
const materializeJsonFaithful = (v, path, seen = new Set()) => {
|
|
357
|
-
if (v === null)
|
|
358
|
-
return { value: null };
|
|
359
|
-
const t = typeof v;
|
|
360
|
-
if (t === 'string' || t === 'boolean')
|
|
361
|
-
return { value: v };
|
|
362
|
-
if (t === 'number') {
|
|
363
|
-
return Number.isFinite(v) ? { value: v } : { bad: `${path}(非有限数 ⇒ 序列化成 null)` };
|
|
364
|
-
}
|
|
365
|
-
if (t !== 'object')
|
|
366
|
-
return { bad: `${path}(typeof=${t} 不是 JSON 值)` };
|
|
367
|
-
const o = v;
|
|
368
|
-
if (seen.has(o))
|
|
369
|
-
return { bad: `${path}(循环引用)` };
|
|
370
|
-
const toJSONProp = o.toJSON;
|
|
371
|
-
if (typeof toJSONProp === 'function')
|
|
372
|
-
return { bad: `${path}(自报 toJSON ⇒ 字节被改写)` };
|
|
373
|
-
seen.add(o);
|
|
374
|
-
try {
|
|
375
|
-
if (Array.isArray(o)) {
|
|
376
|
-
const rawLen = o.length;
|
|
377
|
-
if (typeof rawLen === 'bigint' || typeof rawLen === 'symbol') {
|
|
378
|
-
return { bad: `${path}(length 是 ${typeof rawLen} ⇒ 原生序列化直接抛,归 0 会静默发空表)` };
|
|
379
|
-
}
|
|
380
|
-
let lenNum;
|
|
381
|
-
try {
|
|
382
|
-
lenNum = +rawLen;
|
|
383
|
-
}
|
|
384
|
-
catch {
|
|
385
|
-
return { bad: `${path}(length 按 ToNumber 转换即抛(BigInt/symbol 形)⇒ 原生序列化也抛,归 0 会静默发空表)` };
|
|
386
|
-
}
|
|
387
|
-
if (lenNum === Number.POSITIVE_INFINITY) {
|
|
388
|
-
return { bad: `${path}(length 是 +Infinity ⇒ 原生序列化抛 RangeError,归 0 会静默发空表)` };
|
|
389
|
-
}
|
|
390
|
-
const len = Number.isNaN(lenNum)
|
|
391
|
-
? 0
|
|
392
|
-
: Math.min(Math.max(0, Math.trunc(lenNum)), Number.MAX_SAFE_INTEGER);
|
|
393
|
-
const items = [];
|
|
394
|
-
for (let i = 0; i < len; i++) {
|
|
395
|
-
const r = materializeJsonFaithful(o[i], `${path}[${i}]`, seen);
|
|
396
|
-
if ('bad' in r)
|
|
397
|
-
return r;
|
|
398
|
-
items.push(r.value);
|
|
399
|
-
}
|
|
400
|
-
return { value: items };
|
|
401
|
-
}
|
|
402
|
-
const rec = Object.create(null);
|
|
403
|
-
for (const k of Object.keys(o)) {
|
|
404
|
-
const val = o[k];
|
|
405
|
-
if (val === undefined)
|
|
406
|
-
continue;
|
|
407
|
-
const r = materializeJsonFaithful(val, `${path}.${k}`, seen);
|
|
408
|
-
if ('bad' in r)
|
|
409
|
-
return r;
|
|
410
|
-
Object.defineProperty(rec, k, { value: r.value, enumerable: true, writable: true, configurable: true });
|
|
411
|
-
}
|
|
412
|
-
if (!isPlainRecord(o))
|
|
413
|
-
return { bad: `${path}(${shapeTag(o)})` };
|
|
414
|
-
return { value: rec };
|
|
415
|
-
}
|
|
416
|
-
finally {
|
|
417
|
-
seen.delete(o);
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
404
|
const resolvedSnapshotForWire = (resolved) => {
|
|
421
405
|
if (resolved === undefined || resolved === null)
|
|
422
406
|
return {};
|
|
@@ -461,6 +445,58 @@ const resolvedSnapshotForWire = (resolved) => {
|
|
|
461
445
|
export function hostTurnSettings(input) {
|
|
462
446
|
return buildHostTurnSettings(input, { materialize: (snapshot) => resolvedSnapshotForWire(snapshot), memoryOffDeclared });
|
|
463
447
|
}
|
|
448
|
+
const fileRestoreRequested = (restoreFiles, rewindFilesTo, rewindFiles) => restoreFiles === true || (typeof rewindFilesTo === 'string' && rewindFilesTo.length > 0) || rewindFiles === true;
|
|
449
|
+
function tightenedRequestOf(request, intake, lane) {
|
|
450
|
+
const readData = (key) => {
|
|
451
|
+
try {
|
|
452
|
+
if (!hasOwn(request, key))
|
|
453
|
+
return { ok: true, value: undefined };
|
|
454
|
+
const d = Object.getOwnPropertyDescriptor(request, key);
|
|
455
|
+
if (d === undefined)
|
|
456
|
+
return { ok: true, value: undefined };
|
|
457
|
+
if (!Object.hasOwn(d, 'value'))
|
|
458
|
+
return { ok: false };
|
|
459
|
+
if (d.enumerable !== true)
|
|
460
|
+
return { ok: true, value: undefined };
|
|
461
|
+
const got = request[key];
|
|
462
|
+
return got === d.value ? { ok: true, value: d.value } : { ok: false };
|
|
463
|
+
}
|
|
464
|
+
catch {
|
|
465
|
+
return { ok: false };
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
const unjudged = { kind: 'refuse', notice: hostProjectionNotice() };
|
|
469
|
+
const add = {};
|
|
470
|
+
const tightened = [];
|
|
471
|
+
if (intake.carried.memory === MEMORY_OFF && hostRefuseRowSeated('memory', lane, true)) {
|
|
472
|
+
const sent = readData('memory');
|
|
473
|
+
if (!sent.ok)
|
|
474
|
+
return unjudged;
|
|
475
|
+
if (sent.value !== MEMORY_OFF) {
|
|
476
|
+
add.memory = MEMORY_OFF;
|
|
477
|
+
appendOwnElement(tightened, 'memory');
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (intake.carried.fileHistory === FILE_HISTORY_DISABLED && hostRefuseRowSeated('fileHistory', lane, true)) {
|
|
481
|
+
const sent = readData('fileHistory');
|
|
482
|
+
if (!sent.ok)
|
|
483
|
+
return unjudged;
|
|
484
|
+
if (sent.value !== FILE_HISTORY_DISABLED) {
|
|
485
|
+
const restoreFiles = readData('restoreFiles');
|
|
486
|
+
const rewindFilesTo = readData('rewindFilesTo');
|
|
487
|
+
const rewindFiles = readData('rewindFiles');
|
|
488
|
+
if (!restoreFiles.ok || !rewindFilesTo.ok || !rewindFiles.ok)
|
|
489
|
+
return unjudged;
|
|
490
|
+
if (fileRestoreRequested(restoreFiles.value, rewindFilesTo.value, rewindFiles.value))
|
|
491
|
+
return { kind: 'refuse', notice: hostFileHistoryRestoreNotice() };
|
|
492
|
+
add.fileHistory = FILE_HISTORY_DISABLED;
|
|
493
|
+
appendOwnElement(tightened, 'fileHistory');
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (tightened.length === 0)
|
|
497
|
+
return { kind: 'ok', request, tightened: Object.freeze([]) };
|
|
498
|
+
return { kind: 'ok', request: { ...request, ...add }, tightened: Object.freeze(tightened) };
|
|
499
|
+
}
|
|
464
500
|
export function refilterHostSettings(request, fresh, lane) {
|
|
465
501
|
refuseBadLane(lane);
|
|
466
502
|
const host = hostTurnSettingsOf(fresh);
|
|
@@ -470,16 +506,21 @@ export function refilterHostSettings(request, fresh, lane) {
|
|
|
470
506
|
}
|
|
471
507
|
const refuseNotice = () => intake.notice ?? hostProjectionNotice();
|
|
472
508
|
if (intake.refuses) {
|
|
473
|
-
const refusing = hostRefusalNoticeOf(intake, lane, true);
|
|
509
|
+
const refusing = hostRefusalNoticeOf(intake, lane, true, undefined);
|
|
474
510
|
if (refusing !== undefined)
|
|
475
511
|
return Object.freeze({ kind: 'refuse', notice: refusing });
|
|
476
512
|
}
|
|
477
|
-
const
|
|
513
|
+
const tight = tightenedRequestOf(request, intake, lane);
|
|
514
|
+
if (tight.kind === 'refuse')
|
|
515
|
+
return Object.freeze({ kind: 'refuse', notice: tight.notice });
|
|
516
|
+
const base = tight.request;
|
|
517
|
+
const tightened = tight.tightened;
|
|
518
|
+
const settings = base.settings;
|
|
478
519
|
if (!isPlainRecord(settings) || !Object.hasOwn(settings, 'hooks'))
|
|
479
|
-
return Object.freeze({ kind: 'send', request, hooksDropped: 0 });
|
|
520
|
+
return Object.freeze({ kind: 'send', request: base, hooksDropped: 0, tightened });
|
|
480
521
|
const disposition = intake.dispositions['settings.hooks'];
|
|
481
522
|
if (disposition === 'unwired')
|
|
482
|
-
return Object.freeze({ kind: 'send', request, hooksDropped: 0 });
|
|
523
|
+
return Object.freeze({ kind: 'send', request: base, hooksDropped: 0, tightened });
|
|
483
524
|
const now = intake.carried.hooks;
|
|
484
525
|
const sentHooks = settings.hooks;
|
|
485
526
|
if (!isPlainRecord(sentHooks))
|
|
@@ -488,14 +529,14 @@ export function refilterHostSettings(request, fresh, lane) {
|
|
|
488
529
|
if (!cut.judged)
|
|
489
530
|
return Object.freeze({ kind: 'refuse', notice: refuseNotice() });
|
|
490
531
|
if (cut.dropped === 0)
|
|
491
|
-
return Object.freeze({ kind: 'send', request, hooksDropped: 0 });
|
|
532
|
+
return Object.freeze({ kind: 'send', request: base, hooksDropped: 0, tightened });
|
|
492
533
|
const { hooks: _sentHooks, ...restSettings } = settings;
|
|
493
534
|
void _sentHooks;
|
|
494
535
|
const nextSettings = cut.hooks === undefined ? restSettings : { ...restSettings, hooks: cut.hooks };
|
|
495
|
-
const { settings: _sentSettings, ...restRequest } =
|
|
536
|
+
const { settings: _sentSettings, ...restRequest } = base;
|
|
496
537
|
void _sentSettings;
|
|
497
538
|
const next = Object.keys(nextSettings).length > 0 ? { ...restRequest, settings: nextSettings } : restRequest;
|
|
498
|
-
return Object.freeze({ kind: 'send', request: next, hooksDropped: cut.dropped });
|
|
539
|
+
return Object.freeze({ kind: 'send', request: next, hooksDropped: cut.dropped, tightened });
|
|
499
540
|
}
|
|
500
541
|
export const MEMORY_CAPTURE_OFF = 'off';
|
|
501
542
|
export function memoryCaptureDeclarationField(declared) {
|
|
@@ -540,7 +581,7 @@ const withoutRetiredAttachmentsKeys = (v) => {
|
|
|
540
581
|
const d = Object.getOwnPropertyDescriptor(v, key);
|
|
541
582
|
if (d !== undefined && Object.prototype.hasOwnProperty.call(d, 'value') && d.value === undefined) {
|
|
542
583
|
;
|
|
543
|
-
(drop ??= [])
|
|
584
|
+
appendOwnElement((drop ??= []), key);
|
|
544
585
|
continue;
|
|
545
586
|
}
|
|
546
587
|
throw new AttachmentsSpecRefused(`buildTaskRequest: refusing attachments key ${JSON.stringify(key)} — ${why}`, { token: key, why, allowed: ATTACHMENTS_SPEC_KEYS, key });
|
|
@@ -559,7 +600,7 @@ function allowToolsSnapshot(v) {
|
|
|
559
600
|
return v;
|
|
560
601
|
let n;
|
|
561
602
|
try {
|
|
562
|
-
n =
|
|
603
|
+
n = readOwnDataValue(v, 'length');
|
|
563
604
|
}
|
|
564
605
|
catch {
|
|
565
606
|
return ALLOW_TOOLS_UNREADABLE_ITEM;
|
|
@@ -569,27 +610,31 @@ function allowToolsSnapshot(v) {
|
|
|
569
610
|
const out = new Array(n);
|
|
570
611
|
for (let k = 0; k < n; k += 1) {
|
|
571
612
|
let d;
|
|
613
|
+
let unreadable = false;
|
|
572
614
|
try {
|
|
573
615
|
d = Object.getOwnPropertyDescriptor(v, k);
|
|
574
616
|
}
|
|
575
617
|
catch {
|
|
576
|
-
|
|
577
|
-
continue;
|
|
618
|
+
unreadable = true;
|
|
578
619
|
}
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
|
|
620
|
+
if (unreadable)
|
|
621
|
+
defineOwnIndex(out, k, ALLOW_TOOLS_UNREADABLE_ITEM);
|
|
622
|
+
else if (d !== undefined)
|
|
623
|
+
defineOwnIndex(out, k, Object.hasOwn(d, 'value') ? d.value : ALLOW_TOOLS_UNREADABLE_ITEM);
|
|
582
624
|
}
|
|
583
625
|
return Object.freeze(out);
|
|
584
626
|
}
|
|
627
|
+
const defineOwnIndex = (list, k, value) => {
|
|
628
|
+
Object.defineProperty(list, k, { value, writable: true, enumerable: true, configurable: true });
|
|
629
|
+
};
|
|
585
630
|
const allowToolsCopy = (v) => {
|
|
586
631
|
if (!Array.isArray(v))
|
|
587
632
|
return [];
|
|
588
633
|
const out = [];
|
|
589
634
|
for (let k = 0; k < v.length; k += 1) {
|
|
590
635
|
const d = Object.getOwnPropertyDescriptor(v, k);
|
|
591
|
-
if (d !== undefined && 'value'
|
|
592
|
-
out
|
|
636
|
+
if (d !== undefined && Object.hasOwn(d, 'value') && typeof d.value === 'string')
|
|
637
|
+
appendOwnElement(out, d.value);
|
|
593
638
|
}
|
|
594
639
|
return out;
|
|
595
640
|
};
|
|
@@ -600,7 +645,7 @@ const refuseBadAllowTools = (v) => {
|
|
|
600
645
|
let ok = true;
|
|
601
646
|
for (let k = 0; k < v.length; k += 1) {
|
|
602
647
|
const d = Object.getOwnPropertyDescriptor(v, k);
|
|
603
|
-
if (d === undefined || !('value'
|
|
648
|
+
if (d === undefined || !Object.hasOwn(d, 'value') || typeof d.value !== 'string') {
|
|
604
649
|
ok = false;
|
|
605
650
|
break;
|
|
606
651
|
}
|
|
@@ -619,7 +664,7 @@ const refuseBadUserInvokedSkills = (v) => {
|
|
|
619
664
|
let ok = true;
|
|
620
665
|
for (let k = 0; k < v.length; k += 1) {
|
|
621
666
|
const d = Object.getOwnPropertyDescriptor(v, k);
|
|
622
|
-
if (d === undefined || !('value'
|
|
667
|
+
if (d === undefined || !Object.hasOwn(d, 'value') || typeof d.value !== 'string') {
|
|
623
668
|
ok = false;
|
|
624
669
|
break;
|
|
625
670
|
}
|
|
@@ -645,6 +690,15 @@ const refuseBadInheritEnv = (v) => {
|
|
|
645
690
|
'这一位是「模型驱动的宿主 shell 继承多少用户环境」的两词闭集声明,上游对词表外的值响亮拒;环境变量名单不是请求值。' +
|
|
646
691
|
'本层若静默删键,这一次运行会按缺省清洗跑、还清掉本会话上一条声明,而声明人不会知道。错误文本只报形状,不回显值。');
|
|
647
692
|
};
|
|
693
|
+
const refuseBadProjectMemory = (v) => {
|
|
694
|
+
if (v === undefined || v === null)
|
|
695
|
+
return;
|
|
696
|
+
if (v === PROJECT_MEMORY_DISABLED)
|
|
697
|
+
return;
|
|
698
|
+
throw new TypeError(`buildTaskRequest: projectMemory 只接受字面量 '${PROJECT_MEMORY_DISABLED}' 或缺席(undefined/null)—— 收到 ${coarseShape(v)}。` +
|
|
699
|
+
'这一位是「这一次运行别读部署的项目上下文」的收紧声明,引擎是**单成员闭集**(没有第二个词:要照常读就不带这一键)且对坏值拒启。' +
|
|
700
|
+
'本层若静默删键,请求会照发、项目指令文件会照常递给模型,而声明人不会知道自己的 opt-out 丢了。错误文本只报形状,不回显值。');
|
|
701
|
+
};
|
|
648
702
|
const refuseBadRequireExistingSession = (v) => {
|
|
649
703
|
if (v === undefined || v === null || v === true || v === false)
|
|
650
704
|
return;
|
|
@@ -733,7 +787,7 @@ export function parseMaxCostUsd(text) {
|
|
|
733
787
|
return { ok: false, why: 'not_positive' };
|
|
734
788
|
return { ok: true, value };
|
|
735
789
|
}
|
|
736
|
-
const ACCESSOR_READ_ORDER = ['live', 'memoryCapture', 'hostSettings', 'settings', 'maxCostUsd', 'excludeAllTools', 'maxTokens', 'outputRetries', 'inheritEnv', 'requireExistingSession', 'disableSkills', 'approvalReach', 'allowTools', 'userInvokedSkills'];
|
|
790
|
+
const ACCESSOR_READ_ORDER = ['live', 'memoryCapture', 'hostSettings', 'settings', 'maxCostUsd', 'excludeAllTools', 'maxTokens', 'outputRetries', 'inheritEnv', 'requireExistingSession', 'disableSkills', 'approvalReach', 'allowTools', 'userInvokedSkills', 'projectMemory'];
|
|
737
791
|
const MATERIALIZE_AT_READ = Object.freeze({ allowTools: (v) => allowToolsSnapshot(v), userInvokedSkills: (v) => allowToolsSnapshot(v) });
|
|
738
792
|
function dataFirstSnapshot(input, afterData) {
|
|
739
793
|
let descs;
|
|
@@ -749,10 +803,10 @@ function dataFirstSnapshot(input, afterData) {
|
|
|
749
803
|
const d = descs[k];
|
|
750
804
|
if (d === undefined || (d.enumerable !== true && routeOfTopLevelKey(k) === undefined))
|
|
751
805
|
continue;
|
|
752
|
-
if ('value'
|
|
806
|
+
if (Object.hasOwn(d, 'value'))
|
|
753
807
|
bag[k] = Object.hasOwn(MATERIALIZE_AT_READ, k) ? MATERIALIZE_AT_READ[k](d.value) : d.value;
|
|
754
808
|
else
|
|
755
|
-
accessors
|
|
809
|
+
appendOwnElement(accessors, k);
|
|
756
810
|
}
|
|
757
811
|
afterData?.(bag);
|
|
758
812
|
const ordered = [
|
|
@@ -765,8 +819,9 @@ function dataFirstSnapshot(input, afterData) {
|
|
|
765
819
|
}
|
|
766
820
|
return bag;
|
|
767
821
|
}
|
|
768
|
-
export function assembleTaskRequest(input,
|
|
769
|
-
|
|
822
|
+
export function assembleTaskRequest(input, laneOrIdentity) {
|
|
823
|
+
const { lane, origin } = laneAxesOf(laneOrIdentity, 'assembly');
|
|
824
|
+
refuseOriginAxisDrift();
|
|
770
825
|
let resolvedInEarly;
|
|
771
826
|
let resolvedMaterialized;
|
|
772
827
|
let resolvedMaterializeError;
|
|
@@ -809,7 +864,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
809
864
|
throw new TypeError(renderMessage(msg('config.taskRequest.hostSettingsMalformed', { shape: coarseShape(hostIn) })));
|
|
810
865
|
const resolvedIn = resolvedInEarly;
|
|
811
866
|
const resolvedRoute = SETTINGS_KEY_ROUTES.resolved;
|
|
812
|
-
const resolvedOpen = resolvedRoute.via === 'matrix' && omissionCauseOf(standingOf(resolvedRoute), lane, live) === undefined;
|
|
867
|
+
const resolvedOpen = resolvedRoute.via === 'matrix' && omissionCauseOf(standingOf(resolvedRoute), lane, live, origin) === undefined;
|
|
813
868
|
if (resolvedOpen && resolvedMaterializeError !== undefined)
|
|
814
869
|
throw resolvedMaterializeError;
|
|
815
870
|
const resolvedWire = resolvedOpen ? (resolvedMaterialized ?? resolvedSnapshotForWire(resolvedIn)) : {};
|
|
@@ -822,6 +877,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
822
877
|
const disableSkillsIn = src.disableSkills;
|
|
823
878
|
const approvalReachIn = src.approvalReach;
|
|
824
879
|
const allowToolsIn = src.allowTools;
|
|
880
|
+
const projectMemoryIn = src.projectMemory;
|
|
825
881
|
const INPUT_KEYS = Object.keys(INPUT_KEY_ROUTES);
|
|
826
882
|
const i = snapshotByName(src, INPUT_KEYS, {
|
|
827
883
|
live,
|
|
@@ -835,17 +891,24 @@ export function assembleTaskRequest(input, lane) {
|
|
|
835
891
|
disableSkills: disableSkillsIn,
|
|
836
892
|
approvalReach: approvalReachIn,
|
|
837
893
|
allowTools: allowToolsIn,
|
|
894
|
+
projectMemory: projectMemoryIn,
|
|
838
895
|
settings: settingsIn,
|
|
839
896
|
});
|
|
840
897
|
const SETTINGS_KEYS = Object.keys(SETTINGS_KEY_ROUTES);
|
|
841
898
|
const hostSettingsKeysIn = HOST_SETTINGS_SUBKEYS.filter((k) => hasOwn(settingsObj, k) && present(Reflect.get(settingsObj, k)));
|
|
842
899
|
const hostTopKeysIn = HOST_TOP_KEYS.filter((k) => hasOwn(src, k) && present(Reflect.get(src, k)));
|
|
900
|
+
const approvalFamiliesReadingIn = i.approvalFrameFamiliesReading;
|
|
901
|
+
const familiesJudged = present(approvalFamiliesReadingIn)
|
|
902
|
+
? frameFamiliesJudgementOf(approvalFamiliesReadingIn)
|
|
903
|
+
: undefined;
|
|
904
|
+
const approvalFamilies = familiesJudged?.ok === true ? familiesJudged.families : undefined;
|
|
843
905
|
const s = {
|
|
844
906
|
resolved: resolvedIn,
|
|
845
907
|
webSearch: intake.carried.webSearch,
|
|
846
908
|
ultracode: snapshotByName(settingsObj, ['ultracode']).ultracode,
|
|
847
909
|
hooks: intake.carried.hooks,
|
|
848
910
|
outputStyle: intake.carried.outputStyle,
|
|
911
|
+
approvalFrameFamilies: approvalFamilies,
|
|
849
912
|
};
|
|
850
913
|
refuseBadMemoryCapture(memoryCaptureIn);
|
|
851
914
|
refuseBadMaxCostUsd(maxCostUsdIn);
|
|
@@ -857,6 +920,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
857
920
|
refuseBadDisableSkills(disableSkillsIn, 'buildTaskRequest');
|
|
858
921
|
refuseBadApprovalReach(approvalReachIn, 'buildTaskRequest');
|
|
859
922
|
refuseBadAllowTools(allowToolsIn);
|
|
923
|
+
refuseBadProjectMemory(projectMemoryIn);
|
|
860
924
|
refuseBadUserInvokedSkills(i.userInvokedSkills);
|
|
861
925
|
const rewindRoute = INPUT_KEY_ROUTES.rewind;
|
|
862
926
|
const RETIRED_REWIND_FILES_KEY = 'rewindFiles';
|
|
@@ -878,7 +942,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
878
942
|
const rewindForGate = present(rewindIn) ? rewindWire : rewindIn;
|
|
879
943
|
const omitted = [];
|
|
880
944
|
const omit = (key, cause) => {
|
|
881
|
-
omitted
|
|
945
|
+
appendOwnElement(omitted, Object.freeze({ key, cause }));
|
|
882
946
|
};
|
|
883
947
|
const unknownKeys = [];
|
|
884
948
|
const lateOmitted = [];
|
|
@@ -892,22 +956,22 @@ export function assembleTaskRequest(input, lane) {
|
|
|
892
956
|
continue;
|
|
893
957
|
const route = routeOfTopLevelKey(key);
|
|
894
958
|
if (route === undefined) {
|
|
895
|
-
unknownKeys
|
|
959
|
+
appendOwnElement(unknownKeys, key);
|
|
896
960
|
continue;
|
|
897
961
|
}
|
|
898
962
|
if (route.via !== 'matrix' && route.via !== 'fixed')
|
|
899
963
|
continue;
|
|
900
|
-
const cause = omissionCauseOf(standingOf(route), lane, live);
|
|
964
|
+
const cause = omissionCauseOf(standingOf(route), lane, live, origin);
|
|
901
965
|
if (cause !== undefined)
|
|
902
|
-
lateOmitted
|
|
966
|
+
appendOwnElement(lateOmitted, Object.freeze({ key, cause }));
|
|
903
967
|
}
|
|
904
968
|
for (const sub of Object.keys(settingsObj)) {
|
|
905
|
-
if (hasOwn(SETTINGS_KEY_ROUTES, sub))
|
|
969
|
+
if (hasOwn(SETTINGS_KEY_ROUTES, sub) && !MINTED_SETTINGS_SUBKEYS.includes(sub))
|
|
906
970
|
continue;
|
|
907
971
|
const stray = Reflect.get(settingsObj, sub);
|
|
908
972
|
if (!present(stray))
|
|
909
973
|
continue;
|
|
910
|
-
unknownKeys
|
|
974
|
+
appendOwnElement(unknownKeys, `settings.${sub}`);
|
|
911
975
|
}
|
|
912
976
|
let retiredRewindFiles = false;
|
|
913
977
|
for (const sub of Object.keys(rewindObj)) {
|
|
@@ -918,7 +982,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
918
982
|
continue;
|
|
919
983
|
if (sub === RETIRED_REWIND_FILES_KEY)
|
|
920
984
|
retiredRewindFiles = true;
|
|
921
|
-
unknownKeys
|
|
985
|
+
appendOwnElement(unknownKeys, `rewind.${sub}`);
|
|
922
986
|
}
|
|
923
987
|
if (retiredRewindFiles) {
|
|
924
988
|
throw new TypeError('buildTaskRequest: "rewind.rewindFiles" 是退役键(引擎 core 6.0.0 起退役:「逐轮捕获」那一义被引擎忽略 —— 文件首触追踪恒开,' +
|
|
@@ -943,19 +1007,19 @@ export function assembleTaskRequest(input, lane) {
|
|
|
943
1007
|
'错误文本只报键名,不回显值。');
|
|
944
1008
|
}
|
|
945
1009
|
refuseRequireExistingWithoutSession(requireExistingSessionIn, i.sessionId);
|
|
946
|
-
refuseDisableSkillsConflict(disableSkillsIn, i.skills, Reflect.get(src, 'agents'), 'buildTaskRequest');
|
|
1010
|
+
refuseDisableSkillsConflict(disableSkillsIn, i.skills, Reflect.get(src, 'agents'), 'buildTaskRequest', i.userInvokedSkills);
|
|
947
1011
|
refuseUtilityWithoutToolUnload(lane, excludeAllToolsIn);
|
|
948
1012
|
if (intake.refuses) {
|
|
949
|
-
const refusing = hostRefusalNoticeOf(intake, lane, live);
|
|
1013
|
+
const refusing = hostRefusalNoticeOf(intake, lane, live, origin);
|
|
950
1014
|
if (refusing !== undefined)
|
|
951
|
-
throw
|
|
1015
|
+
throw hostSettingsRefusedError(refusing, intake, intake.refusingKeys.find((k) => hostRefuseRowSeated(k, lane, live, origin)));
|
|
952
1016
|
}
|
|
953
1017
|
const carries = (route, value, key) => {
|
|
954
1018
|
if (route.via === 'always')
|
|
955
1019
|
return present(value);
|
|
956
1020
|
if (route.via === 'control' || route.via === 'settings')
|
|
957
1021
|
return false;
|
|
958
|
-
const cause = omissionCauseOf(standingOf(route), lane, live);
|
|
1022
|
+
const cause = omissionCauseOf(standingOf(route), lane, live, origin);
|
|
959
1023
|
if (!inPlay(key, value))
|
|
960
1024
|
return false;
|
|
961
1025
|
if (cause === undefined)
|
|
@@ -991,6 +1055,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
991
1055
|
...(onSetting('ultracode') ? { ultracode: s.ultracode } : {}),
|
|
992
1056
|
...(onSetting('hooks') ? { hooks: s.hooks } : {}),
|
|
993
1057
|
...(s.outputStyle !== undefined ? { outputStyle: s.outputStyle } : {}),
|
|
1058
|
+
...(onSetting('approvalFrameFamilies') ? { approvalFrameFamilies: [...(s.approvalFrameFamilies ?? [])] } : {}),
|
|
994
1059
|
};
|
|
995
1060
|
const attachmentsForWire = on('attachments') ? withoutRetiredAttachmentsKeys(i.attachments) : undefined;
|
|
996
1061
|
const out = {
|
|
@@ -1036,12 +1101,16 @@ export function assembleTaskRequest(input, lane) {
|
|
|
1036
1101
|
...(on('requireExistingSession') ? { requireExistingSession: true } : {}),
|
|
1037
1102
|
...(on('disableSkills') ? { disableSkills: true } : {}),
|
|
1038
1103
|
...(on('approvalReach') ? { approvalReach: approvalReachIn } : {}),
|
|
1104
|
+
...(on('projectMemory') ? { projectMemory: PROJECT_MEMORY_DISABLED } : {}),
|
|
1039
1105
|
...(Object.keys(settingsOut).length > 0 ? { settings: settingsOut } : {}),
|
|
1040
1106
|
};
|
|
1041
|
-
|
|
1107
|
+
const familiesRoute = SETTINGS_KEY_ROUTES.approvalFrameFamilies;
|
|
1108
|
+
const familiesSeated = (familiesRoute.via === 'matrix' || familiesRoute.via === 'fixed') && omissionCauseOf(standingOf(familiesRoute), lane, live, origin) === undefined;
|
|
1109
|
+
const familiesWithheld = familiesSeated && approvalFamilies === undefined ? Object.freeze({ cause: familiesJudged === undefined || familiesJudged.ok ? 'reading_absent' : familiesJudged.cause }) : undefined;
|
|
1110
|
+
return Object.freeze({ request: out, omitted: Object.freeze([...omitted, ...lateOmitted]), host, ...(familiesWithheld !== undefined ? { approvalFrameFamiliesWithheld: familiesWithheld } : {}) });
|
|
1042
1111
|
}
|
|
1043
|
-
export function buildTaskRequest(input,
|
|
1044
|
-
return assembleTaskRequest(input,
|
|
1112
|
+
export function buildTaskRequest(input, laneOrIdentity) {
|
|
1113
|
+
return assembleTaskRequest(input, laneOrIdentity).request;
|
|
1045
1114
|
}
|
|
1046
1115
|
export function applyLiveRequestDefaults(req, host) {
|
|
1047
1116
|
const out = { ...req };
|
|
@@ -1059,7 +1128,7 @@ export function applyLiveRequestDefaults(req, host) {
|
|
|
1059
1128
|
out.retainSubagentSessions = true;
|
|
1060
1129
|
if (out.agents === undefined && host.agents !== undefined)
|
|
1061
1130
|
out.agents = host.agents;
|
|
1062
|
-
refuseDisableSkillsConflict(out.disableSkills, out.skills, out.agents, 'applyLiveRequestDefaults');
|
|
1131
|
+
refuseDisableSkillsConflict(out.disableSkills, out.skills, out.agents, 'applyLiveRequestDefaults', Array.isArray(out.userInvokedSkills) ? out.userInvokedSkills : undefined);
|
|
1063
1132
|
if (typeof out.scenario === 'string' && host.mockScenarioKeys?.has(out.scenario)) {
|
|
1064
1133
|
delete out.scenario;
|
|
1065
1134
|
}
|
|
@@ -1116,25 +1185,25 @@ export function unregisteredRequestKeys(req, lane) {
|
|
|
1116
1185
|
if (settings === null || typeof settings !== 'object')
|
|
1117
1186
|
continue;
|
|
1118
1187
|
if (typeof settings.toJSON === 'function')
|
|
1119
|
-
out
|
|
1188
|
+
appendOwnElement(out, 'settings.toJSON');
|
|
1120
1189
|
for (const [sub, value] of Object.entries(settings)) {
|
|
1121
1190
|
if (sub === 'toJSON')
|
|
1122
1191
|
continue;
|
|
1123
1192
|
if (typeof value === 'function') {
|
|
1124
|
-
out
|
|
1193
|
+
appendOwnElement(out, `settings.${sub}`);
|
|
1125
1194
|
continue;
|
|
1126
1195
|
}
|
|
1127
1196
|
if (laneSettingsKeys.has(sub) || liveDefaults.has(`settings.${sub}`))
|
|
1128
1197
|
continue;
|
|
1129
1198
|
if (settingsIsOpenSet && !foreignSettingsKeys.has(sub))
|
|
1130
1199
|
continue;
|
|
1131
|
-
out
|
|
1200
|
+
appendOwnElement(out, `settings.${sub}`);
|
|
1132
1201
|
}
|
|
1133
1202
|
continue;
|
|
1134
1203
|
}
|
|
1135
1204
|
if (laneTopKeys.has(key) || liveDefaults.has(key))
|
|
1136
1205
|
continue;
|
|
1137
|
-
out
|
|
1206
|
+
appendOwnElement(out, key);
|
|
1138
1207
|
}
|
|
1139
1208
|
return out;
|
|
1140
1209
|
}
|