@sema-agent/client-core 0.91.0 → 0.93.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +351 -0
- package/README.md +51 -34
- package/dist/adapt/arms.js +6 -12
- package/dist/adapt/panelTasks.d.ts +0 -2
- package/dist/adapt/panelTasks.js +6 -26
- package/dist/adapt/toolCards.js +6 -4
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +3 -3
- package/dist/adapter/activeRunSelfHeal.d.ts +0 -2
- package/dist/adapter/activeRunSelfHeal.js +5 -27
- package/dist/adapter/downstream/terminalToSdkResult.js +16 -7
- package/dist/adapter/runStream.js +6 -2
- package/dist/agentsWireCaps.js +1 -1
- package/dist/approvalDecidedByCapability.d.ts +16 -0
- package/dist/approvalDecidedByCapability.js +47 -0
- package/dist/approvalsStreamLiveCapability.js +3 -3
- package/dist/askSurvivesStandingAnswer.d.ts +4 -1
- package/dist/askSurvivesStandingAnswer.js +13 -0
- package/dist/autoModeUnavailable.js +3 -2
- package/dist/centerWiringCapability.js +1 -1
- package/dist/cloudConfigWireCaps.js +10 -9
- package/dist/compensations.js +7 -7
- package/dist/controlRouter.d.ts +23 -23
- package/dist/controlRouter.js +114 -49
- package/dist/coreValuePorts.d.ts +4 -2
- package/dist/coreValuePorts.js +5 -0
- package/dist/decideFailureNote.js +4 -2
- package/dist/decideReceipt.d.ts +11 -0
- package/dist/decideReceipt.js +95 -9
- package/dist/detachWire.d.ts +2 -14
- package/dist/detachWire.js +1 -47
- package/dist/deviceExecutorManagementCapability.d.ts +6 -2
- package/dist/deviceExecutorManagementCapability.js +61 -15
- package/dist/displayUntrusted.js +2 -1
- package/dist/effectiveFacts.d.ts +14 -4
- package/dist/effectiveFacts.js +45 -5
- package/dist/engineAgentAbsence.js +2 -1
- package/dist/engineCapReader.js +16 -10
- package/dist/engineCapsCache.d.ts +2 -0
- package/dist/engineCapsCache.js +13 -2
- package/dist/engineConfigDrift.d.ts +20 -0
- package/dist/engineConfigDrift.js +54 -0
- package/dist/engineErrorCodes.d.ts +17 -0
- package/dist/engineErrorCodes.js +45 -0
- package/dist/engineInlineTaskStats.d.ts +1 -0
- package/dist/engineNoticeCodes.d.ts +16 -2
- package/dist/engineNoticeCodes.js +71 -0
- package/dist/engineWireFor.d.ts +22 -0
- package/dist/engineWireFor.js +154 -9
- package/dist/engineWireSdk.d.ts +0 -1
- package/dist/engineWireSdk.js +0 -3
- package/dist/executionLaneCapability.js +4 -2
- package/dist/fileHistoryCaptureCapability.d.ts +1 -1
- package/dist/fileHistoryCaptureCapability.js +1 -6
- package/dist/fileHistoryLegNotice.d.ts +1 -1
- package/dist/fileHistoryLegNotice.js +1 -6
- package/dist/gateOutcome.js +2 -17
- package/dist/gateVocabulary.d.ts +2 -8
- package/dist/gateVocabulary.js +6 -32
- package/dist/generated/engineFactTables.d.ts +17 -1
- package/dist/generated/engineFactTables.js +91 -0
- package/dist/generated/engineNoticeTables.d.ts +1 -1
- package/dist/generated/engineNoticeTables.js +4 -1
- package/dist/generated/settingsSchemaTables.d.ts +8 -0
- package/dist/generated/settingsSchemaTables.js +40 -0
- package/dist/goalStopHook.d.ts +1 -8
- package/dist/goalStopHook.js +2 -58
- package/dist/headlessPermissionModeWire.d.ts +3 -2
- package/dist/headlessPermissionModeWire.js +46 -5
- package/dist/hitl/allowRuleShadow.d.ts +21 -0
- package/dist/hitl/allowRuleShadow.js +167 -0
- package/dist/hitl/askClassPair.d.ts +14 -0
- package/dist/hitl/askClassPair.js +42 -0
- package/dist/hitl/askGateWire.js +1 -0
- package/dist/hitl/askParkRowRouting.js +2 -2
- package/dist/hitl/askSurvivesPosture.d.ts +5 -0
- package/dist/hitl/askSurvivesPosture.js +17 -0
- package/dist/hitl/automaticAnswerVerdict.d.ts +21 -0
- package/dist/hitl/automaticAnswerVerdict.js +143 -0
- package/dist/hitl/crashConverged.d.ts +1 -0
- package/dist/hitl/crashConverged.js +1 -1
- package/dist/hitl/frameRouter.d.ts +2 -0
- package/dist/hitl/frameRouter.js +73 -16
- package/dist/hitl/gateLedger.d.ts +7 -0
- package/dist/hitl/gateLedger.js +37 -5
- package/dist/hitl/hitlBridge.d.ts +1 -0
- package/dist/hitl/hitlBridge.js +6 -1
- package/dist/hitl/hitlHostSurface.d.ts +5 -2
- package/dist/hitl/hitlHostSurface.js +25 -3
- package/dist/hitl/livePendingAsk.js +24 -5
- package/dist/hitl/parkResolver.js +24 -4
- package/dist/hitl/persistedRulesWire.d.ts +4 -1
- package/dist/hitl/persistedRulesWire.js +38 -19
- package/dist/hitl/planReviewWire.d.ts +0 -2
- package/dist/hitl/planReviewWire.js +3 -20
- package/dist/hitl/replayedApproval.d.ts +21 -0
- package/dist/hitl/replayedApproval.js +89 -0
- package/dist/hitl/sessionPolicyDeliverable.js +20 -2
- package/dist/hitl/sessionPolicyWire.d.ts +10 -0
- package/dist/hitl/sessionPolicyWire.js +19 -6
- package/dist/hitl/toolApprovalWire.d.ts +27 -7
- package/dist/hitl/toolApprovalWire.js +153 -94
- package/dist/hookMatcherVerdict.js +2 -1
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +1 -1
- package/dist/humanTurn.js +3 -4
- package/dist/index.d.ts +21 -6
- package/dist/index.js +17 -4
- package/dist/inheritEnvWire.d.ts +1 -4
- package/dist/inheritEnvWire.js +3 -22
- package/dist/limitsWire.d.ts +0 -6
- package/dist/limitsWire.js +0 -38
- package/dist/mcpLiveness.js +2 -1
- package/dist/mcpProbeCapability.js +1 -1
- package/dist/mcpProbeWire.js +10 -12
- package/dist/mcpReconnect.d.ts +5 -0
- package/dist/mcpReconnect.js +28 -0
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/memoryVerbsWire.d.ts +1 -1
- package/dist/memoryVerbsWire.js +17 -13
- package/dist/model/catalog.js +2 -1
- package/dist/model/providerPresets.d.ts +3 -1
- package/dist/model/tierVocabulary.d.ts +2 -1
- package/dist/model/tierVocabulary.js +3 -8
- package/dist/ownKey.d.ts +2 -0
- package/dist/ownKey.js +15 -0
- package/dist/peerFrames.js +2 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.d.ts +16 -0
- package/dist/permissionModesCapability.js +71 -0
- package/dist/permissionRuleIssue.js +10 -7
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionWireCaps.d.ts +2 -0
- package/dist/permissionWireCaps.js +8 -1
- package/dist/permissionsAllowGrantCapability.js +7 -2
- package/dist/permissionsDeclaration.d.ts +7 -1
- package/dist/permissionsDeclaration.js +29 -20
- package/dist/pluginHooksWire.js +2 -11
- package/dist/postureKnob.js +1 -1
- package/dist/promptProfileWireCaps.d.ts +2 -1
- package/dist/protocolSegment.d.ts +11 -0
- package/dist/protocolSegment.js +31 -0
- package/dist/readFacePosture.js +1 -1
- package/dist/request/taskRequest.js +1 -15
- package/dist/resumeRefusalCopy.d.ts +1 -0
- package/dist/resumeRefusalCopy.js +26 -3
- package/dist/retryStatus.js +2 -1
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/ruleCompileVerdict.d.ts +2 -0
- package/dist/ruleCompileVerdict.js +13 -0
- package/dist/ruleRemovalConsequence.d.ts +2 -1
- package/dist/runCancelContext.d.ts +12 -0
- package/dist/runCancelContext.js +83 -1
- package/dist/runTerminal.d.ts +16 -0
- package/dist/runTerminal.js +32 -3
- package/dist/seam.d.ts +1 -0
- package/dist/seam.js +1 -1
- package/dist/seatContract.d.ts +2 -1
- package/dist/sessionMemoryStatus.d.ts +2 -4
- package/dist/sessionPolicyCapability.js +1 -1
- package/dist/sessionSyncFileHistoryCapability.d.ts +18 -0
- package/dist/sessionSyncFileHistoryCapability.js +50 -0
- package/dist/skillToolListsCapability.d.ts +18 -0
- package/dist/skillToolListsCapability.js +50 -0
- package/dist/sqlEngineCapability.js +2 -9
- package/dist/steerPriorityCapability.d.ts +18 -0
- package/dist/steerPriorityCapability.js +80 -0
- package/dist/steerReceipt.d.ts +9 -0
- package/dist/steerReceipt.js +25 -0
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/engineSubagentSteer.js +2 -9
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +15 -5
- package/dist/taskRequestWords.d.ts +4 -2
- package/dist/taskRequestWords.js +1 -1
- package/dist/toolHistoryBadTurn.js +1 -2
- package/dist/toolResult.d.ts +10 -1
- package/dist/toolResult.js +80 -6
- package/dist/types/engineState.d.ts +2 -12
- package/dist/userInvokedSkillsCapability.d.ts +18 -0
- package/dist/userInvokedSkillsCapability.js +50 -0
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/webSearchWireCaps.d.ts +1 -1
- package/dist/webSearchWireCaps.js +40 -2
- package/dist/wireFailureShape.d.ts +2 -0
- package/dist/wireFailureShape.js +6 -2
- package/dist/wireRefusalCopy.d.ts +9 -3
- package/dist/wireRefusalCopy.js +41 -4
- package/dist/workflowsJournalCapability.d.ts +18 -0
- package/dist/workflowsJournalCapability.js +50 -0
- package/dist/writeProtectionCapability.d.ts +2 -4
- package/dist/writeProtectionCapability.js +1 -1
- package/docs/INTEGRATION-CLIENTS.md +1516 -18
- package/package.json +2 -2
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import { CORE_CC_MODEL_TIER_ALIASES, CORE_DEFAULT_TIER_ORDER } from '../generated/engineFactTables.js';
|
|
2
|
+
export const TIER_ORDER = CORE_DEFAULT_TIER_ORDER;
|
|
2
3
|
export const SURFACED_TIERS = ['max', 'pro', 'flash', 'lite'];
|
|
3
|
-
export const CC_TIER_ALIASES =
|
|
4
|
-
fable: 'max',
|
|
5
|
-
mythos: 'max',
|
|
6
|
-
opus: 'pro',
|
|
7
|
-
sonnet: 'flash',
|
|
8
|
-
haiku: 'lite',
|
|
9
|
-
};
|
|
4
|
+
export const CC_TIER_ALIASES = CORE_CC_MODEL_TIER_ALIASES;
|
|
10
5
|
export const DEFAULT_TIER = 'pro';
|
|
11
6
|
export const TIER_BLURBS = {
|
|
12
7
|
ultra: 'reserved above max — binds when a stronger model lands',
|
package/dist/ownKey.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export declare function putOwnKey<T>(table: Record<string, T>, key: string, value: T): void;
|
|
2
2
|
export declare function readOwnNonEmptyString(v: object | null | undefined, key: string): string | undefined;
|
|
3
|
+
export declare function readOwnDataNonEmptyString(v: object | null | undefined, key: string): string | undefined;
|
|
4
|
+
export declare function readOwnDataValue<T>(v: object | null | undefined, key: string): T | undefined;
|
package/dist/ownKey.js
CHANGED
|
@@ -7,3 +7,18 @@ export function readOwnNonEmptyString(v, key) {
|
|
|
7
7
|
const raw = v[key];
|
|
8
8
|
return typeof raw === 'string' && raw !== '' ? raw : undefined;
|
|
9
9
|
}
|
|
10
|
+
export function readOwnDataNonEmptyString(v, key) {
|
|
11
|
+
if (typeof v !== 'object' || v === null)
|
|
12
|
+
return undefined;
|
|
13
|
+
const d = Object.getOwnPropertyDescriptor(v, key);
|
|
14
|
+
if (d === undefined || !Object.hasOwn(d, 'value'))
|
|
15
|
+
return undefined;
|
|
16
|
+
const raw = d.value;
|
|
17
|
+
return typeof raw === 'string' && raw !== '' ? raw : undefined;
|
|
18
|
+
}
|
|
19
|
+
export function readOwnDataValue(v, key) {
|
|
20
|
+
if (typeof v !== 'object' || v === null)
|
|
21
|
+
return undefined;
|
|
22
|
+
const d = Object.getOwnPropertyDescriptor(v, key);
|
|
23
|
+
return d !== undefined && Object.hasOwn(d, 'value') ? d.value : undefined;
|
|
24
|
+
}
|
package/dist/peerFrames.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { applyDisplayFace, LEGACY_NAME_FACE } from './displayUntrusted.js';
|
|
2
|
-
import { CORE_ENGINE_AUTHORITY_ENVELOPE_TAGS } from './generated/engineFactTables.js';
|
|
2
|
+
import { CORE_ENGINE_AUTHORITY_ENVELOPE_TAGS, CORE_PERMISSION_MODE_CLASSES } from './generated/engineFactTables.js';
|
|
3
3
|
const WIRE_KEY_FROM = 'from';
|
|
4
4
|
const WIRE_KEY_BODY = 'body';
|
|
5
5
|
const WIRE_KEY_KIND = 'kind';
|
|
@@ -21,7 +21,7 @@ export const AGENT_MESSAGE_TAG = 'agent-message';
|
|
|
21
21
|
export const CROSS_SESSION_MESSAGE_TAG = 'cross-session-message';
|
|
22
22
|
export const PEER_FRAME_LANES = Object.freeze(['agent_message', 'cross_session_message', 'cross_session_notice']);
|
|
23
23
|
export const CROSS_SESSION_NOTICE_KINDS = Object.freeze(['delivery_notice', 'idle_notice']);
|
|
24
|
-
export const PEER_MODE_CLASSES =
|
|
24
|
+
export const PEER_MODE_CLASSES = CORE_PERMISSION_MODE_CLASSES;
|
|
25
25
|
function dataProp(o, key) {
|
|
26
26
|
if (o === null || typeof o !== 'object')
|
|
27
27
|
return undefined;
|
|
@@ -35,9 +35,9 @@ export function peerLaneAvailable(reading) {
|
|
|
35
35
|
export function peerLaneDoctorDetail(reading) {
|
|
36
36
|
switch (reading.kind) {
|
|
37
37
|
case 'unobserved':
|
|
38
|
-
return 'cross-session lane not observed — the engine reports it on /v1/capabilities (peerLane); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
38
|
+
return 'cross-session lane not observed — the engine reports it on /v1/capabilities (peerLane); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
39
39
|
case 'not_reported':
|
|
40
|
-
return 'cross-session lane not reported by this engine —
|
|
40
|
+
return 'cross-session lane not reported by this engine — its capabilities reading carries no entry for the lane, so whether this deployment has cross-session discovery or delivery is unknown to this client';
|
|
41
41
|
case 'absent':
|
|
42
42
|
return 'no cross-session lane on this deployment — cross-session discovery and delivery (listing other sessions, addressing one by id) are unavailable';
|
|
43
43
|
case 'present':
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type PermissionModesReading = {
|
|
2
|
+
kind: 'unobserved';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'not_reported';
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'present';
|
|
7
|
+
modes: readonly string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function projectPermissionModesCapability(caps: unknown): PermissionModesReading | undefined;
|
|
10
|
+
export declare function noteEngineCapsForPermissionModes(baseUrl: string, caps: unknown, opts?: {
|
|
11
|
+
generation?: number;
|
|
12
|
+
}): void;
|
|
13
|
+
export declare function observedPermissionModes(baseUrl?: string | undefined): PermissionModesReading;
|
|
14
|
+
export declare function permissionModeAdmitted(reading: PermissionModesReading | undefined, mode: string): boolean;
|
|
15
|
+
export declare function forgetPermissionModesReading(baseUrl: string | undefined): void;
|
|
16
|
+
export declare function __resetPermissionModesReadingsForTests(): void;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
+
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
import { readOwnDataValue } from './ownKey.js';
|
|
4
|
+
function readModesStrict(v) {
|
|
5
|
+
try {
|
|
6
|
+
if (!Array.isArray(v))
|
|
7
|
+
return undefined;
|
|
8
|
+
const length = v.length;
|
|
9
|
+
if (length === 0)
|
|
10
|
+
return undefined;
|
|
11
|
+
const modes = [];
|
|
12
|
+
for (let i = 0; i < length; i++) {
|
|
13
|
+
const item = readOwnDataValue(v, String(i));
|
|
14
|
+
if (typeof item !== 'string' || item.length === 0)
|
|
15
|
+
return undefined;
|
|
16
|
+
modes.push(item);
|
|
17
|
+
}
|
|
18
|
+
return modes;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function projectPermissionModesCapability(caps) {
|
|
25
|
+
try {
|
|
26
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
27
|
+
return undefined;
|
|
28
|
+
if (!Object.hasOwn(caps, 'permissionModes'))
|
|
29
|
+
return { kind: 'not_reported' };
|
|
30
|
+
const v = caps.permissionModes;
|
|
31
|
+
if (v === undefined)
|
|
32
|
+
return { kind: 'not_reported' };
|
|
33
|
+
const modes = readModesStrict(v);
|
|
34
|
+
return modes === undefined ? undefined : { kind: 'present', modes };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const reader = createEngineCapReader({
|
|
41
|
+
name: 'permissionModes',
|
|
42
|
+
project: projectPermissionModesCapability,
|
|
43
|
+
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
44
|
+
});
|
|
45
|
+
export function noteEngineCapsForPermissionModes(baseUrl, caps, opts) {
|
|
46
|
+
reader.note(baseUrl, caps, opts);
|
|
47
|
+
}
|
|
48
|
+
export function observedPermissionModes(baseUrl = engineWireTarget()?.baseUrl) {
|
|
49
|
+
return reader.observed(baseUrl);
|
|
50
|
+
}
|
|
51
|
+
export function permissionModeAdmitted(reading, mode) {
|
|
52
|
+
try {
|
|
53
|
+
if (typeof mode !== 'string' || mode.length === 0)
|
|
54
|
+
return false;
|
|
55
|
+
if (reading === null || reading === undefined || typeof reading !== 'object' || Array.isArray(reading))
|
|
56
|
+
return false;
|
|
57
|
+
if (readOwnDataValue(reading, 'kind') !== 'present')
|
|
58
|
+
return false;
|
|
59
|
+
const modes = readModesStrict(readOwnDataValue(reading, 'modes'));
|
|
60
|
+
return modes !== undefined && modes.includes(mode);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function forgetPermissionModesReading(baseUrl) {
|
|
67
|
+
reader.forget(baseUrl);
|
|
68
|
+
}
|
|
69
|
+
export function __resetPermissionModesReadingsForTests() {
|
|
70
|
+
reader.__resetForTests();
|
|
71
|
+
}
|
|
@@ -3,15 +3,15 @@ export const PERMISSION_RULE_ISSUE_CODES = Object.freeze([
|
|
|
3
3
|
'invalid.empty_tool',
|
|
4
4
|
'invalid.paren',
|
|
5
5
|
'invalid.param_split',
|
|
6
|
-
'invalid.allow_param_rule',
|
|
7
6
|
'invalid.primary_field',
|
|
8
7
|
'invalid.cap_exceeded',
|
|
9
|
-
'unsupported.
|
|
8
|
+
'unsupported.allow',
|
|
9
|
+
'invalid.behavior',
|
|
10
10
|
'invalid.command_rule',
|
|
11
|
+
'invalid.entry_type',
|
|
11
12
|
'unsupported.param_unknown',
|
|
12
13
|
'unsupported.param_non_scalar',
|
|
13
14
|
'unsupported.tool_unknown',
|
|
14
|
-
'unsupported.file_glob',
|
|
15
15
|
'unsupported.path_base',
|
|
16
16
|
'unsupported.mcp_paren',
|
|
17
17
|
'unsupported.covering_paren',
|
|
@@ -22,18 +22,21 @@ const ISSUE_SENTENCES = Object.freeze({
|
|
|
22
22
|
'invalid.empty_tool': 'this rule is invalid: it names no tool',
|
|
23
23
|
'invalid.paren': 'this rule is invalid: its parentheses do not parse (escape a literal one as \\( or \\))',
|
|
24
24
|
'invalid.param_split': 'this rule is invalid: its parentheses do not hold a parameter rule written name:pattern',
|
|
25
|
-
'invalid.allow_param_rule': 'this rule is invalid: an allow rule cannot carry a parameter pattern — only bare tool rules auto-allow',
|
|
26
25
|
'invalid.primary_field': "this rule is invalid: it patterns the tool's primary field, which matches the whole trimmed string rather than a prefix",
|
|
27
|
-
'invalid.cap_exceeded': 'this rule set is invalid: it is over one of the deployment caps (rule count, rule length, pattern length, or star count)',
|
|
26
|
+
'invalid.cap_exceeded': 'this rule set is invalid: it is over one of the deployment caps (rule count, rule length, pattern length, or star count); this client cannot tell which from the code alone',
|
|
27
|
+
'invalid.behavior': 'this rule is invalid: its behavior is neither deny nor ask, so it would never fire',
|
|
28
28
|
'invalid.command_rule': 'this rule is invalid: the command pattern was rejected by the command-rule validator',
|
|
29
|
-
'
|
|
29
|
+
'invalid.entry_type': 'this allow list is invalid: it must be a list of rule strings, and it or one of its entries is not a string',
|
|
30
|
+
'unsupported.allow': 'an allow rule is not supported in a rule set that only says deny or ask — a standing approval belongs on the allow list instead',
|
|
30
31
|
'unsupported.param_unknown': 'this parameter rule is not supported: the tool carries no such parameter, so it could never match',
|
|
31
32
|
'unsupported.param_non_scalar': 'this parameter rule is not supported: that parameter holds an object or an array, so it could never match',
|
|
32
33
|
'unsupported.tool_unknown': "this rule is not supported on this leg: the resolver it supplied does not know the tool, so the rule's face cannot be checked",
|
|
33
|
-
'unsupported.file_glob': 'a standing approval by path belongs in the consent store, so this allow rule is not supported here (deny and ask path rules do compile)',
|
|
34
34
|
'unsupported.path_base': 'this path rule is not supported as spelled: it needs a base this policy was not given, so it would reach nothing and is refused rather than compiled',
|
|
35
35
|
'unsupported.mcp_paren': 'a parenthesised parameter rule is not supported on an MCP tool name',
|
|
36
36
|
'unsupported.covering_paren': 'a parenthesised parameter rule is not supported on a covering protocol name — the parameter grammar is keyed by an exact tool name, so no mounted tool could ever bear it',
|
|
37
|
+
'invalid.allow_param_rule': 'this rule is invalid: an allow rule cannot carry a parameter pattern — only bare tool rules auto-allow',
|
|
38
|
+
'unsupported.bash_prefix': 'a standing approval for a command belongs in the persisted-rule store, so this allow rule is not supported here (deny and ask rules with the same shape do compile)',
|
|
39
|
+
'unsupported.file_glob': 'a standing approval by path belongs in the consent store, so this allow rule is not supported here (deny and ask path rules do compile)',
|
|
37
40
|
});
|
|
38
41
|
const PARAM_SPLIT_WITH_COLON = 'this rule is invalid: a parameter rule is written name:pattern, and the name before the colon or the pattern after it is empty';
|
|
39
42
|
const PARAM_SPLIT_NO_COLON = 'this rule is invalid: there is no colon inside the parentheses, so this is not a parameter rule (a parameter rule is written name:pattern)';
|
|
@@ -31,11 +31,11 @@ export function permissionRulesWriteAvailable(reading) {
|
|
|
31
31
|
export function permissionRulesWriteDoctorDetail(reading) {
|
|
32
32
|
switch (reading.kind) {
|
|
33
33
|
case 'unobserved':
|
|
34
|
-
return 'permission-rule write entry not observed — the engine reports it on /v1/capabilities (permissionRulesWrite); this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
34
|
+
return 'permission-rule write entry not observed — the engine reports it on /v1/capabilities (permissionRulesWrite); this process has no usable capabilities reading cached for it (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which)';
|
|
35
35
|
case 'not_reported':
|
|
36
36
|
return 'permission-rule write entry not reported by this engine — this binary predates the entry itself; hide it rather than calling it';
|
|
37
37
|
case 'absent':
|
|
38
|
-
return 'permission-rule write entry unreachable for this call — either the rules lane is not open on this deployment, or this call cannot bring a verifiable identity';
|
|
38
|
+
return 'permission-rule write entry unreachable for this call — either the rules lane is not open on this deployment, or this call cannot bring a verifiable identity; the engine reports one bit for both, so this client cannot tell which';
|
|
39
39
|
case 'present':
|
|
40
40
|
return 'permission-rule write entry reachable for this call — a per-call attempt still answers for itself whether the direction, text, and scope are accepted';
|
|
41
41
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { type TaskRequestPermissionMode } from './taskRequestWords.js';
|
|
2
|
+
import { type PermissionModesReading } from './permissionModesCapability.js';
|
|
2
3
|
export type PermissionMode = TaskRequestPermissionMode;
|
|
3
4
|
export interface PermissionModeField {
|
|
4
5
|
permissionMode?: PermissionMode;
|
|
5
6
|
}
|
|
6
7
|
export declare function permissionModeField(mode: string | undefined, opts?: {
|
|
7
8
|
stampDefault?: boolean;
|
|
9
|
+
permissionModes?: PermissionModesReading | undefined;
|
|
8
10
|
}): PermissionModeField;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { PERMISSION_MODE_WORDS } from './taskRequestWords.js';
|
|
2
|
-
|
|
2
|
+
import { permissionModeAdmitted } from './permissionModesCapability.js';
|
|
3
|
+
const BIT_GATED_MODE = 'dontAsk';
|
|
4
|
+
const KNOWN = new Set(PERMISSION_MODE_WORDS.filter((w) => w !== BIT_GATED_MODE));
|
|
3
5
|
export function permissionModeField(mode, opts) {
|
|
4
6
|
if (typeof mode === 'string' && mode !== 'default' && KNOWN.has(mode)) {
|
|
5
7
|
return { permissionMode: mode };
|
|
6
8
|
}
|
|
9
|
+
if (mode === BIT_GATED_MODE) {
|
|
10
|
+
if (permissionModeAdmitted(opts?.permissionModes, mode))
|
|
11
|
+
return { permissionMode: mode };
|
|
12
|
+
return opts?.stampDefault === true ? { permissionMode: 'default' } : {};
|
|
13
|
+
}
|
|
7
14
|
if (opts?.stampDefault === true && (mode === undefined || mode === 'default')) {
|
|
8
15
|
return { permissionMode: 'default' };
|
|
9
16
|
}
|
|
@@ -65,7 +65,12 @@ export function permissionsAllowGrantDoctorDetail(reading, settingsRead) {
|
|
|
65
65
|
return 'allow rules sent to the engine — it reads them as rules, not as an exclusive list: a matching call counts as answered for, and the engine still raises its own prompts where it requires them';
|
|
66
66
|
}
|
|
67
67
|
if (gate === 'settings_read_not_clean') {
|
|
68
|
-
|
|
68
|
+
const why = settingsRead === 'partial'
|
|
69
|
+
? 'was reported partial (at least one settings file carried a bad field)'
|
|
70
|
+
: settingsRead === 'unreadable'
|
|
71
|
+
? 'was reported unreadable (at least one settings file could not be read)'
|
|
72
|
+
: 'came with no recognized read health';
|
|
73
|
+
return `allow rules from settings files kept on this side — this engine reads allow rules as rules, but the settings read that produced them ${why}, so they are not sent; command-line and session allow rules are still sent, and matching approvals are still answered here`;
|
|
69
74
|
}
|
|
70
75
|
const kind = ownReadingField(reading, 'kind');
|
|
71
76
|
if (kind === 'present' && ownReadingField(reading, 'grants') === false) {
|
|
@@ -74,7 +79,7 @@ export function permissionsAllowGrantDoctorDetail(reading, settingsRead) {
|
|
|
74
79
|
if (kind === 'not_reported') {
|
|
75
80
|
return 'allow rules kept on this side — this engine does not say how it reads allow rules; sending them to an engine that reads them as an exclusive list would block every tool not on it, so they are not sent and matching approvals are still answered here';
|
|
76
81
|
}
|
|
77
|
-
return 'allow rules kept on this side — no usable capabilities reading is cached for this engine (none received, or the last one was
|
|
82
|
+
return 'allow rules kept on this side — no usable capabilities reading is cached for this engine (none received, the last one was unreadable, or the last one was discarded when the engine connection was reset; this process cannot tell which), so allow rules are not sent and matching approvals are still answered here';
|
|
78
83
|
}
|
|
79
84
|
export function forgetPermissionsAllowGrantReading(baseUrl) {
|
|
80
85
|
reader.forget(baseUrl);
|
|
@@ -22,7 +22,7 @@ export interface PermissionsDeclarationBuckets {
|
|
|
22
22
|
export interface PermissionsDeclaration {
|
|
23
23
|
permissions?: PermissionsDeclarationBuckets;
|
|
24
24
|
}
|
|
25
|
-
export declare const PERMISSIONS_KEPT_REASONS: readonly ["allow_capability_off", "settings_read_not_clean", "empty_rule", "paren_in_tool_name", "retired_tool_name", "unprefixed_namespaced_name", "incomplete_protocol_name", "home_relative_path", "compile_refused", "content_form_not_grantable", "judge_failed", "duplicate"];
|
|
25
|
+
export declare const PERMISSIONS_KEPT_REASONS: readonly ["allow_capability_off", "settings_read_not_clean", "empty_rule", "paren_in_tool_name", "retired_tool_name", "unprefixed_namespaced_name", "incomplete_protocol_name", "unminted_protocol_segment", "home_relative_path", "compile_refused", "content_form_not_grantable", "judge_failed", "duplicate"];
|
|
26
26
|
export type PermissionsKeptReason = (typeof PERMISSIONS_KEPT_REASONS)[number];
|
|
27
27
|
export interface PermissionsKeptRule {
|
|
28
28
|
rule: string;
|
|
@@ -38,10 +38,16 @@ export interface PermissionsUncheckedRule {
|
|
|
38
38
|
rule: string;
|
|
39
39
|
bucket: 'deny' | 'ask';
|
|
40
40
|
}
|
|
41
|
+
export interface PermissionsUnreachableRule {
|
|
42
|
+
rule: string;
|
|
43
|
+
bucket: 'deny' | 'ask';
|
|
44
|
+
mintedPrefix?: string;
|
|
45
|
+
}
|
|
41
46
|
export interface PermissionsDeclarationReport extends PermissionsDeclaration {
|
|
42
47
|
kept: PermissionsKeptRule[];
|
|
43
48
|
rewritten: PermissionsRewrittenRule[];
|
|
44
49
|
unchecked: PermissionsUncheckedRule[];
|
|
50
|
+
unreachable: PermissionsUnreachableRule[];
|
|
45
51
|
}
|
|
46
52
|
export declare function permissionsDeclaration(input: PermissionsDeclarationInput, caps: PermissionsAllowGrantReading): PermissionsDeclaration;
|
|
47
53
|
export declare function permissionsDeclarationReport(input: PermissionsDeclarationInput, caps: PermissionsAllowGrantReading): PermissionsDeclarationReport;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { hasCoreValuePort, protocolOf, retiredToolNames, ruleToolGrammarOf
|
|
1
|
+
import { hasCoreValuePort, protocolOf, retiredToolNames, ruleToolGrammarOf } from './coreValuePorts.js';
|
|
2
|
+
import { protocolSegmentOf } from './protocolSegment.js';
|
|
3
|
+
import { ruleCompileVerdict } from './ruleCompileVerdict.js';
|
|
2
4
|
import { allowRulesGate } from './permissionsAllowGrantCapability.js';
|
|
3
5
|
const RULE_TRUST_ORDER = [
|
|
4
6
|
'policySettings',
|
|
@@ -17,6 +19,7 @@ export const PERMISSIONS_KEPT_REASONS = Object.freeze([
|
|
|
17
19
|
'retired_tool_name',
|
|
18
20
|
'unprefixed_namespaced_name',
|
|
19
21
|
'incomplete_protocol_name',
|
|
22
|
+
'unminted_protocol_segment',
|
|
20
23
|
'home_relative_path',
|
|
21
24
|
'compile_refused',
|
|
22
25
|
'content_form_not_grantable',
|
|
@@ -93,19 +96,14 @@ function wholeServerRuleName(name) {
|
|
|
93
96
|
const peer = read.slice(ns.prefix.length);
|
|
94
97
|
return peer !== '' && !peer.includes('__') && !peer.endsWith('_') ? `${read}__*` : name;
|
|
95
98
|
}
|
|
96
|
-
const
|
|
97
|
-
function compileVerdict(rule, behavior) {
|
|
98
|
-
try {
|
|
99
|
-
const issues = validatePermissionRules([{ rule, behavior }], { pathBases: { root: RULE_ROOT } });
|
|
100
|
-
if (!Array.isArray(issues))
|
|
101
|
-
return 'unknown';
|
|
102
|
-
return issues.length === 0 ? 'compiles' : 'refused';
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
return 'unknown';
|
|
106
|
-
}
|
|
107
|
-
}
|
|
99
|
+
const compileVerdict = ruleCompileVerdict;
|
|
108
100
|
const kept = (reason) => ({ sent: false, reason });
|
|
101
|
+
function sentFate(wire, toolName, unchecked) {
|
|
102
|
+
const segment = protocolSegmentOf(toolName);
|
|
103
|
+
return segment.kind === 'unminted'
|
|
104
|
+
? { sent: true, wire, unchecked, unreachable: segment.minted !== undefined ? { minted: segment.minted } : {} }
|
|
105
|
+
: { sent: true, wire, unchecked };
|
|
106
|
+
}
|
|
109
107
|
function judgeList(rules, behavior) {
|
|
110
108
|
let portsChecked = false;
|
|
111
109
|
return rules.map((rule) => {
|
|
@@ -121,24 +119,31 @@ function judgeList(rules, behavior) {
|
|
|
121
119
|
const issue = wireIssue(name);
|
|
122
120
|
if (issue !== undefined)
|
|
123
121
|
return kept(issue);
|
|
124
|
-
|
|
122
|
+
if (behavior === 'allow') {
|
|
123
|
+
const segment = protocolSegmentOf(name);
|
|
124
|
+
if (segment.kind === 'unminted')
|
|
125
|
+
return kept('unminted_protocol_segment');
|
|
126
|
+
if (segment.kind === 'unknown')
|
|
127
|
+
return kept('judge_failed');
|
|
128
|
+
}
|
|
129
|
+
const verdict = compileVerdict(name, behavior === 'ask' ? 'ask' : 'deny');
|
|
125
130
|
if (verdict === 'refused')
|
|
126
131
|
return kept('compile_refused');
|
|
127
132
|
if (verdict === 'unknown' && behavior === 'allow')
|
|
128
133
|
return kept('judge_failed');
|
|
129
|
-
return { sent: true, wire: name, unchecked: verdict === 'unknown'
|
|
134
|
+
return behavior === 'allow' ? { sent: true, wire: name, unchecked: false } : sentFate(name, name, verdict === 'unknown');
|
|
130
135
|
}
|
|
131
136
|
const issue = wireIssue(parsed.toolName);
|
|
132
137
|
if (issue !== undefined)
|
|
133
138
|
return kept(issue);
|
|
134
139
|
if (ruleToolGrammarOf(parsed.toolName) === 'path' && parsed.ruleContent.startsWith('~/'))
|
|
135
140
|
return kept('home_relative_path');
|
|
141
|
+
if (behavior === 'allow')
|
|
142
|
+
return kept('content_form_not_grantable');
|
|
136
143
|
const verdict = compileVerdict(rule, behavior);
|
|
137
144
|
if (verdict === 'refused')
|
|
138
|
-
return kept(
|
|
139
|
-
|
|
140
|
-
return kept('judge_failed');
|
|
141
|
-
return { sent: true, wire: rule, unchecked: verdict === 'unknown' };
|
|
145
|
+
return kept('compile_refused');
|
|
146
|
+
return sentFate(rule, parsed.toolName, verdict === 'unknown');
|
|
142
147
|
});
|
|
143
148
|
}
|
|
144
149
|
function outsideSettingsFiles(origin) {
|
|
@@ -275,6 +280,7 @@ function assemble(input, caps) {
|
|
|
275
280
|
const keptRows = [];
|
|
276
281
|
const rewritten = [];
|
|
277
282
|
const unchecked = [];
|
|
283
|
+
const unreachable = [];
|
|
278
284
|
const rows = [
|
|
279
285
|
['deny', [...denySlots, ...cliSlots], denyJ],
|
|
280
286
|
['ask', askSlots, askJ],
|
|
@@ -293,9 +299,12 @@ function assemble(input, caps) {
|
|
|
293
299
|
const f = (winner.list === 'cliDeny' ? j.fates[denySlots.length + winner.at] : j.fates[winner.at]);
|
|
294
300
|
if (f.sent && f.unchecked && bucket !== 'allow')
|
|
295
301
|
unchecked.push({ rule: wire, bucket });
|
|
302
|
+
if (f.sent && f.unreachable !== undefined && bucket !== 'allow') {
|
|
303
|
+
unreachable.push({ rule: wire, bucket, ...(f.unreachable.minted !== undefined ? { mintedPrefix: f.unreachable.minted } : {}) });
|
|
304
|
+
}
|
|
296
305
|
}
|
|
297
306
|
}
|
|
298
|
-
return { buckets, report: { kept: keptRows, rewritten, unchecked } };
|
|
307
|
+
return { buckets, report: { kept: keptRows, rewritten, unchecked, unreachable } };
|
|
299
308
|
}
|
|
300
309
|
export function permissionsDeclaration(input, caps) {
|
|
301
310
|
const { buckets } = assemble(input, caps);
|
package/dist/pluginHooksWire.js
CHANGED
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { displayUntrusted } from './displayUntrusted.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
'PostToolUse',
|
|
5
|
-
'PostToolUseFailure',
|
|
6
|
-
'PostToolBatch',
|
|
7
|
-
'PreCompact',
|
|
8
|
-
'PostCompact',
|
|
9
|
-
'Stop',
|
|
10
|
-
'StopFailure',
|
|
11
|
-
'UserPromptSubmit',
|
|
12
|
-
];
|
|
2
|
+
import { SETTINGS_ENGINE_OWNED_HOOK_EVENTS } from './generated/settingsSchemaTables.js';
|
|
3
|
+
export const ENGINE_FIRED_HOOK_EVENTS = SETTINGS_ENGINE_OWNED_HOOK_EVENTS;
|
|
13
4
|
export const PLUGIN_HOOK_DISPOSITIONS = ['engine', 'shell', 'not_run'];
|
|
14
5
|
export const PLUGIN_HOOK_REASONS = [
|
|
15
6
|
'projected',
|
package/dist/postureKnob.js
CHANGED
|
@@ -87,7 +87,7 @@ export function postureKnobDetail(knob, opts) {
|
|
|
87
87
|
? `${label} ${word} (source: ${source} — ${note})`
|
|
88
88
|
: `${label} ${word} (source: ${source})`;
|
|
89
89
|
}
|
|
90
|
-
return `${label} not reported by this engine (
|
|
90
|
+
return `${label} not reported by this engine (this end found no usable reading for it: the engine does not send one, or what it sent could not be parsed here; this end cannot tell which)`;
|
|
91
91
|
}
|
|
92
92
|
const _postureKnobShapePin = (w) => w;
|
|
93
93
|
void _postureKnobShapePin;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TaskRequest } from '@sema-agent/sdk';
|
|
1
2
|
import { type EnvLike } from './hostEnv.js';
|
|
2
|
-
export type PromptProfile = '
|
|
3
|
+
export type PromptProfile = NonNullable<TaskRequest['promptProfile']>;
|
|
3
4
|
export declare function promptProfileFromEnv(env?: EnvLike): PromptProfile | undefined;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ProtocolSegment = {
|
|
2
|
+
readonly kind: 'ok';
|
|
3
|
+
} | {
|
|
4
|
+
readonly kind: 'empty';
|
|
5
|
+
} | {
|
|
6
|
+
readonly kind: 'unminted';
|
|
7
|
+
readonly minted?: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly kind: 'unknown';
|
|
10
|
+
};
|
|
11
|
+
export declare function protocolSegmentOf(name: string): ProtocolSegment;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { hasCoreValuePort, mintNamespacePrefix, protocolOf } from './coreValuePorts.js';
|
|
2
|
+
import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
|
|
3
|
+
export function protocolSegmentOf(name) {
|
|
4
|
+
if (CORE_PROTOCOL_PREFIXES.some((prefix) => name.startsWith(prefix) && name.slice(prefix.length).split('__')[0] === ''))
|
|
5
|
+
return { kind: 'empty' };
|
|
6
|
+
const ns = protocolOf(name);
|
|
7
|
+
if (ns === undefined)
|
|
8
|
+
return hasCoreValuePort('protocolOf') ? { kind: 'ok' } : { kind: 'unknown' };
|
|
9
|
+
let parsed;
|
|
10
|
+
try {
|
|
11
|
+
parsed = ns.parse(name);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return { kind: 'unknown' };
|
|
15
|
+
}
|
|
16
|
+
const peer = parsed?.peer;
|
|
17
|
+
if (typeof peer !== 'string')
|
|
18
|
+
return { kind: 'ok' };
|
|
19
|
+
if (peer.includes('*'))
|
|
20
|
+
return { kind: 'unminted' };
|
|
21
|
+
let minted;
|
|
22
|
+
try {
|
|
23
|
+
minted = mintNamespacePrefix(ns, peer);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return { kind: 'unknown' };
|
|
27
|
+
}
|
|
28
|
+
if (typeof minted !== 'string')
|
|
29
|
+
return { kind: 'unknown' };
|
|
30
|
+
return minted === `${ns.prefix}${peer}__` ? { kind: 'ok' } : { kind: 'unminted', minted };
|
|
31
|
+
}
|
package/dist/readFacePosture.js
CHANGED
|
@@ -30,7 +30,7 @@ export function readFacePostureDetail(view, opts) {
|
|
|
30
30
|
if (!opts.reachable) {
|
|
31
31
|
return "read face not observed (this end could not read the engine's diagnostics)";
|
|
32
32
|
}
|
|
33
|
-
return 'read face not reported by this engine (
|
|
33
|
+
return 'read face not reported by this engine (this end found no usable reading for it: the engine does not send one, or what it sent could not be parsed here; this end cannot tell which)';
|
|
34
34
|
}
|
|
35
35
|
export function readFaceDisagreement(capFace, posture) {
|
|
36
36
|
if (posture === undefined)
|
|
@@ -44,7 +44,7 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
44
44
|
{ 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 提交的系统提示由壳整段给出 —— 它不是用户会话的续谈,不该继承用户那一份' },
|
|
45
45
|
{ field: 'reasoningEffort', lanes: ['interactive', 'print', 'utility'], live: false, why: '思考档位(sdk `TaskRequest.reasoningEffort` 七词闭集;上游对表外词 400 响亮拒 ⇒ 本层不预铸第二判官)。档位是请求级的位、与车道无关:交互面 = `/effort` 拨盘,无人值守面 = 档位旗。🔴 端交的必须是**档位词**:「思考 token 数」今天没有上游对位(见 `UPSTREAM_ABSENT_REQUEST_INTENTS` 的 `maxThinkingTokens`),别把一个数字折成档位词发出去', whyUtilityLane: '有座:side-channel 该用显式低档(省钱省时);与 model 同一条理由 —— 本车道上这两位都由壳显式给,不跟用户会话的拨盘走' },
|
|
46
46
|
{ 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` 拨盘走)' },
|
|
47
|
-
{ field: 'images', lanes: ['interactive'], live: false, why: '
|
|
47
|
+
{ field: 'images', lanes: ['interactive', 'print'], live: false, why: '图片输入(sdk `TaskRequest.images`;base64 / url 两形,原样透传)。两条用户车道都是提交面、都有来源:交互面 = 粘贴图与 `@` 图片像素,一次性车道 = 结构化输入里的图片块。张数、单张与合计的座位判定归人类提交装配口 `encodeHumanTurn`(两条车道同一份判定,本表不另判);请求体与图片张数的上限归上游判', whyUtilityLane: '无座:贴图是交互动作,side-channel 的提交体里没有图片块' },
|
|
48
48
|
{ 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 是一次性的独立会话,没有可回退的历史' },
|
|
49
49
|
{ field: 'clientContext', lanes: ['interactive'], live: false, why: 'IANA 时区 + 可选邮箱 → core 本地化 `# Environment` 的 today;print 同样跑在用户机器上,缺席让引擎误标 (UTC)', gap: true, whyUtilityLane: '无座:本地化 today 的用途在用户会话的环境段,而 side-channel 的系统提示由壳整段给出 —— 这一列我判不准要不要(与本行 `gap` 同一条待办:要补先单独立项)' },
|
|
50
50
|
{ field: 'scratchpadDir', lanes: ['interactive'], live: true, why: '[816]③ per-session 暂存目录;print 也有 session,缺席让 `-p` 的工具写不进 exemptDir', gap: true, whyUtilityLane: '无座:per-session 暂存目录是给**工具**写的,零工具面上没人写' },
|
|
@@ -483,13 +483,6 @@ const refuseBadExcludeAllTools = (v) => {
|
|
|
483
483
|
`收到 ${coarseShape(v)}。这一位是**整只工具面卸载**的收紧声明:本层若把坏值静默删键,这一次运行会挂上声明人以为已经卸掉的全部工具。` +
|
|
484
484
|
'错误文本只报形状,不回显值。');
|
|
485
485
|
};
|
|
486
|
-
const RETIRED_APPROVER_POSTURE_KEY = 'approverPosture';
|
|
487
|
-
const refuseRetiredApproverPosture = () => {
|
|
488
|
-
throw new TypeError('buildTaskRequest: "approverPosture" 是退役键(引擎 core 7.34.0 起在任务规格入口按名拒收;服务端 7.106.0 起提交体带它整条 400 ' +
|
|
489
|
-
'request.body_shape,unknownKeys 点名它)。它只是一句渲给模型看的审批姿态声明,从不授权任何东西 —— 删掉它不改变这一次运行被允许做什么。' +
|
|
490
|
-
'本包在装配前拒:在场即拒,任何值同判(undefined / null = 缺席)。处置:删掉这个键,不要改发别的键来顶替它;' +
|
|
491
|
-
'若确实要引擎侧放行审批,那是另一件事:显式给权限模式 permissionMode(那是一项授权,受部署策略管)。错误文本只报键名,不回显值。');
|
|
492
|
-
};
|
|
493
486
|
const refuseBadFileHistory = (v) => {
|
|
494
487
|
if (v === undefined || v === null)
|
|
495
488
|
return;
|
|
@@ -715,17 +708,12 @@ export function assembleTaskRequest(input, lane) {
|
|
|
715
708
|
};
|
|
716
709
|
const unknownKeys = [];
|
|
717
710
|
const lateOmitted = [];
|
|
718
|
-
let retiredApproverPosture = false;
|
|
719
711
|
for (const key of Object.keys(src)) {
|
|
720
712
|
if (hasOwn(INPUT_KEY_ROUTES, key))
|
|
721
713
|
continue;
|
|
722
714
|
const stray = Reflect.get(src, key);
|
|
723
715
|
if (!present(stray))
|
|
724
716
|
continue;
|
|
725
|
-
if (key === RETIRED_APPROVER_POSTURE_KEY) {
|
|
726
|
-
retiredApproverPosture = true;
|
|
727
|
-
continue;
|
|
728
|
-
}
|
|
729
717
|
const route = routeOfTopLevelKey(key);
|
|
730
718
|
if (route === undefined) {
|
|
731
719
|
unknownKeys.push(key);
|
|
@@ -756,8 +744,6 @@ export function assembleTaskRequest(input, lane) {
|
|
|
756
744
|
retiredRewindFiles = true;
|
|
757
745
|
unknownKeys.push(`rewind.${sub}`);
|
|
758
746
|
}
|
|
759
|
-
if (retiredApproverPosture)
|
|
760
|
-
refuseRetiredApproverPosture();
|
|
761
747
|
if (retiredRewindFiles) {
|
|
762
748
|
throw new TypeError('buildTaskRequest: "rewind.rewindFiles" 是退役键(引擎 core 6.0.0 起退役:「逐轮捕获」那一义被引擎忽略 —— 文件首触追踪恒开,' +
|
|
763
749
|
'无需请求;「回退时一并还原文件」那一义被引擎拒收、改名为 restoreFiles)。本包在装配前拒:在场即拒,true / false 同判。' +
|