@sema-agent/client-core 0.84.0 → 0.85.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 +247 -0
- package/README.md +27 -13
- package/dist/abortableSleep.d.ts +10 -0
- package/dist/abortableSleep.js +37 -0
- package/dist/adapt/arms.js +1 -1
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +1 -1
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +1 -0
- package/dist/adapter/downstream/terminalToSdkResult.js +19 -10
- package/dist/adapter/runStream.js +6 -2
- package/dist/agentSession/engineSessionBackgroundStop.d.ts +50 -0
- package/dist/agentSession/engineSessionBackgroundStop.js +291 -0
- package/dist/agentsWireCaps.d.ts +2 -1
- package/dist/agentsWireCaps.js +8 -0
- package/dist/cloudConfigWireCaps.js +2 -1
- package/dist/corruptSession.d.ts +3 -0
- package/dist/corruptSession.js +29 -0
- package/dist/corruptSessionCopy.d.ts +1 -0
- package/dist/corruptSessionCopy.js +4 -0
- package/dist/decideFailureNote.d.ts +2 -1
- package/dist/decideFailureNote.js +8 -3
- package/dist/decideReceipt.d.ts +6 -0
- package/dist/decideReceipt.js +30 -1
- package/dist/detachWire.d.ts +1 -0
- package/dist/detachWire.js +13 -5
- package/dist/displayUntrusted.js +114 -18
- package/dist/effortWire.d.ts +2 -1
- package/dist/effortWire.js +2 -4
- package/dist/engineErrorCodes.d.ts +11 -0
- package/dist/engineErrorCodes.js +32 -0
- package/dist/engineNoticeCodes.d.ts +39 -4
- package/dist/engineNoticeCodes.js +117 -161
- package/dist/engineWireFor.d.ts +43 -0
- package/dist/engineWireFor.js +399 -0
- package/dist/engineWireSdk.d.ts +6 -0
- package/dist/fileHistoryCaptureCapability.d.ts +4 -1
- package/dist/fileHistoryCaptureCapability.js +43 -9
- package/dist/gateVocabulary.d.ts +1 -2
- package/dist/gateVocabulary.js +1 -22
- package/dist/generated/engineNoticeTables.d.ts +3 -0
- package/dist/generated/engineNoticeTables.js +156 -0
- package/dist/generated/toolNameTables.d.ts +2 -0
- package/dist/generated/toolNameTables.js +43 -0
- package/dist/headlessPermissionModeWire.js +2 -4
- package/dist/hitl/askGateWire.d.ts +1 -1
- package/dist/hitl/askGateWire.js +1 -1
- package/dist/hitl/frameRouter.js +4 -2
- package/dist/hitl/hitlHostSurface.js +1 -1
- package/dist/hitl/parkResolver.d.ts +1 -0
- package/dist/hitl/parkResolver.js +11 -3
- package/dist/hitl/planReviewWire.d.ts +41 -3
- package/dist/hitl/planReviewWire.js +264 -49
- package/dist/hitl/rosterMountedNames.d.ts +2 -0
- package/dist/hitl/rosterMountedNames.js +38 -0
- package/dist/hitl/sessionPolicyDeliverable.d.ts +8 -2
- package/dist/hitl/sessionPolicyDeliverable.js +39 -48
- package/dist/hitl/sessionPolicyWire.d.ts +40 -0
- package/dist/hitl/sessionPolicyWire.js +173 -0
- package/dist/hitl/toolApprovalWire.d.ts +4 -2
- package/dist/hitl/toolApprovalWire.js +6 -4
- package/dist/index.d.ts +10 -3
- package/dist/index.js +7 -2
- package/dist/liveInitToolFace.js +28 -10
- package/dist/permissionWireCaps.d.ts +2 -1
- package/dist/permissionWireCaps.js +2 -7
- package/dist/request/taskRequest.d.ts +2 -0
- package/dist/request/taskRequest.js +18 -1
- package/dist/resumeRefusalCopy.d.ts +11 -0
- package/dist/resumeRefusalCopy.js +42 -2
- package/dist/runTerminal.js +4 -0
- package/dist/sandboxWire.js +1 -1
- package/dist/sealedKeyCapability.d.ts +17 -0
- package/dist/sealedKeyCapability.js +42 -0
- package/dist/seatContract.d.ts +2 -1
- package/dist/seatContract.js +5 -21
- package/dist/subagent/engineCompactWire.d.ts +13 -2
- package/dist/subagent/engineCompactWire.js +48 -37
- package/dist/subagent/engineDelegatedPrompt.d.ts +9 -1
- package/dist/subagent/engineDelegatedPrompt.js +16 -16
- package/dist/subagent/engineRowStopGate.d.ts +2 -2
- package/dist/subagent/engineRowStopGate.js +4 -4
- package/dist/subagent/engineSubagentOutput.d.ts +8 -0
- package/dist/subagent/engineSubagentOutput.js +37 -18
- package/dist/subagent/engineSubagentResume.d.ts +11 -2
- package/dist/subagent/engineSubagentResume.js +28 -14
- package/dist/subagent/engineSubagentSteer.d.ts +10 -1
- package/dist/subagent/engineSubagentSteer.js +16 -11
- package/dist/subagent/engineSubagentTail.d.ts +10 -1
- package/dist/subagent/engineSubagentTail.js +35 -17
- package/dist/subagent/engineTaskHandleWire.d.ts +13 -0
- package/dist/subagent/engineTaskHandleWire.js +41 -20
- package/dist/systemReminderTag.d.ts +5 -0
- package/dist/systemReminderTag.js +20 -9
- package/dist/taskRequestWords.d.ts +5 -0
- package/dist/taskRequestWords.js +4 -0
- package/dist/wireErrorTriage.d.ts +1 -0
- package/dist/wireErrorTriage.js +3 -1
- package/dist/wireRefusalCopy.d.ts +10 -0
- package/dist/wireRefusalCopy.js +62 -2
- package/docs/INTEGRATION-CLIENTS.md +1128 -22
- package/package.json +1 -1
|
@@ -23,6 +23,7 @@ export const REQUEST_FIELD_MATRIX = [
|
|
|
23
23
|
{ field: 'memoryCapture', lanes: ['interactive', 'print', 'utility'], live: true, why: '本会话永远不进长期记忆的**声明形**(server §12.4 body 键,单成员闭集 "off");每条车道都是提交面 ⇒ 都能声明。与 memoryWrite:false 不是一个轴(那是「本 run 只读平面」)。⚠️ parked 续跑腿结构性拿不到声明(决策/续跑端点从持久 body 重建 spec),那是引擎侧事实,不是本层的漏', whyUtilityLane: '有座:side-channel 提交是壳自己的一次性问答,**绝不该**进用户的长期记忆 —— 这一位正是那句声明,且它是收紧方向,带上去只会更严' },
|
|
24
24
|
{ field: 'memory', lanes: ['interactive', 'print', 'utility'], live: true, why: '这一次运行不挂记忆面的**请求级**开关(server §12.7 body 键,单成员闭集 "off");每条车道都是提交面 ⇒ 都能声明。与 memoryCapture(采集面)不是一个轴、可并存;与 memoryWrite:false(只读平面)也不是一个轴', whyUtilityLane: '有座:side-channel 提交不需要挂记忆面(不挂记忆段 / 索引 / 三只记忆工具),省 token 且零记忆写入;与 memoryCapture 不是一个轴,两条都带' },
|
|
25
25
|
{ field: 'approverPosture', lanes: ['interactive', 'print'], live: true, why: '宿主对这个 run 的**审批姿态声明**(「这个 run 的审批卡由我自己自动答」;单成员闭集 `"bypass"`)。🔴 它不授权任何东西、也不是一只门:引擎只把这句声明**渲**给模型(它自己的标记块,首个回合),没有任何裁决腿读它 —— 与 `permissionMode` 的 `bypassPermissions`(选门的形状)**不是一回事**,两键在请求体上各自原样过境、**互不派生**:宿主完全可以一边留着缺省权限模式、一边自己自动答这个 run 的审批卡。🔴 **声明它的唯一条件是「宿主确实自己自动答这个 run 的审批卡」,不许据此推导或改动 `permissionMode`** —— 拿这一位当理由去把门放宽,是把一句只渲给模型看的话读成了授权。宿主并不自动答卡却声明了它 ⇒ 那是对模型说了一句与实际不符的话,修法是**别声明**,不是去动门。加座的理由是**一个事实一处铸点**:同样一句话,要么由引擎在它自己的标记块里说,要么由壳把提醒形文本拼进本 turn 的输入 —— 后者在模型眼里是一段**没有引擎标记**的提醒形副本,按标记声明它该当**数据**处理并报出来。所以壳从此停拼,交这一位。两条用户车道都是提交面 ⇒ 都能声明。坏词由引擎响亮拒(单成员闭集,打错字不许被折成缺席),本层同律在构造期就拒(见 `refuseBadApproverPosture`)。⚠️ 上游的**提交体**与**引擎规格**两层都真读这一键,而装着的 sdk 型面尚未镜像它 ⇒ 本层的字面按提交体的形声明,不从 sdk 取型', whyUtilityLane: '无座:审批姿态是**用户**对他自己那条会话的声明,而 side-channel 是壳自己的提交 —— 把用户的 bypass 姿态带进一条他没参与的提交,等于替他重申一句他没说过的话;况且零工具面根本产不出审批卡' },
|
|
26
|
+
{ field: 'fileHistory', lanes: ['interactive', 'print'], live: true, why: '「这一次运行别捕获文件历史」的**请求级声明**(server 7.104.0 提交体键,单成员闭集 "disabled";`POST /v1/tasks` · `/v1/tasks/stream` · `/v1/runs` 同收,子代继承)。两条用户车道都是提交面、都跑在用户的文件上 ⇒ 都能声明;「本会话不捕获」= 每个提交都带(续跑腿重放同一个体)。🔴 只在能力读数 `on-optional` 时发(老 server 对表外键 400),值由片段口 `fileHistoryDeclarationField` 唯一铸出。与 rewind 还原键同交 ⇒ 上游 400 `request.field_conflict`', whyUtilityLane: '无座:side-channel 强制零工具面(`excludeAllTools`),不会改任何文件 ⇒ 没有可捕获的东西;带上它只会在不认识这一键的老 server 上给这条提交多一种 400' },
|
|
26
27
|
{ field: 'finalVerification', lanes: ['print'], live: true, why: 'P1-1 终验:无人值守车道才需要引擎自证;交互 REPL 由人当场看结果。#106 裁 B(让位+告知)后交互面默认关', whyUtilityLane: '无座:终验让引擎再跑一轮自证,而 side-channel 要的是一次小提交的即时答案;「无人值守才需要引擎自证」这条理由在本车道上让位给「小预算优先」' },
|
|
27
28
|
{ field: 'limits', lanes: ['print', 'utility'], live: true, why: 'P2-3-b:`-p` 的预算护栏(--max-* flag 族),交互 REPL 由人随时 Esc', whyUtilityLane: '有座:side-channel 必须带预算护栏(墙钟 / 输出 token / 轮数)—— 它同样没有人看着,而且没有后续回合可以中断' },
|
|
28
29
|
{ field: 'interactiveTools', lanes: ['print', 'utility'], live: true, why: '[909]B 件3:无人值守 stamp false,从 roster 源头灭掉 AskUserQuestion/plan 门。交互车道 stamp false 等于自废武功', whyUtilityLane: '有座:side-channel 绝不该弹交互问答 / plan 门(没有人在看这条提交)。它与 excludeAllTools 是**两条独立**的收紧声明、在这条车道上**并存**(本车道强制带卸载声明,见 `refuseUtilityWithoutToolUnload`;这一位是它旁边那条「连问都别问」的声明,不是它的降级替身)' },
|
|
@@ -125,6 +126,7 @@ const INPUT_KEY_ROUTES = {
|
|
|
125
126
|
memoryCapture: row('memoryCapture'),
|
|
126
127
|
memory: row('memory'),
|
|
127
128
|
approverPosture: row('approverPosture'),
|
|
129
|
+
fileHistory: row('fileHistory'),
|
|
128
130
|
rewind: row('resumeAt/resumeAtMode/restoreFiles/rewindFilesTo'),
|
|
129
131
|
repo: row('repo'),
|
|
130
132
|
council: row('council'),
|
|
@@ -197,6 +199,7 @@ const VALUE_LEVEL_IN_PLAY = Object.freeze({
|
|
|
197
199
|
memoryCapture: (v) => v === 'off',
|
|
198
200
|
memory: (v) => v === 'off',
|
|
199
201
|
approverPosture: (v) => v === APPROVER_POSTURE_BYPASS,
|
|
202
|
+
fileHistory: (v) => v === FILE_HISTORY_DISABLED,
|
|
200
203
|
rewind: (v) => typeof v === 'object' && v !== null && rewindSubKeys().some((k) => hasOwn(v, k) && present(v[k])),
|
|
201
204
|
});
|
|
202
205
|
const inPlay = (key, v) => present(v) && (VALUE_LEVEL_IN_PLAY[key]?.(v) ?? true);
|
|
@@ -377,6 +380,7 @@ void true;
|
|
|
377
380
|
export function approverPostureDeclarationField(declared) {
|
|
378
381
|
return declared ? { approverPosture: APPROVER_POSTURE_BYPASS } : {};
|
|
379
382
|
}
|
|
383
|
+
export const FILE_HISTORY_DISABLED = 'disabled';
|
|
380
384
|
export function memoryOffDeclared(input) {
|
|
381
385
|
if (typeof input !== 'object' || input === null)
|
|
382
386
|
return false;
|
|
@@ -426,6 +430,15 @@ const refuseBadApproverPosture = (v) => {
|
|
|
426
430
|
'**响亮拒**,刻意不把打错的词折回缺席。本层若静默删键,这一次提交的模型不会被告知姿态,而声明人不会知道。' +
|
|
427
431
|
'错误文本只报形状,不回显值。');
|
|
428
432
|
};
|
|
433
|
+
const refuseBadFileHistory = (v) => {
|
|
434
|
+
if (v === undefined || v === null)
|
|
435
|
+
return;
|
|
436
|
+
if (v === FILE_HISTORY_DISABLED)
|
|
437
|
+
return;
|
|
438
|
+
throw new TypeError('buildTaskRequest: fileHistory 只接受字面量 `\'disabled\'` 或缺席(undefined/null)—— ' +
|
|
439
|
+
`收到 ${coarseShape(v)}。这一位是「这一次运行别捕获文件历史」的收紧声明,上游是**单成员闭集**(没有第二个词)且对坏值` +
|
|
440
|
+
'**响亮拒**。本层若静默删键,这一次运行照常捕获而声明人不会知道。错误文本只报形状,不回显值。');
|
|
441
|
+
};
|
|
429
442
|
const refuseBadMaxTokens = (v) => {
|
|
430
443
|
if (v === undefined || v === null)
|
|
431
444
|
return;
|
|
@@ -495,7 +508,7 @@ export function parseMaxCostUsd(text) {
|
|
|
495
508
|
return { ok: false, why: 'not_positive' };
|
|
496
509
|
return { ok: true, value };
|
|
497
510
|
}
|
|
498
|
-
const ACCESSOR_READ_ORDER = ['live', 'memoryCapture', 'memory', 'settings', 'maxCostUsd', 'excludeAllTools', 'approverPosture', 'maxTokens', 'outputRetries'];
|
|
511
|
+
const ACCESSOR_READ_ORDER = ['live', 'memoryCapture', 'memory', 'settings', 'maxCostUsd', 'excludeAllTools', 'approverPosture', 'maxTokens', 'outputRetries', 'fileHistory'];
|
|
499
512
|
function dataFirstSnapshot(input, afterData) {
|
|
500
513
|
let descs;
|
|
501
514
|
try {
|
|
@@ -563,6 +576,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
563
576
|
const approverPostureIn = src.approverPosture;
|
|
564
577
|
const maxTokensIn = src.maxTokens;
|
|
565
578
|
const outputRetriesIn = src.outputRetries;
|
|
579
|
+
const fileHistoryIn = src.fileHistory;
|
|
566
580
|
const INPUT_KEYS = Object.keys(INPUT_KEY_ROUTES);
|
|
567
581
|
const i = snapshotByName(src, INPUT_KEYS, {
|
|
568
582
|
live,
|
|
@@ -573,6 +587,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
573
587
|
excludeAllTools: excludeAllToolsIn,
|
|
574
588
|
approverPosture: approverPostureIn,
|
|
575
589
|
outputRetries: outputRetriesIn,
|
|
590
|
+
fileHistory: fileHistoryIn,
|
|
576
591
|
settings: settingsIn,
|
|
577
592
|
});
|
|
578
593
|
const SETTINGS_KEYS = Object.keys(SETTINGS_KEY_ROUTES);
|
|
@@ -584,6 +599,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
584
599
|
refuseBadApproverPosture(approverPostureIn);
|
|
585
600
|
refuseBadMaxTokens(maxTokensIn);
|
|
586
601
|
refuseBadOutputRetries(outputRetriesIn);
|
|
602
|
+
refuseBadFileHistory(fileHistoryIn);
|
|
587
603
|
const rewindRoute = INPUT_KEY_ROUTES.rewind;
|
|
588
604
|
const RETIRED_REWIND_FILES_KEY = 'rewindFiles';
|
|
589
605
|
const REWIND_KEYS = rewindRoute.via === 'matrix' ? rewindRoute.field.split('/') : [];
|
|
@@ -733,6 +749,7 @@ export function assembleTaskRequest(input, lane) {
|
|
|
733
749
|
...(on('memoryCapture') ? { memoryCapture: 'off' } : {}),
|
|
734
750
|
...(on('memory') ? { memory: 'off' } : {}),
|
|
735
751
|
...(on('approverPosture') ? { approverPosture: APPROVER_POSTURE_BYPASS } : {}),
|
|
752
|
+
...(on('fileHistory') ? { fileHistory: FILE_HISTORY_DISABLED } : {}),
|
|
736
753
|
...(Object.keys(settingsOut).length > 0 ? { settings: settingsOut } : {}),
|
|
737
754
|
};
|
|
738
755
|
return Object.freeze({ request: out, omitted: Object.freeze([...omitted, ...lateOmitted]) });
|
|
@@ -33,3 +33,14 @@ export interface ResumeContextUnavailableDetail {
|
|
|
33
33
|
}
|
|
34
34
|
export declare function resumeContextUnavailableFromError(err: unknown): ResumeContextUnavailableDetail | null;
|
|
35
35
|
export declare function resumeContextUnavailableContent(d: ResumeContextUnavailableDetail): string;
|
|
36
|
+
export type ParkedResumeStartupDecision = 'approve' | 'deny';
|
|
37
|
+
export type ParkedResumeStartupCause = 'resume_rejected' | 'undetermined';
|
|
38
|
+
export interface ParkedResumeStartupDetail {
|
|
39
|
+
code: string;
|
|
40
|
+
cause: ParkedResumeStartupCause;
|
|
41
|
+
taskId?: string;
|
|
42
|
+
resendable: false;
|
|
43
|
+
denyStaysOpen: true;
|
|
44
|
+
}
|
|
45
|
+
export declare function parkedResumeStartupFromError(err: unknown, decision?: ParkedResumeStartupDecision): ParkedResumeStartupDetail | null;
|
|
46
|
+
export declare function parkedResumeStartupContent(detail: ParkedResumeStartupDetail): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readErrorNumber, readErrorString } from './wireFailureShape.js';
|
|
2
|
-
import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_ENV_FAILED, RESUME_TOOL_UNAVAILABLE, RESUME_POLICY_FOLD_CODE, } from './engineErrorCodes.js';
|
|
2
|
+
import { RESUME_CONTEXT_UNAVAILABLE, RESUME_PLACEMENT_MISMATCH, RESUME_PREFLIGHT_REJECTED, RESUME_REOPEN_CODES, RESUME_ENV_FAILED, RESUME_TOOL_UNAVAILABLE, RESUME_POLICY_FOLD_CODE, PARKED_RESUME_STARTUP_FAILED, isStatusDerivedCoarseCode, } from './engineErrorCodes.js';
|
|
3
3
|
import { capForDisplay } from './fleetTaskDesc.js';
|
|
4
4
|
import { resumeRetryLaterFromError } from './wireErrorTriage.js';
|
|
5
5
|
export const RESUME_REFUSAL_CODES = Object.freeze([
|
|
@@ -73,7 +73,9 @@ export function resumePolicyBlockFromError(err) {
|
|
|
73
73
|
export function resumePolicyBlockContent(detail) {
|
|
74
74
|
const b = detail.blockedBy;
|
|
75
75
|
const reason = b.kind === 'named'
|
|
76
|
-
?
|
|
76
|
+
? isStatusDerivedCoarseCode(b.code)
|
|
77
|
+
? `The refusal did not name a more specific check (it carried only the generic code for its HTTP status: ${b.code})`
|
|
78
|
+
: `The check that refused it: ${capForDisplay(b.code, 80)}`
|
|
77
79
|
: b.kind === 'absent'
|
|
78
80
|
? 'The refusal did not name a more specific check'
|
|
79
81
|
: 'The refusal carried a more specific reason that could not be read';
|
|
@@ -134,3 +136,41 @@ export function resumeContextUnavailableContent(d) {
|
|
|
134
136
|
third,
|
|
135
137
|
].join(' · ');
|
|
136
138
|
}
|
|
139
|
+
export function parkedResumeStartupFromError(err, decision) {
|
|
140
|
+
if (typeof err !== 'object' || err === null)
|
|
141
|
+
return null;
|
|
142
|
+
let code;
|
|
143
|
+
try {
|
|
144
|
+
code = err.errorCode;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
if (code !== PARKED_RESUME_STARTUP_FAILED)
|
|
150
|
+
return null;
|
|
151
|
+
const rawTaskId = readErrorString(err, 'taskId');
|
|
152
|
+
const taskId = rawTaskId !== undefined && rawTaskId.length > 0 ? rawTaskId : undefined;
|
|
153
|
+
return {
|
|
154
|
+
code: PARKED_RESUME_STARTUP_FAILED,
|
|
155
|
+
cause: decision === 'deny' ? 'resume_rejected' : 'undetermined',
|
|
156
|
+
...(taskId !== undefined ? { taskId } : {}),
|
|
157
|
+
resendable: false,
|
|
158
|
+
denyStaysOpen: true,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const PARKED_RESUME_STARTUP_STATE = 'This refusal does not say whether the card is still waiting — re-fetch the pending approvals';
|
|
162
|
+
const PARKED_RESUME_STARTUP_SENTENCES = Object.freeze({
|
|
163
|
+
resume_rejected: [
|
|
164
|
+
'The engine could not start the parked work to apply this decision (its session may be gone, or the engine rejected the decision itself)',
|
|
165
|
+
PARKED_RESUME_STARTUP_STATE,
|
|
166
|
+
'If the card is still there, decide it again from the fresh list',
|
|
167
|
+
].join(' · '),
|
|
168
|
+
undetermined: [
|
|
169
|
+
'The engine could not start the parked work to apply this decision',
|
|
170
|
+
PARKED_RESUME_STARTUP_STATE,
|
|
171
|
+
'If the card is still there: when the engine rejected the decision itself (for example an answer given to the wrong question), correct it and decide again; when the approved tool is one the agent inherits from the task that started it, approving it again will not work on this server — deny the card, or wait for a server upgrade',
|
|
172
|
+
].join(' · '),
|
|
173
|
+
});
|
|
174
|
+
export function parkedResumeStartupContent(detail) {
|
|
175
|
+
return detail.cause === 'resume_rejected' ? PARKED_RESUME_STARTUP_SENTENCES.resume_rejected : PARKED_RESUME_STARTUP_SENTENCES.undetermined;
|
|
176
|
+
}
|
package/dist/runTerminal.js
CHANGED
|
@@ -32,6 +32,10 @@ export function readRunTerminal(result) {
|
|
|
32
32
|
const kind = str(c.kind);
|
|
33
33
|
if (kind === undefined)
|
|
34
34
|
return { kind: 'unknown', plane: 'cause' };
|
|
35
|
+
const parkWord = str(r.status);
|
|
36
|
+
if (parkWord !== undefined && FLAT_PAUSED_STATUSES.includes(parkWord)) {
|
|
37
|
+
return { kind: 'paused', plane: 'cause', flatStatus: parkWord, ...(kind === 'paused' ? (pauseOf(c) ?? {}) : {}) };
|
|
38
|
+
}
|
|
35
39
|
switch (kind) {
|
|
36
40
|
case 'completed':
|
|
37
41
|
return { kind: 'completed', plane: 'cause' };
|
package/dist/sandboxWire.js
CHANGED
|
@@ -55,7 +55,7 @@ export function sandboxDegradeHint(err) {
|
|
|
55
55
|
'Re-run without --sandbox (worker default image), or point the shell at a k8s-lane worker (sema cloud engine connect <url>).');
|
|
56
56
|
}
|
|
57
57
|
if (e.status === 400 && msg.includes(SANDBOX_NO_IMAGE_INDEX_400_ANCHOR)) {
|
|
58
|
-
return ('This worker has no sandbox image index configured (sema-
|
|
58
|
+
return ('This worker has no sandbox image index configured (the sema-web-admin config center is not attached), so per-task profiles cannot resolve.\n' +
|
|
59
59
|
'Re-run without --sandbox, or use a worker with the image index enabled.');
|
|
60
60
|
}
|
|
61
61
|
if (e.status === 404 && msg.includes(SANDBOX_NO_PUBLISHED_IMAGE_404_ANCHOR)) {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SealedKeyReading = {
|
|
2
|
+
kind: 'unobserved';
|
|
3
|
+
} | {
|
|
4
|
+
kind: 'not_reported';
|
|
5
|
+
} | {
|
|
6
|
+
kind: 'present';
|
|
7
|
+
alg: string;
|
|
8
|
+
publicKeyId: string;
|
|
9
|
+
publicKey: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function projectSealedKeyCapability(caps: unknown): SealedKeyReading | undefined;
|
|
12
|
+
export declare function noteEngineCapsForSealedKey(baseUrl: string, caps: unknown, opts?: {
|
|
13
|
+
generation?: number;
|
|
14
|
+
}): void;
|
|
15
|
+
export declare function observedSealedKey(baseUrl?: string | undefined): SealedKeyReading;
|
|
16
|
+
export declare function forgetSealedKeyReading(baseUrl: string | undefined): void;
|
|
17
|
+
export declare function __resetSealedKeyReadingsForTests(): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
2
|
+
import { createEngineCapReader } from './engineCapReader.js';
|
|
3
|
+
function ownNonEmpty(seg, key) {
|
|
4
|
+
if (!Object.hasOwn(seg, key))
|
|
5
|
+
return undefined;
|
|
6
|
+
const v = seg[key];
|
|
7
|
+
return typeof v === 'string' && v.length > 0 ? v : undefined;
|
|
8
|
+
}
|
|
9
|
+
export function projectSealedKeyCapability(caps) {
|
|
10
|
+
if (caps === null || typeof caps !== 'object' || Array.isArray(caps))
|
|
11
|
+
return undefined;
|
|
12
|
+
if (!Object.hasOwn(caps, 'sealedKey'))
|
|
13
|
+
return { kind: 'not_reported' };
|
|
14
|
+
const seg = caps.sealedKey;
|
|
15
|
+
if (seg === undefined)
|
|
16
|
+
return { kind: 'not_reported' };
|
|
17
|
+
if (seg === null || typeof seg !== 'object' || Array.isArray(seg))
|
|
18
|
+
return undefined;
|
|
19
|
+
const alg = ownNonEmpty(seg, 'alg');
|
|
20
|
+
const publicKeyId = ownNonEmpty(seg, 'publicKeyId');
|
|
21
|
+
const publicKey = ownNonEmpty(seg, 'publicKey');
|
|
22
|
+
if (alg === undefined || publicKeyId === undefined || publicKey === undefined)
|
|
23
|
+
return undefined;
|
|
24
|
+
return { kind: 'present', alg, publicKeyId, publicKey };
|
|
25
|
+
}
|
|
26
|
+
const reader = createEngineCapReader({
|
|
27
|
+
name: 'sealedKey',
|
|
28
|
+
project: projectSealedKeyCapability,
|
|
29
|
+
makeUnobserved: () => ({ kind: 'unobserved' }),
|
|
30
|
+
});
|
|
31
|
+
export function noteEngineCapsForSealedKey(baseUrl, caps, opts) {
|
|
32
|
+
reader.note(baseUrl, caps, opts);
|
|
33
|
+
}
|
|
34
|
+
export function observedSealedKey(baseUrl = engineWireTarget()?.baseUrl) {
|
|
35
|
+
return reader.observed(baseUrl);
|
|
36
|
+
}
|
|
37
|
+
export function forgetSealedKeyReading(baseUrl) {
|
|
38
|
+
reader.forget(baseUrl);
|
|
39
|
+
}
|
|
40
|
+
export function __resetSealedKeyReadingsForTests() {
|
|
41
|
+
reader.__resetForTests();
|
|
42
|
+
}
|
package/dist/seatContract.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ReasoningEffort } from "./effortWire.js";
|
|
2
|
+
import type { PermissionMode } from "./permissionWireCaps.js";
|
|
2
3
|
import type { LaneProof } from "./seam.js";
|
|
3
4
|
import type { QuestionAnswer } from "./liveQuestionStore.js";
|
|
4
5
|
import type { ToolApprovalDelegation } from "./hitl/toolApprovalWire.js";
|
|
@@ -101,7 +102,7 @@ export interface StartSessionOptions {
|
|
|
101
102
|
cwd?: string;
|
|
102
103
|
excludeTools?: string[];
|
|
103
104
|
}
|
|
104
|
-
export type PermissionModeIntent =
|
|
105
|
+
export type PermissionModeIntent = PermissionMode;
|
|
105
106
|
export declare const PERMISSION_MODE_INTENTS: readonly PermissionModeIntent[];
|
|
106
107
|
export declare const ATTACHMENT_IDS_PER_TASK_CAP = 16;
|
|
107
108
|
export declare const SEAT_REASONING_EFFORTS: readonly ReasoningEffort[];
|
package/dist/seatContract.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PERMISSION_MODE_WORDS, REASONING_EFFORT_WORDS } from "./taskRequestWords.js";
|
|
1
2
|
const bad = (reason, field) => field === undefined ? { reason } : { reason, field };
|
|
2
3
|
const nested = (prefix, verdict) => {
|
|
3
4
|
const path = verdict.field === undefined
|
|
@@ -71,25 +72,9 @@ export const HITL_RESOLUTION_OUTCOMES = [
|
|
|
71
72
|
"decline",
|
|
72
73
|
"cancel",
|
|
73
74
|
];
|
|
74
|
-
const
|
|
75
|
-
"default",
|
|
76
|
-
"plan",
|
|
77
|
-
"acceptEdits",
|
|
78
|
-
"bypassPermissions",
|
|
79
|
-
"auto",
|
|
80
|
-
];
|
|
81
|
-
export const PERMISSION_MODE_INTENTS = PERMISSION_MODE_INTENT_TUPLE;
|
|
75
|
+
export const PERMISSION_MODE_INTENTS = [...PERMISSION_MODE_WORDS];
|
|
82
76
|
export const ATTACHMENT_IDS_PER_TASK_CAP = 16;
|
|
83
|
-
const
|
|
84
|
-
"off",
|
|
85
|
-
"minimal",
|
|
86
|
-
"low",
|
|
87
|
-
"medium",
|
|
88
|
-
"high",
|
|
89
|
-
"xhigh",
|
|
90
|
-
"max",
|
|
91
|
-
];
|
|
92
|
-
export const SEAT_REASONING_EFFORTS = SEAT_REASONING_EFFORT_TUPLE;
|
|
77
|
+
export const SEAT_REASONING_EFFORTS = [...REASONING_EFFORT_WORDS];
|
|
93
78
|
export const SEAT_TURN_SETTINGS_KEYS = ["ultracode"];
|
|
94
79
|
export const ATTACHMENT_UPLOAD_REQUEST_KEYS = ["name", "mimeType", "bytes"];
|
|
95
80
|
export const SESSION_SEARCH_RESULT_KEYS = ["sessionId", "title", "matches"];
|
|
@@ -224,8 +209,8 @@ const checkLocalSessionEvent = (v) => {
|
|
|
224
209
|
}
|
|
225
210
|
if (!isAbsent(v.permissionMode)) {
|
|
226
211
|
const mode = v.permissionMode;
|
|
227
|
-
if (typeof mode !== "string" || !inTuple(
|
|
228
|
-
return bad(`permissionMode must be one of ${
|
|
212
|
+
if (typeof mode !== "string" || !inTuple(PERMISSION_MODE_INTENTS, mode)) {
|
|
213
|
+
return bad(`permissionMode must be one of ${PERMISSION_MODE_INTENTS.join("|")}`, "permissionMode");
|
|
229
214
|
}
|
|
230
215
|
}
|
|
231
216
|
if (!isAbsent(v.session)) {
|
|
@@ -718,7 +703,6 @@ const _seatContractPins = [
|
|
|
718
703
|
true, true,
|
|
719
704
|
true, true,
|
|
720
705
|
true, true, true, true,
|
|
721
|
-
true, true, true, true,
|
|
722
706
|
true, true,
|
|
723
707
|
true, true,
|
|
724
708
|
true, true,
|
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
import type { AgentClient } from '@sema-agent/sdk';
|
|
2
|
+
import type { EngineWireInjection } from '../engineWireSdk.js';
|
|
3
|
+
export type EngineCompactWireClient = {
|
|
4
|
+
capabilities: AgentClient['capabilities'];
|
|
5
|
+
runs: Pick<AgentClient['runs'], 'compact'>;
|
|
6
|
+
};
|
|
7
|
+
export type EngineCompactWire = EngineWireInjection<EngineCompactWireClient>;
|
|
1
8
|
export declare function isEngineCompactPending(sessionKey?: string): boolean;
|
|
2
9
|
export declare function resetManualCompactCapability(): void;
|
|
3
10
|
export declare function __resetEngineCompactArmForTests(): void;
|
|
4
|
-
export declare function requestEngineCompact(sessionKey?: string
|
|
5
|
-
|
|
11
|
+
export declare function requestEngineCompact(sessionKey?: string, opts?: {
|
|
12
|
+
wire?: EngineCompactWire;
|
|
13
|
+
}): 'fired' | 'armed' | 'offline' | 'unsupported';
|
|
14
|
+
export declare function onEngineTaskBound(taskId: string, sessionKey?: string, opts?: {
|
|
15
|
+
wire?: EngineCompactWire;
|
|
16
|
+
}): void;
|
|
@@ -1,34 +1,38 @@
|
|
|
1
1
|
import { hostLog, hostTimersFor } from '../host.js';
|
|
2
|
-
import {
|
|
3
|
-
import { engineWireTargetFor } from '../engineWireTarget.js';
|
|
2
|
+
import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, settleInjected, } from '../engineWireFor.js';
|
|
4
3
|
import { activeEngineRunIdFor, engineSessionParamFor } from '../engineSessionParam.js';
|
|
5
4
|
import { DEFAULT_SESSION_KEY } from '../sessionSlot.js';
|
|
5
|
+
function usableCompactClient(client) {
|
|
6
|
+
return clientHasVerbs(client, [['capabilities'], ['runs', 'compact']]);
|
|
7
|
+
}
|
|
8
|
+
const COMPACT_PROBE_SETTLE_MS = 5000;
|
|
6
9
|
const pendingCompactKeys = new Set();
|
|
7
10
|
export function isEngineCompactPending(sessionKey = DEFAULT_SESSION_KEY) {
|
|
8
11
|
return pendingCompactKeys.has(sessionKey);
|
|
9
12
|
}
|
|
10
13
|
const manualCompactCapableByBase = new Map();
|
|
11
14
|
const capabilitiesProbeByBase = new Map();
|
|
12
|
-
function probeManualCompactCapability(
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
15
|
+
function probeManualCompactCapability(wire) {
|
|
16
|
+
const base = wire.kind === 'injected' ? wire.capsBaseUrl : wire.target.baseUrl;
|
|
17
|
+
if (base === undefined)
|
|
15
18
|
return;
|
|
16
|
-
const base = cfg.baseUrl;
|
|
17
19
|
if (capabilitiesProbeByBase.has(base))
|
|
18
20
|
return;
|
|
19
21
|
capabilitiesProbeByBase.set(base, (async () => {
|
|
20
22
|
try {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
let caps;
|
|
24
|
+
if (wire.kind === 'injected') {
|
|
25
|
+
const injected = wire.client;
|
|
26
|
+
caps = await settleInjected(COMPACT_PROBE_SETTLE_MS, undefined, (signal) => injected.capabilities({ signal }));
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const client = wire.make({ timeoutMs: 5000 });
|
|
30
|
+
if (!client) {
|
|
31
|
+
capabilitiesProbeByBase.delete(base);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
caps = await client.capabilities();
|
|
30
35
|
}
|
|
31
|
-
const caps = await client.capabilities();
|
|
32
36
|
if (typeof caps.manualCompact === 'boolean')
|
|
33
37
|
manualCompactCapableByBase.set(base, caps.manualCompact);
|
|
34
38
|
else
|
|
@@ -55,31 +59,35 @@ function deferFire(ms, fn, why, sessionKey) {
|
|
|
55
59
|
timers.setTimer(ms, fn);
|
|
56
60
|
return true;
|
|
57
61
|
}
|
|
58
|
-
function freezeCompactShot(taskId, sessionKey) {
|
|
59
|
-
|
|
60
|
-
if (!cfg)
|
|
62
|
+
function freezeCompactShot(taskId, sessionKey, wire) {
|
|
63
|
+
if (wire.kind === 'no-target' || wire.kind === 'injected-unusable')
|
|
61
64
|
return null;
|
|
62
65
|
const sid = engineSessionParamFor(sessionKey);
|
|
66
|
+
let client;
|
|
67
|
+
if (wire.kind === 'injected') {
|
|
68
|
+
const injected = wire.client;
|
|
69
|
+
client = () => injected;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const make = wire.make;
|
|
73
|
+
client = () => make();
|
|
74
|
+
}
|
|
63
75
|
return {
|
|
64
76
|
taskId,
|
|
65
77
|
sessionKey,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
...(cfg.principal !== undefined ? { principal: cfg.principal } : {}),
|
|
78
|
+
client,
|
|
79
|
+
injected: wire.kind === 'injected',
|
|
69
80
|
...(sid !== undefined ? { session: sid } : {}),
|
|
70
81
|
};
|
|
71
82
|
}
|
|
72
83
|
async function postCompact(shot, retriesLeft = 1) {
|
|
73
|
-
const client =
|
|
74
|
-
baseUrl: shot.baseUrl,
|
|
75
|
-
...(shot.token ? { token: shot.token } : {}),
|
|
76
|
-
principal: shot.principal,
|
|
77
|
-
});
|
|
84
|
+
const client = shot.client();
|
|
78
85
|
if (!client)
|
|
79
86
|
return;
|
|
80
87
|
const taskId = shot.taskId;
|
|
81
88
|
try {
|
|
82
|
-
const
|
|
89
|
+
const fire = (signal) => client.runs.compact(taskId, { ...(shot.session !== undefined ? { session: shot.session } : {}), ...(signal ? { signal } : {}) });
|
|
90
|
+
const ack = shot.injected ? await settleInjected(INJECTED_WIRE_SETTLE_MS, undefined, fire) : await fire(undefined);
|
|
83
91
|
hostLog('debug', `engineCompactWire: POST compact ${taskId} → ok${ack?.status ? ` (${ack.status})` : ''}`);
|
|
84
92
|
}
|
|
85
93
|
catch (e) {
|
|
@@ -94,18 +102,19 @@ async function postCompact(shot, retriesLeft = 1) {
|
|
|
94
102
|
hostLog('debug', `engineCompactWire: compact fire failed (best-effort): ${String(e)}`);
|
|
95
103
|
}
|
|
96
104
|
}
|
|
97
|
-
export function requestEngineCompact(sessionKey = DEFAULT_SESSION_KEY) {
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
105
|
+
export function requestEngineCompact(sessionKey = DEFAULT_SESSION_KEY, opts) {
|
|
106
|
+
const wire = engineWireFor(opts?.wire, sessionKey, usableCompactClient);
|
|
107
|
+
if (wire.kind === 'no-target' || wire.kind === 'injected-unusable')
|
|
100
108
|
return 'offline';
|
|
101
|
-
probeManualCompactCapability(
|
|
102
|
-
|
|
109
|
+
probeManualCompactCapability(wire);
|
|
110
|
+
const capsKey = wire.kind === 'injected' ? wire.capsBaseUrl : wire.target.baseUrl;
|
|
111
|
+
if (capsKey !== undefined && manualCompactCapableByBase.get(capsKey) === false) {
|
|
103
112
|
hostLog('debug', 'engineCompactWire: engine capabilities report manualCompact:false — verb suppressed (TOC-local runStore-less engine, [488])');
|
|
104
113
|
return 'unsupported';
|
|
105
114
|
}
|
|
106
115
|
const taskId = activeEngineRunIdFor(sessionKey);
|
|
107
116
|
if (taskId) {
|
|
108
|
-
const shot = freezeCompactShot(taskId, sessionKey);
|
|
117
|
+
const shot = freezeCompactShot(taskId, sessionKey, wire);
|
|
109
118
|
if (shot !== null)
|
|
110
119
|
void postCompact(shot);
|
|
111
120
|
return 'fired';
|
|
@@ -114,11 +123,13 @@ export function requestEngineCompact(sessionKey = DEFAULT_SESSION_KEY) {
|
|
|
114
123
|
return 'armed';
|
|
115
124
|
}
|
|
116
125
|
const BOUND_FIRE_DELAY_MS = 1500;
|
|
117
|
-
export function onEngineTaskBound(taskId, sessionKey = DEFAULT_SESSION_KEY) {
|
|
118
|
-
|
|
126
|
+
export function onEngineTaskBound(taskId, sessionKey = DEFAULT_SESSION_KEY, opts) {
|
|
127
|
+
const wire = engineWireFor(opts?.wire, sessionKey, usableCompactClient);
|
|
128
|
+
if (wire.kind !== 'no-target' && wire.kind !== 'injected-unusable')
|
|
129
|
+
probeManualCompactCapability(wire);
|
|
119
130
|
if (!pendingCompactKeys.has(sessionKey))
|
|
120
131
|
return;
|
|
121
|
-
const shot = freezeCompactShot(taskId, sessionKey);
|
|
132
|
+
const shot = freezeCompactShot(taskId, sessionKey, wire);
|
|
122
133
|
if (shot === null)
|
|
123
134
|
return;
|
|
124
135
|
if (deferFire(BOUND_FIRE_DELAY_MS, () => void postCompact(shot), 'bind 后发射', sessionKey)) {
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import type { AgentClient } from '@sema-agent/sdk';
|
|
2
|
+
import type { EngineWireInjection } from '../engineWireSdk.js';
|
|
3
|
+
export type DelegatedPromptWireClient = {
|
|
4
|
+
sessions: Pick<AgentClient['sessions'], 'get'>;
|
|
5
|
+
};
|
|
6
|
+
export type DelegatedPromptWire = EngineWireInjection<DelegatedPromptWireClient>;
|
|
1
7
|
export declare function recordEngineTranscriptId(taskId: string, transcriptId: string): void;
|
|
2
8
|
export declare function getEngineTranscriptId(taskId: string): string | undefined;
|
|
3
9
|
export declare function __resetEngineDelegatedPromptForTests(): void;
|
|
@@ -9,5 +15,7 @@ export interface DelegatedPromptFetch {
|
|
|
9
15
|
prompt?: string;
|
|
10
16
|
outcome: 'hit' | 'skipped' | 'unreadable' | 'absent';
|
|
11
17
|
}
|
|
12
|
-
export declare function fetchDelegatedPrompt(taskId: string
|
|
18
|
+
export declare function fetchDelegatedPrompt(taskId: string, opts?: {
|
|
19
|
+
wire?: DelegatedPromptWire;
|
|
20
|
+
}): Promise<DelegatedPromptFetch>;
|
|
13
21
|
export {};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { stripSystemReminderBlocks } from '../systemReminderTag.js';
|
|
2
2
|
import { hostLog } from '../host.js';
|
|
3
|
-
import {
|
|
4
|
-
import { engineWireTargetFor } from '../engineWireTarget.js';
|
|
3
|
+
import { clientHasVerbs, engineWireFor, INJECTED_WIRE_SETTLE_MS, settleInjected } from '../engineWireFor.js';
|
|
5
4
|
import { resolveOwnerContext } from './engineSubagentResume.js';
|
|
5
|
+
function usableDelegatedPromptClient(client) {
|
|
6
|
+
return clientHasVerbs(client, [['sessions', 'get']]);
|
|
7
|
+
}
|
|
6
8
|
const TAIL_WINDOW = 200;
|
|
7
9
|
const BLOB_CAP = 8 * 1024;
|
|
8
10
|
const transcriptIdByTask = new Map();
|
|
@@ -89,27 +91,25 @@ let transcriptWindowReader = null;
|
|
|
89
91
|
export function __setTranscriptWindowReaderForTests(r) {
|
|
90
92
|
transcriptWindowReader = r;
|
|
91
93
|
}
|
|
92
|
-
async function readTranscriptWindow(transcriptId, sessionKey) {
|
|
94
|
+
async function readTranscriptWindow(transcriptId, sessionKey, injectedWire) {
|
|
93
95
|
if (transcriptWindowReader)
|
|
94
96
|
return transcriptWindowReader(transcriptId);
|
|
95
|
-
const
|
|
96
|
-
if (
|
|
97
|
+
const wire = engineWireFor(injectedWire, sessionKey, usableDelegatedPromptClient);
|
|
98
|
+
if (wire.kind === 'no-target' || wire.kind === 'injected-unusable')
|
|
97
99
|
return null;
|
|
98
|
-
const client =
|
|
99
|
-
baseUrl: cfg.baseUrl,
|
|
100
|
-
...(cfg.token ? { token: cfg.token } : {}),
|
|
101
|
-
principal: cfg.principal,
|
|
102
|
-
});
|
|
100
|
+
const client = wire.kind === 'injected' ? wire.client : wire.make();
|
|
103
101
|
if (!client)
|
|
104
102
|
return null;
|
|
105
|
-
const rec =
|
|
106
|
-
tail: TAIL_WINDOW,
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
const rec = wire.kind === 'injected'
|
|
104
|
+
? await settleInjected(INJECTED_WIRE_SETTLE_MS, undefined, (signal) => client.sessions.get(transcriptId, { tail: TAIL_WINDOW, blobCap: BLOB_CAP, signal }))
|
|
105
|
+
: await client.sessions.get(transcriptId, {
|
|
106
|
+
tail: TAIL_WINDOW,
|
|
107
|
+
blobCap: BLOB_CAP,
|
|
108
|
+
});
|
|
109
109
|
const msgs = rec.messages;
|
|
110
110
|
return Array.isArray(msgs) ? msgs : null;
|
|
111
111
|
}
|
|
112
|
-
export async function fetchDelegatedPrompt(taskId) {
|
|
112
|
+
export async function fetchDelegatedPrompt(taskId, opts) {
|
|
113
113
|
if (promptHydrateInFlight.has(taskId))
|
|
114
114
|
return { outcome: 'skipped' };
|
|
115
115
|
const transcriptId = transcriptIdByTask.get(taskId);
|
|
@@ -118,7 +118,7 @@ export async function fetchDelegatedPrompt(taskId) {
|
|
|
118
118
|
promptHydrateInFlight.add(taskId);
|
|
119
119
|
let msgs = null;
|
|
120
120
|
try {
|
|
121
|
-
msgs = await readTranscriptWindow(transcriptId, resolveOwnerContext(taskId).key);
|
|
121
|
+
msgs = await readTranscriptWindow(transcriptId, resolveOwnerContext(taskId).key, opts?.wire);
|
|
122
122
|
}
|
|
123
123
|
catch (e) {
|
|
124
124
|
promptHydrateInFlight.delete(taskId);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const engineOwnedRowIds: Set<string>;
|
|
2
2
|
export declare const fleetViewStubRowIds: Set<string>;
|
|
3
3
|
export declare function isEngineViewRow(taskId: string): boolean;
|
|
4
|
-
export declare function engineTaskHandlesCapable(sessionKey?: string): boolean;
|
|
5
|
-
export declare function engineRowNeedsStopConfirm(taskId: string, sessionKey?: string): boolean;
|
|
4
|
+
export declare function engineTaskHandlesCapable(sessionKey?: string, capsBaseUrl?: string): boolean;
|
|
5
|
+
export declare function engineRowNeedsStopConfirm(taskId: string, sessionKey?: string, capsBaseUrl?: string): boolean;
|
|
@@ -6,9 +6,9 @@ export const fleetViewStubRowIds = new Set();
|
|
|
6
6
|
export function isEngineViewRow(taskId) {
|
|
7
7
|
return engineOwnedRowIds.has(taskId) || fleetViewStubRowIds.has(taskId);
|
|
8
8
|
}
|
|
9
|
-
export function engineTaskHandlesCapable(sessionKey = DEFAULT_SESSION_KEY) {
|
|
10
|
-
return engineCapTrue(engineWireTargetFor(sessionKey)?.baseUrl, 'taskHandles');
|
|
9
|
+
export function engineTaskHandlesCapable(sessionKey = DEFAULT_SESSION_KEY, capsBaseUrl) {
|
|
10
|
+
return engineCapTrue(capsBaseUrl ?? engineWireTargetFor(sessionKey)?.baseUrl, 'taskHandles');
|
|
11
11
|
}
|
|
12
|
-
export function engineRowNeedsStopConfirm(taskId, sessionKey) {
|
|
13
|
-
return isEngineViewRow(taskId) && engineTaskHandlesCapable(sessionKey ?? DEFAULT_SESSION_KEY);
|
|
12
|
+
export function engineRowNeedsStopConfirm(taskId, sessionKey, capsBaseUrl) {
|
|
13
|
+
return isEngineViewRow(taskId) && engineTaskHandlesCapable(sessionKey ?? DEFAULT_SESSION_KEY, capsBaseUrl);
|
|
14
14
|
}
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import type { AgentClient } from '@sema-agent/sdk';
|
|
2
|
+
import type { EngineWireInjection } from '../engineWireSdk.js';
|
|
3
|
+
export type SubagentReportWireClient = {
|
|
4
|
+
capabilities: AgentClient['capabilities'];
|
|
5
|
+
runs: Pick<AgentClient['runs'], 'subagentOutput'>;
|
|
6
|
+
};
|
|
7
|
+
export type SubagentReportWire = EngineWireInjection<SubagentReportWireClient>;
|
|
1
8
|
export declare function __resetSubagentOutputCapCacheForTests(): void;
|
|
2
9
|
export interface EngineSubagentReport {
|
|
3
10
|
content: string;
|
|
@@ -5,4 +12,5 @@ export interface EngineSubagentReport {
|
|
|
5
12
|
}
|
|
6
13
|
export declare function fetchEngineSubagentReport(taskId: string, opts?: {
|
|
7
14
|
signal?: AbortSignal;
|
|
15
|
+
wire?: SubagentReportWire;
|
|
8
16
|
}): Promise<EngineSubagentReport | null>;
|