@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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { capForDisplay } from './fleetTaskDesc.js';
|
|
2
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
3
|
+
import { createEngineCapReader } from './engineCapReader.js';
|
|
4
|
+
export function projectSteerPriorityCapability(caps) {
|
|
5
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
6
|
+
return undefined;
|
|
7
|
+
if (!Object.hasOwn(caps, 'fleet'))
|
|
8
|
+
return { kind: 'not_reported' };
|
|
9
|
+
const fleet = caps.fleet;
|
|
10
|
+
if (fleet === undefined || fleet === false)
|
|
11
|
+
return { kind: 'not_reported' };
|
|
12
|
+
if (fleet === null || typeof fleet !== 'object' || Array.isArray(fleet))
|
|
13
|
+
return undefined;
|
|
14
|
+
if (!Object.hasOwn(fleet, 'steerPriority'))
|
|
15
|
+
return { kind: 'not_reported' };
|
|
16
|
+
const v = fleet.steerPriority;
|
|
17
|
+
if (v === undefined)
|
|
18
|
+
return { kind: 'not_reported' };
|
|
19
|
+
if (typeof v !== 'string' || v.length === 0)
|
|
20
|
+
return undefined;
|
|
21
|
+
return { kind: 'present', word: v };
|
|
22
|
+
}
|
|
23
|
+
const reader = createEngineCapReader({
|
|
24
|
+
name: 'fleet.steerPriority',
|
|
25
|
+
project: projectSteerPriorityCapability,
|
|
26
|
+
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
27
|
+
});
|
|
28
|
+
export function noteEngineCapsForSteerPriority(baseUrl, caps, opts) {
|
|
29
|
+
reader.note(baseUrl, caps, opts);
|
|
30
|
+
}
|
|
31
|
+
export function observedSteerPriority(baseUrl = engineWireTarget()?.baseUrl) {
|
|
32
|
+
return reader.observed(baseUrl);
|
|
33
|
+
}
|
|
34
|
+
export function steerPriorityMode(reading) {
|
|
35
|
+
try {
|
|
36
|
+
if (reading === null || typeof reading !== 'object' || Array.isArray(reading))
|
|
37
|
+
return 'unknown';
|
|
38
|
+
if (!Object.hasOwn(reading, 'kind') || reading.kind !== 'present')
|
|
39
|
+
return 'unknown';
|
|
40
|
+
if (!Object.hasOwn(reading, 'word'))
|
|
41
|
+
return 'unknown';
|
|
42
|
+
const word = reading.word;
|
|
43
|
+
return word === 'engine' ? 'engine' : word === 'advisory' ? 'advisory' : 'unknown';
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return 'unknown';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const WORD_DETAIL_MAX = 40;
|
|
50
|
+
export function steerPriorityDoctorDetail(reading) {
|
|
51
|
+
const unobserved = 'steer priority not observed — the engine reports it on /v1/capabilities (fleet.steerPriority); this process has no usable capabilities reading cached for it, so a "now" or "later" steer is not sent';
|
|
52
|
+
let kind;
|
|
53
|
+
let word;
|
|
54
|
+
try {
|
|
55
|
+
if (reading === null || typeof reading !== 'object')
|
|
56
|
+
return unobserved;
|
|
57
|
+
kind = Object.hasOwn(reading, 'kind') ? reading.kind : undefined;
|
|
58
|
+
word = kind === 'present' && Object.hasOwn(reading, 'word') ? reading.word : undefined;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return unobserved;
|
|
62
|
+
}
|
|
63
|
+
if (kind === 'not_reported') {
|
|
64
|
+
return 'steer priority not reported by this engine — its capabilities reading carries no fleet.steerPriority (the fleet face is not reported, or the face carries no such field; this client cannot tell which), so a "now" or "later" steer is not sent (steers without a priority work as before)';
|
|
65
|
+
}
|
|
66
|
+
if (kind !== 'present' || typeof word !== 'string' || word.length === 0)
|
|
67
|
+
return unobserved;
|
|
68
|
+
if (word === 'engine')
|
|
69
|
+
return 'steer priority applied by the engine — "now" interrupts the running turn, "later" waits until the run would have stopped';
|
|
70
|
+
if (word === 'advisory') {
|
|
71
|
+
return 'steer priority accepted but not applied on this deployment — a "now" or "later" steer is not sent (steers without a priority work as before)';
|
|
72
|
+
}
|
|
73
|
+
return `steer priority reported as "${capForDisplay(word, WORD_DETAIL_MAX)}" — a value this client does not know yet, so whether it is applied is unknown and a "now" or "later" steer is not sent`;
|
|
74
|
+
}
|
|
75
|
+
export function forgetSteerPriorityReading(baseUrl) {
|
|
76
|
+
reader.forget(baseUrl);
|
|
77
|
+
}
|
|
78
|
+
export function __resetSteerPriorityReadingsForTests() {
|
|
79
|
+
reader.__resetForTests();
|
|
80
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SteerPriority } from '@sema-agent/sdk';
|
|
2
|
+
export interface SteerReceiptReading {
|
|
3
|
+
readonly delivery: string | null;
|
|
4
|
+
readonly status: string | null;
|
|
5
|
+
readonly messageId?: string;
|
|
6
|
+
readonly priority?: SteerPriority;
|
|
7
|
+
}
|
|
8
|
+
export declare function ownNonEmptyStringOf(body: unknown, key: string): string | undefined;
|
|
9
|
+
export declare function readSteerReceipt(receipt: unknown): SteerReceiptReading;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function ownNonEmptyStringOf(body, key) {
|
|
2
|
+
try {
|
|
3
|
+
if (typeof body !== 'object' || body === null || !Object.hasOwn(body, key))
|
|
4
|
+
return undefined;
|
|
5
|
+
const v = body[key];
|
|
6
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function priorityEchoOf(body) {
|
|
13
|
+
const v = ownNonEmptyStringOf(body, 'priority');
|
|
14
|
+
return v === 'now' || v === 'next' || v === 'later' ? v : undefined;
|
|
15
|
+
}
|
|
16
|
+
export function readSteerReceipt(receipt) {
|
|
17
|
+
const messageId = ownNonEmptyStringOf(receipt, 'messageId');
|
|
18
|
+
const priority = priorityEchoOf(receipt);
|
|
19
|
+
return Object.freeze({
|
|
20
|
+
delivery: ownNonEmptyStringOf(receipt, 'delivery') ?? null,
|
|
21
|
+
status: ownNonEmptyStringOf(receipt, 'status') ?? null,
|
|
22
|
+
...(messageId !== undefined ? { messageId } : {}),
|
|
23
|
+
...(priority !== undefined ? { priority } : {}),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
@@ -90,7 +90,7 @@ export function storePostureDoctorDetail(reading) {
|
|
|
90
90
|
const unobserved = 'store posture not observed — the engine reports it on /v1/capabilities; this process has no usable capabilities reading cached for it, so whether this deployment persists its state is unknown';
|
|
91
91
|
const r = presentView(reading);
|
|
92
92
|
if (r?.kind === 'not_reported') {
|
|
93
|
-
return 'store posture not reported by this engine
|
|
93
|
+
return 'store posture not reported by this engine; this does not say whether this deployment persists its state';
|
|
94
94
|
}
|
|
95
95
|
if (r?.kind !== 'present')
|
|
96
96
|
return unobserved;
|
|
@@ -120,7 +120,7 @@ export function storePostureDoctorDetail(reading) {
|
|
|
120
120
|
return `${assembled} — ${lost} (degraded: the declared database could not be opened at start-up, so the engine fell back rather than refusing to start)`;
|
|
121
121
|
}
|
|
122
122
|
if (reason === 'local_unwritable') {
|
|
123
|
-
return `${assembled} — ${lost} (degraded: the default local file store could not be created
|
|
123
|
+
return `${assembled} — ${lost} (degraded: the default local file store could not be created — a read-only or full data directory is one possible cause, and this client cannot tell which applies)`;
|
|
124
124
|
}
|
|
125
125
|
return `${assembled} — ${lost} (degraded for a reason this client does not know yet: "${word(reason)}")`;
|
|
126
126
|
}
|
|
@@ -4,19 +4,12 @@ import { engineSessionParamFor } from '../engineSessionParam.js';
|
|
|
4
4
|
import { resolveOwnerContext, resolveOwnerRunId } from './engineSubagentResume.js';
|
|
5
5
|
import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
|
|
6
6
|
import { errCodes, steeringRefusedBeforeEngine } from '../controlRouter.js';
|
|
7
|
+
import { ownNonEmptyStringOf } from '../steerReceipt.js';
|
|
7
8
|
function usableSteerClient(client) {
|
|
8
9
|
return clientHasVerbs(client, [['runs', 'steerSubagent']]);
|
|
9
10
|
}
|
|
10
11
|
function steerReceiptMessageId(body) {
|
|
11
|
-
|
|
12
|
-
if (typeof body !== 'object' || body === null || !Object.hasOwn(body, 'messageId'))
|
|
13
|
-
return undefined;
|
|
14
|
-
const v = body.messageId;
|
|
15
|
-
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
12
|
+
return ownNonEmptyStringOf(body, 'messageId');
|
|
20
13
|
}
|
|
21
14
|
export async function steerEngineSubagent(target, text, childTaskId, opts) {
|
|
22
15
|
const named = typeof childTaskId === 'string' && childTaskId !== '' ? childTaskId : undefined;
|
package/dist/supportFloor.d.ts
CHANGED
|
@@ -8,3 +8,4 @@ export declare const SUPPORT_FLOOR: Readonly<SupportFloor>;
|
|
|
8
8
|
export declare function supportFloorOf(component: unknown): string | undefined;
|
|
9
9
|
export type EngineVersionTier = 'engine' | 'legacy' | 'unknown';
|
|
10
10
|
export declare function engineVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
|
11
|
+
export declare function coreVersionTier(version: unknown, floor?: string): EngineVersionTier;
|
package/dist/supportFloor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export const SUPPORT_FLOOR = Object.freeze({
|
|
2
|
-
server: '7.
|
|
3
|
-
core: '7.
|
|
2
|
+
server: '7.106.0',
|
|
3
|
+
core: '7.35.2',
|
|
4
4
|
sdk: '12.0.1',
|
|
5
5
|
});
|
|
6
6
|
export function supportFloorOf(component) {
|
|
@@ -25,12 +25,16 @@ function compareTriple(a, b) {
|
|
|
25
25
|
}
|
|
26
26
|
return 0;
|
|
27
27
|
}
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
function versionTierAgainst(version, base, floor, caller) {
|
|
29
|
+
const baseTriple = releaseTriple(base);
|
|
30
|
+
if (baseTriple === undefined) {
|
|
31
|
+
throw new TypeError(`${caller}: 门槛只接受纯 x.y.z 版本串(整串、无前导零、无前后缀)—— 收到 typeof=${base === null ? 'null' : typeof base}。错误文本只报形状,不回显值。`);
|
|
32
|
+
}
|
|
33
|
+
let need = baseTriple;
|
|
30
34
|
if (floor !== undefined) {
|
|
31
35
|
const own = releaseTriple(floor);
|
|
32
36
|
if (own === undefined) {
|
|
33
|
-
throw new TypeError(
|
|
37
|
+
throw new TypeError(`${caller}: floor 只接受纯 x.y.z 版本串(整串、无前导零、无前后缀)或缺席 —— 收到 typeof=${floor === null ? 'null' : typeof floor}。错误文本只报形状,不回显值。`);
|
|
34
38
|
}
|
|
35
39
|
if (compareTriple(own, need) > 0)
|
|
36
40
|
need = own;
|
|
@@ -40,3 +44,9 @@ export function engineVersionTier(version, floor) {
|
|
|
40
44
|
return 'unknown';
|
|
41
45
|
return compareTriple(got, need) >= 0 ? 'engine' : 'legacy';
|
|
42
46
|
}
|
|
47
|
+
export function engineVersionTier(version, floor) {
|
|
48
|
+
return versionTierAgainst(version, SUPPORT_FLOOR.server, floor, 'engineVersionTier');
|
|
49
|
+
}
|
|
50
|
+
export function coreVersionTier(version, floor) {
|
|
51
|
+
return versionTierAgainst(version, SUPPORT_FLOOR.core, floor, 'coreVersionTier');
|
|
52
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { TaskRequest } from '@sema-agent/sdk';
|
|
2
2
|
export type TaskRequestReasoningEffort = NonNullable<TaskRequest['reasoningEffort']>;
|
|
3
3
|
export declare const REASONING_EFFORT_WORDS: readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"];
|
|
4
|
-
|
|
5
|
-
export
|
|
4
|
+
type SdkTaskRequestPermissionMode = NonNullable<TaskRequest['permissionMode']>;
|
|
5
|
+
export type TaskRequestPermissionMode = SdkTaskRequestPermissionMode | 'dontAsk';
|
|
6
|
+
export declare const PERMISSION_MODE_WORDS: readonly ["default", "plan", "acceptEdits", "bypassPermissions", "auto", "dontAsk"];
|
|
6
7
|
export interface RetiredAttachmentsKey {
|
|
7
8
|
readonly key: string;
|
|
8
9
|
readonly why: string;
|
|
@@ -10,3 +11,4 @@ export interface RetiredAttachmentsKey {
|
|
|
10
11
|
readonly remedy: string;
|
|
11
12
|
}
|
|
12
13
|
export declare function retiredAttachmentsKeyOf(nameOrToken: string, form?: 'token' | 'key'): RetiredAttachmentsKey | undefined;
|
|
14
|
+
export {};
|
package/dist/taskRequestWords.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const REASONING_EFFORT_WORDS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'];
|
|
2
|
-
export const PERMISSION_MODE_WORDS = ['default', 'plan', 'acceptEdits', 'bypassPermissions', 'auto'];
|
|
2
|
+
export const PERMISSION_MODE_WORDS = ['default', 'plan', 'acceptEdits', 'bypassPermissions', 'auto', 'dontAsk'];
|
|
3
3
|
const _taskRequestWordPins = [true, true, true, true];
|
|
4
4
|
void _taskRequestWordPins;
|
|
5
5
|
export function retiredAttachmentsKeyOf(nameOrToken, form = 'token') {
|
|
@@ -2,8 +2,7 @@ import { displayUntrusted } from './displayUntrusted.js';
|
|
|
2
2
|
const BAD_TURN_PREVIEW_MAX = 60;
|
|
3
3
|
export function toolHistoryBadTurnSentence(promptText) {
|
|
4
4
|
const text = typeof promptText === 'string' ? promptText : '';
|
|
5
|
-
const
|
|
6
|
-
const washed = displayUntrusted(flat, { foldLines: false, mark: 'dot' });
|
|
5
|
+
const washed = displayUntrusted(stripDisplayTagBlocks(text), { mark: 'dot' }).replace(/\s+/g, ' ').trim();
|
|
7
6
|
const points = Array.from(washed);
|
|
8
7
|
const preview = points.length > BAD_TURN_PREVIEW_MAX ? `${points.slice(0, BAD_TURN_PREVIEW_MAX).join('')}...` : washed;
|
|
9
8
|
return preview.length > 0
|
package/dist/toolResult.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export declare const PROTOCOL_MARKERS: {
|
|
|
15
15
|
readonly delegationTrailerFork: "Verify this result before concluding. If it leaves more to do, continue the work yourself or fork again.";
|
|
16
16
|
readonly taskOutputLabel: RegExp;
|
|
17
17
|
readonly taskOutputStatus: RegExp;
|
|
18
|
+
readonly taskOutputHeadSlots: RegExp;
|
|
19
|
+
readonly taskOutputResultNote: RegExp;
|
|
18
20
|
readonly taskOutputNoneSentinel: "(none)";
|
|
19
21
|
readonly taskOutputStdoutLine: RegExp;
|
|
20
22
|
readonly taskOutputStderrLine: RegExp;
|
|
@@ -62,10 +64,16 @@ export type ModelFacingTaskOutput = {
|
|
|
62
64
|
taskId?: string | undefined;
|
|
63
65
|
status?: string | undefined;
|
|
64
66
|
output: string;
|
|
67
|
+
state?: string;
|
|
68
|
+
error?: string;
|
|
69
|
+
resultNote?: string;
|
|
70
|
+
headRest?: string;
|
|
65
71
|
} | {
|
|
66
72
|
kind: 'unknown';
|
|
67
73
|
taskId?: string | undefined;
|
|
68
74
|
status?: string | undefined;
|
|
75
|
+
state?: string;
|
|
76
|
+
error?: string;
|
|
69
77
|
};
|
|
70
78
|
export declare function parseModelFacingTaskOutput(text: string): ModelFacingTaskOutput;
|
|
71
79
|
export declare function backgroundReceiptParseCalls(): number;
|
|
@@ -92,7 +100,8 @@ export interface EngineBgShellRegistration {
|
|
|
92
100
|
receipt: string;
|
|
93
101
|
source: 'bash' | 'monitor';
|
|
94
102
|
}
|
|
95
|
-
export declare function detectEngineBgShellReceipt(toolName: string, rawInput: unknown, outputText: string | undefined): EngineBgShellRegistration | null;
|
|
103
|
+
export declare function detectEngineBgShellReceipt(toolName: string, rawInput: unknown, outputText: string | undefined, structured?: unknown): EngineBgShellRegistration | null;
|
|
104
|
+
export declare function detectEngineBgShellDetach(toolName: string, rawInput: unknown, structured: unknown, outputText: string | undefined): EngineBgShellRegistration | null;
|
|
96
105
|
export declare function todoWriteToolUseResult(rawInput: unknown, oldTodos: unknown[], isError: boolean): {
|
|
97
106
|
toolUseResult: unknown;
|
|
98
107
|
isError: boolean;
|
package/dist/toolResult.js
CHANGED
|
@@ -30,6 +30,8 @@ export const PROTOCOL_MARKERS = {
|
|
|
30
30
|
delegationTrailerFork: 'Verify this result before concluding. If it leaves more to do, continue the work yourself or fork again.',
|
|
31
31
|
taskOutputLabel: /^TaskOutput\s+(\S+)$/,
|
|
32
32
|
taskOutputStatus: /^status:\s*(.+)$/m,
|
|
33
|
+
taskOutputHeadSlots: /^(\r?\n)(?:(state: ([^\r\n\u2028\u2029\u0085]*)(?:\r?\n|$)))?(?:(error: ([^\r\n\u2028\u2029\u0085]*)(?:\r?\n|$)))?/,
|
|
34
|
+
taskOutputResultNote: /^--- result \(([^)\n]*)\) ---/,
|
|
33
35
|
taskOutputNoneSentinel: '(none)',
|
|
34
36
|
taskOutputStdoutLine: /^--- (?:new )?stdout[^\n]*---\n?/m,
|
|
35
37
|
taskOutputStderrLine: /^--- (?:new )?stderr[^\n]*---\n?/m,
|
|
@@ -140,7 +142,8 @@ export function parseModelFacingTaskOutput(text) {
|
|
|
140
142
|
const fence = stripUntrustedFence(text);
|
|
141
143
|
const body = fence ? fence.body : text;
|
|
142
144
|
const taskId = fence ? PROTOCOL_MARKERS.taskOutputLabel.exec(fence.label)?.[1] : undefined;
|
|
143
|
-
const
|
|
145
|
+
const mStatus = PROTOCOL_MARKERS.taskOutputStatus.exec(body);
|
|
146
|
+
const status = mStatus?.[1]?.trim();
|
|
144
147
|
const none = (s) => {
|
|
145
148
|
const t = s.replace(/\n$/, '');
|
|
146
149
|
return t === PROTOCOL_MARKERS.taskOutputNoneSentinel ? '' : t;
|
|
@@ -159,9 +162,50 @@ export function parseModelFacingTaskOutput(text) {
|
|
|
159
162
|
}
|
|
160
163
|
const mRes = PROTOCOL_MARKERS.taskOutputResultLine.exec(body);
|
|
161
164
|
if (mRes) {
|
|
162
|
-
|
|
165
|
+
const lead = taskOutputHeadOf(body, mStatus, mRes.index);
|
|
166
|
+
const statusEnd = lead === null || mStatus === null ? 0 : mStatus[0].length;
|
|
167
|
+
const rest = lead === null ? body.slice(0, mRes.index) : body.slice(statusEnd + lead.consumed, mRes.index);
|
|
168
|
+
const resultNote = PROTOCOL_MARKERS.taskOutputResultNote.exec(mRes[0])?.[1];
|
|
169
|
+
return {
|
|
170
|
+
kind: 'agent',
|
|
171
|
+
taskId,
|
|
172
|
+
status,
|
|
173
|
+
output: body.slice(mRes.index + mRes[0].length).trimEnd(),
|
|
174
|
+
...(lead?.state !== undefined ? { state: lead.state } : {}),
|
|
175
|
+
...(lead?.error !== undefined ? { error: lead.error } : {}),
|
|
176
|
+
...(resultNote !== undefined ? { resultNote } : {}),
|
|
177
|
+
...(rest !== '' ? { headRest: rest } : {}),
|
|
178
|
+
};
|
|
163
179
|
}
|
|
164
|
-
|
|
180
|
+
const lead = taskOutputHeadOf(body, mStatus, body.length);
|
|
181
|
+
return {
|
|
182
|
+
kind: 'unknown',
|
|
183
|
+
taskId,
|
|
184
|
+
status,
|
|
185
|
+
...(lead?.state !== undefined ? { state: lead.state } : {}),
|
|
186
|
+
...(lead?.error !== undefined ? { error: lead.error } : {}),
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function taskOutputHeadOf(body, status, limit) {
|
|
190
|
+
if (status === null || status.index !== 0 || /[^\S \t]/.test(status[0]))
|
|
191
|
+
return null;
|
|
192
|
+
const head = PROTOCOL_MARKERS.taskOutputHeadSlots.exec(body.slice(status.index + status[0].length, limit));
|
|
193
|
+
if (head === null)
|
|
194
|
+
return null;
|
|
195
|
+
let consumed = head[1]?.length ?? 0;
|
|
196
|
+
let state;
|
|
197
|
+
let error;
|
|
198
|
+
if (head[2] !== undefined) {
|
|
199
|
+
if ((head[3] ?? '').trim() === '')
|
|
200
|
+
return { consumed };
|
|
201
|
+
state = head[3];
|
|
202
|
+
consumed += head[2].length;
|
|
203
|
+
}
|
|
204
|
+
if (head[4] !== undefined && (head[5] ?? '').trim() !== '') {
|
|
205
|
+
error = head[5];
|
|
206
|
+
consumed += head[4].length;
|
|
207
|
+
}
|
|
208
|
+
return { ...(state !== undefined ? { state } : {}), ...(error !== undefined ? { error } : {}), consumed };
|
|
165
209
|
}
|
|
166
210
|
const THREE_GEN_BG_RECEIPT_RE = /^(?:Started in background|Command running in background|Command moved to background); task_id=([A-Za-z0-9_-]+)/;
|
|
167
211
|
const MONITOR_BG_RECEIPT_RE = /^Monitoring in background; task_id=([A-Za-z0-9_-]+)/;
|
|
@@ -630,7 +674,7 @@ export function structuredToToolUseResult(structured, modelText, leaderLedger =
|
|
|
630
674
|
return null;
|
|
631
675
|
}
|
|
632
676
|
}
|
|
633
|
-
export function detectEngineBgShellReceipt(toolName, rawInput, outputText) {
|
|
677
|
+
export function detectEngineBgShellReceipt(toolName, rawInput, outputText, structured) {
|
|
634
678
|
if (typeof outputText !== 'string')
|
|
635
679
|
return null;
|
|
636
680
|
const input = (rawInput ?? {});
|
|
@@ -639,6 +683,8 @@ export function detectEngineBgShellReceipt(toolName, rawInput, outputText) {
|
|
|
639
683
|
if (toolName === 'Bash') {
|
|
640
684
|
if (input.run_in_background !== true)
|
|
641
685
|
return null;
|
|
686
|
+
if (readBashDetachView(structured)?.registerFailed === true)
|
|
687
|
+
return null;
|
|
642
688
|
m = THREE_GEN_BG_RECEIPT_RE.exec(outputText);
|
|
643
689
|
source = 'bash';
|
|
644
690
|
}
|
|
@@ -651,17 +697,45 @@ export function detectEngineBgShellReceipt(toolName, rawInput, outputText) {
|
|
|
651
697
|
}
|
|
652
698
|
if (!m?.[1])
|
|
653
699
|
return null;
|
|
700
|
+
return engineBgShellRegistrationBody(m[1], input, outputText, source);
|
|
701
|
+
}
|
|
702
|
+
function engineBgShellRegistrationBody(taskId, rawInput, receipt, source) {
|
|
703
|
+
const input = (rawInput ?? {});
|
|
654
704
|
const command = typeof input.command === 'string' ? input.command : '(engine bash)';
|
|
655
705
|
const description = typeof input.description === 'string' ? input.description : undefined;
|
|
656
706
|
return {
|
|
657
707
|
kind: 'register',
|
|
658
|
-
taskId
|
|
708
|
+
taskId,
|
|
659
709
|
command,
|
|
660
710
|
...(description !== undefined ? { description } : {}),
|
|
661
|
-
receipt
|
|
711
|
+
receipt,
|
|
662
712
|
source,
|
|
663
713
|
};
|
|
664
714
|
}
|
|
715
|
+
export function detectEngineBgShellDetach(toolName, rawInput, structured, outputText) {
|
|
716
|
+
if (toolName !== 'Bash')
|
|
717
|
+
return null;
|
|
718
|
+
const view = readBashDetachView(structured);
|
|
719
|
+
if (view === null || !view.detached || view.registerFailed || view.taskId === undefined)
|
|
720
|
+
return null;
|
|
721
|
+
return engineBgShellRegistrationBody(view.taskId, rawInput, typeof outputText === 'string' ? outputText : '', 'bash');
|
|
722
|
+
}
|
|
723
|
+
function readBashDetachView(structured) {
|
|
724
|
+
if (typeof structured !== 'object' || structured === null)
|
|
725
|
+
return null;
|
|
726
|
+
const s = structured;
|
|
727
|
+
const type = s.type;
|
|
728
|
+
if (type !== 'bash')
|
|
729
|
+
return null;
|
|
730
|
+
const detached = s.detached;
|
|
731
|
+
const registerFailed = s.registerFailed;
|
|
732
|
+
const taskId = s.task_id;
|
|
733
|
+
return {
|
|
734
|
+
detached: detached === true,
|
|
735
|
+
registerFailed: registerFailed === true,
|
|
736
|
+
taskId: typeof taskId === 'string' && taskId.length > 0 ? taskId : undefined,
|
|
737
|
+
};
|
|
738
|
+
}
|
|
665
739
|
export function todoWriteToolUseResult(rawInput, oldTodos, isError) {
|
|
666
740
|
const todos = rawInput?.todos;
|
|
667
741
|
if (!Array.isArray(todos))
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
model?: string;
|
|
4
|
-
sessionBackend?: string;
|
|
5
|
-
sessions?: number;
|
|
6
|
-
instanceId?: string;
|
|
7
|
-
dataRoot?: string;
|
|
8
|
-
configHash?: string;
|
|
9
|
-
pid?: number;
|
|
10
|
-
port?: number;
|
|
11
|
-
restartRequired?: boolean;
|
|
12
|
-
version?: string;
|
|
1
|
+
import type { EngineHealth } from '@sema-agent/sdk';
|
|
2
|
+
export interface HealthResponse extends Pick<EngineHealth, 'status' | 'model' | 'sessionBackend' | 'sessions' | 'instanceId' | 'dataRoot' | 'configHash' | 'pid' | 'port' | 'restartRequired' | 'version'> {
|
|
13
3
|
}
|
|
14
4
|
export interface EnginePortFile {
|
|
15
5
|
port: number;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type UserInvokedSkillsReading = {
|
|
2
|
+
kind: 'unobserved';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'not_reported';
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'absent';
|
|
7
|
+
} | {
|
|
8
|
+
kind: 'present';
|
|
9
|
+
};
|
|
10
|
+
export declare function projectUserInvokedSkillsCapability(caps: unknown): UserInvokedSkillsReading | undefined;
|
|
11
|
+
export declare function noteEngineCapsForUserInvokedSkills(baseUrl: string, caps: unknown, opts?: {
|
|
12
|
+
generation?: number;
|
|
13
|
+
}): void;
|
|
14
|
+
export declare function observedUserInvokedSkills(baseUrl?: string | undefined): UserInvokedSkillsReading;
|
|
15
|
+
export declare function userInvokedSkillsAvailable(reading: UserInvokedSkillsReading): 'yes' | 'no' | 'unknown';
|
|
16
|
+
export declare function userInvokedSkillsDoctorDetail(reading: UserInvokedSkillsReading): string;
|
|
17
|
+
export declare function forgetUserInvokedSkillsReading(baseUrl: string | undefined): void;
|
|
18
|
+
export declare function __resetUserInvokedSkillsReadingsForTests(): void;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
+
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
export function projectUserInvokedSkillsCapability(caps) {
|
|
4
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
5
|
+
return undefined;
|
|
6
|
+
if (!Object.hasOwn(caps, 'userInvokedSkills'))
|
|
7
|
+
return { kind: 'not_reported' };
|
|
8
|
+
const v = caps.userInvokedSkills;
|
|
9
|
+
if (v === undefined)
|
|
10
|
+
return { kind: 'not_reported' };
|
|
11
|
+
if (typeof v !== 'boolean')
|
|
12
|
+
return undefined;
|
|
13
|
+
return v ? { kind: 'present' } : { kind: 'absent' };
|
|
14
|
+
}
|
|
15
|
+
const reader = createEngineCapReader({
|
|
16
|
+
name: 'userInvokedSkills',
|
|
17
|
+
project: projectUserInvokedSkillsCapability,
|
|
18
|
+
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
19
|
+
});
|
|
20
|
+
export function noteEngineCapsForUserInvokedSkills(baseUrl, caps, opts) {
|
|
21
|
+
reader.note(baseUrl, caps, opts);
|
|
22
|
+
}
|
|
23
|
+
export function observedUserInvokedSkills(baseUrl = engineWireTarget()?.baseUrl) {
|
|
24
|
+
return reader.observed(baseUrl);
|
|
25
|
+
}
|
|
26
|
+
export function userInvokedSkillsAvailable(reading) {
|
|
27
|
+
if (reading.kind === 'present')
|
|
28
|
+
return 'yes';
|
|
29
|
+
if (reading.kind === 'absent' || reading.kind === 'not_reported')
|
|
30
|
+
return 'no';
|
|
31
|
+
return 'unknown';
|
|
32
|
+
}
|
|
33
|
+
export function userInvokedSkillsDoctorDetail(reading) {
|
|
34
|
+
switch (reading.kind) {
|
|
35
|
+
case 'unobserved':
|
|
36
|
+
return 'user-invoked skills not observed — the engine reports it on /v1/capabilities (userInvokedSkills); 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)';
|
|
37
|
+
case 'not_reported':
|
|
38
|
+
return 'user-invoked skills not reported by this engine — the engine predates it, so naming skills on a request is refused (do not send the key)';
|
|
39
|
+
case 'absent':
|
|
40
|
+
return 'user-invoked skills off on this deployment — naming skills on a request is not accepted';
|
|
41
|
+
case 'present':
|
|
42
|
+
return 'user-invoked skills on — skills the user names on a request take effect when the run starts';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export function forgetUserInvokedSkillsReading(baseUrl) {
|
|
46
|
+
reader.forget(baseUrl);
|
|
47
|
+
}
|
|
48
|
+
export function __resetUserInvokedSkillsReadingsForTests() {
|
|
49
|
+
reader.__resetForTests();
|
|
50
|
+
}
|
|
@@ -38,9 +38,9 @@ export function webSearchBackendDoctorDetail(reading) {
|
|
|
38
38
|
switch (reading.kind) {
|
|
39
39
|
case 'unobserved':
|
|
40
40
|
return ('deployment default backend not observed — the engine reports it on /v1/capabilities; ' +
|
|
41
|
-
'this process has no usable capabilities reading cached for it (none received, or the last one was
|
|
41
|
+
'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)');
|
|
42
42
|
case 'not_reported':
|
|
43
|
-
return ('deployment default backend not reported by this engine
|
|
43
|
+
return ('deployment default backend not reported by this engine; ' +
|
|
44
44
|
'this does not say whether the deployment has a search backend');
|
|
45
45
|
case 'none':
|
|
46
46
|
return (`deployment default backend none — ${DEPLOY_ENV} is unset or not a provider word on the engine, ` +
|
|
@@ -32,6 +32,37 @@ function judgeText(raw) {
|
|
|
32
32
|
return { ok: false, issue: 'must be a string' };
|
|
33
33
|
return { ok: true, value: isBlankText(raw) ? undefined : raw };
|
|
34
34
|
}
|
|
35
|
+
const API_KEY_ISSUE = 'must be usable as an HTTP header value (it contains a character an HTTP header cannot carry, such as a line break)';
|
|
36
|
+
const isHttpWhitespaceCode = (c) => c === 0x09 || c === 0x0a || c === 0x0d || c === 0x20;
|
|
37
|
+
function isHttpHeaderValue(value) {
|
|
38
|
+
let start = 0;
|
|
39
|
+
let end = value.length;
|
|
40
|
+
while (start < end && isHttpWhitespaceCode(value.charCodeAt(start)))
|
|
41
|
+
start++;
|
|
42
|
+
while (end > start && isHttpWhitespaceCode(value.charCodeAt(end - 1)))
|
|
43
|
+
end--;
|
|
44
|
+
for (let i = start; i < end; i++) {
|
|
45
|
+
const c = value.charCodeAt(i);
|
|
46
|
+
if (!(c === 0x09 || (c >= 0x20 && c <= 0x7e) || (c >= 0x80 && c <= 0xff)))
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
function apiKeyHeaderValue(provider, key) {
|
|
52
|
+
switch (provider) {
|
|
53
|
+
case 'brave':
|
|
54
|
+
case 'searxng':
|
|
55
|
+
return key;
|
|
56
|
+
case 'tavily':
|
|
57
|
+
return `Bearer ${key}`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function judgeApiKey(provider, raw) {
|
|
61
|
+
const text = judgeText(raw);
|
|
62
|
+
if (!text.ok || text.value === undefined)
|
|
63
|
+
return text;
|
|
64
|
+
return isHttpHeaderValue(apiKeyHeaderValue(provider, text.value)) ? text : { ok: false, issue: API_KEY_ISSUE };
|
|
65
|
+
}
|
|
35
66
|
const ENDPOINT_ISSUE = 'must be an absolute URL with a scheme and a host, such as https://search.example.com (a bare host or host:port is not one)';
|
|
36
67
|
function judgeEndpoint(raw) {
|
|
37
68
|
if (raw === undefined || raw === null)
|
|
@@ -114,9 +145,10 @@ function judgeSection(raw, source, apiKeyFor) {
|
|
|
114
145
|
injected = undefined;
|
|
115
146
|
}
|
|
116
147
|
}
|
|
117
|
-
const
|
|
148
|
+
const useInjected = typeof injected === 'string' && !isBlankText(injected);
|
|
149
|
+
const apiKey = judgeApiKey(provider.value, useInjected ? injected : s.apiKey);
|
|
118
150
|
if (!apiKey.ok)
|
|
119
|
-
return { kind: 'malformed', source, field: 'apiKey', issue: apiKey.issue };
|
|
151
|
+
return { kind: 'malformed', source: useInjected ? 'host' : source, field: 'apiKey', issue: apiKey.issue };
|
|
120
152
|
const endpoint = judgeEndpoint(s.endpoint);
|
|
121
153
|
if (!endpoint.ok)
|
|
122
154
|
return { kind: 'malformed', source, field: 'endpoint', issue: endpoint.issue };
|
|
@@ -191,6 +223,12 @@ function envNameOfField(field) {
|
|
|
191
223
|
export function webSearchVerdictMessage(verdict, context = 'submit') {
|
|
192
224
|
if (verdict.kind !== 'malformed')
|
|
193
225
|
return undefined;
|
|
226
|
+
if (verdict.source === 'host') {
|
|
227
|
+
const head = `Web search is misconfigured: the API key your host supplied for webSearch is malformed; it ${verdict.issue}.`;
|
|
228
|
+
return context === 'submit'
|
|
229
|
+
? `${head} The request was not sent — the key needs replacing where your host keeps it.`
|
|
230
|
+
: `${head} Requests will be refused until the key is replaced where your host keeps it.`;
|
|
231
|
+
}
|
|
194
232
|
const where = verdict.source === 'env' ? envNameOfField(verdict.field) : verdict.field === 'section' ? 'the webSearch section in settings' : `webSearch.${verdict.field} in settings`;
|
|
195
233
|
const fix = verdict.source === 'env' ? 'fix it or unset the SEMA_WEBSEARCH_* variables' : 'fix it or remove the webSearch section';
|
|
196
234
|
return context === 'submit'
|
|
@@ -5,6 +5,8 @@ interface WireFailureShape {
|
|
|
5
5
|
committed?: 'no' | 'unknown' | 'unreadable';
|
|
6
6
|
bodyField?: string;
|
|
7
7
|
bodyName?: string;
|
|
8
|
+
bodyVerdict?: string;
|
|
9
|
+
bodyCurrentName?: string;
|
|
8
10
|
message: string;
|
|
9
11
|
}
|
|
10
12
|
export declare function readErrorNumber(o: object, key: string): number | undefined;
|
package/dist/wireFailureShape.js
CHANGED
|
@@ -66,9 +66,9 @@ export function readErrorStrictStringList(o, key) {
|
|
|
66
66
|
return true;
|
|
67
67
|
};
|
|
68
68
|
const v = readErrorSlot(o, key, strict);
|
|
69
|
-
if (!Array.isArray(v))
|
|
70
|
-
return undefined;
|
|
71
69
|
try {
|
|
70
|
+
if (!Array.isArray(v))
|
|
71
|
+
return undefined;
|
|
72
72
|
const out = [];
|
|
73
73
|
const len = v.length;
|
|
74
74
|
for (let i = 0; i < len; i++) {
|
|
@@ -131,6 +131,8 @@ export function wireFailureShapeOf(e) {
|
|
|
131
131
|
};
|
|
132
132
|
const bodyField = ownString('field');
|
|
133
133
|
const bodyName = ownString('name');
|
|
134
|
+
const bodyVerdict = ownString('verdict');
|
|
135
|
+
const bodyCurrentName = ownString('currentName');
|
|
134
136
|
let message;
|
|
135
137
|
try {
|
|
136
138
|
message = typeof rawMessage === 'string' && rawMessage !== '' ? rawMessage : String(e);
|
|
@@ -155,6 +157,8 @@ export function wireFailureShapeOf(e) {
|
|
|
155
157
|
...(committed !== undefined ? { committed } : {}),
|
|
156
158
|
...(bodyField !== undefined ? { bodyField } : {}),
|
|
157
159
|
...(bodyName !== undefined ? { bodyName } : {}),
|
|
160
|
+
...(bodyVerdict !== undefined ? { bodyVerdict } : {}),
|
|
161
|
+
...(bodyCurrentName !== undefined ? { bodyCurrentName } : {}),
|
|
158
162
|
message,
|
|
159
163
|
};
|
|
160
164
|
}
|