@sema-agent/client-core 0.98.0 → 0.100.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 +376 -0
- package/README.md +61 -35
- package/dist/adapt/arms.js +120 -55
- package/dist/adapt/panelTasks.d.ts +3 -2
- package/dist/adapt/panelTasks.js +34 -11
- package/dist/adapt/textStream.d.ts +1 -1
- package/dist/adapt/textStream.js +51 -28
- package/dist/adapter/activeRunSelfHeal.d.ts +11 -3
- package/dist/adapter/activeRunSelfHeal.js +210 -294
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +25 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +176 -12
- package/dist/adapter/downstream/terminalToSdkResult.js +10 -0
- package/dist/adapter/downstream/wiringManifestView.d.ts +3 -1
- package/dist/adapter/downstream/wiringManifestView.js +1 -0
- package/dist/adapter/runStream.js +82 -40
- package/dist/adapter/types.d.ts +2 -0
- package/dist/adapter/types.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +16 -8
- package/dist/agentsWireCaps.d.ts +7 -3
- package/dist/agentsWireCaps.js +133 -39
- package/dist/cloudConfigWireCaps.d.ts +10 -1
- package/dist/cloudConfigWireCaps.js +181 -65
- package/dist/compactionStatus.d.ts +34 -0
- package/dist/compactionStatus.js +196 -0
- package/dist/controlRouter.d.ts +4 -2
- package/dist/controlRouter.js +39 -51
- package/dist/coreValuePorts.d.ts +26 -1
- package/dist/coreValuePorts.js +10 -0
- package/dist/corruptSessionCopy.d.ts +2 -1
- package/dist/corruptSessionCopy.js +3 -3
- package/dist/decideFailureNote.js +3 -3
- package/dist/declared/supportFloorDeclared.js +1 -1
- package/dist/detachWire.js +3 -2
- package/dist/devicesFace.d.ts +34 -0
- package/dist/devicesFace.js +90 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +153 -5
- package/dist/engineAgentPanelStore.d.ts +14 -4
- package/dist/engineAgentPanelStore.js +14 -0
- package/dist/engineCapReader.d.ts +2 -1
- package/dist/engineCapReader.js +7 -5
- package/dist/engineCapsCache.d.ts +8 -0
- package/dist/engineCapsCache.js +59 -6
- package/dist/engineCapsChange.d.ts +2 -0
- package/dist/engineCapsChange.js +9 -0
- package/dist/engineErrorCodes.d.ts +11 -2
- package/dist/engineErrorCodes.js +11 -12
- package/dist/engineRowRef.js +4 -0
- package/dist/engineSessionMessages.d.ts +1 -0
- package/dist/engineSessionMessages.js +7 -1
- package/dist/engineTargetSeat.d.ts +27 -0
- package/dist/engineTargetSeat.js +199 -0
- package/dist/engineToolDirectory.d.ts +3 -0
- package/dist/engineToolDirectory.js +4 -2
- package/dist/engineWireFor.js +3 -8
- package/dist/env/uiLanguage.d.ts +2 -1
- package/dist/env/uiLanguage.js +3 -2
- package/dist/eventLeg.d.ts +7 -5
- package/dist/eventLeg.js +68 -49
- package/dist/fileHistoryCaptureCapability.d.ts +2 -4
- package/dist/fileHistoryCaptureCapability.js +12 -22
- package/dist/fileHistoryLegNotice.d.ts +2 -1
- package/dist/fileHistoryLegNotice.js +3 -3
- package/dist/frameBinding.d.ts +3 -0
- package/dist/frameBinding.js +12 -0
- package/dist/gateOutcome.js +16 -2
- package/dist/gateVocabulary.d.ts +8 -7
- package/dist/gateVocabulary.js +71 -73
- package/dist/generated/engineFactTables.d.ts +18 -1
- package/dist/generated/engineFactTables.js +56 -0
- package/dist/generated/engineNoticeTables.js +12 -3
- package/dist/generated/settingsSchemaFns.d.ts +18 -0
- package/dist/generated/settingsSchemaFns.js +70 -0
- package/dist/generated/settingsSchemaHooksClassifier.d.ts +2 -0
- package/dist/generated/settingsSchemaHooksClassifier.js +254 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -0
- package/dist/generated/settingsSchemaMcpRequestEntry.js +162 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +9 -0
- package/dist/generated/settingsSchemaTypes.d.ts +133 -0
- package/dist/generated/settingsSchemaTypes.js +1 -0
- package/dist/hitl/allowRuleShadow.d.ts +2 -1
- package/dist/hitl/allowRuleShadow.js +18 -15
- package/dist/hitl/approvalCardReasons.d.ts +3 -2
- package/dist/hitl/approvalCardReasons.js +29 -30
- package/dist/hitl/approvalHolds.d.ts +17 -0
- package/dist/hitl/approvalHolds.js +114 -29
- package/dist/hitl/askClassPair.d.ts +2 -2
- package/dist/hitl/askClassPair.js +16 -0
- package/dist/hitl/askGateWire.js +2 -1
- package/dist/hitl/askSettlementLine.d.ts +14 -4
- package/dist/hitl/askSettlementLine.js +67 -47
- package/dist/hitl/attributionLadder.d.ts +23 -0
- package/dist/hitl/attributionLadder.js +67 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +2 -1
- package/dist/hitl/automaticAnswerVerdict.js +8 -8
- package/dist/hitl/crashConvergedNotice.d.ts +5 -4
- package/dist/hitl/crashConvergedNotice.js +28 -41
- package/dist/hitl/decisionLedger.d.ts +55 -0
- package/dist/hitl/decisionLedger.js +156 -0
- package/dist/hitl/decisionRefusal.d.ts +1 -0
- package/dist/hitl/decisionRefusal.js +1 -1
- package/dist/hitl/decisionSend.d.ts +113 -0
- package/dist/hitl/decisionSend.js +579 -0
- package/dist/hitl/frameRouter.js +7 -8
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +21 -9
- package/dist/hitl/persistedRulesWire.d.ts +6 -5
- package/dist/hitl/persistedRulesWire.js +55 -73
- package/dist/hitl/planReviewWire.d.ts +5 -0
- package/dist/hitl/planReviewWire.js +53 -76
- package/dist/hitl/sessionPolicyDeliverable.d.ts +2 -0
- package/dist/hitl/sessionPolicyDeliverable.js +49 -9
- package/dist/hitl/sessionPolicyWire.d.ts +2 -1
- package/dist/hitl/sessionPolicyWire.js +23 -24
- package/dist/hitl/suspendedReopen.d.ts +2 -1
- package/dist/hitl/suspendedReopen.js +7 -10
- package/dist/hitl/toolApprovalWire.d.ts +17 -5
- package/dist/hitl/toolApprovalWire.js +120 -147
- package/dist/hooksWireCaps.js +145 -56
- package/dist/host.d.ts +21 -0
- package/dist/hostTurnSettings.d.ts +110 -0
- package/dist/hostTurnSettings.js +692 -0
- package/dist/humanTurn.d.ts +15 -1
- package/dist/humanTurn.js +100 -12
- package/dist/humanTurnRead.d.ts +2 -0
- package/dist/humanTurnRead.js +22 -1
- package/dist/i18n/messages.en.d.ts +713 -0
- package/dist/i18n/messages.en.js +713 -0
- package/dist/i18n/messages.zh.js +854 -1
- package/dist/index.d.ts +45 -13
- package/dist/index.js +27 -9
- package/dist/inheritEnvCapability.d.ts +4 -2
- package/dist/inheritEnvCapability.js +12 -5
- package/dist/inheritEnvWire.d.ts +3 -2
- package/dist/inheritEnvWire.js +14 -16
- package/dist/injectionLaneNotice.d.ts +5 -0
- package/dist/injectionLaneNotice.js +46 -0
- package/dist/interactiveHalt.js +17 -6
- package/dist/liveModelCatalog.d.ts +2 -1
- package/dist/liveModelCatalog.js +14 -8
- package/dist/mcpPanel.d.ts +10 -1
- package/dist/mcpPanel.js +42 -13
- package/dist/mcpProbeCapability.d.ts +2 -1
- package/dist/mcpProbeCapability.js +7 -11
- package/dist/mcpProbeWire.d.ts +3 -1
- package/dist/mcpProbeWire.js +5 -0
- package/dist/mcpReconnect.js +2 -2
- package/dist/mcpToolToggles.d.ts +6 -0
- package/dist/mcpToolToggles.js +46 -0
- package/dist/mcpWireCaps.d.ts +43 -3
- package/dist/mcpWireCaps.js +194 -59
- package/dist/mcpWireTransport.d.ts +4 -0
- package/dist/mcpWireTransport.js +18 -0
- package/dist/memoryEntriesWire.js +5 -10
- package/dist/model/onboardJudgement.d.ts +93 -0
- package/dist/model/onboardJudgement.js +415 -0
- package/dist/model/tierVocabulary.d.ts +2 -0
- package/dist/model/tierVocabulary.js +17 -5
- package/dist/modelCapabilityProbe.d.ts +65 -0
- package/dist/modelCapabilityProbe.js +601 -0
- package/dist/modelIdentityResolvability.d.ts +5 -0
- package/dist/modelIdentityResolvability.js +49 -22
- package/dist/ownKey.d.ts +33 -0
- package/dist/ownKey.js +109 -0
- package/dist/panelReduce.d.ts +11 -1
- package/dist/panelReduce.js +95 -16
- package/dist/panelStateHolder.d.ts +1 -0
- package/dist/panelStateHolder.js +10 -1
- package/dist/permissionRuleIssue.d.ts +2 -1
- package/dist/permissionRuleIssue.js +23 -20
- package/dist/permissionRulesWriteCapability.d.ts +2 -1
- package/dist/permissionRulesWriteCapability.js +8 -6
- package/dist/pluginHooksWire.d.ts +46 -3
- package/dist/pluginHooksWire.js +220 -12
- package/dist/prepareRefusal.d.ts +8 -0
- package/dist/prepareRefusal.js +72 -0
- package/dist/printModelStatus.d.ts +63 -0
- package/dist/printModelStatus.js +155 -0
- package/dist/request/taskRequest.d.ts +16 -10
- package/dist/request/taskRequest.js +195 -58
- package/dist/resumeRefusalCopy.d.ts +14 -9
- package/dist/resumeRefusalCopy.js +89 -144
- package/dist/retryStatus.d.ts +55 -0
- package/dist/retryStatus.js +155 -19
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +58 -0
- package/dist/sandboxWire.d.ts +2 -1
- package/dist/sandboxWire.js +55 -21
- package/dist/scenarioRefusal.d.ts +10 -0
- package/dist/scenarioRefusal.js +111 -0
- package/dist/seam.d.ts +48 -9
- package/dist/seam.js +54 -5
- package/dist/seatContract.d.ts +272 -14
- package/dist/seatContract.js +711 -23
- package/dist/selfOrchestrationDenial.js +7 -19
- package/dist/sessionIdSegment.d.ts +6 -0
- package/dist/sessionIdSegment.js +24 -0
- package/dist/sessionMemoryStatus.js +6 -11
- package/dist/sessionPolicyCapability.d.ts +2 -1
- package/dist/sessionPolicyCapability.js +8 -6
- package/dist/settingsCredentialKeyPaths.d.ts +8 -0
- package/dist/settingsCredentialKeyPaths.js +219 -0
- package/dist/settingsHooksSalvage.d.ts +44 -0
- package/dist/settingsHooksSalvage.js +211 -0
- package/dist/skillToolListsCapability.d.ts +2 -1
- package/dist/skillToolListsCapability.js +8 -6
- package/dist/skillsWireCaps.d.ts +0 -3
- package/dist/skillsWireCaps.js +1 -2
- package/dist/sseIdleTriage.js +3 -2
- package/dist/subagent/engineSubagentResume.js +15 -9
- package/dist/subagentContentStore.d.ts +4 -0
- package/dist/subagentContentStore.js +157 -27
- package/dist/toolHistoryMismatch.js +3 -2
- package/dist/toolRoster.d.ts +3 -2
- package/dist/toolRoster.js +21 -20
- package/dist/toolsFlagNames.d.ts +8 -0
- package/dist/toolsFlagNames.js +110 -0
- package/dist/turnFailurePresentation.d.ts +12 -1
- package/dist/turnFailurePresentation.js +220 -15
- package/dist/usageAnalytics.js +6 -11
- package/dist/userAttachmentEnvelope.d.ts +1 -0
- package/dist/userAttachmentEnvelope.js +37 -7
- package/dist/userAttachmentSeat.d.ts +21 -0
- package/dist/userAttachmentSeat.js +75 -0
- package/dist/userInvokedSkillsCapability.d.ts +11 -1
- package/dist/userInvokedSkillsCapability.js +31 -7
- package/dist/wireErrorTriage.d.ts +7 -0
- package/dist/wireErrorTriage.js +23 -1
- package/dist/wireFailureShape.js +2 -1
- package/dist/wireRefusalCopy.d.ts +62 -16
- package/dist/wireRefusalCopy.js +307 -148
- package/dist/workflowsJournalCapability.d.ts +2 -1
- package/dist/workflowsJournalCapability.js +8 -6
- package/docs/INTEGRATION-CLIENTS.md +951 -42
- package/package.json +5 -5
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { refuseBadDisableSkills, refuseDisableSkillsConflict } from '../disableSkillsWire.js';
|
|
2
2
|
import { ATTACHMENTS_SPEC_KEYS, AttachmentsSpecRefused } from '../attachmentsWireCaps.js';
|
|
3
3
|
import { retiredAttachmentsKeyOf } from '../taskRequestWords.js';
|
|
4
|
+
import { msg, renderMessage } from '../i18n/translate.js';
|
|
4
5
|
import { outputStyleSeatAdmitted } from '../outputStyleSeatCapability.js';
|
|
5
6
|
import { refuseBadApprovalReach } from '../approvalReachWire.js';
|
|
7
|
+
import { HOST_SUPPLIED_KEYS, HostSettingsRefused, UNWIRED_HOST_TURN_SETTINGS, buildHostTurnSettings, hostIntakeSnapshotOf, hostProjectionNotice, hostTurnSettingsOf, intersectHostHooks, rethrowHostResolvedDeferred, } from '../hostTurnSettings.js';
|
|
6
8
|
export const REQUEST_FIELD_MATRIX = [
|
|
7
9
|
{ field: 'objective', lanes: ['interactive', 'print', 'utility'], live: false, why: '本 turn 的真实输入,每条车道都必需', whyUtilityLane: '恒座:三条车道都必须带上本次提交的模型面输入' },
|
|
8
10
|
{ field: 'sessionId', lanes: ['interactive', 'print', 'utility'], live: false, why: '单命名空间(TP-A Step 2):壳 id 即引擎 session id;print 在非 live 下保留 mock 常量', whyUtilityLane: '恒座:side-channel 提交走**独立**会话 id(壳另铸一个,绝不复用用户会话那一个 —— 复用会把这次提交的转录混进用户会话)' },
|
|
@@ -16,6 +18,7 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
16
18
|
{ field: 'enableFork', lanes: ['interactive', 'print'], live: true, why: '显式布尔才 stamp([503]② fail-OPEN 教训:off 必须显式)', whyUtilityLane: '无座:分叉是会话面的动作,而 side-channel 提交是一次性的独立会话' },
|
|
17
19
|
{ field: 'attachments', lanes: ['interactive', 'print'], live: true, why: 'design/133 + G1 缺省开的 turn 边界 attachment', whyUtilityLane: '无座:turn 边界的附件配置属用户会话;side-channel 提交不带附件' },
|
|
18
20
|
{ 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 一行同理)' },
|
|
19
22
|
{ field: 'mcpServers', lanes: ['interactive', 'print'], live: true, why: '本地 .mcp.json 投影;service 单用户门决定是否兑现', whyUtilityLane: '无座:MCP 服务挂的是工具,与零工具面矛盾' },
|
|
20
23
|
{ field: 'settings.webSearch', lanes: ['interactive', 'print'], live: true, why: 'SEMA_WEBSEARCH_* / settings.json;per-request 配置赢过部署 env', whyUtilityLane: '无座:联网检索是一只工具,与零工具面矛盾' },
|
|
21
24
|
{ field: 'settings.hooks', lanes: ['interactive', 'print'], live: true, why: '[495]① 用户 settings 文件 hooks 逐字上 wire', whyUtilityLane: '无座:hook 挂在工具门上(零工具面没有门),而且 side-channel 是壳自己的提交,不该继承用户那份 hook 表' },
|
|
@@ -44,6 +47,7 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
44
47
|
{ field: 'reasoningEffort', lanes: ['interactive', 'print', 'utility'], live: false, why: '思考档位(sdk `TaskRequest.reasoningEffort` 七词闭集;上游对表外词 400 响亮拒 ⇒ 本层不预铸第二判官)。档位是请求级的位、与车道无关:交互面 = `/effort` 拨盘,无人值守面 = 档位旗。🔴 端交的必须是**档位词**:「思考 token 数」今天没有上游对位(见 `UPSTREAM_ABSENT_REQUEST_INTENTS` 的 `maxThinkingTokens`),别把一个数字折成档位词发出去', whyUtilityLane: '有座:side-channel 该用显式低档(省钱省时);与 model 同一条理由 —— 本车道上这两位都由壳显式给,不跟用户会话的拨盘走' },
|
|
45
48
|
{ 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` 拨盘走)' },
|
|
46
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 是壳自己的一次性提交,没有用户 `@` 附件' },
|
|
47
51
|
{ 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 是一次性的独立会话,没有可回退的历史' },
|
|
48
52
|
{ field: 'clientContext', lanes: ['interactive'], live: false, why: 'IANA 时区 + 可选邮箱 → core 本地化 `# Environment` 的 today;print 同样跑在用户机器上,缺席让引擎误标 (UTC)', gap: true, whyUtilityLane: '无座:本地化 today 的用途在用户会话的环境段,而 side-channel 的系统提示由壳整段给出 —— 这一列我判不准要不要(与本行 `gap` 同一条待办:要补先单独立项)' },
|
|
49
53
|
{ field: 'scratchpadDir', lanes: ['interactive'], live: true, why: '[816]③ per-session 暂存目录;print 也有 session,缺席让 `-p` 的工具写不进 exemptDir', gap: true, whyUtilityLane: '无座:per-session 暂存目录是给**工具**写的,零工具面上没人写' },
|
|
@@ -122,7 +126,9 @@ const INPUT_KEY_ROUTES = {
|
|
|
122
126
|
reasoningEffort: row('reasoningEffort'),
|
|
123
127
|
model: row('model'),
|
|
124
128
|
images: row('images'),
|
|
129
|
+
userAttachments: row('userAttachments'),
|
|
125
130
|
skills: row('skills'),
|
|
131
|
+
userInvokedSkills: row('userInvokedSkills'),
|
|
126
132
|
mcpServers: row('mcpServers'),
|
|
127
133
|
clientContext: row('clientContext'),
|
|
128
134
|
scratchpadDir: row('scratchpadDir'),
|
|
@@ -162,16 +168,26 @@ const INPUT_KEY_ROUTES = {
|
|
|
162
168
|
why: '思考 token 数上限:sdk `TaskRequest` 上思考强度只有档位词(`reasoningEffort` 七词闭集),没有 token 数这一位;把数字折成档位词 = 替用户编一个他没说过的档位',
|
|
163
169
|
},
|
|
164
170
|
memoryCapture: row('memoryCapture'),
|
|
165
|
-
memory: row('memory'),
|
|
166
|
-
fileHistory: row('fileHistory'),
|
|
167
171
|
inheritEnv: row('inheritEnv'),
|
|
168
172
|
requireExistingSession: row('requireExistingSession'),
|
|
169
173
|
disableSkills: row('disableSkills'),
|
|
170
174
|
rewind: row('resumeAt/resumeAtMode/restoreFiles/rewindFilesTo'),
|
|
171
175
|
repo: row('repo'),
|
|
172
176
|
allowTools: row('allowTools'),
|
|
177
|
+
hostSettings: { via: 'control' },
|
|
173
178
|
settings: { via: 'settings' },
|
|
174
179
|
};
|
|
180
|
+
const HOST_TOP_KEY_ROUTES = {
|
|
181
|
+
memory: row('memory'),
|
|
182
|
+
fileHistory: row('fileHistory'),
|
|
183
|
+
};
|
|
184
|
+
const HOST_TOP_KEYS = Object.freeze(Object.keys(HOST_TOP_KEY_ROUTES));
|
|
185
|
+
const _hostTopKeysPin = [true];
|
|
186
|
+
void _hostTopKeysPin;
|
|
187
|
+
const HOST_TOP_ASK_AFTER = 'memoryCapture';
|
|
188
|
+
const HOST_SETTINGS_SUBKEYS = Object.freeze(HOST_SUPPLIED_KEYS.filter((k) => k.startsWith('settings.')).map((k) => k.slice('settings.'.length)));
|
|
189
|
+
const _hostSubkeysPin = [true, true, true];
|
|
190
|
+
void _hostSubkeysPin;
|
|
175
191
|
const SETTINGS_KEY_ROUTES = {
|
|
176
192
|
resolved: row('settings.<resolved>'),
|
|
177
193
|
webSearch: row('settings.webSearch'),
|
|
@@ -185,6 +201,8 @@ const liveDefaultKeyNames = () => new Set(LIVE_DEFAULT_FIELDS.flatMap(item => it
|
|
|
185
201
|
const routeOfTopLevelKey = (key) => {
|
|
186
202
|
if (hasOwn(INPUT_KEY_ROUTES, key))
|
|
187
203
|
return INPUT_KEY_ROUTES[key];
|
|
204
|
+
if (hasOwn(HOST_TOP_KEY_ROUTES, key))
|
|
205
|
+
return HOST_TOP_KEY_ROUTES[key];
|
|
188
206
|
if (!key.includes('.') && liveDefaultKeyNames().has(key))
|
|
189
207
|
return { via: 'fixed', cause: 'other_channel' };
|
|
190
208
|
return undefined;
|
|
@@ -211,6 +229,42 @@ const OMISSION_JUDGES = {
|
|
|
211
229
|
not_live: (s, _lane, live) => s.via === 'matrix' && s.spec.live && !live,
|
|
212
230
|
};
|
|
213
231
|
const omissionCauseOf = (s, lane, live) => TASK_REQUEST_OMISSION_CAUSES.find(cause => OMISSION_JUDGES[cause](s, lane, live));
|
|
232
|
+
const hostRefusalNoticeOf = (intake, lane, live) => {
|
|
233
|
+
const verdictNotice = intake.notice ?? hostProjectionNotice();
|
|
234
|
+
try {
|
|
235
|
+
const refusing = intake.refusingKeys;
|
|
236
|
+
if (refusing.length === 0)
|
|
237
|
+
return verdictNotice;
|
|
238
|
+
const turnNotices = intake.turnNotices;
|
|
239
|
+
const aligned = turnNotices !== undefined && turnNotices.length === refusing.length;
|
|
240
|
+
for (const [i, key] of refusing.entries()) {
|
|
241
|
+
if (!hostRefuseRowSeated(key, lane, live))
|
|
242
|
+
continue;
|
|
243
|
+
return aligned ? (turnNotices[i] ?? verdictNotice) : verdictNotice;
|
|
244
|
+
}
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
return verdictNotice;
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
const hostRefuseRowSeated = (key, lane, live) => {
|
|
252
|
+
if (hasOwn(HOST_TOP_KEY_ROUTES, key)) {
|
|
253
|
+
const top = HOST_TOP_KEY_ROUTES[key];
|
|
254
|
+
return top === undefined || (top.via !== 'matrix' && top.via !== 'fixed') || omissionCauseOf(standingOf(top), lane, live) === undefined;
|
|
255
|
+
}
|
|
256
|
+
if (!key.startsWith('settings.'))
|
|
257
|
+
return true;
|
|
258
|
+
const sub = key.slice('settings.'.length);
|
|
259
|
+
if (!hasOwn(SETTINGS_KEY_ROUTES, sub))
|
|
260
|
+
return true;
|
|
261
|
+
const route = SETTINGS_KEY_ROUTES[sub];
|
|
262
|
+
if (route === undefined || route.via === 'always')
|
|
263
|
+
return true;
|
|
264
|
+
if (route.via === 'matrix' || route.via === 'fixed')
|
|
265
|
+
return omissionCauseOf(standingOf(route), lane, live) === undefined;
|
|
266
|
+
return true;
|
|
267
|
+
};
|
|
214
268
|
const REQUEST_LANE_SET = { interactive: true, print: true, utility: true };
|
|
215
269
|
export const REQUEST_LANES = Object.freeze(Object.keys(REQUEST_LANE_SET));
|
|
216
270
|
const refuseBadLane = (lane) => {
|
|
@@ -228,6 +282,8 @@ const VALUE_LEVEL_IN_PLAY = Object.freeze({
|
|
|
228
282
|
oneShot: (v) => v === true,
|
|
229
283
|
interactiveTools: (v) => v === false,
|
|
230
284
|
images: (v) => Array.isArray(v) && v.length > 0,
|
|
285
|
+
userAttachments: (v) => Array.isArray(v) && v.length > 0,
|
|
286
|
+
userInvokedSkills: (v) => Array.isArray(v) && v.length > 0,
|
|
231
287
|
attachmentIds: (v) => Array.isArray(v) && v.length > 0,
|
|
232
288
|
excludeTools: (v) => Array.isArray(v) && v.length > 0,
|
|
233
289
|
excludeAllTools: (v) => v === true,
|
|
@@ -402,14 +458,50 @@ const resolvedSnapshotForWire = (resolved) => {
|
|
|
402
458
|
}
|
|
403
459
|
return out;
|
|
404
460
|
};
|
|
461
|
+
export function hostTurnSettings(input) {
|
|
462
|
+
return buildHostTurnSettings(input, { materialize: (snapshot) => resolvedSnapshotForWire(snapshot), memoryOffDeclared });
|
|
463
|
+
}
|
|
464
|
+
export function refilterHostSettings(request, fresh, lane) {
|
|
465
|
+
refuseBadLane(lane);
|
|
466
|
+
const host = hostTurnSettingsOf(fresh);
|
|
467
|
+
const intake = host === undefined || host === UNWIRED_HOST_TURN_SETTINGS ? undefined : hostIntakeSnapshotOf(host);
|
|
468
|
+
if (host === undefined || intake === undefined) {
|
|
469
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.hostSettingsMalformed', { shape: coarseShape(fresh) })));
|
|
470
|
+
}
|
|
471
|
+
const refuseNotice = () => intake.notice ?? hostProjectionNotice();
|
|
472
|
+
if (intake.refuses) {
|
|
473
|
+
const refusing = hostRefusalNoticeOf(intake, lane, true);
|
|
474
|
+
if (refusing !== undefined)
|
|
475
|
+
return Object.freeze({ kind: 'refuse', notice: refusing });
|
|
476
|
+
}
|
|
477
|
+
const settings = request.settings;
|
|
478
|
+
if (!isPlainRecord(settings) || !Object.hasOwn(settings, 'hooks'))
|
|
479
|
+
return Object.freeze({ kind: 'send', request, hooksDropped: 0 });
|
|
480
|
+
const disposition = intake.dispositions['settings.hooks'];
|
|
481
|
+
if (disposition === 'unwired')
|
|
482
|
+
return Object.freeze({ kind: 'send', request, hooksDropped: 0 });
|
|
483
|
+
const now = intake.carried.hooks;
|
|
484
|
+
const sentHooks = settings.hooks;
|
|
485
|
+
if (!isPlainRecord(sentHooks))
|
|
486
|
+
return Object.freeze({ kind: 'refuse', notice: refuseNotice() });
|
|
487
|
+
const cut = intersectHostHooks(sentHooks, now);
|
|
488
|
+
if (!cut.judged)
|
|
489
|
+
return Object.freeze({ kind: 'refuse', notice: refuseNotice() });
|
|
490
|
+
if (cut.dropped === 0)
|
|
491
|
+
return Object.freeze({ kind: 'send', request, hooksDropped: 0 });
|
|
492
|
+
const { hooks: _sentHooks, ...restSettings } = settings;
|
|
493
|
+
void _sentHooks;
|
|
494
|
+
const nextSettings = cut.hooks === undefined ? restSettings : { ...restSettings, hooks: cut.hooks };
|
|
495
|
+
const { settings: _sentSettings, ...restRequest } = request;
|
|
496
|
+
void _sentSettings;
|
|
497
|
+
const next = Object.keys(nextSettings).length > 0 ? { ...restRequest, settings: nextSettings } : restRequest;
|
|
498
|
+
return Object.freeze({ kind: 'send', request: next, hooksDropped: cut.dropped });
|
|
499
|
+
}
|
|
405
500
|
export const MEMORY_CAPTURE_OFF = 'off';
|
|
406
501
|
export function memoryCaptureDeclarationField(declared) {
|
|
407
502
|
return declared ? { memoryCapture: MEMORY_CAPTURE_OFF } : {};
|
|
408
503
|
}
|
|
409
504
|
export const MEMORY_OFF = 'off';
|
|
410
|
-
export function memoryOffDeclarationField(declared) {
|
|
411
|
-
return declared ? { memory: MEMORY_OFF } : {};
|
|
412
|
-
}
|
|
413
505
|
export const FILE_HISTORY_DISABLED = 'disabled';
|
|
414
506
|
export const INHERIT_ENV_WORDS = Object.freeze(['all', 'scrub']);
|
|
415
507
|
export function isInheritEnvWord(v) {
|
|
@@ -427,26 +519,16 @@ export function memoryOffDeclared(input) {
|
|
|
427
519
|
const sm = input.settingsMemory;
|
|
428
520
|
if (sm !== undefined && sm !== null) {
|
|
429
521
|
if (typeof sm !== 'object' || Array.isArray(sm)) {
|
|
430
|
-
throw new TypeError(
|
|
522
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.memoryOff.settingsSectionNotObject', { shape: coarseShape(sm) })));
|
|
431
523
|
}
|
|
432
524
|
const enabled = sm.enabled;
|
|
433
525
|
if (enabled !== undefined && typeof enabled !== 'boolean') {
|
|
434
|
-
throw new TypeError(
|
|
526
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.memoryOff.enabledNotBoolean', { shape: coarseShape(enabled) })));
|
|
435
527
|
}
|
|
436
528
|
fromSettings = enabled === false;
|
|
437
529
|
}
|
|
438
530
|
return flag === MEMORY_OFF || fromSettings;
|
|
439
531
|
}
|
|
440
|
-
const refuseBadMemoryOff = (v) => {
|
|
441
|
-
if (v === undefined || v === null)
|
|
442
|
-
return;
|
|
443
|
-
if (v === 'off')
|
|
444
|
-
return;
|
|
445
|
-
throw new TypeError('buildTaskRequest: memory 只接受字面量 `\'off\'` 或缺席(undefined/null)—— ' +
|
|
446
|
-
`收到 ${coarseShape(v)}。这一位是**请求级整面开关**(「这一次别给我记忆」),上游是**单成员闭集**(没有 ` +
|
|
447
|
-
'`"on"`,`{ enabled: false }` 对象形也不是 wire 拼法)且对坏拼写**响亮拒**(server 400 `request.field_invalid`)。' +
|
|
448
|
-
'本层若静默删键,这一次运行会照常挂上记忆面而声明人不会知道 —— 与 memoryCapture 同一条纪律。错误文本只报形状,不回显值。');
|
|
449
|
-
};
|
|
450
532
|
const withoutRetiredAttachmentsKeys = (v) => {
|
|
451
533
|
if (typeof v !== 'object' || v === null)
|
|
452
534
|
return v;
|
|
@@ -530,6 +612,23 @@ const refuseBadAllowTools = (v) => {
|
|
|
530
612
|
`收到 ${coarseShape(v)}。这一位是**可用性选择器**(收紧声明):本层若把坏形静默删键,这一次运行会挂上声明人以为已经收窄掉的全部工具。` +
|
|
531
613
|
'错误文本只报形状,不回显值。');
|
|
532
614
|
};
|
|
615
|
+
const refuseBadUserInvokedSkills = (v) => {
|
|
616
|
+
if (v === undefined || v === null)
|
|
617
|
+
return;
|
|
618
|
+
if (Array.isArray(v) && v.length <= ALLOW_TOOLS_MAX_LENGTH) {
|
|
619
|
+
let ok = true;
|
|
620
|
+
for (let k = 0; k < v.length; k += 1) {
|
|
621
|
+
const d = Object.getOwnPropertyDescriptor(v, k);
|
|
622
|
+
if (d === undefined || !('value' in d) || typeof d.value !== 'string') {
|
|
623
|
+
ok = false;
|
|
624
|
+
break;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
if (ok)
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.userInvokedSkillsMalformed', { shape: coarseShape(v) })));
|
|
631
|
+
};
|
|
533
632
|
const refuseBadExcludeAllTools = (v) => {
|
|
534
633
|
if (v === undefined || v === null || v === true || v === false)
|
|
535
634
|
return;
|
|
@@ -537,15 +636,6 @@ const refuseBadExcludeAllTools = (v) => {
|
|
|
537
636
|
`收到 ${coarseShape(v)}。这一位是**整只工具面卸载**的收紧声明:本层若把坏值静默删键,这一次运行会挂上声明人以为已经卸掉的全部工具。` +
|
|
538
637
|
'错误文本只报形状,不回显值。');
|
|
539
638
|
};
|
|
540
|
-
const refuseBadFileHistory = (v) => {
|
|
541
|
-
if (v === undefined || v === null)
|
|
542
|
-
return;
|
|
543
|
-
if (v === FILE_HISTORY_DISABLED)
|
|
544
|
-
return;
|
|
545
|
-
throw new TypeError('buildTaskRequest: fileHistory 只接受字面量 `\'disabled\'` 或缺席(undefined/null)—— ' +
|
|
546
|
-
`收到 ${coarseShape(v)}。这一位是「这一次运行别捕获文件历史」的收紧声明,上游是**单成员闭集**(没有第二个词)且对坏值` +
|
|
547
|
-
'**响亮拒**。本层若静默删键,这一次运行照常捕获而声明人不会知道。错误文本只报形状,不回显值。');
|
|
548
|
-
};
|
|
549
639
|
const refuseBadInheritEnv = (v) => {
|
|
550
640
|
if (v === undefined || v === null)
|
|
551
641
|
return;
|
|
@@ -563,13 +653,16 @@ const refuseBadRequireExistingSession = (v) => {
|
|
|
563
653
|
'上游对非布尔值同样拒收。错误文本只报形状,不回显值。');
|
|
564
654
|
};
|
|
565
655
|
const hasResumableSessionId = (sid) => typeof sid === 'string' && sid.length > 0;
|
|
566
|
-
const refuseRequireExistingWithoutSession = (requireExisting, sessionId) => {
|
|
656
|
+
const refuseRequireExistingWithoutSession = (requireExisting, sessionId, where = 'buildTaskRequest') => {
|
|
567
657
|
if (requireExisting !== true || hasResumableSessionId(sessionId))
|
|
568
658
|
return;
|
|
569
|
-
const shape = sessionId === undefined
|
|
570
|
-
|
|
571
|
-
'
|
|
572
|
-
|
|
659
|
+
const shape = sessionId === undefined
|
|
660
|
+
? renderMessage(msg('config.taskRequest.requireExisting.shapeAbsent'))
|
|
661
|
+
: typeof sessionId === 'string'
|
|
662
|
+
? renderMessage(msg('config.taskRequest.requireExisting.shapeEmpty'))
|
|
663
|
+
: coarseShape(sessionId);
|
|
664
|
+
const layer = renderMessage(msg(where === 'buildTaskRequest' ? 'config.taskRequest.requireExisting.layerAssembly' : 'config.taskRequest.requireExisting.layerLive'));
|
|
665
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.requireExisting.noSession', { where, shape, layer })));
|
|
573
666
|
};
|
|
574
667
|
const refuseBadMaxTokens = (v) => {
|
|
575
668
|
if (v === undefined || v === null)
|
|
@@ -640,15 +733,15 @@ export function parseMaxCostUsd(text) {
|
|
|
640
733
|
return { ok: false, why: 'not_positive' };
|
|
641
734
|
return { ok: true, value };
|
|
642
735
|
}
|
|
643
|
-
const ACCESSOR_READ_ORDER = ['live', 'memoryCapture', '
|
|
644
|
-
const MATERIALIZE_AT_READ = Object.freeze({ allowTools: (v) => allowToolsSnapshot(v) });
|
|
736
|
+
const ACCESSOR_READ_ORDER = ['live', 'memoryCapture', 'hostSettings', 'settings', 'maxCostUsd', 'excludeAllTools', 'maxTokens', 'outputRetries', 'inheritEnv', 'requireExistingSession', 'disableSkills', 'approvalReach', 'allowTools', 'userInvokedSkills'];
|
|
737
|
+
const MATERIALIZE_AT_READ = Object.freeze({ allowTools: (v) => allowToolsSnapshot(v), userInvokedSkills: (v) => allowToolsSnapshot(v) });
|
|
645
738
|
function dataFirstSnapshot(input, afterData) {
|
|
646
739
|
let descs;
|
|
647
740
|
try {
|
|
648
741
|
descs = Object.getOwnPropertyDescriptors(input);
|
|
649
742
|
}
|
|
650
743
|
catch {
|
|
651
|
-
throw new TypeError(
|
|
744
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.inputKeysUnreadable')));
|
|
652
745
|
}
|
|
653
746
|
const bag = Object.create(null);
|
|
654
747
|
const accessors = [];
|
|
@@ -678,39 +771,52 @@ export function assembleTaskRequest(input, lane) {
|
|
|
678
771
|
let resolvedMaterialized;
|
|
679
772
|
let resolvedMaterializeError;
|
|
680
773
|
let resolvedHookRan = false;
|
|
774
|
+
let intakeEarly;
|
|
775
|
+
const materializeAtRead = (product) => (raw) => {
|
|
776
|
+
resolvedInEarly = raw;
|
|
777
|
+
try {
|
|
778
|
+
rethrowHostResolvedDeferred(product);
|
|
779
|
+
resolvedMaterialized = resolvedSnapshotForWire(resolvedInEarly);
|
|
780
|
+
}
|
|
781
|
+
catch (e) {
|
|
782
|
+
resolvedMaterializeError = e;
|
|
783
|
+
}
|
|
784
|
+
};
|
|
681
785
|
const src = dataFirstSnapshot(input, (bag) => {
|
|
682
|
-
|
|
683
|
-
|
|
786
|
+
if (!Object.hasOwn(bag, 'hostSettings'))
|
|
787
|
+
return;
|
|
788
|
+
const product = hostTurnSettingsOf(bag['hostSettings'], 'shape');
|
|
789
|
+
if (product !== undefined) {
|
|
684
790
|
resolvedHookRan = true;
|
|
685
|
-
|
|
686
|
-
try {
|
|
687
|
-
resolvedMaterialized = resolvedSnapshotForWire(resolvedInEarly);
|
|
688
|
-
}
|
|
689
|
-
catch (e) {
|
|
690
|
-
resolvedMaterializeError = e;
|
|
691
|
-
}
|
|
791
|
+
intakeEarly = hostIntakeSnapshotOf(product, materializeAtRead(product));
|
|
692
792
|
}
|
|
693
793
|
});
|
|
694
794
|
const live = src.live;
|
|
695
795
|
const memoryCaptureIn = src.memoryCapture;
|
|
696
|
-
const memoryIn = src.memory;
|
|
697
796
|
const settingsIn = src.settings;
|
|
698
797
|
if (present(settingsIn) && (typeof settingsIn !== 'object' || Array.isArray(settingsIn))) {
|
|
699
798
|
throw new TypeError(`buildTaskRequest: settings 只接受对象或缺席(undefined/null)—— 收到 ${coarseShape(settingsIn)}。` +
|
|
700
799
|
'这一位装着已解析权限面与 hooks:把畸形容器当成「没给」= 请求带着被剥掉的权限面照发。错误文本只报形状,不回显值。');
|
|
701
800
|
}
|
|
702
801
|
const settingsObj = present(settingsIn) ? settingsIn : {};
|
|
703
|
-
const
|
|
802
|
+
const hostIn = src.hostSettings;
|
|
803
|
+
const host = hostTurnSettingsOf(hostIn);
|
|
804
|
+
if (host === undefined) {
|
|
805
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.hostSettingsMalformed', { shape: coarseShape(hostIn) })));
|
|
806
|
+
}
|
|
807
|
+
const intake = resolvedHookRan ? intakeEarly : hostIntakeSnapshotOf(host, materializeAtRead(host));
|
|
808
|
+
if (intake === undefined)
|
|
809
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.hostSettingsMalformed', { shape: coarseShape(hostIn) })));
|
|
810
|
+
const resolvedIn = resolvedInEarly;
|
|
704
811
|
const resolvedRoute = SETTINGS_KEY_ROUTES.resolved;
|
|
705
812
|
const resolvedOpen = resolvedRoute.via === 'matrix' && omissionCauseOf(standingOf(resolvedRoute), lane, live) === undefined;
|
|
706
|
-
if (resolvedOpen &&
|
|
813
|
+
if (resolvedOpen && resolvedMaterializeError !== undefined)
|
|
707
814
|
throw resolvedMaterializeError;
|
|
708
815
|
const resolvedWire = resolvedOpen ? (resolvedMaterialized ?? resolvedSnapshotForWire(resolvedIn)) : {};
|
|
709
816
|
const maxCostUsdIn = src.maxCostUsd;
|
|
710
817
|
const excludeAllToolsIn = src.excludeAllTools;
|
|
711
818
|
const maxTokensIn = src.maxTokens;
|
|
712
819
|
const outputRetriesIn = src.outputRetries;
|
|
713
|
-
const fileHistoryIn = src.fileHistory;
|
|
714
820
|
const inheritEnvIn = src.inheritEnv;
|
|
715
821
|
const requireExistingSessionIn = src.requireExistingSession;
|
|
716
822
|
const disableSkillsIn = src.disableSkills;
|
|
@@ -720,12 +826,10 @@ export function assembleTaskRequest(input, lane) {
|
|
|
720
826
|
const i = snapshotByName(src, INPUT_KEYS, {
|
|
721
827
|
live,
|
|
722
828
|
memoryCapture: memoryCaptureIn,
|
|
723
|
-
memory: memoryIn,
|
|
724
829
|
maxCostUsd: maxCostUsdIn,
|
|
725
830
|
maxTokens: maxTokensIn,
|
|
726
831
|
excludeAllTools: excludeAllToolsIn,
|
|
727
832
|
outputRetries: outputRetriesIn,
|
|
728
|
-
fileHistory: fileHistoryIn,
|
|
729
833
|
inheritEnv: inheritEnvIn,
|
|
730
834
|
requireExistingSession: requireExistingSessionIn,
|
|
731
835
|
disableSkills: disableSkillsIn,
|
|
@@ -734,19 +838,26 @@ export function assembleTaskRequest(input, lane) {
|
|
|
734
838
|
settings: settingsIn,
|
|
735
839
|
});
|
|
736
840
|
const SETTINGS_KEYS = Object.keys(SETTINGS_KEY_ROUTES);
|
|
737
|
-
const
|
|
841
|
+
const hostSettingsKeysIn = HOST_SETTINGS_SUBKEYS.filter((k) => hasOwn(settingsObj, k) && present(Reflect.get(settingsObj, k)));
|
|
842
|
+
const hostTopKeysIn = HOST_TOP_KEYS.filter((k) => hasOwn(src, k) && present(Reflect.get(src, k)));
|
|
843
|
+
const s = {
|
|
844
|
+
resolved: resolvedIn,
|
|
845
|
+
webSearch: intake.carried.webSearch,
|
|
846
|
+
ultracode: snapshotByName(settingsObj, ['ultracode']).ultracode,
|
|
847
|
+
hooks: intake.carried.hooks,
|
|
848
|
+
outputStyle: intake.carried.outputStyle,
|
|
849
|
+
};
|
|
738
850
|
refuseBadMemoryCapture(memoryCaptureIn);
|
|
739
|
-
refuseBadMemoryOff(memoryIn);
|
|
740
851
|
refuseBadMaxCostUsd(maxCostUsdIn);
|
|
741
852
|
refuseBadExcludeAllTools(excludeAllToolsIn);
|
|
742
853
|
refuseBadMaxTokens(maxTokensIn);
|
|
743
854
|
refuseBadOutputRetries(outputRetriesIn);
|
|
744
|
-
refuseBadFileHistory(fileHistoryIn);
|
|
745
855
|
refuseBadInheritEnv(inheritEnvIn);
|
|
746
856
|
refuseBadRequireExistingSession(requireExistingSessionIn);
|
|
747
857
|
refuseBadDisableSkills(disableSkillsIn, 'buildTaskRequest');
|
|
748
858
|
refuseBadApprovalReach(approvalReachIn, 'buildTaskRequest');
|
|
749
859
|
refuseBadAllowTools(allowToolsIn);
|
|
860
|
+
refuseBadUserInvokedSkills(i.userInvokedSkills);
|
|
750
861
|
const rewindRoute = INPUT_KEY_ROUTES.rewind;
|
|
751
862
|
const RETIRED_REWIND_FILES_KEY = 'rewindFiles';
|
|
752
863
|
const REWIND_KEYS = rewindRoute.via === 'matrix' ? rewindRoute.field.split('/') : [];
|
|
@@ -774,6 +885,8 @@ export function assembleTaskRequest(input, lane) {
|
|
|
774
885
|
for (const key of Object.keys(src)) {
|
|
775
886
|
if (hasOwn(INPUT_KEY_ROUTES, key))
|
|
776
887
|
continue;
|
|
888
|
+
if (hasOwn(HOST_TOP_KEY_ROUTES, key))
|
|
889
|
+
continue;
|
|
777
890
|
const stray = Reflect.get(src, key);
|
|
778
891
|
if (!present(stray))
|
|
779
892
|
continue;
|
|
@@ -813,6 +926,12 @@ export function assembleTaskRequest(input, lane) {
|
|
|
813
926
|
'处置:删掉这个键;要在回退会话时一并还原文件,改交 ' +
|
|
814
927
|
'rewind.restoreFiles: true(必须与 rewind.resumeAt 同交);只还原文件、不动会话,交 rewind.rewindFilesTo。错误文本只报键名,不回显值。');
|
|
815
928
|
}
|
|
929
|
+
if (hostSettingsKeysIn.length > 0 || hostTopKeysIn.length > 0) {
|
|
930
|
+
throw new TypeError(renderMessage(msg('config.taskRequest.hostSuppliedKeysByHand', {
|
|
931
|
+
keys: [...hostSettingsKeysIn.map((k) => `settings.${k}`), ...hostTopKeysIn].join(', '),
|
|
932
|
+
fields: [...hostSettingsKeysIn, ...hostTopKeysIn].map((k) => `${k}: …`).join(', '),
|
|
933
|
+
})));
|
|
934
|
+
}
|
|
816
935
|
if (unknownKeys.length > 0) {
|
|
817
936
|
const shown = unknownKeys.slice(0, MAX_UNKNOWN_KEYS_SHOWN).map(keyForDisplay).join(', ');
|
|
818
937
|
const more = unknownKeys.length > MAX_UNKNOWN_KEYS_SHOWN ? ` 等共 ${unknownKeys.length} 个` : '';
|
|
@@ -826,6 +945,11 @@ export function assembleTaskRequest(input, lane) {
|
|
|
826
945
|
refuseRequireExistingWithoutSession(requireExistingSessionIn, i.sessionId);
|
|
827
946
|
refuseDisableSkillsConflict(disableSkillsIn, i.skills, Reflect.get(src, 'agents'), 'buildTaskRequest');
|
|
828
947
|
refuseUtilityWithoutToolUnload(lane, excludeAllToolsIn);
|
|
948
|
+
if (intake.refuses) {
|
|
949
|
+
const refusing = hostRefusalNoticeOf(intake, lane, live);
|
|
950
|
+
if (refusing !== undefined)
|
|
951
|
+
throw new HostSettingsRefused(refusing);
|
|
952
|
+
}
|
|
829
953
|
const carries = (route, value, key) => {
|
|
830
954
|
if (route.via === 'always')
|
|
831
955
|
return present(value);
|
|
@@ -840,15 +964,25 @@ export function assembleTaskRequest(input, lane) {
|
|
|
840
964
|
return false;
|
|
841
965
|
};
|
|
842
966
|
const gate = Object.create(null);
|
|
843
|
-
|
|
967
|
+
const askInput = (key) => {
|
|
844
968
|
const route = INPUT_KEY_ROUTES[key];
|
|
845
969
|
if (route.via === 'settings') {
|
|
846
970
|
for (const sub of SETTINGS_KEYS)
|
|
847
971
|
gate[`settings.${sub}`] = carries(SETTINGS_KEY_ROUTES[sub], s[sub], `settings.${sub}`);
|
|
848
|
-
|
|
972
|
+
return;
|
|
849
973
|
}
|
|
850
974
|
gate[key] = carries(route, key === 'rewind' ? rewindForGate : i[key], key);
|
|
851
|
-
}
|
|
975
|
+
};
|
|
976
|
+
const anchorAt = INPUT_KEYS.indexOf(HOST_TOP_ASK_AFTER);
|
|
977
|
+
const hostTopAt = anchorAt < 0 ? INPUT_KEYS.length : anchorAt + 1;
|
|
978
|
+
for (const key of INPUT_KEYS.slice(0, hostTopAt))
|
|
979
|
+
askInput(key);
|
|
980
|
+
const hostTopGate = {
|
|
981
|
+
memory: carries(HOST_TOP_KEY_ROUTES.memory, intake.carried.memory, 'memory'),
|
|
982
|
+
fileHistory: carries(HOST_TOP_KEY_ROUTES.fileHistory, intake.carried.fileHistory, 'fileHistory'),
|
|
983
|
+
};
|
|
984
|
+
for (const key of INPUT_KEYS.slice(hostTopAt))
|
|
985
|
+
askInput(key);
|
|
852
986
|
const on = (key) => gate[key] === true;
|
|
853
987
|
const onSetting = (sub) => gate[`settings.${sub}`] === true;
|
|
854
988
|
const settingsOut = {
|
|
@@ -867,7 +1001,9 @@ export function assembleTaskRequest(input, lane) {
|
|
|
867
1001
|
...(on('reasoningEffort') ? { reasoningEffort: i.reasoningEffort } : {}),
|
|
868
1002
|
...(on('model') ? { model: i.model } : {}),
|
|
869
1003
|
...(on('images') ? { images: i.images } : {}),
|
|
1004
|
+
...(on('userAttachments') ? { userAttachments: [...(i.userAttachments ?? [])] } : {}),
|
|
870
1005
|
...(on('skills') ? { skills: i.skills } : {}),
|
|
1006
|
+
...(on('userInvokedSkills') ? { userInvokedSkills: allowToolsCopy(i.userInvokedSkills) } : {}),
|
|
871
1007
|
...(on('mcpServers') ? { mcpServers: i.mcpServers } : {}),
|
|
872
1008
|
...(on('rewind') ? rewindWire : {}),
|
|
873
1009
|
...(on('permissionMode') ? { permissionMode: i.permissionMode } : {}),
|
|
@@ -894,15 +1030,15 @@ export function assembleTaskRequest(input, lane) {
|
|
|
894
1030
|
...(on('maxCostUsd') ? { maxCostUsd: maxCostUsdIn } : {}),
|
|
895
1031
|
...(on('maxTokens') ? { maxTokens: i.maxTokens } : {}),
|
|
896
1032
|
...(on('memoryCapture') ? { memoryCapture: 'off' } : {}),
|
|
897
|
-
...(
|
|
898
|
-
...(
|
|
1033
|
+
...(hostTopGate.memory ? { memory: 'off' } : {}),
|
|
1034
|
+
...(hostTopGate.fileHistory ? { fileHistory: FILE_HISTORY_DISABLED } : {}),
|
|
899
1035
|
...(on('inheritEnv') ? { inheritEnv: inheritEnvIn } : {}),
|
|
900
1036
|
...(on('requireExistingSession') ? { requireExistingSession: true } : {}),
|
|
901
1037
|
...(on('disableSkills') ? { disableSkills: true } : {}),
|
|
902
1038
|
...(on('approvalReach') ? { approvalReach: approvalReachIn } : {}),
|
|
903
1039
|
...(Object.keys(settingsOut).length > 0 ? { settings: settingsOut } : {}),
|
|
904
1040
|
};
|
|
905
|
-
return Object.freeze({ request: out, omitted: Object.freeze([...omitted, ...lateOmitted]) });
|
|
1041
|
+
return Object.freeze({ request: out, omitted: Object.freeze([...omitted, ...lateOmitted]), host });
|
|
906
1042
|
}
|
|
907
1043
|
export function buildTaskRequest(input, lane) {
|
|
908
1044
|
return assembleTaskRequest(input, lane).request;
|
|
@@ -955,6 +1091,7 @@ export function applyLiveRequestDefaults(req, host) {
|
|
|
955
1091
|
out.sessionId === host.mockSessionIdConstant) {
|
|
956
1092
|
delete out.sessionId;
|
|
957
1093
|
}
|
|
1094
|
+
refuseRequireExistingWithoutSession(out.requireExistingSession, out.sessionId, 'applyLiveRequestDefaults');
|
|
958
1095
|
return out;
|
|
959
1096
|
}
|
|
960
1097
|
export function unregisteredRequestKeys(req, lane) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { UiLanguage } from './env/uiLanguage.js';
|
|
1
2
|
import type { ResumeStartupCause } from '@sema-agent/sdk';
|
|
2
3
|
import { RESUME_CONTEXT_UNAVAILABLE, CHECKPOINT_UNSUPPORTED_VERSION, CHECKPOINT_WALLTIME_AXIS_RETIRED, CHECKPOINT_CONFIG_REFUSED } from './engineErrorCodes.js';
|
|
3
4
|
export declare const RESUME_REFUSAL_CODES: readonly string[];
|
|
@@ -7,7 +8,7 @@ export interface ResumeRefusalDetail {
|
|
|
7
8
|
waitable: boolean;
|
|
8
9
|
}
|
|
9
10
|
export declare function resumeRefusalFromError(err: unknown): ResumeRefusalDetail | null;
|
|
10
|
-
export declare function resumeRefusalContent(detail: ResumeRefusalDetail): string;
|
|
11
|
+
export declare function resumeRefusalContent(detail: ResumeRefusalDetail, lang?: UiLanguage): string;
|
|
11
12
|
export interface ResumePolicyBlockDetail {
|
|
12
13
|
blockedBy: {
|
|
13
14
|
kind: 'named';
|
|
@@ -19,7 +20,7 @@ export interface ResumePolicyBlockDetail {
|
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
export declare function resumePolicyBlockFromError(err: unknown): ResumePolicyBlockDetail | null;
|
|
22
|
-
export declare function resumePolicyBlockContent(detail: ResumePolicyBlockDetail): string;
|
|
23
|
+
export declare function resumePolicyBlockContent(detail: ResumePolicyBlockDetail, lang?: UiLanguage): string;
|
|
23
24
|
export { resumeReopenFromError, resumeReopenContent } from './hitl/suspendedReopen.js';
|
|
24
25
|
export type { ResumeReopenDetail } from './hitl/suspendedReopen.js';
|
|
25
26
|
export type RequireExistingSessionRefusalForm = 'session_not_found' | 'session_id_missing';
|
|
@@ -28,26 +29,28 @@ export interface RequireExistingSessionRefusalDetail {
|
|
|
28
29
|
readonly form: RequireExistingSessionRefusalForm;
|
|
29
30
|
}
|
|
30
31
|
export declare function requireExistingSessionRefusalFromError(err: unknown): RequireExistingSessionRefusalDetail | null;
|
|
31
|
-
export declare function requireExistingSessionRefusalContent(detail: Pick<RequireExistingSessionRefusalDetail, 'form'
|
|
32
|
+
export declare function requireExistingSessionRefusalContent(detail: Pick<RequireExistingSessionRefusalDetail, 'form'>, lang?: UiLanguage): string;
|
|
32
33
|
export interface ResumeContextUnavailableDetail {
|
|
33
34
|
code: typeof RESUME_CONTEXT_UNAVAILABLE;
|
|
34
35
|
staleAfterSec?: number;
|
|
35
36
|
runId?: string;
|
|
36
37
|
}
|
|
37
38
|
export declare function resumeContextUnavailableFromError(err: unknown): ResumeContextUnavailableDetail | null;
|
|
38
|
-
export declare function resumeContextUnavailableContent(d: ResumeContextUnavailableDetail): string;
|
|
39
|
+
export declare function resumeContextUnavailableContent(d: ResumeContextUnavailableDetail, lang?: UiLanguage): string;
|
|
39
40
|
export type ParkedResumeStartupDecision = 'approve' | 'deny';
|
|
40
41
|
export type ParkedResumeStartupCause = 'resume_rejected' | 'undetermined';
|
|
41
42
|
export interface ParkedResumeStartupDetail {
|
|
42
43
|
code: string;
|
|
43
44
|
cause: ParkedResumeStartupCause;
|
|
44
45
|
taskId?: string;
|
|
45
|
-
startupCause?: ResumeStartupCause;
|
|
46
|
+
startupCause?: ResumeStartupCause | ResumeCauseCoreAhead;
|
|
46
47
|
resendable: false;
|
|
47
48
|
denyStaysOpen: true;
|
|
48
49
|
}
|
|
50
|
+
declare const RESUME_CAUSE_CORE_AHEAD: readonly ["transcript_corrupt"];
|
|
51
|
+
type ResumeCauseCoreAhead = Exclude<(typeof RESUME_CAUSE_CORE_AHEAD)[number], ResumeStartupCause>;
|
|
49
52
|
export declare function parkedResumeStartupFromError(err: unknown, decision?: ParkedResumeStartupDecision): ParkedResumeStartupDetail | null;
|
|
50
|
-
export declare function parkedResumeStartupContent(detail: ParkedResumeStartupDetail): string;
|
|
53
|
+
export declare function parkedResumeStartupContent(detail: ParkedResumeStartupDetail, lang?: UiLanguage): string;
|
|
51
54
|
export interface CheckpointUnsupportedVersionDetail {
|
|
52
55
|
code: 'checkpoint.unsupported_version';
|
|
53
56
|
retriable: true;
|
|
@@ -60,12 +63,14 @@ export interface CheckpointUnsupportedVersionContext {
|
|
|
60
63
|
readonly parkKind?: CheckpointUnsupportedParkKind;
|
|
61
64
|
readonly runId?: string;
|
|
62
65
|
}
|
|
63
|
-
export declare function checkpointUnsupportedVersionContent(detail: CheckpointUnsupportedVersionDetail, ctx?: CheckpointUnsupportedVersionContext): string;
|
|
66
|
+
export declare function checkpointUnsupportedVersionContent(detail: CheckpointUnsupportedVersionDetail, ctx?: CheckpointUnsupportedVersionContext, lang?: UiLanguage): string;
|
|
64
67
|
export type RefusedParkCode = typeof CHECKPOINT_UNSUPPORTED_VERSION | typeof CHECKPOINT_WALLTIME_AXIS_RETIRED | typeof CHECKPOINT_CONFIG_REFUSED;
|
|
65
68
|
export interface RefusedParkFacts {
|
|
66
69
|
readonly code: RefusedParkCode;
|
|
67
70
|
readonly field?: string;
|
|
68
71
|
readonly stillPending?: boolean;
|
|
72
|
+
readonly blockedBy?: string;
|
|
73
|
+
readonly reason?: string;
|
|
69
74
|
}
|
|
70
75
|
export declare function refusedParkFromError(failure: unknown): RefusedParkFacts | null;
|
|
71
76
|
export interface RefusedParkContentInput {
|
|
@@ -74,5 +79,5 @@ export interface RefusedParkContentInput {
|
|
|
74
79
|
readonly lane: 'interactive' | 'print';
|
|
75
80
|
readonly runId?: string;
|
|
76
81
|
}
|
|
77
|
-
export declare function refusedParkContent(input: RefusedParkContentInput): string;
|
|
78
|
-
export declare function refusedParkBlockedContent(taskId: string, lane?: 'interactive' | 'print'): string;
|
|
82
|
+
export declare function refusedParkContent(input: RefusedParkContentInput, lang?: UiLanguage): string;
|
|
83
|
+
export declare function refusedParkBlockedContent(taskId: string, lane?: 'interactive' | 'print', lang?: UiLanguage): string;
|