@sema-agent/client-core 0.104.1 → 0.106.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 +310 -0
- package/README.md +36 -14
- package/dist/adapt/arms.js +23 -6
- package/dist/adapter/activeRunSelfHeal.d.ts +14 -2
- package/dist/adapter/activeRunSelfHeal.js +90 -12
- package/dist/adapter/downstream/eventToSdkMessage.d.ts +0 -5
- package/dist/adapter/downstream/eventToSdkMessage.js +24 -23
- package/dist/adapter/downstream/terminalToSdkResult.js +2 -3
- package/dist/adapter/downstream/wiringManifestView.d.ts +7 -3
- package/dist/adapter/downstream/wiringManifestView.js +25 -1
- package/dist/adapter/runStream.js +8 -5
- package/dist/approvalReachWire.d.ts +1 -0
- package/dist/approvalReachWire.js +4 -1
- package/dist/approvalSeat.d.ts +21 -0
- package/dist/approvalSeat.js +73 -0
- package/dist/assistantInbox.d.ts +2 -0
- package/dist/assistantInbox.js +3 -0
- package/dist/checkpointRowVerdict.d.ts +23 -0
- package/dist/checkpointRowVerdict.js +89 -0
- package/dist/cloudConfigWireCaps.js +3 -0
- package/dist/compensations.js +6 -6
- package/dist/coreValuePorts.d.ts +14 -1
- package/dist/coreValuePorts.js +14 -0
- package/dist/decideFailureNote.js +3 -1
- package/dist/decideReceipt.d.ts +9 -0
- package/dist/decideReceipt.js +29 -1
- package/dist/declared/supportFloorDeclared.js +2 -2
- package/dist/deviceRebind.d.ts +7 -0
- package/dist/deviceRebind.js +39 -5
- package/dist/displayUntrusted.d.ts +4 -2
- package/dist/displayUntrusted.js +45 -22
- package/dist/engineAddress.d.ts +3 -0
- package/dist/engineAddress.js +25 -0
- package/dist/engineDirectory.js +9 -17
- package/dist/engineErrorCodes.d.ts +8 -0
- package/dist/engineErrorCodes.js +8 -0
- package/dist/engineGenerationPort.d.ts +11 -2
- package/dist/engineGenerationPort.js +63 -9
- package/dist/engineHealthFacts.d.ts +5 -0
- package/dist/engineHealthFacts.js +11 -0
- package/dist/engineNoticeCodes.d.ts +26 -3
- package/dist/engineNoticeCodes.js +52 -7
- package/dist/engineRowRef.js +1 -1
- package/dist/errorSupplementRoles.js +2 -0
- package/dist/eventLeg.d.ts +3 -3
- package/dist/eventLeg.js +25 -4
- package/dist/fleet/fleetProjection.js +26 -5
- package/dist/generated/engineFactTables.d.ts +3 -1
- package/dist/generated/engineFactTables.js +4 -1
- package/dist/generated/engineNoticeTables.js +19 -4
- package/dist/generated/sdkFactTables.d.ts +5 -0
- package/dist/generated/sdkFactTables.js +24 -0
- package/dist/generated/settingsSchemaFns.d.ts +11 -0
- package/dist/generated/settingsSchemaFns.js +2 -1
- package/dist/generated/settingsSchemaSafetyMergeSpec.js +1 -1
- package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -1
- package/dist/generated/settingsSchemaSettingsSources.js +22 -2
- package/dist/headlessReconnectWire.js +31 -4
- package/dist/hitl/approvalLiveFace.d.ts +17 -0
- package/dist/hitl/approvalLiveFace.js +35 -0
- package/dist/hitl/approvalQueueRow.d.ts +21 -0
- package/dist/hitl/approvalQueueRow.js +69 -0
- package/dist/hitl/approvalsFeed.d.ts +5 -4
- package/dist/hitl/approvalsFeed.js +38 -6
- package/dist/hitl/askGateWire.js +26 -2
- package/dist/hitl/askParkRowRouting.d.ts +4 -3
- package/dist/hitl/askParkRowRouting.js +15 -3
- package/dist/hitl/automaticAnswerVerdict.js +13 -10
- package/dist/hitl/crashConverged.d.ts +5 -1
- package/dist/hitl/decisionConflict.js +2 -1
- package/dist/hitl/decisionRefusal.js +1 -1
- package/dist/hitl/decisionSend.d.ts +1 -0
- package/dist/hitl/decisionSend.js +14 -2
- package/dist/hitl/frameRouter.d.ts +4 -0
- package/dist/hitl/frameRouter.js +18 -5
- package/dist/hitl/gateIdentity.d.ts +1 -0
- package/dist/hitl/gateIdentity.js +3 -0
- package/dist/hitl/hitlBridge.d.ts +1 -1
- package/dist/hitl/hitlBridge.js +26 -5
- package/dist/hitl/livePendingAsk.d.ts +5 -0
- package/dist/hitl/livePendingAsk.js +6 -1
- package/dist/hitl/planReviewCard.d.ts +23 -0
- package/dist/hitl/planReviewCard.js +250 -0
- package/dist/hitl/planReviewWire.d.ts +39 -14
- package/dist/hitl/planReviewWire.js +450 -163
- package/dist/hitl/sessionAllowRoute.d.ts +2 -0
- package/dist/hitl/sessionAllowRoute.js +7 -0
- package/dist/hitl/sessionPolicyWire.d.ts +1 -7
- package/dist/hitl/sessionPolicyWire.js +3 -43
- package/dist/hitl/subagentSource.d.ts +1 -0
- package/dist/hitl/subagentSource.js +13 -0
- package/dist/hitl/toolApprovalWire.d.ts +3 -2
- package/dist/hitl/toolApprovalWire.js +79 -37
- package/dist/hostSettingsSource.d.ts +5 -2
- package/dist/hostSettingsSource.js +19 -10
- package/dist/hostTurnSettings.d.ts +5 -6
- package/dist/hostTurnSettings.js +106 -26
- package/dist/i18n/messages.en.d.ts +85 -12
- package/dist/i18n/messages.en.js +85 -12
- package/dist/i18n/messages.zh.js +88 -12
- package/dist/index.d.ts +35 -4
- package/dist/index.js +19 -2
- package/dist/liveInitToolFace.js +0 -1
- package/dist/liveModelCatalog.d.ts +15 -0
- package/dist/liveModelCatalog.js +40 -0
- package/dist/mcpTransportKindsCapability.d.ts +18 -0
- package/dist/mcpTransportKindsCapability.js +75 -0
- package/dist/mcpWireCaps.d.ts +4 -1
- package/dist/mcpWireCaps.js +25 -14
- package/dist/modelCapabilityProbe.js +66 -33
- package/dist/notifications.d.ts +9 -0
- package/dist/notifications.js +11 -2
- package/dist/ownKey.d.ts +4 -1
- package/dist/ownKey.js +8 -2
- package/dist/permissionModeWriteCapability.d.ts +13 -0
- package/dist/permissionModeWriteCapability.js +35 -0
- package/dist/permissionsAllowGrantCapability.d.ts +3 -0
- package/dist/permissionsAllowGrantCapability.js +26 -3
- package/dist/permissionsDeclaration.d.ts +25 -3
- package/dist/permissionsDeclaration.js +69 -41
- package/dist/planReviewCardFacts.d.ts +116 -0
- package/dist/planReviewCardFacts.js +469 -0
- package/dist/projectSeed.d.ts +39 -0
- package/dist/projectSeed.js +80 -0
- package/dist/promptDelivery.js +1 -1
- package/dist/reattachWindow.d.ts +8 -1
- package/dist/reattachWindow.js +44 -12
- package/dist/replayBody.d.ts +7 -6
- package/dist/replayBody.js +62 -7
- package/dist/request/taskRequest.js +3 -4
- package/dist/ruleCompileVerdict.d.ts +0 -2
- package/dist/ruleCompileVerdict.js +0 -31
- package/dist/ruleRefusalSentence.js +0 -3
- package/dist/runFollow.d.ts +30 -0
- package/dist/runFollow.js +117 -0
- package/dist/runLedgerSnapshot.d.ts +20 -0
- package/dist/runLedgerSnapshot.js +272 -0
- package/dist/runPermissionModeSwitch.d.ts +57 -0
- package/dist/runPermissionModeSwitch.js +135 -0
- package/dist/runReattachPolicy.d.ts +16 -5
- package/dist/runReattachPolicy.js +72 -24
- package/dist/runTerminal.js +30 -8
- package/dist/sandboxWire.d.ts +0 -3
- package/dist/sandboxWire.js +0 -9
- package/dist/seam.d.ts +17 -7
- package/dist/seam.js +13 -1
- package/dist/seatContract.d.ts +57 -7
- package/dist/seatContract.js +133 -3
- package/dist/serverSupportRange.d.ts +18 -0
- package/dist/serverSupportRange.js +25 -0
- package/dist/sessionEngine.d.ts +156 -0
- package/dist/sessionEngine.js +464 -0
- package/dist/sessionMap.d.ts +11 -1
- package/dist/sessionMap.js +35 -9
- package/dist/sessionMemoryErase.d.ts +1 -1
- package/dist/sessionMemoryErase.js +5 -0
- package/dist/sessionMemoryStatus.d.ts +27 -1
- package/dist/sessionMemoryStatus.js +117 -0
- package/dist/sessionMemorySync.d.ts +31 -0
- package/dist/sessionMemorySync.js +95 -0
- package/dist/sessionRowTag.d.ts +4 -0
- package/dist/sessionRowTag.js +18 -0
- package/dist/settingsLayerAdmission.d.ts +1 -0
- package/dist/settingsLayerAdmission.js +4 -1
- package/dist/sseIdleTriage.d.ts +3 -1
- package/dist/sseIdleTriage.js +19 -4
- package/dist/subagent/engineSubagentTail.js +2 -0
- package/dist/subagentContentStore.d.ts +3 -0
- package/dist/subagentContentStore.js +10 -1
- package/dist/toolResult.js +1 -1
- package/dist/turnFailurePresentation.d.ts +5 -2
- package/dist/turnFailurePresentation.js +12 -4
- package/dist/wireRefusalCopy.js +2 -6
- package/docs/INTEGRATION-CLIENTS.md +1507 -18
- package/package.json +5 -5
package/dist/sessionMap.js
CHANGED
|
@@ -1,22 +1,41 @@
|
|
|
1
|
+
import { tupleOriginUrlOf } from './engineAddress.js';
|
|
2
|
+
import { readOwnDataValue } from './ownKey.js';
|
|
1
3
|
export function engineNamespaceKeyFor(baseUrl) {
|
|
2
4
|
if (!baseUrl)
|
|
3
5
|
return 'local';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!/^(?:https?|wss?|ftp):$/.test(u.protocol))
|
|
7
|
-
return baseUrl.toLowerCase();
|
|
8
|
-
return u.origin.toLowerCase() + u.pathname.replace(/\/+$/, '');
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
6
|
+
const u = tupleOriginUrlOf(baseUrl);
|
|
7
|
+
if (u === undefined)
|
|
11
8
|
return baseUrl.toLowerCase();
|
|
12
|
-
|
|
9
|
+
return u.origin.toLowerCase() + u.pathname.replace(/\/+$/, '');
|
|
10
|
+
}
|
|
11
|
+
function boundEntryKept(prior, nextEngines) {
|
|
12
|
+
const key = prior?.boundEngine?.key;
|
|
13
|
+
if (typeof key !== 'string')
|
|
14
|
+
return true;
|
|
15
|
+
const before = prior?.engines !== undefined && Object.hasOwn(prior.engines, key) ? prior.engines[key] : undefined;
|
|
16
|
+
const has = nextEngines !== undefined && nextEngines !== null && Object.hasOwn(nextEngines, key);
|
|
17
|
+
const after = has ? readOwnDataValue(nextEngines, key) : undefined;
|
|
18
|
+
if (has && after === undefined)
|
|
19
|
+
return false;
|
|
20
|
+
if (before === undefined || after === undefined)
|
|
21
|
+
return before === after;
|
|
22
|
+
if (after === before)
|
|
23
|
+
return true;
|
|
24
|
+
return typeof after === 'object' && after !== null && readOwnDataValue(after, 'engineSessionId') === before.engineSessionId;
|
|
13
25
|
}
|
|
14
26
|
const isoNow = () => new Date().toISOString();
|
|
15
27
|
export function mergeSessionMapRecord(prior, partial, now = isoNow) {
|
|
16
28
|
const shellSessionId = partial.shellSessionId ?? prior?.shellSessionId;
|
|
17
29
|
if (!shellSessionId)
|
|
18
30
|
return { ok: false, reason: 'no-shell-session-id' };
|
|
19
|
-
|
|
31
|
+
const record = { ...prior, ...partial, shellSessionId, updatedAt: now() };
|
|
32
|
+
if (prior?.boundEngine !== undefined)
|
|
33
|
+
record.boundEngine = prior.boundEngine;
|
|
34
|
+
else
|
|
35
|
+
delete record.boundEngine;
|
|
36
|
+
if (!boundEntryKept(prior, record.engines))
|
|
37
|
+
return { ok: false, reason: 'bound-entry-conflict' };
|
|
38
|
+
return { ok: true, record };
|
|
20
39
|
}
|
|
21
40
|
export function mergeEngineEntry(prior, key, partial, shellSessionId, now = isoNow) {
|
|
22
41
|
const priorEntry = prior?.engines?.[key];
|
|
@@ -26,6 +45,13 @@ export function mergeEngineEntry(prior, key, partial, shellSessionId, now = isoN
|
|
|
26
45
|
const sid = shellSessionId ?? prior?.shellSessionId;
|
|
27
46
|
if (!sid)
|
|
28
47
|
return { ok: false, reason: 'no-shell-session-id' };
|
|
48
|
+
if (prior?.boundEngine !== undefined && key === prior.boundEngine.key) {
|
|
49
|
+
if (priorEntry === undefined ||
|
|
50
|
+
engineSessionId !== priorEntry.engineSessionId ||
|
|
51
|
+
(Object.hasOwn(partial, 'engineSessionId') && readOwnDataValue(partial, 'engineSessionId') !== priorEntry.engineSessionId)) {
|
|
52
|
+
return { ok: false, reason: 'bound-entry-conflict' };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
29
55
|
const entry = { ...priorEntry, ...partial, engineSessionId, updatedAt: now() };
|
|
30
56
|
return {
|
|
31
57
|
ok: true,
|
|
@@ -33,7 +33,7 @@ export type SessionMemoryEraseAnswer = {
|
|
|
33
33
|
detail: string;
|
|
34
34
|
};
|
|
35
35
|
export declare function eraseSessionMemory(call: SessionMemoryEraseCall, wire: SessionMemoryEraseWire, opts?: SessionMemoryEraseOptions): Promise<SessionMemoryEraseAnswer>;
|
|
36
|
-
export type SessionMemoryEraseRefusalReason = 'bad_input' | 'no_connection' | 'cancelled_before_send' | 'credentials_required' | 'not_permitted' | 'memory_engine_absent' | 'session_not_found' | 'route_absent' | 'request_rejected' | 'evidence_unavailable' | 'request_id_reused' | 'store_unreadable';
|
|
36
|
+
export type SessionMemoryEraseRefusalReason = 'bad_input' | 'no_connection' | 'cancelled_before_send' | 'credentials_required' | 'not_permitted' | 'memory_engine_absent' | 'session_not_found' | 'route_absent' | 'request_rejected' | 'evidence_unavailable' | 'request_id_reused' | 'store_unreadable' | 'personal_store_unjudged';
|
|
37
37
|
export type SessionMemoryEraseUnconfirmedWhy = 'no_answer' | 'receipt_unreadable' | 'receipt_mismatch' | 'store_link_outside' | 'store_home_not_directory' | 'control_plane_corrupt' | 'engine_fault' | 'unclassified' | 'no_code' | 'unreadable';
|
|
38
38
|
export type SessionMemoryEraseRetry = 'not_needed' | 'same_request_id' | 'new_request_id' | 'needs_operator' | 'needs_consent' | 'human_decision' | 'pointless';
|
|
39
39
|
type SessionMemoryEraseReceipt = Extract<MemoryEraseReceiptReading, {
|
|
@@ -3,6 +3,7 @@ import { INJECTED_WIRE_SETTLE_MS, connectionLostDetail, noAnswerDetailFrom, noAn
|
|
|
3
3
|
import { memoryEraseReplayPosture, readMemoryEraseReceipt } from './memoryEntriesWire.js';
|
|
4
4
|
import { normalizeWirePrincipal } from './principalWire.js';
|
|
5
5
|
import { isSessionIdPathSegment } from './sessionIdSegment.js';
|
|
6
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
6
7
|
const PRINCIPAL_HEADER = 'x-agent-principal';
|
|
7
8
|
const MAX_TIMER_MS = 2_147_483_647;
|
|
8
9
|
const NOT_SENT = ' — nothing was sent';
|
|
@@ -231,6 +232,7 @@ const REFUSAL_TEXT = {
|
|
|
231
232
|
evidence_unavailable: "Nothing was erased: this deployment's memory store cannot keep proof of an erase, so the erase was declined.",
|
|
232
233
|
request_id_reused: 'Nothing was erased: this request id was already used for a different erase.',
|
|
233
234
|
store_unreadable: 'Nothing was erased: part of the memory store could not be read, so the erase was declined before anything changed; the deployment operator needs to repair the store.',
|
|
235
|
+
personal_store_unjudged: renderMessage(msg('session.memoryErase.personalStoreUnjudged')),
|
|
234
236
|
};
|
|
235
237
|
const UNCONFIRMED_TEXT = {
|
|
236
238
|
no_answer: 'Not confirmed: no answer came back from the engine, so the erase may or may not have happened.',
|
|
@@ -290,6 +292,7 @@ const REFUSAL_RETRY = {
|
|
|
290
292
|
evidence_unavailable: 'needs_consent',
|
|
291
293
|
request_id_reused: 'new_request_id',
|
|
292
294
|
store_unreadable: 'needs_operator',
|
|
295
|
+
personal_store_unjudged: 'pointless',
|
|
293
296
|
};
|
|
294
297
|
export const SESSION_MEMORY_ERASE_REFUSAL_REASONS = Object.freeze(Object.keys(REFUSAL_TEXT));
|
|
295
298
|
export const SESSION_MEMORY_ERASE_UNCONFIRMED_WHYS = Object.freeze(Object.keys(UNCONFIRMED_TEXT));
|
|
@@ -350,6 +353,8 @@ function bandOfCode(code) {
|
|
|
350
353
|
return { refused: 'request_id_reused' };
|
|
351
354
|
case 'memory.erasure_census_incomplete':
|
|
352
355
|
return { refused: 'store_unreadable' };
|
|
356
|
+
case 'memory.erasure_store_unjudged':
|
|
357
|
+
return { refused: 'personal_store_unjudged' };
|
|
353
358
|
case 'memory.target_outside_store':
|
|
354
359
|
return { unconfirmed: 'store_link_outside' };
|
|
355
360
|
case 'memory.scope_home_not_directory':
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SessionMemoryStatus, SessionMemoryStatusResponse } from '@sema-agent/sdk';
|
|
2
|
+
import { type UiLanguage } from './env/uiLanguage.js';
|
|
2
3
|
export interface MemoryStatusClientLike {
|
|
3
4
|
sessions: {
|
|
4
5
|
memoryStatus(sessionId: string, opts?: {
|
|
@@ -8,7 +9,17 @@ export interface MemoryStatusClientLike {
|
|
|
8
9
|
} & SessionMemoryStatus>;
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
|
-
export type MemoryStatusFacts = Omit<SessionMemoryStatusResponse, 'sessionId'
|
|
12
|
+
export type MemoryStatusFacts = Omit<SessionMemoryStatusResponse, 'sessionId' | 'memorySync'> & {
|
|
13
|
+
readonly memorySync?: MemorySyncFacts;
|
|
14
|
+
};
|
|
15
|
+
export interface MemorySyncFacts {
|
|
16
|
+
readonly parked: readonly MemorySyncParkedFacts[];
|
|
17
|
+
}
|
|
18
|
+
export interface MemorySyncParkedFacts {
|
|
19
|
+
readonly scope: string;
|
|
20
|
+
readonly wayOut: string;
|
|
21
|
+
}
|
|
22
|
+
export declare const MEMORY_SYNC_WAY_OUT_DELETE_CURSOR: "delete_cursor";
|
|
12
23
|
export type MemoryStatusVerdict = {
|
|
13
24
|
readonly kind: 'ok';
|
|
14
25
|
readonly sessionId: string;
|
|
@@ -44,4 +55,19 @@ export declare function readLastCapture(s: SessionMemoryStatus): LastCaptureRead
|
|
|
44
55
|
export declare function readSessionMemoryStatus(client: MemoryStatusClientLike, sessionId: string, opts?: {
|
|
45
56
|
signal?: AbortSignal;
|
|
46
57
|
}): Promise<MemoryStatusVerdict>;
|
|
58
|
+
export type MemorySyncParkingReading = {
|
|
59
|
+
readonly state: 'syncing';
|
|
60
|
+
} | {
|
|
61
|
+
readonly state: 'parked';
|
|
62
|
+
readonly layers: readonly MemorySyncParkedLayerReading[];
|
|
63
|
+
} | {
|
|
64
|
+
readonly state: 'not_reported';
|
|
65
|
+
};
|
|
66
|
+
export interface MemorySyncParkedLayerReading {
|
|
67
|
+
readonly scope: string;
|
|
68
|
+
readonly wayOut: string;
|
|
69
|
+
readonly deleteCursor: boolean;
|
|
70
|
+
}
|
|
71
|
+
export declare function readMemorySyncParking(facts: MemoryStatusFacts | null | undefined): MemorySyncParkingReading;
|
|
72
|
+
export declare function memorySyncParkingNotice(reading: MemorySyncParkingReading, lang?: UiLanguage | (string & {})): string | undefined;
|
|
47
73
|
export declare function readAutoConsolidationArmed(facts: MemoryStatusFacts | null | undefined): 'armed' | 'unarmed' | 'indeterminate';
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { isSessionIdPathSegment } from './sessionIdSegment.js';
|
|
2
2
|
import { readThrownSlot, THROWN_SLOT_UNREADABLE } from './wireFailureShape.js';
|
|
3
|
+
import { isUiLanguage } from './env/uiLanguage.js';
|
|
4
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
5
|
+
export const MEMORY_SYNC_WAY_OUT_DELETE_CURSOR = 'delete_cursor';
|
|
6
|
+
const MEMORY_SYNC_PARKED_READ_MAX = 256;
|
|
3
7
|
export function classifyMemoryStatusFailure(e) {
|
|
4
8
|
const rawCode = readThrownSlot(e, 'errorCode', 'data');
|
|
5
9
|
const rawStatus = readThrownSlot(e, 'status', 'data');
|
|
@@ -64,6 +68,7 @@ export async function readSessionMemoryStatus(client, sessionId, opts) {
|
|
|
64
68
|
: {}),
|
|
65
69
|
...(typeof o.lastCaptureAt === 'number' ? { lastCaptureAt: o.lastCaptureAt } : {}),
|
|
66
70
|
...(typeof o.autoConsolidationArmed === 'boolean' ? { autoConsolidationArmed: o.autoConsolidationArmed } : {}),
|
|
71
|
+
...memorySyncSpread(o),
|
|
67
72
|
},
|
|
68
73
|
};
|
|
69
74
|
}
|
|
@@ -71,6 +76,118 @@ export async function readSessionMemoryStatus(client, sessionId, opts) {
|
|
|
71
76
|
return classifyMemoryStatusFailure(e);
|
|
72
77
|
}
|
|
73
78
|
}
|
|
79
|
+
function ownDataSlot(o, key) {
|
|
80
|
+
try {
|
|
81
|
+
const d = Object.getOwnPropertyDescriptor(o, key);
|
|
82
|
+
if (d === undefined)
|
|
83
|
+
return { ok: true, value: undefined };
|
|
84
|
+
return Object.hasOwn(d, 'value') ? { ok: true, value: d.value } : { ok: false };
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return { ok: false };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
91
|
+
function memorySyncFactsOf(raw) {
|
|
92
|
+
try {
|
|
93
|
+
if (!isPlainObject(raw))
|
|
94
|
+
return undefined;
|
|
95
|
+
const parkedSlot = ownDataSlot(raw, 'parked');
|
|
96
|
+
if (!parkedSlot.ok || !Array.isArray(parkedSlot.value))
|
|
97
|
+
return undefined;
|
|
98
|
+
const arr = parkedSlot.value;
|
|
99
|
+
const len = ownDataSlot(arr, 'length');
|
|
100
|
+
if (!len.ok || typeof len.value !== 'number' || !Number.isSafeInteger(len.value) || len.value < 0 || len.value > MEMORY_SYNC_PARKED_READ_MAX)
|
|
101
|
+
return undefined;
|
|
102
|
+
const parked = [];
|
|
103
|
+
for (let i = 0; i < len.value; i++) {
|
|
104
|
+
const el = ownDataSlot(arr, String(i));
|
|
105
|
+
if (!el.ok || !isPlainObject(el.value))
|
|
106
|
+
return undefined;
|
|
107
|
+
const scope = ownDataSlot(el.value, 'scope');
|
|
108
|
+
const wayOut = ownDataSlot(el.value, 'wayOut');
|
|
109
|
+
if (!scope.ok || !wayOut.ok || typeof scope.value !== 'string' || scope.value.length === 0 || typeof wayOut.value !== 'string' || wayOut.value.length === 0)
|
|
110
|
+
return undefined;
|
|
111
|
+
parked.push(Object.freeze({ scope: scope.value, wayOut: wayOut.value }));
|
|
112
|
+
}
|
|
113
|
+
return Object.freeze({ parked: Object.freeze(parked) });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function memorySyncSpread(o) {
|
|
120
|
+
const slot = ownDataSlot(o, 'memorySync');
|
|
121
|
+
if (!slot.ok || slot.value === undefined)
|
|
122
|
+
return {};
|
|
123
|
+
const facts = memorySyncFactsOf(slot.value);
|
|
124
|
+
return facts === undefined ? {} : { memorySync: facts };
|
|
125
|
+
}
|
|
126
|
+
export function readMemorySyncParking(facts) {
|
|
127
|
+
let sync;
|
|
128
|
+
try {
|
|
129
|
+
if (!isPlainObject(facts))
|
|
130
|
+
return Object.freeze({ state: 'not_reported' });
|
|
131
|
+
const slot = ownDataSlot(facts, 'memorySync');
|
|
132
|
+
sync = slot.ok ? memorySyncFactsOf(slot.value) : undefined;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
sync = undefined;
|
|
136
|
+
}
|
|
137
|
+
if (sync === undefined)
|
|
138
|
+
return Object.freeze({ state: 'not_reported' });
|
|
139
|
+
if (sync.parked.length === 0)
|
|
140
|
+
return Object.freeze({ state: 'syncing' });
|
|
141
|
+
return Object.freeze({
|
|
142
|
+
state: 'parked',
|
|
143
|
+
layers: Object.freeze(sync.parked.map((p) => Object.freeze({ scope: p.scope, wayOut: p.wayOut, deleteCursor: p.wayOut === MEMORY_SYNC_WAY_OUT_DELETE_CURSOR }))),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const MEMORY_SYNC_SCOPE_NAME_MAX = 120;
|
|
147
|
+
export function memorySyncParkingNotice(reading, lang) {
|
|
148
|
+
try {
|
|
149
|
+
if (typeof reading !== 'object' || reading === null)
|
|
150
|
+
return undefined;
|
|
151
|
+
const state = Object.getOwnPropertyDescriptor(reading, 'state');
|
|
152
|
+
if (state === undefined || !Object.hasOwn(state, 'value') || state.value !== 'parked')
|
|
153
|
+
return undefined;
|
|
154
|
+
const layersSlot = Object.getOwnPropertyDescriptor(reading, 'layers');
|
|
155
|
+
if (layersSlot === undefined || !Object.hasOwn(layersSlot, 'value') || !Array.isArray(layersSlot.value))
|
|
156
|
+
return undefined;
|
|
157
|
+
const raw = layersSlot.value;
|
|
158
|
+
const lenSlot = Object.getOwnPropertyDescriptor(raw, 'length');
|
|
159
|
+
const count = lenSlot?.value;
|
|
160
|
+
if (typeof count !== 'number' || !Number.isSafeInteger(count) || count < 1 || count > MEMORY_SYNC_PARKED_READ_MAX)
|
|
161
|
+
return undefined;
|
|
162
|
+
const scopes = [];
|
|
163
|
+
let named = true;
|
|
164
|
+
let allDeleteCursor = true;
|
|
165
|
+
for (let i = 0; i < count; i++) {
|
|
166
|
+
const el = Object.getOwnPropertyDescriptor(raw, String(i));
|
|
167
|
+
const layer = el !== undefined && Object.hasOwn(el, 'value') ? el.value : undefined;
|
|
168
|
+
if (typeof layer !== 'object' || layer === null)
|
|
169
|
+
return undefined;
|
|
170
|
+
const scope = Object.getOwnPropertyDescriptor(layer, 'scope');
|
|
171
|
+
const del = Object.getOwnPropertyDescriptor(layer, 'deleteCursor');
|
|
172
|
+
const s = scope !== undefined && Object.hasOwn(scope, 'value') ? scope.value : undefined;
|
|
173
|
+
if (typeof s !== 'string' || s.length === 0 || s.length > MEMORY_SYNC_SCOPE_NAME_MAX || /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u.test(s))
|
|
174
|
+
named = false;
|
|
175
|
+
else
|
|
176
|
+
scopes.push(s);
|
|
177
|
+
if (del === undefined || !Object.hasOwn(del, 'value') || del.value !== true)
|
|
178
|
+
allDeleteCursor = false;
|
|
179
|
+
}
|
|
180
|
+
const wayOut = msg(allDeleteCursor ? 'session.memorySync.wayOut.deleteCursor' : 'session.memorySync.wayOut.unrecognized');
|
|
181
|
+
if (!named)
|
|
182
|
+
return renderMessage(msg(count === 1 ? 'session.memorySync.parkedUnnamed.one' : 'session.memorySync.parkedUnnamed.other', { count, wayOut }), isUiLanguage(lang) ? lang : undefined);
|
|
183
|
+
if (count === 1)
|
|
184
|
+
return renderMessage(msg('session.memorySync.parked.one', { scope: scopes[0] ?? '', wayOut }), isUiLanguage(lang) ? lang : undefined);
|
|
185
|
+
return renderMessage(msg('session.memorySync.parked.other', { count, scopes: scopes.join(lang === 'zh' ? '、' : ', '), wayOut }), isUiLanguage(lang) ? lang : undefined);
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
return undefined;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
74
191
|
export function readAutoConsolidationArmed(facts) {
|
|
75
192
|
if (typeof facts !== 'object' || facts === null)
|
|
76
193
|
return 'indeterminate';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { SDK_SESSION_MEMORY_UNOBSERVED_REASONS } from './generated/sdkFactTables.js';
|
|
2
|
+
import { type UiLanguage } from './env/uiLanguage.js';
|
|
3
|
+
type UnobservedReason = (typeof SDK_SESSION_MEMORY_UNOBSERVED_REASONS)[number];
|
|
4
|
+
export type SessionMemorySyncReportReading = {
|
|
5
|
+
readonly scopes: readonly string[];
|
|
6
|
+
} & ({
|
|
7
|
+
readonly layers: readonly object[];
|
|
8
|
+
readonly refused?: undefined;
|
|
9
|
+
} | {
|
|
10
|
+
readonly refused: object;
|
|
11
|
+
readonly layers?: undefined;
|
|
12
|
+
});
|
|
13
|
+
export type SessionMemorySyncState = {
|
|
14
|
+
readonly kind: 'not_configured';
|
|
15
|
+
readonly report: SessionMemorySyncReportReading;
|
|
16
|
+
} | {
|
|
17
|
+
readonly kind: 'reported';
|
|
18
|
+
readonly report: SessionMemorySyncReportReading;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: 'unobtainable';
|
|
21
|
+
readonly reason?: UnobservedReason;
|
|
22
|
+
readonly activeTaskId?: string;
|
|
23
|
+
};
|
|
24
|
+
export type SessionMemorySyncSettled = {
|
|
25
|
+
readonly report: {} | null | undefined;
|
|
26
|
+
} | {
|
|
27
|
+
readonly error: {} | null | undefined;
|
|
28
|
+
};
|
|
29
|
+
export declare function sessionMemorySyncStateOf(settled: SessionMemorySyncSettled | null | undefined): SessionMemorySyncState | null;
|
|
30
|
+
export declare function sessionMemorySyncNotice(state: SessionMemorySyncState | null | undefined, lang?: UiLanguage | (string & {})): string | undefined;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { CONFLICT_SESSION_MEMORY_UNOBSERVED } from './engineErrorCodes.js';
|
|
2
|
+
import { SDK_SESSION_MEMORY_UNOBSERVED_REASONS } from './generated/sdkFactTables.js';
|
|
3
|
+
import { isUiLanguage } from './env/uiLanguage.js';
|
|
4
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
5
|
+
import { slotReadOf, isSlotCarrier, readErrorString } from './wireFailureShape.js';
|
|
6
|
+
import { effectiveWireErrorCode } from './wireErrorTriage.js';
|
|
7
|
+
const reasonOf = (v) => SDK_SESSION_MEMORY_UNOBSERVED_REASONS.find((w) => w === v);
|
|
8
|
+
function scopesOf(report) {
|
|
9
|
+
const r = slotReadOf(report, 'scopes');
|
|
10
|
+
if (r.presence !== 'present' || !Array.isArray(r.value))
|
|
11
|
+
return undefined;
|
|
12
|
+
const out = [];
|
|
13
|
+
const len = r.value.length;
|
|
14
|
+
if (typeof len !== 'number' || !Number.isSafeInteger(len) || len < 0)
|
|
15
|
+
return undefined;
|
|
16
|
+
for (let i = 0; i < len; i++) {
|
|
17
|
+
const item = r.value[i];
|
|
18
|
+
if (typeof item !== 'string')
|
|
19
|
+
return undefined;
|
|
20
|
+
out.push(item);
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
}
|
|
24
|
+
export function sessionMemorySyncStateOf(settled) {
|
|
25
|
+
try {
|
|
26
|
+
if (typeof settled !== 'object' || settled === null)
|
|
27
|
+
return null;
|
|
28
|
+
const reportSlot = slotReadOf(settled, 'report');
|
|
29
|
+
const errorSlot = slotReadOf(settled, 'error');
|
|
30
|
+
if (reportSlot.presence === 'present' && errorSlot.presence === 'absent') {
|
|
31
|
+
const report = reportSlot.value;
|
|
32
|
+
if (typeof report !== 'object' || report === null || Array.isArray(report))
|
|
33
|
+
return null;
|
|
34
|
+
const scopes = scopesOf(report);
|
|
35
|
+
if (scopes === undefined)
|
|
36
|
+
return null;
|
|
37
|
+
const refused = slotReadOf(report, 'refused');
|
|
38
|
+
const layers = slotReadOf(report, 'layers');
|
|
39
|
+
if (refused.presence === 'unreadable' || layers.presence === 'unreadable')
|
|
40
|
+
return null;
|
|
41
|
+
const refusedArm = refused.presence === 'present';
|
|
42
|
+
if (refusedArm === (layers.presence === 'present'))
|
|
43
|
+
return null;
|
|
44
|
+
if (refusedArm ? typeof refused.value !== 'object' || refused.value === null || Array.isArray(refused.value) : !Array.isArray(layers.value))
|
|
45
|
+
return null;
|
|
46
|
+
const kind = scopes.length === 0 && !refusedArm ? 'not_configured' : 'reported';
|
|
47
|
+
return Object.freeze({ kind, report: report });
|
|
48
|
+
}
|
|
49
|
+
if (errorSlot.presence === 'present' && reportSlot.presence === 'absent') {
|
|
50
|
+
const err = errorSlot.value;
|
|
51
|
+
if (!isSlotCarrier(err))
|
|
52
|
+
return null;
|
|
53
|
+
if (effectiveWireErrorCode(err) !== CONFLICT_SESSION_MEMORY_UNOBSERVED)
|
|
54
|
+
return null;
|
|
55
|
+
const o = err;
|
|
56
|
+
const reason = reasonOf(readErrorString(o, 'reason'));
|
|
57
|
+
const active = readErrorString(o, 'activeTaskId');
|
|
58
|
+
return Object.freeze({
|
|
59
|
+
kind: 'unobtainable',
|
|
60
|
+
...(reason !== undefined ? { reason } : {}),
|
|
61
|
+
...(typeof active === 'string' && active !== '' ? { activeTaskId: active } : {}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const UNOBTAINABLE_KEYS = Object.freeze({
|
|
71
|
+
no_settled_run: 'session.memorySyncTrigger.noSettledRun',
|
|
72
|
+
run_result_missing: 'session.memorySyncTrigger.runUnobserved',
|
|
73
|
+
run_result_unobserved: 'session.memorySyncTrigger.runUnobserved',
|
|
74
|
+
memory_not_mounted: 'session.memorySyncTrigger.memoryNotMounted',
|
|
75
|
+
no_leaf: 'session.memorySyncTrigger.noLeaf',
|
|
76
|
+
});
|
|
77
|
+
export function sessionMemorySyncNotice(state, lang) {
|
|
78
|
+
try {
|
|
79
|
+
if (typeof state !== 'object' || state === null)
|
|
80
|
+
return undefined;
|
|
81
|
+
const kind = slotReadOf(state, 'kind');
|
|
82
|
+
if (kind.presence !== 'present')
|
|
83
|
+
return undefined;
|
|
84
|
+
if (kind.value === 'not_configured')
|
|
85
|
+
return renderMessage(msg('session.memorySyncTrigger.notConfigured'), isUiLanguage(lang) ? lang : undefined);
|
|
86
|
+
if (kind.value !== 'unobtainable')
|
|
87
|
+
return undefined;
|
|
88
|
+
const reason = slotReadOf(state, 'reason');
|
|
89
|
+
const word = reason.presence === 'present' && typeof reason.value === 'string' ? reasonOf(reason.value) : undefined;
|
|
90
|
+
return renderMessage(msg(word !== undefined ? UNOBTAINABLE_KEYS[word] : 'session.memorySyncTrigger.unobtainable'), isUiLanguage(lang) ? lang : undefined);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
}
|
package/dist/sessionRowTag.d.ts
CHANGED
|
@@ -20,5 +20,9 @@ export type SessionRowPatchRefusal = {
|
|
|
20
20
|
} | {
|
|
21
21
|
readonly kind: 'tag-unsupported';
|
|
22
22
|
};
|
|
23
|
+
export interface SessionRowUnreadable {
|
|
24
|
+
readonly errorCode?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function sessionRowUnreadableOf(row: object | null | undefined): SessionRowUnreadable | undefined;
|
|
23
27
|
export declare function sessionRowTagOf(row: object | null | undefined): string | undefined;
|
|
24
28
|
export declare function sessionRowPatchRefusalOf(error: {} | null | undefined, sent: Readonly<SessionRowPatchFields> | null | undefined): SessionRowPatchRefusal | null;
|
package/dist/sessionRowTag.js
CHANGED
|
@@ -8,6 +8,24 @@ function ownData(v, key) {
|
|
|
8
8
|
return undefined;
|
|
9
9
|
return guardedRead(() => readOwnDataValue(v, key));
|
|
10
10
|
}
|
|
11
|
+
export function sessionRowUnreadableOf(row) {
|
|
12
|
+
try {
|
|
13
|
+
const marker = ownData(row, 'unreadable');
|
|
14
|
+
if (!isPlainMarker(marker))
|
|
15
|
+
return undefined;
|
|
16
|
+
const code = ownData(marker, 'errorCode');
|
|
17
|
+
return Object.freeze(typeof code === 'string' && code.length > 0 ? { errorCode: code } : {});
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function isPlainMarker(v) {
|
|
24
|
+
if (typeof v !== 'object' || v === null || Array.isArray(v))
|
|
25
|
+
return false;
|
|
26
|
+
const proto = Object.getPrototypeOf(v);
|
|
27
|
+
return proto === null || (typeof proto === 'object' && Object.getPrototypeOf(proto) === null);
|
|
28
|
+
}
|
|
11
29
|
export function sessionRowTagOf(row) {
|
|
12
30
|
const v = ownData(row, 'rowTag');
|
|
13
31
|
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { HostSettingsLayer, WorkspaceTrustState } from './hostSettingsSource.js';
|
|
2
|
+
export declare function layerAdmissionReading(trust: WorkspaceTrustState | 'unreadable'): WorkspaceTrustState;
|
|
2
3
|
export declare function layerAdmissionWord(layer: HostSettingsLayer, trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): string;
|
|
3
4
|
export declare function layerAdmitted(layer: HostSettingsLayer, trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): boolean;
|
|
4
5
|
export declare function admittedLayers<L extends HostSettingsLayer>(layers: readonly L[], trust: WorkspaceTrustState | 'unreadable', category: string, member?: string): readonly L[];
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { SETTINGS_LAYER_ADMISSION } from './generated/settingsSchemaFns.js';
|
|
2
2
|
const TRUST_UNREADABLE_READING = 'declined';
|
|
3
3
|
const ADMITTED = 'admitted';
|
|
4
|
+
export function layerAdmissionReading(trust) {
|
|
5
|
+
return trust === 'unreadable' ? TRUST_UNREADABLE_READING : trust;
|
|
6
|
+
}
|
|
4
7
|
function layerAdmissionOf(layer, trust, category, member) {
|
|
5
|
-
const reading = trust
|
|
8
|
+
const reading = layerAdmissionReading(trust);
|
|
6
9
|
return member === undefined ? SETTINGS_LAYER_ADMISSION(layer, reading, category) : SETTINGS_LAYER_ADMISSION(layer, reading, category, member);
|
|
7
10
|
}
|
|
8
11
|
export function layerAdmissionWord(layer, trust, category, member) {
|
package/dist/sseIdleTriage.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type EnvLike } from './hostEnv.js';
|
|
2
|
+
import { type RunNotFollowed } from './runFollow.js';
|
|
2
3
|
export declare const SSE_HEARTBEAT_GRACE_ENV = "SEMA_SSE_HEARTBEAT_GRACE_MS";
|
|
3
4
|
export declare const SSE_GRACE_MIN_MS = 5000;
|
|
4
5
|
export declare const SSE_GRACE_MAX_MS = 600000;
|
|
@@ -7,9 +8,10 @@ export declare function resolveSseHeartbeatGraceMs(env?: EnvLike): number | unde
|
|
|
7
8
|
export declare function markEngineAliveIdle<E extends Error>(err: E): E;
|
|
8
9
|
export declare function engineAliveIdleElapsedMs(err: unknown): number | undefined;
|
|
9
10
|
export declare function isSseIdleError(err: unknown): boolean;
|
|
11
|
+
export declare function isStreamEndedWithoutTerminalError(err: {} | null | undefined): boolean;
|
|
10
12
|
export declare function probeEngineAlive(baseUrl: string, timeoutMs?: number): Promise<boolean>;
|
|
11
13
|
export declare function diagnoseSseIdleTear<T>(inner: AsyncGenerator<T>, baseUrl: string, signal?: AbortSignal): AsyncGenerator<T>;
|
|
12
14
|
export declare function engineAliveIdleContent(elapsedMs: number, detach?: {
|
|
13
15
|
detached: true;
|
|
14
16
|
taskId?: string;
|
|
15
|
-
}): string;
|
|
17
|
+
}, notFollowed?: RunNotFollowed): string;
|
package/dist/sseIdleTriage.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { hostEnv } from './hostEnv.js';
|
|
2
|
-
import { SseIdleError, probeHealth as sdkProbeHealth } from '@sema-agent/sdk';
|
|
2
|
+
import { SseIdleError, StreamEndedWithoutTerminalError, probeHealth as sdkProbeHealth } from '@sema-agent/sdk';
|
|
3
3
|
import { readThrownSlot, thrownIsInstanceOf } from './wireFailureShape.js';
|
|
4
|
+
import { msg, renderMessage } from './i18n/translate.js';
|
|
5
|
+
import { runNotFollowedNoticeRef } from './runFollow.js';
|
|
4
6
|
export const SSE_HEARTBEAT_GRACE_ENV = 'SEMA_SSE_HEARTBEAT_GRACE_MS';
|
|
5
7
|
export const SSE_GRACE_MIN_MS = 5_000;
|
|
6
8
|
export const SSE_GRACE_MAX_MS = 600_000;
|
|
@@ -17,8 +19,12 @@ export function resolveSseHeartbeatGraceMs(env = hostEnv()) {
|
|
|
17
19
|
return n;
|
|
18
20
|
}
|
|
19
21
|
export function markEngineAliveIdle(err) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
try {
|
|
23
|
+
;
|
|
24
|
+
err.semaTearVerdict = 'engine-alive-idle';
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
}
|
|
22
28
|
return err;
|
|
23
29
|
}
|
|
24
30
|
export function engineAliveIdleElapsedMs(err) {
|
|
@@ -32,6 +38,11 @@ export function isSseIdleError(err) {
|
|
|
32
38
|
return true;
|
|
33
39
|
return readThrownSlot(err, 'name', 'data') === 'SseIdleError';
|
|
34
40
|
}
|
|
41
|
+
export function isStreamEndedWithoutTerminalError(err) {
|
|
42
|
+
if (thrownIsInstanceOf(err, StreamEndedWithoutTerminalError))
|
|
43
|
+
return true;
|
|
44
|
+
return readThrownSlot(err, 'name', 'data') === 'StreamEndedWithoutTerminalError';
|
|
45
|
+
}
|
|
35
46
|
export async function probeEngineAlive(baseUrl, timeoutMs = 2_000) {
|
|
36
47
|
return (await sdkProbeHealth(baseUrl, timeoutMs)).alive;
|
|
37
48
|
}
|
|
@@ -46,8 +57,12 @@ export async function* diagnoseSseIdleTear(inner, baseUrl, signal) {
|
|
|
46
57
|
throw err;
|
|
47
58
|
}
|
|
48
59
|
}
|
|
49
|
-
export function engineAliveIdleContent(elapsedMs, detach) {
|
|
60
|
+
export function engineAliveIdleContent(elapsedMs, detach, notFollowed) {
|
|
50
61
|
const secs = Math.max(1, Math.round((elapsedMs > 0 ? elapsedMs : SDK_DEFAULT_GRACE_MS) / 1000));
|
|
62
|
+
if (notFollowed !== undefined && notFollowed !== null) {
|
|
63
|
+
const grace = msg('follow.notFollowed.idleGrace', { env: SSE_HEARTBEAT_GRACE_ENV, min: SSE_GRACE_MIN_MS, max: SSE_GRACE_MAX_MS, default: SDK_DEFAULT_GRACE_MS });
|
|
64
|
+
return renderMessage(msg('follow.notFollowed.idleTear', { secs, notice: runNotFollowedNoticeRef(notFollowed), grace }));
|
|
65
|
+
}
|
|
51
66
|
const graceTail = `If your tasks legitimately go quiet this long (e.g. a long build), raise the idle grace: set ${SSE_HEARTBEAT_GRACE_ENV} ` +
|
|
52
67
|
`(settings env, integer ms, ${SSE_GRACE_MIN_MS}-${SSE_GRACE_MAX_MS}; default ${SDK_DEFAULT_GRACE_MS}).`;
|
|
53
68
|
if (detach?.detached) {
|
|
@@ -6,6 +6,7 @@ import { engineSessionParamFor } from '../engineSessionParam.js';
|
|
|
6
6
|
import { resolveOwnerContext } from './engineSubagentResume.js';
|
|
7
7
|
import { coerceOutput, parentToolCallIdOf, publishSubagentContentEvent, settleSubagentContent, } from '../subagentContentStore.js';
|
|
8
8
|
import { noteBgOwnerAbsence } from './subagentOwnerAbsence.js';
|
|
9
|
+
import { readFrameTrueMark } from '../ownKey.js';
|
|
9
10
|
function usableTailClient(client) {
|
|
10
11
|
return clientHasVerbs(client, [['capabilities'], ['runs', 'subagentStream']]);
|
|
11
12
|
}
|
|
@@ -140,6 +141,7 @@ export function tailEngineSubagent(taskId, opts) {
|
|
|
140
141
|
...(typeof d.toolName === 'string' ? { toolName: d.toolName } : {}),
|
|
141
142
|
...(out !== undefined ? { output: out } : {}),
|
|
142
143
|
...(d.isError === true ? { isError: true } : {}),
|
|
144
|
+
...(readFrameTrueMark(d, 'notExecuted') ? { notExecuted: true } : {}),
|
|
143
145
|
});
|
|
144
146
|
}
|
|
145
147
|
else if (t === 'task_settled') {
|
|
@@ -11,6 +11,7 @@ export type SubagentContentItem = {
|
|
|
11
11
|
input: unknown;
|
|
12
12
|
output?: string;
|
|
13
13
|
isError?: boolean;
|
|
14
|
+
notExecuted?: true;
|
|
14
15
|
} | {
|
|
15
16
|
kind: 'echo';
|
|
16
17
|
text: string;
|
|
@@ -31,6 +32,7 @@ export interface SubagentContentEvent {
|
|
|
31
32
|
args?: unknown;
|
|
32
33
|
output?: string | undefined;
|
|
33
34
|
isError?: boolean | undefined;
|
|
35
|
+
notExecuted?: true | undefined;
|
|
34
36
|
}
|
|
35
37
|
export declare function coerceOutput(v: unknown): string | undefined;
|
|
36
38
|
export declare function subagentContentEventOf(ev: {
|
|
@@ -82,6 +84,7 @@ export type SubagentViewSlot = {
|
|
|
82
84
|
input: unknown;
|
|
83
85
|
output?: string;
|
|
84
86
|
isError?: boolean;
|
|
87
|
+
notExecuted?: true;
|
|
85
88
|
};
|
|
86
89
|
export declare function planSubagentViewSlots(taskId: string): SubagentViewSlot[];
|
|
87
90
|
export declare function parentToolCallIdOf(taskId: string): string | undefined;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DEFAULT_SESSION_KEY } from './sessionSlot.js';
|
|
2
|
+
import { readFrameTrueMark } from './ownKey.js';
|
|
2
3
|
import { toolEndOutputText } from './toolResultContent.js';
|
|
3
4
|
export function coerceOutput(v) {
|
|
4
5
|
return toolEndOutputText(v);
|
|
@@ -23,6 +24,7 @@ export function subagentContentEventOf(ev) {
|
|
|
23
24
|
args: sub.args,
|
|
24
25
|
output: coerceOutput(sub.output),
|
|
25
26
|
isError: sub.isError,
|
|
27
|
+
notExecuted: readFrameTrueMark(sub, 'notExecuted') ? true : undefined,
|
|
26
28
|
};
|
|
27
29
|
}
|
|
28
30
|
const MAX_ITEMS_PER_TASK = 200;
|
|
@@ -567,12 +569,17 @@ export function publishSubagentContentEvent(ev) {
|
|
|
567
569
|
const before = itemBytesOf(it);
|
|
568
570
|
const outBefore = it.output;
|
|
569
571
|
const errBefore = it.isError;
|
|
572
|
+
const notExecBefore = it.notExecuted;
|
|
570
573
|
it.output = ev.output ?? '';
|
|
571
574
|
it.isError = ev.isError === true;
|
|
575
|
+
if (ev.notExecuted === true)
|
|
576
|
+
it.notExecuted = true;
|
|
577
|
+
else
|
|
578
|
+
delete it.notExecuted;
|
|
572
579
|
const delta = itemBytesOf(it) - before;
|
|
573
580
|
s.itemBytes[at] = (s.itemBytes[at] ?? 0) + delta;
|
|
574
581
|
addBytes(s, delta);
|
|
575
|
-
stampPhase(s, it.id, 'end', ev.eventId, it.output !== outBefore || it.isError !== errBefore);
|
|
582
|
+
stampPhase(s, it.id, 'end', ev.eventId, it.output !== outBefore || it.isError !== errBefore || it.notExecuted !== notExecBefore);
|
|
576
583
|
break;
|
|
577
584
|
}
|
|
578
585
|
const synthId = id ?? `${ev.taskId}-tool-${s.items.length}`;
|
|
@@ -583,6 +590,7 @@ export function publishSubagentContentEvent(ev) {
|
|
|
583
590
|
input: ev.args ?? {},
|
|
584
591
|
output: ev.output ?? '',
|
|
585
592
|
isError: ev.isError === true,
|
|
593
|
+
...(ev.notExecuted === true ? { notExecuted: true } : {}),
|
|
586
594
|
});
|
|
587
595
|
recordCut(s);
|
|
588
596
|
stampPhase(s, synthId, 'end', ev.eventId, true);
|
|
@@ -626,6 +634,7 @@ export function planSubagentViewSlots(taskId) {
|
|
|
626
634
|
input: it.input,
|
|
627
635
|
...(it.output !== undefined ? { output: it.output } : {}),
|
|
628
636
|
...(it.isError === true ? { isError: true } : {}),
|
|
637
|
+
...(it.notExecuted === true ? { notExecuted: true } : {}),
|
|
629
638
|
});
|
|
630
639
|
}
|
|
631
640
|
else if (it.kind === 'text') {
|
package/dist/toolResult.js
CHANGED
|
@@ -28,7 +28,7 @@ export const PROTOCOL_MARKERS = {
|
|
|
28
28
|
delegationTrailer: 'Verify this result before concluding. If it leaves more to do, continue or delegate again.',
|
|
29
29
|
delegationTrailerFork: 'Verify this result before concluding. If it leaves more to do, continue the work yourself or fork again.',
|
|
30
30
|
delegationFieldLine: /^(status|error|error_kind|observer|stats|worktree):(?: ([^\r\u2028\u2029\u0085]*))?/,
|
|
31
|
-
taskOutputLabel: /^TaskOutput\s+(\S+)$/,
|
|
31
|
+
taskOutputLabel: /^(?:TaskOutput|task)\s+(\S+)$/,
|
|
32
32
|
taskOutputStatus: /^status:\s*(.+)$/m,
|
|
33
33
|
taskOutputHeadSlots: /^(\r?\n)(?:(state: ([^\r\n\u2028\u2029\u0085]*)(?:\r?\n|$)))?(?:(error: ([^\r\n\u2028\u2029\u0085]*)(?:\r?\n|$)))?/,
|
|
34
34
|
taskOutputResultNote: /^--- result \(([^)\n]*)\) ---/,
|