@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
|
@@ -3,7 +3,7 @@ import { eventToSdkMessage, turnEndUsage } from './downstream/eventToSdkMessage.
|
|
|
3
3
|
import { turnUsageToModelUsage } from './downstream/turnUsageToModelUsage.js';
|
|
4
4
|
import { readRunCostFacts, terminalToSdkResult, TOOL_INPUT_JOIN_MAX_CALLS } from './downstream/terminalToSdkResult.js';
|
|
5
5
|
import { terminalRunIdOf, terminalUuidOf } from '../engineRowRef.js';
|
|
6
|
-
import {
|
|
6
|
+
import { publishSubagentContentEvent, subagentContentEventOf } from '../subagentContentStore.js';
|
|
7
7
|
import { OUTPUT_INVALID, activeRunBusyCarrierOf, classifyActiveRunBusy, isCorruptSessionCode, isLimitsExceededCode } from '../engineErrorCodes.js';
|
|
8
8
|
import { doneResultView, isReplayedTerminal } from '../replayBody.js';
|
|
9
9
|
import { readFrameStringKey } from '../ownKey.js';
|
|
@@ -13,11 +13,25 @@ import { classifyToolHistoryMismatch, noteToolHistoryTerminal, openToolHistoryGe
|
|
|
13
13
|
import { isReviewPark, readRunTerminal, runTerminalCode } from '../runTerminal.js';
|
|
14
14
|
import { parkHeldCallIdOf } from '../engineRowRef.js';
|
|
15
15
|
import { providerRejectionResend } from '../providerRejection.js';
|
|
16
|
-
import { washCredentials } from '../displayUntrusted.js';
|
|
16
|
+
import { displayUntrusted, washCredentials } from '../displayUntrusted.js';
|
|
17
17
|
import { PROMPT_BLOCKED_BY_HOOK_ROW_LEAD, runBlockedText } from '../promptBlockedCopy.js';
|
|
18
18
|
import { ccToolDenialKindForToolEnd, gateDeniedBy, gateOutcomeOf } from '../gateOutcome.js';
|
|
19
19
|
import { resumeReopenContent, resumeReopenFromError, suspendedReopenOf } from '../hitl/suspendedReopen.js';
|
|
20
20
|
import { isCcToolDenialKind, isCcToolDenialKindADenial, isGateDeniedByWord } from '../gateVocabulary.js';
|
|
21
|
+
const ENGINE_TURN_USAGE_KEYS = Object.freeze(['inputTokens', 'totalInputTokens', 'outputTokens', 'cacheReadTokens', 'cacheWriteTokens', 'costMicroUsd']);
|
|
22
|
+
const _engineTurnUsageKeysPin = true;
|
|
23
|
+
void _engineTurnUsageKeysPin;
|
|
24
|
+
function closedEngineTurnUsage(raw) {
|
|
25
|
+
const out = {};
|
|
26
|
+
let unknownKeys = 0;
|
|
27
|
+
for (const k of Object.keys(raw)) {
|
|
28
|
+
if (ENGINE_TURN_USAGE_KEYS.includes(k))
|
|
29
|
+
out[k] = raw[k];
|
|
30
|
+
else
|
|
31
|
+
unknownKeys++;
|
|
32
|
+
}
|
|
33
|
+
return { usage: out, unknownKeys };
|
|
34
|
+
}
|
|
21
35
|
const mainLane = () => ({ lane: 'main' });
|
|
22
36
|
function emitChromeFireAndForget(ctx, event) {
|
|
23
37
|
try {
|
|
@@ -111,7 +125,23 @@ export function isModelOutputErrorRowText(text) {
|
|
|
111
125
|
return text.trimStart().startsWith(`${MODEL_OUTPUT_ERROR_PREFIX}:`);
|
|
112
126
|
}
|
|
113
127
|
export const OUTCOME_UNKNOWN_ROW_PREFIX = 'Outcome unknown';
|
|
114
|
-
function
|
|
128
|
+
function apiErrorRowBitsOf(read) {
|
|
129
|
+
try {
|
|
130
|
+
const status = read.carrier.status;
|
|
131
|
+
const providerCondition = read.detail !== undefined && ownDataBit(read.detail, 'kind') === PROVIDER_REJECTED_DETAIL ? nonEmptyStr(ownDataBit(read.detail, 'providerCondition')) : undefined;
|
|
132
|
+
const errorCode = nonEmptyStr(read.carrier.code);
|
|
133
|
+
const bits = {
|
|
134
|
+
...(typeof status === 'number' && Number.isInteger(status) && status >= 100 && status <= 999 ? { status } : {}),
|
|
135
|
+
...(providerCondition !== undefined ? { providerCondition } : {}),
|
|
136
|
+
...(errorCode !== undefined ? { errorCode } : {}),
|
|
137
|
+
};
|
|
138
|
+
return Object.keys(bits).length > 0 ? bits : undefined;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function syntheticTerminalRow(ctx, identity, replayed, text, historyKey, resend, apiError, owner) {
|
|
115
145
|
return stamp(ctx, {
|
|
116
146
|
uuid: identity.runId === undefined ? undefined : terminalUuidOf(identity.runId, identity.label),
|
|
117
147
|
session_id: undefined,
|
|
@@ -121,9 +151,38 @@ function syntheticTerminalRow(ctx, identity, replayed, text, historyKey, resend)
|
|
|
121
151
|
_sema_api_error_message: true,
|
|
122
152
|
...(historyKey !== undefined ? { _sema_tool_history_mismatch: historyKey } : {}),
|
|
123
153
|
...(resend !== undefined ? { _sema_provider_rejection_resend: { resend: resend.resend, text: resend.text, kind: resend.kind } } : {}),
|
|
154
|
+
...(apiError?.status !== undefined ? { _sema_api_error_status: apiError.status } : {}),
|
|
155
|
+
...(apiError?.providerCondition !== undefined ? { _sema_provider_condition: apiError.providerCondition } : {}),
|
|
156
|
+
...(apiError?.errorCode !== undefined ? { _sema_api_error_code: apiError.errorCode } : {}),
|
|
124
157
|
...(replayed ? { _sema_replay: true } : {}),
|
|
158
|
+
...(owner !== undefined ? { _sema_terminal_owner: owner } : {}),
|
|
125
159
|
});
|
|
126
160
|
}
|
|
161
|
+
function withTerminalOwner(frame, owner) {
|
|
162
|
+
return owner === undefined ? frame : { ...frame, _sema_terminal_owner: owner };
|
|
163
|
+
}
|
|
164
|
+
function terminalOwnerOfStream(ctx, busy, busyHandle, runId) {
|
|
165
|
+
const hostString = (k) => {
|
|
166
|
+
try {
|
|
167
|
+
const d = Object.getOwnPropertyDescriptor(ctx, k);
|
|
168
|
+
return d !== undefined && 'value' in d && typeof d.value === 'string' && d.value.length > 0 ? d.value : undefined;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return undefined;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
const followed = hostString('followedRun');
|
|
175
|
+
if (followed !== undefined)
|
|
176
|
+
return { kind: 'followed-run', taskId: followed, ...(runId !== undefined ? { runId } : {}) };
|
|
177
|
+
if (!busy)
|
|
178
|
+
return undefined;
|
|
179
|
+
const requestId = hostString('requestId');
|
|
180
|
+
return {
|
|
181
|
+
kind: 'request-not-sent',
|
|
182
|
+
...(requestId !== undefined ? { requestId } : {}),
|
|
183
|
+
...(typeof busyHandle === 'string' && busyHandle.length > 0 ? { heldBy: busyHandle } : {}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
127
186
|
function engineResultOf(result) {
|
|
128
187
|
const v = doneResultView(result);
|
|
129
188
|
return v.replay ? (v.engine ?? result) : result;
|
|
@@ -233,7 +292,7 @@ function ownTerminalSnapshot(result) {
|
|
|
233
292
|
const ts = ownDataCopy(t, ['kind', 'code', 'message']);
|
|
234
293
|
const detail = plainObjectOf(ownDataBit(t, 'detail'));
|
|
235
294
|
if (detail !== undefined)
|
|
236
|
-
ts.detail = ownDataCopy(detail, ['kind', 'status', 'code']);
|
|
295
|
+
ts.detail = ownDataCopy(detail, ['kind', 'status', 'code', 'providerCondition']);
|
|
237
296
|
snap.terminal = ts;
|
|
238
297
|
return snap;
|
|
239
298
|
}
|
|
@@ -314,12 +373,10 @@ function apiErrorTerminalOfRowFrame(ev, facts) {
|
|
|
314
373
|
}
|
|
315
374
|
const reportedDroppedTypes = new Set();
|
|
316
375
|
const DROPPED_TYPE_MEMO_CAP = 64;
|
|
317
|
-
const
|
|
318
|
-
function
|
|
319
|
-
const
|
|
320
|
-
return
|
|
321
|
-
? `${flattened.slice(0, DROPPED_TYPE_DISPLAY_CAP)}…`
|
|
322
|
-
: flattened;
|
|
376
|
+
const DROPPED_TYPE_DISPLAY_MAX = 60;
|
|
377
|
+
function droppedTypeForLog(type) {
|
|
378
|
+
const full = displayUntrusted(type);
|
|
379
|
+
return full.length > DROPPED_TYPE_DISPLAY_MAX ? `${displayUntrusted(type, { max: DROPPED_TYPE_DISPLAY_MAX })}…` : full;
|
|
323
380
|
}
|
|
324
381
|
const DROPPED_WHY_SENTENCE = Object.freeze({
|
|
325
382
|
duplicate_seq: 'a frame with this event id was already consumed on this run stream, so it was dropped as a replay (durable idempotency, contract 02 §1.1). ' +
|
|
@@ -348,7 +405,7 @@ function reportDroppedFrame(why, type, ctx) {
|
|
|
348
405
|
return;
|
|
349
406
|
if (reportedDroppedTypes.size < DROPPED_TYPE_MEMO_CAP)
|
|
350
407
|
reportedDroppedTypes.add(type);
|
|
351
|
-
console.error(`[client-core] dropped an engine frame (${why}): type="${
|
|
408
|
+
console.error(`[client-core] dropped an engine frame (${why}): type="${droppedTypeForLog(type)}" — ${droppedWhySentence(why)}`);
|
|
352
409
|
}
|
|
353
410
|
export function _resetDroppedFrameReportForTest() {
|
|
354
411
|
reportedDroppedTypes.clear();
|
|
@@ -512,27 +569,9 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
512
569
|
}
|
|
513
570
|
}
|
|
514
571
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
ev.type === 'reasoning' ||
|
|
519
|
-
ev.type === 'tool_start' ||
|
|
520
|
-
ev.type === 'tool_end') &&
|
|
521
|
-
typeof ev.parentToolCallId === 'string') {
|
|
522
|
-
const sub = ev;
|
|
523
|
-
publishSubagentContentEvent({
|
|
524
|
-
type: sub.type,
|
|
525
|
-
taskId: sub.taskId ?? sub.parentToolCallId,
|
|
526
|
-
parentToolCallId: sub.parentToolCallId,
|
|
527
|
-
delta: sub.delta,
|
|
528
|
-
text: sub.text,
|
|
529
|
-
eventId: sub.eventId,
|
|
530
|
-
toolCallId: sub.toolCallId,
|
|
531
|
-
toolName: sub.toolName,
|
|
532
|
-
args: sub.args,
|
|
533
|
-
output: coerceOutput(sub.output),
|
|
534
|
-
isError: sub.isError,
|
|
535
|
-
});
|
|
572
|
+
const sub = subagentContentEventOf(ev);
|
|
573
|
+
if (sub !== undefined) {
|
|
574
|
+
publishSubagentContentEvent(sub);
|
|
536
575
|
if (!(ctx.lane === 'print' && (sub.type === 'tool_start' || sub.type === 'tool_end')))
|
|
537
576
|
continue;
|
|
538
577
|
}
|
|
@@ -546,10 +585,10 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
546
585
|
const responseModelRaw = turnEndLoose.responseModel;
|
|
547
586
|
const responseModelWord = typeof responseModelRaw === 'string' && responseModelRaw.length > 0 ? responseModelRaw : undefined;
|
|
548
587
|
const rawUsage = ev.usage;
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
const usage =
|
|
588
|
+
const closedUsage = typeof rawUsage === 'object' && rawUsage !== null && !Array.isArray(rawUsage) ? closedEngineTurnUsage(rawUsage) : undefined;
|
|
589
|
+
const engineUsage = closedUsage?.usage;
|
|
590
|
+
const usageUnknownKeys = closedUsage !== undefined && closedUsage.unknownKeys > 0 ? { engineUsageUnknownKeys: closedUsage.unknownKeys } : {};
|
|
591
|
+
const usage = closedUsage !== undefined ? turnUsageToModelUsage(rawUsage) : undefined;
|
|
553
592
|
const measured = turnEndUsage(ev);
|
|
554
593
|
if (engineUsage === undefined || usage === undefined) {
|
|
555
594
|
usageMissingObserved = true;
|
|
@@ -577,6 +616,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
577
616
|
laneProof: mainLane(),
|
|
578
617
|
usage,
|
|
579
618
|
engineUsage,
|
|
619
|
+
...usageUnknownKeys,
|
|
580
620
|
...(usageMissing ? { usageMissing: true } : {}),
|
|
581
621
|
...(stopWord !== undefined ? { stopReason: stopWord } : {}),
|
|
582
622
|
...(responseModelWord !== undefined ? { responseModel: responseModelWord } : {}),
|
|
@@ -600,6 +640,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
600
640
|
parentToolCallId: parent,
|
|
601
641
|
usage,
|
|
602
642
|
engineUsage,
|
|
643
|
+
...usageUnknownKeys,
|
|
603
644
|
...(usageMissing ? { usageMissing: true } : {}),
|
|
604
645
|
...(stopWord !== undefined ? { stopReason: stopWord } : {}),
|
|
605
646
|
...(responseModelWord !== undefined ? { responseModel: responseModelWord } : {}),
|
|
@@ -640,6 +681,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
640
681
|
const doneTerminal = rowFacts.doneTerminal;
|
|
641
682
|
const terminalRunId = terminalRunIdOf(ev);
|
|
642
683
|
const replayed = isReplayedTerminal(ev);
|
|
684
|
+
const owner = terminalOwnerOfStream(ctx, rowFacts.busy.busy, rowFacts.busy.handle, terminalRunId);
|
|
643
685
|
const errText = rowFacts.errText;
|
|
644
686
|
if (errText) {
|
|
645
687
|
const busy = rowFacts.busy;
|
|
@@ -680,7 +722,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
680
722
|
: '';
|
|
681
723
|
const resend = historyTerminal.detail !== undefined ? providerRejectionResend(historyTerminal.detail, historyTerminal.carrier) : undefined;
|
|
682
724
|
const resendLine = resend !== undefined ? `\n${resend.text}` : '';
|
|
683
|
-
yield syntheticTerminalRow(ctx, { runId: terminalRunId, label: 'terminal-row' }, replayed, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${abortNote !== undefined ? `\n${abortNote}` : ''}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend);
|
|
725
|
+
yield syntheticTerminalRow(ctx, { runId: terminalRunId, label: 'terminal-row' }, replayed, `${sessionUnreadable ? `${rowText}\n${corruptSessionContent()}` : rowText}${abortNote !== undefined ? `\n${abortNote}` : ''}${rewindLine}${resendLine}`, historyMismatch === null ? undefined : toolHistoryMismatchRowKey(historyMismatch, historyRepeat, rewindOffered), resend, arm === 'apiError' ? apiErrorRowBitsOf(historyTerminal) : undefined, owner);
|
|
684
726
|
}
|
|
685
727
|
else {
|
|
686
728
|
const echoedSid = ev.type === 'done' ? engineSessionIdOf(engineResultOf(ev.result)) : undefined;
|
|
@@ -706,7 +748,7 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
706
748
|
emitChromeFireAndForget(ctx, { kind: 'run_cost_reconciled', laneProof: mainLane(), ...costFacts.reconcile });
|
|
707
749
|
}
|
|
708
750
|
}
|
|
709
|
-
const resultFrame = terminalToSdkResult(ev, ctx, {
|
|
751
|
+
const resultFrame = withTerminalOwner(terminalToSdkResult(ev, ctx, {
|
|
710
752
|
usageMissingObserved,
|
|
711
753
|
nestedUsageByTask,
|
|
712
754
|
toolInputByCallId,
|
|
@@ -716,13 +758,13 @@ async function* runStreamInner(events, ctx, handle = {}) {
|
|
|
716
758
|
streamSawRunOpen,
|
|
717
759
|
deniedToolNameByCallId,
|
|
718
760
|
deniedCallsOverflowed,
|
|
719
|
-
});
|
|
761
|
+
}), owner);
|
|
720
762
|
const outcome = resultFrame.
|
|
721
763
|
_sema_outcome;
|
|
722
764
|
if (outcome === 'unknown') {
|
|
723
765
|
const errs = resultFrame.errors;
|
|
724
766
|
const sentence = Array.isArray(errs) && typeof errs[0] === 'string' ? errs[0] : 'the run ended without a terminal record this client can read';
|
|
725
|
-
yield syntheticTerminalRow(ctx, { runId: terminalRunId, label: 'outcome-unknown' }, replayed, `${OUTCOME_UNKNOWN_ROW_PREFIX}: ${sentence}
|
|
767
|
+
yield syntheticTerminalRow(ctx, { runId: terminalRunId, label: 'outcome-unknown' }, replayed, `${OUTCOME_UNKNOWN_ROW_PREFIX}: ${sentence}`, undefined, undefined, undefined, owner);
|
|
726
768
|
}
|
|
727
769
|
yield terminalFactOf(ev, doneTerminal);
|
|
728
770
|
yield resultFrame;
|
package/dist/adapter/types.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export interface EmitContext {
|
|
|
23
23
|
emitChrome?(event: ChromeEvent): void | Promise<void>;
|
|
24
24
|
onDroppedFrame?(info: DroppedFrameInfo): void;
|
|
25
25
|
boundRun?(frame: AgentEvent): EngineBoundRun | undefined;
|
|
26
|
+
requestId?: string;
|
|
27
|
+
followedRun?: string;
|
|
26
28
|
}
|
|
27
29
|
export declare function stamp<T extends {
|
|
28
30
|
uuid?: string | undefined;
|
package/dist/adapter/types.js
CHANGED
|
@@ -4,7 +4,7 @@ import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, noAnswerDetailF
|
|
|
4
4
|
import { engineWireDebugEnabled } from '../engineWireTarget.js';
|
|
5
5
|
import { hostLog } from '../host.js';
|
|
6
6
|
import { isSessionIdPathSegment } from '../sessionIdSegment.js';
|
|
7
|
-
import { wireFailureTextsOf } from '../wireFailureShape.js';
|
|
7
|
+
import { readThrownSlot, readThrownStatusSlot, THROWN_SLOT_UNREADABLE, wireFailureTextsOf } from '../wireFailureShape.js';
|
|
8
8
|
import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
9
9
|
const NOTHING_SENT = ' — nothing sent';
|
|
10
10
|
const DETAIL_BAD_SESSION = `the session id must be a non-empty string that is not a dot segment${NOTHING_SENT}`;
|
|
@@ -155,13 +155,16 @@ function refusedWhyOf(rawCode, status) {
|
|
|
155
155
|
return undefined;
|
|
156
156
|
}
|
|
157
157
|
function diagOf(e) {
|
|
158
|
-
const
|
|
159
|
-
const
|
|
158
|
+
const rawStatus = readThrownStatusSlot(e);
|
|
159
|
+
const rawCode = readThrownSlot(e, 'errorCode', 'data');
|
|
160
|
+
if (rawStatus === THROWN_SLOT_UNREADABLE || rawCode === THROWN_SLOT_UNREADABLE)
|
|
161
|
+
return undefined;
|
|
160
162
|
const status = typeof rawStatus === 'number' && Number.isInteger(rawStatus) ? rawStatus : undefined;
|
|
161
|
-
const errorCode = typeof
|
|
162
|
-
const ra =
|
|
163
|
+
const errorCode = typeof rawCode === 'string' && rawCode.length > 0 ? rawCode : undefined;
|
|
164
|
+
const ra = readThrownSlot(e, 'retryAfterMs', 'data');
|
|
163
165
|
const retryAfterMs = typeof ra === 'number' && Number.isFinite(ra) && ra >= 0 ? ra : undefined;
|
|
164
|
-
const
|
|
166
|
+
const rawMessage = readThrownSlot(e, 'message');
|
|
167
|
+
const message = typeof rawMessage === 'string' && rawMessage.length > 0 ? rawMessage : undefined;
|
|
165
168
|
return {
|
|
166
169
|
...(status !== undefined ? { status } : {}),
|
|
167
170
|
...(errorCode !== undefined ? { errorCode } : {}),
|
|
@@ -169,6 +172,10 @@ function diagOf(e) {
|
|
|
169
172
|
...(message !== undefined ? { message } : {}),
|
|
170
173
|
};
|
|
171
174
|
}
|
|
175
|
+
function unreadableFailure() {
|
|
176
|
+
note('error (the failure could not be read)');
|
|
177
|
+
return { kind: 'error', detail: 'the stop request failed (the error could not be read)' };
|
|
178
|
+
}
|
|
172
179
|
function classifyFailure(e) {
|
|
173
180
|
try {
|
|
174
181
|
if (typeof e !== 'object' || e === null) {
|
|
@@ -176,6 +183,8 @@ function classifyFailure(e) {
|
|
|
176
183
|
return { kind: 'error', detail: `the stop request failed: ${wireFailureTextsOf(e).reason.slice(0, 200)}` };
|
|
177
184
|
}
|
|
178
185
|
const d = diagOf(e);
|
|
186
|
+
if (d === undefined)
|
|
187
|
+
return unreadableFailure();
|
|
179
188
|
if (d.status === undefined && d.errorCode === undefined) {
|
|
180
189
|
const noAnswer = noAnswerDetailFrom(e);
|
|
181
190
|
if (noAnswer !== null) {
|
|
@@ -200,8 +209,7 @@ function classifyFailure(e) {
|
|
|
200
209
|
return { kind: 'error', detail: (d.message ?? 'the stop request failed').slice(0, 300), ...diag };
|
|
201
210
|
}
|
|
202
211
|
catch {
|
|
203
|
-
|
|
204
|
-
return { kind: 'error', detail: 'the stop request failed (the error could not be read)' };
|
|
212
|
+
return unreadableFailure();
|
|
205
213
|
}
|
|
206
214
|
}
|
|
207
215
|
export async function stopEngineSessionBackground(sessionId, body, opts) {
|
package/dist/agentsWireCaps.d.ts
CHANGED
|
@@ -3,9 +3,6 @@ import type { ReasoningEffort } from './effortWire.js';
|
|
|
3
3
|
import type { ToolRosterView } from './toolRoster.js';
|
|
4
4
|
import { type AssemblyRefusal } from './wireFailureShape.js';
|
|
5
5
|
export declare const MAX_TASK_AGENTS = 32;
|
|
6
|
-
export declare const MAX_AGENT_TEXT_CHARS = 4096;
|
|
7
|
-
export declare const MAX_AGENT_SYSTEM_PROMPT_CHARS = 65536;
|
|
8
|
-
export declare const MAX_AGENT_SKILL_CONTENT_CHARS = 1048576;
|
|
9
6
|
export declare const TASK_AGENT_WIRE_FIELDS: readonly ["name", "whenToUse", "whenToUseLean", "allowTools", "denyTools", "skills", "background", "isolation", "model", "thinking", "systemPrompt", "maxTurns", "memory", "observer", "observerMessage"];
|
|
10
7
|
export type WireThinkingLevel = ReasoningEffort;
|
|
11
8
|
export type TaskAgentWireSkill = {
|
|
@@ -49,6 +46,12 @@ export type AgentDefLike = {
|
|
|
49
46
|
source: string;
|
|
50
47
|
getSystemPrompt?: (arg?: unknown) => string;
|
|
51
48
|
};
|
|
49
|
+
export declare const REFUSED_PROJECT_SERVER_CAUSES: readonly ["rejected", "not_approved", "disabled", "policy_blocked", "plugin_only", "malformed_config"];
|
|
50
|
+
export type RefusedProjectServerCause = (typeof REFUSED_PROJECT_SERVER_CAUSES)[number];
|
|
51
|
+
export interface RefusedProjectServer {
|
|
52
|
+
readonly name: string;
|
|
53
|
+
readonly cause: RefusedProjectServerCause;
|
|
54
|
+
}
|
|
52
55
|
export type ProjectAgentsDeps = {
|
|
53
56
|
resolveModel: (frontmatterModel: string | undefined) => {
|
|
54
57
|
model: string;
|
|
@@ -58,6 +61,7 @@ export type ProjectAgentsDeps = {
|
|
|
58
61
|
skillSpecs?: TaskAgentWireSkill[];
|
|
59
62
|
toolRoster?: ToolRosterView | null;
|
|
60
63
|
agentSourceLabel?: (agentName: string) => string | undefined;
|
|
64
|
+
refusedProjectServers?: readonly RefusedProjectServer[];
|
|
61
65
|
};
|
|
62
66
|
export type ProjectAgentsResult = {
|
|
63
67
|
agents: TaskAgentWireItem[] | undefined;
|
package/dist/agentsWireCaps.js
CHANGED
|
@@ -8,11 +8,10 @@ import { CORE_PROTOCOL_PREFIXES } from './generated/toolNameTables.js';
|
|
|
8
8
|
import { rosterMountedNames } from './rosterMountedNames.js';
|
|
9
9
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
10
10
|
import { deniedEntryToolName } from './engineToolDirectory.js';
|
|
11
|
-
import {
|
|
11
|
+
import { hasCoreValuePort, mcpNamespace, mintNamespacePrefix } from './coreValuePorts.js';
|
|
12
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
13
|
+
import { assemblyRefusal, withAssemblyRefusal } from './wireFailureShape.js';
|
|
12
14
|
export const MAX_TASK_AGENTS = 32;
|
|
13
|
-
export const MAX_AGENT_TEXT_CHARS = 4_096;
|
|
14
|
-
export const MAX_AGENT_SYSTEM_PROMPT_CHARS = 65_536;
|
|
15
|
-
export const MAX_AGENT_SKILL_CONTENT_CHARS = 1_048_576;
|
|
16
15
|
export const TASK_AGENT_WIRE_FIELDS = [
|
|
17
16
|
'name',
|
|
18
17
|
'whenToUse',
|
|
@@ -31,6 +30,7 @@ export const TASK_AGENT_WIRE_FIELDS = [
|
|
|
31
30
|
'observerMessage',
|
|
32
31
|
];
|
|
33
32
|
export const AGENT_MEMORY_WORDS = frozenSet(['user', 'project', 'local']);
|
|
33
|
+
export const REFUSED_PROJECT_SERVER_CAUSES = Object.freeze(['rejected', 'not_approved', 'disabled', 'policy_blocked', 'plugin_only', 'malformed_config']);
|
|
34
34
|
const SOURCE_RANK = {
|
|
35
35
|
policySettings: 0,
|
|
36
36
|
flagSettings: 1,
|
|
@@ -98,8 +98,76 @@ function toolListFlawPhrase(f) {
|
|
|
98
98
|
return `${entry} could not be checked here, because the engine's tool-name check is not available in this client`;
|
|
99
99
|
return `${entry} differs from the tool ${JSON.stringify(f.currentName ?? '')} only in letter case`;
|
|
100
100
|
}
|
|
101
|
+
function listShapeWord(v) {
|
|
102
|
+
try {
|
|
103
|
+
if (v === null)
|
|
104
|
+
return 'null';
|
|
105
|
+
if (typeof v === 'string')
|
|
106
|
+
return 'a string';
|
|
107
|
+
if (typeof v === 'object')
|
|
108
|
+
return 'an object';
|
|
109
|
+
return `a ${typeof v}`;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return 'unreadable';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function toolListShapeRefusal(agent, key, v) {
|
|
116
|
+
return withAssemblyRefusal(new TypeError(`projectAgentsForWire: agent "${capForDisplay(agent, 80)}" has ${key} written as ${listShapeWord(v)}, but it must be an array of tool-name strings — ` +
|
|
117
|
+
'refusing to assemble the agents list (a list dropped silently would give the agent every tool, or remove a deny rule). Fix the definition.'), 'input_malformed');
|
|
118
|
+
}
|
|
119
|
+
const REFUSED_SERVER_PHRASE_KEYS = Object.freeze({
|
|
120
|
+
rejected: ['config.agentsWire.refusedServer.cause.rejected', 'config.agentsWire.refusedServer.way.rejected'],
|
|
121
|
+
not_approved: ['config.agentsWire.refusedServer.cause.notApproved', 'config.agentsWire.refusedServer.way.notApproved'],
|
|
122
|
+
disabled: ['config.agentsWire.refusedServer.cause.disabled', 'config.agentsWire.refusedServer.way.disabled'],
|
|
123
|
+
policy_blocked: ['config.agentsWire.refusedServer.cause.policyBlocked', 'config.agentsWire.refusedServer.way.policyBlocked'],
|
|
124
|
+
plugin_only: ['config.agentsWire.refusedServer.cause.pluginOnly', 'config.agentsWire.refusedServer.way.pluginOnly'],
|
|
125
|
+
malformed_config: ['config.agentsWire.refusedServer.cause.malformedConfig', 'config.agentsWire.refusedServer.way.malformedConfig'],
|
|
126
|
+
});
|
|
127
|
+
const REFUSED_SERVER_UNKNOWN_PHRASE = ['config.agentsWire.refusedServer.cause.unknown', 'config.agentsWire.refusedServer.way.unknown'];
|
|
128
|
+
const REFUSED_SERVER_NAME_MAX = 80;
|
|
129
|
+
function refusedServerIndexOf(list) {
|
|
130
|
+
try {
|
|
131
|
+
if (!Array.isArray(list) || list.length === 0)
|
|
132
|
+
return [];
|
|
133
|
+
if (!hasCoreValuePort('protocolOf') || !hasCoreValuePort('mintNamespacePrefix'))
|
|
134
|
+
return [];
|
|
135
|
+
const ns = mcpNamespace();
|
|
136
|
+
if (ns === undefined)
|
|
137
|
+
return [];
|
|
138
|
+
const out = [];
|
|
139
|
+
const seen = new Set();
|
|
140
|
+
for (const row of list) {
|
|
141
|
+
try {
|
|
142
|
+
if (row === null || typeof row !== 'object')
|
|
143
|
+
continue;
|
|
144
|
+
const name = row.name;
|
|
145
|
+
const cause = row.cause;
|
|
146
|
+
if (typeof name !== 'string' || name === '' || seen.has(name))
|
|
147
|
+
continue;
|
|
148
|
+
const prefix = mintNamespacePrefix(ns, name);
|
|
149
|
+
if (typeof prefix !== 'string' || prefix.length === 0)
|
|
150
|
+
continue;
|
|
151
|
+
seen.add(name);
|
|
152
|
+
const known = typeof cause === 'string' && Object.hasOwn(REFUSED_SERVER_PHRASE_KEYS, cause) ? REFUSED_SERVER_PHRASE_KEYS[cause] : undefined;
|
|
153
|
+
out.push({ name, prefix, phrase: known ?? REFUSED_SERVER_UNKNOWN_PHRASE });
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return [];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function entryNamesServer(entry, prefix) {
|
|
166
|
+
return entry.startsWith(prefix) || entry === prefix.slice(0, -2);
|
|
167
|
+
}
|
|
101
168
|
export function projectAgentsForWire(defs, deps) {
|
|
102
169
|
const warnings = [];
|
|
170
|
+
const refusedServers = refusedServerIndexOf(deps.refusedProjectServers);
|
|
103
171
|
const customs = defs
|
|
104
172
|
.filter(d => d.source !== 'built-in')
|
|
105
173
|
.slice()
|
|
@@ -121,25 +189,24 @@ export function projectAgentsForWire(defs, deps) {
|
|
|
121
189
|
continue;
|
|
122
190
|
seen.add(name);
|
|
123
191
|
const item = { name };
|
|
124
|
-
if (typeof def.whenToUse === 'string' && def.whenToUse.length > 0)
|
|
125
|
-
item.whenToUse =
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
192
|
+
if (typeof def.whenToUse === 'string' && def.whenToUse.length > 0)
|
|
193
|
+
item.whenToUse = def.whenToUse;
|
|
194
|
+
const rawTools = def.tools;
|
|
195
|
+
const rawDeny = def.disallowedTools;
|
|
196
|
+
if (rawTools !== undefined && !Array.isArray(rawTools))
|
|
197
|
+
throw toolListShapeRefusal(name, 'tools', rawTools);
|
|
198
|
+
if (rawDeny !== undefined && !Array.isArray(rawDeny))
|
|
199
|
+
throw toolListShapeRefusal(name, 'disallowedTools', rawDeny);
|
|
133
200
|
const toolEntries = (list, label) => {
|
|
134
201
|
const entries = list.filter((t) => typeof t === 'string' && t.length > 0);
|
|
135
202
|
if (entries.length !== list.length)
|
|
136
203
|
warnings.push(`agents wire: agent "${name}" ${label} had invalid entries — dropped`);
|
|
137
204
|
return entries;
|
|
138
205
|
};
|
|
139
|
-
if (Array.isArray(
|
|
140
|
-
item.allowTools = toolEntries(
|
|
141
|
-
if (Array.isArray(
|
|
142
|
-
const denyTools = toolEntries(
|
|
206
|
+
if (Array.isArray(rawTools))
|
|
207
|
+
item.allowTools = toolEntries(rawTools, 'tools');
|
|
208
|
+
if (Array.isArray(rawDeny)) {
|
|
209
|
+
const denyTools = toolEntries(rawDeny, 'disallowedTools');
|
|
143
210
|
if (denyTools.length > 0)
|
|
144
211
|
item.denyTools = denyTools;
|
|
145
212
|
}
|
|
@@ -177,7 +244,30 @@ export function projectAgentsForWire(defs, deps) {
|
|
|
177
244
|
for (const f of flaws) {
|
|
178
245
|
if (f.list !== 'tools')
|
|
179
246
|
continue;
|
|
180
|
-
warnings.push(
|
|
247
|
+
warnings.push(renderMessage(msg('config.agentsWire.toolEntry.sentence', { who, phrase: toolListFlawPhrase(f) })));
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (refusedServers.length > 0 && item.allowTools !== undefined) {
|
|
251
|
+
const told = new Set();
|
|
252
|
+
const mounted = rosterMountedNames(deps.toolRoster);
|
|
253
|
+
const mountedNames = typeof mounted === 'object' ? mounted : undefined;
|
|
254
|
+
for (const entry of item.allowTools) {
|
|
255
|
+
if (mountedNames?.has(entry) === true)
|
|
256
|
+
continue;
|
|
257
|
+
const hit = refusedServers.find((r) => entryNamesServer(entry, r.prefix));
|
|
258
|
+
if (hit === undefined)
|
|
259
|
+
continue;
|
|
260
|
+
const sentence = renderMessage(msg('config.agentsWire.refusedServer.sentence', {
|
|
261
|
+
who: whoOf(),
|
|
262
|
+
entry: JSON.stringify(entry),
|
|
263
|
+
server: JSON.stringify(capForDisplay(hit.name, REFUSED_SERVER_NAME_MAX)),
|
|
264
|
+
cause: msg(hit.phrase[0]),
|
|
265
|
+
way: msg(hit.phrase[1]),
|
|
266
|
+
}));
|
|
267
|
+
if (told.has(sentence))
|
|
268
|
+
continue;
|
|
269
|
+
told.add(sentence);
|
|
270
|
+
warnings.push(sentence);
|
|
181
271
|
}
|
|
182
272
|
}
|
|
183
273
|
if (def.memory !== undefined) {
|
|
@@ -199,7 +289,7 @@ export function projectAgentsForWire(defs, deps) {
|
|
|
199
289
|
if (typeof skillName !== 'string' || skillName.length === 0)
|
|
200
290
|
continue;
|
|
201
291
|
const spec = byName.get(skillName.toLowerCase());
|
|
202
|
-
if (spec && spec.content.length > 0
|
|
292
|
+
if (spec && spec.content.length > 0) {
|
|
203
293
|
joined.push(spec);
|
|
204
294
|
}
|
|
205
295
|
else {
|
|
@@ -236,13 +326,8 @@ export function projectAgentsForWire(defs, deps) {
|
|
|
236
326
|
catch {
|
|
237
327
|
prompt = undefined;
|
|
238
328
|
}
|
|
239
|
-
if (typeof prompt === 'string' && prompt.length > 0)
|
|
240
|
-
if (prompt.length > MAX_AGENT_SYSTEM_PROMPT_CHARS) {
|
|
241
|
-
warnings.push(`agents wire: agent "${name}" system prompt truncated to ${MAX_AGENT_SYSTEM_PROMPT_CHARS} chars`);
|
|
242
|
-
prompt = prompt.slice(0, MAX_AGENT_SYSTEM_PROMPT_CHARS);
|
|
243
|
-
}
|
|
329
|
+
if (typeof prompt === 'string' && prompt.length > 0)
|
|
244
330
|
item.systemPrompt = prompt;
|
|
245
|
-
}
|
|
246
331
|
}
|
|
247
332
|
if (def.maxTurns !== undefined)
|
|
248
333
|
item.maxTurns = def.maxTurns;
|
|
@@ -291,6 +376,12 @@ let preparedKey = null;
|
|
|
291
376
|
let preparedCapsGen = null;
|
|
292
377
|
let preparedPromise = null;
|
|
293
378
|
let payload;
|
|
379
|
+
function setPayload(agents, warnings) {
|
|
380
|
+
payload = { agents, warnings: Object.freeze([...warnings]) };
|
|
381
|
+
}
|
|
382
|
+
function clearPayload() {
|
|
383
|
+
payload = undefined;
|
|
384
|
+
}
|
|
294
385
|
let currentGeneration = null;
|
|
295
386
|
function concludeGeneration(generation, outcome) {
|
|
296
387
|
if (generation !== null && preparedPromise === generation && currentGeneration !== null)
|
|
@@ -326,7 +417,7 @@ function watchCapsVerdict(baseUrl) {
|
|
|
326
417
|
void engineCapsSettled(baseUrl).then(() => {
|
|
327
418
|
if (preparedKey !== baseUrl || capsVerdictAt(baseUrl) !== false)
|
|
328
419
|
return;
|
|
329
|
-
|
|
420
|
+
clearPayload();
|
|
330
421
|
concludeGeneration(preparedPromise, 'ok');
|
|
331
422
|
currentGeneration?.settle();
|
|
332
423
|
});
|
|
@@ -336,12 +427,10 @@ function applyProjectionIfCurrent(generation, projected) {
|
|
|
336
427
|
return false;
|
|
337
428
|
const accepted = capsVerdictAt(preparedKey) !== false;
|
|
338
429
|
if (accepted) {
|
|
339
|
-
|
|
340
|
-
warnOnce(w);
|
|
341
|
-
payload = projected.agents;
|
|
430
|
+
setPayload(projected.agents, projected.warnings);
|
|
342
431
|
}
|
|
343
432
|
else {
|
|
344
|
-
|
|
433
|
+
clearPayload();
|
|
345
434
|
}
|
|
346
435
|
concludeGeneration(generation, 'ok');
|
|
347
436
|
currentGeneration?.settle();
|
|
@@ -352,7 +441,7 @@ async function runPrepare(cfg, projector, generation) {
|
|
|
352
441
|
const [, projected] = await Promise.all([capsSettledAt(cfg.baseUrl), projector()]);
|
|
353
442
|
if (capsVerdictAt(cfg.baseUrl) === false) {
|
|
354
443
|
if (preparedKey === cfg.baseUrl) {
|
|
355
|
-
|
|
444
|
+
clearPayload();
|
|
356
445
|
concludeGeneration(generation, 'ok');
|
|
357
446
|
if (projected.agents) {
|
|
358
447
|
warnOnce(`agents wire: this engine does not support per-task custom agents (capabilities.taskAgents is not true: the engine does not report it, or this deployment turns it off, for example a multi-tenant one; this client cannot tell which) — ${projected.agents.length} custom agent definition(s) will NOT be sent`);
|
|
@@ -362,13 +451,14 @@ async function runPrepare(cfg, projector, generation) {
|
|
|
362
451
|
}
|
|
363
452
|
if (!applyProjectionIfCurrent(generation, projected))
|
|
364
453
|
return;
|
|
365
|
-
|
|
366
|
-
|
|
454
|
+
const sent = payload?.agents;
|
|
455
|
+
if (sent && hostEnv().SEMA_DEBUG) {
|
|
456
|
+
console.error(`[sema] agents wire: ${sent.length} custom agent(s) → TaskRequest.agents (${sent.map(a => a.name).join(', ')})`);
|
|
367
457
|
}
|
|
368
458
|
}
|
|
369
459
|
catch (e) {
|
|
370
460
|
if (preparedPromise === generation)
|
|
371
|
-
|
|
461
|
+
clearPayload();
|
|
372
462
|
concludeGeneration(generation, 'failed');
|
|
373
463
|
if (hostEnv().SEMA_DEBUG) {
|
|
374
464
|
console.error('[sema] agents wire prepare failed (the readiness gate refuses this turn):', e);
|
|
@@ -403,7 +493,7 @@ export function invalidateTaskAgentsWire() {
|
|
|
403
493
|
const projector = activeProjector;
|
|
404
494
|
if (!preparedPromise || !projector)
|
|
405
495
|
return Promise.resolve();
|
|
406
|
-
|
|
496
|
+
clearPayload();
|
|
407
497
|
return startGeneration(generation => runReproject(projector, generation));
|
|
408
498
|
}
|
|
409
499
|
async function runReproject(projector, generation) {
|
|
@@ -434,7 +524,7 @@ export async function awaitTaskAgentsWire(timeoutMs = 4000) {
|
|
|
434
524
|
return taskAgentsReady();
|
|
435
525
|
const projector = activeProjector;
|
|
436
526
|
if (currentGeneration?.outcome === 'failed' && projector !== null) {
|
|
437
|
-
|
|
527
|
+
clearPayload();
|
|
438
528
|
void startGeneration(generation => runReproject(projector, generation));
|
|
439
529
|
}
|
|
440
530
|
let timeoutHandle;
|
|
@@ -493,10 +583,14 @@ function kickTaskAgentsRefresh() {
|
|
|
493
583
|
export function taskAgentsField() {
|
|
494
584
|
const base = preparedKey;
|
|
495
585
|
if (capsVerdictAt(base) === false) {
|
|
496
|
-
|
|
586
|
+
clearPayload();
|
|
497
587
|
return {};
|
|
498
588
|
}
|
|
499
|
-
const
|
|
589
|
+
const held = payload;
|
|
590
|
+
const current = held?.agents;
|
|
591
|
+
if (held !== undefined)
|
|
592
|
+
for (const w of held.warnings)
|
|
593
|
+
warnOnce(w);
|
|
500
594
|
kickTaskAgentsRefresh();
|
|
501
595
|
return current ? { agents: current } : {};
|
|
502
596
|
}
|
|
@@ -506,6 +600,6 @@ export function _resetAgentsWireForTest() {
|
|
|
506
600
|
preparedCapsGen = null;
|
|
507
601
|
preparedPromise = null;
|
|
508
602
|
currentGeneration = null;
|
|
509
|
-
|
|
603
|
+
clearPayload();
|
|
510
604
|
emittedWarnings.clear();
|
|
511
605
|
}
|