@sema-agent/client-core 0.82.0 → 0.82.2
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 +33 -0
- package/README.md +10 -7
- package/dist/adapt/toolCards.d.ts +15 -0
- package/dist/adapt/toolCards.js +34 -19
- package/dist/adapter/activeRunSelfHeal.d.ts +3 -0
- package/dist/adapter/activeRunSelfHeal.js +37 -7
- package/dist/adapter/downstream/eventToSdkMessage.js +7 -4
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +2 -0
- package/dist/adapter/downstream/terminalToSdkResult.js +44 -5
- package/dist/adapter/runStream.js +33 -4
- package/dist/adapter/types.d.ts +2 -0
- package/dist/agentsWireCaps.d.ts +1 -0
- package/dist/agentsWireCaps.js +110 -29
- package/dist/cloudConfigWireCaps.d.ts +77 -2
- package/dist/cloudConfigWireCaps.js +405 -8
- package/dist/decideFailureNote.d.ts +1 -0
- package/dist/decideFailureNote.js +8 -0
- package/dist/engineNoticeCodes.js +2 -0
- package/dist/executionLaneCapability.js +3 -0
- package/dist/fileHistoryCaptureCapability.d.ts +18 -0
- package/dist/fileHistoryCaptureCapability.js +58 -0
- package/dist/gateOutcome.js +2 -0
- package/dist/hitl/askGateWire.d.ts +1 -1
- package/dist/hitl/askGateWire.js +1 -1
- package/dist/hitl/frameRouter.d.ts +2 -1
- package/dist/hitl/hitlBridge.d.ts +29 -1
- package/dist/hitl/hitlBridge.js +135 -3
- package/dist/hitl/hitlHostSurface.js +2 -3
- package/dist/hitl/parkResolver.d.ts +1 -0
- package/dist/hitl/parkResolver.js +17 -9
- package/dist/hitl/planReviewWire.d.ts +6 -0
- package/dist/hitl/planReviewWire.js +8 -2
- package/dist/hitl/toolApprovalWire.d.ts +2 -1
- package/dist/hitl/toolApprovalWire.js +105 -102
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/modelIdentityResolvability.d.ts +31 -0
- package/dist/modelIdentityResolvability.js +145 -0
- package/dist/notifications.d.ts +3 -1
- package/dist/notifications.js +18 -2
- package/dist/printToolResultFrame.js +15 -1
- package/dist/resumeRefusalCopy.d.ts +12 -0
- package/dist/resumeRefusalCopy.js +45 -1
- package/dist/seam.d.ts +2 -0
- package/dist/toolResult.d.ts +2 -2
- package/dist/toolResult.js +7 -6
- package/docs/INTEGRATION-CLIENTS.md +168 -11
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export * from './retainBackgroundWireCaps.js';
|
|
|
78
78
|
export * from './oneShotWireCaps.js';
|
|
79
79
|
export * from './rewindWireCaps.js';
|
|
80
80
|
export * from './rewindArchiveCapability.js';
|
|
81
|
+
export * from './fileHistoryCaptureCapability.js';
|
|
81
82
|
export * from './registryQuotaUsage.js';
|
|
82
83
|
export * from './selfOrchestrationWireCaps.js';
|
|
83
84
|
export * from './skillsWireCaps.js';
|
|
@@ -86,6 +87,7 @@ export * from './selfOrchestrationDenial.js';
|
|
|
86
87
|
export * from './webSearchWireCaps.js';
|
|
87
88
|
export * from './liveModelCatalog.js';
|
|
88
89
|
export * from './modelBudgetRule.js';
|
|
90
|
+
export * from './modelIdentityResolvability.js';
|
|
89
91
|
export * from './sessionModelLatch.js';
|
|
90
92
|
export * from './effortWire.js';
|
|
91
93
|
export * from './adapter/types.js';
|
package/dist/index.js
CHANGED
|
@@ -77,6 +77,7 @@ export * from './retainBackgroundWireCaps.js';
|
|
|
77
77
|
export * from './oneShotWireCaps.js';
|
|
78
78
|
export * from './rewindWireCaps.js';
|
|
79
79
|
export * from './rewindArchiveCapability.js';
|
|
80
|
+
export * from './fileHistoryCaptureCapability.js';
|
|
80
81
|
export * from './registryQuotaUsage.js';
|
|
81
82
|
export * from './selfOrchestrationWireCaps.js';
|
|
82
83
|
export * from './skillsWireCaps.js';
|
|
@@ -85,6 +86,7 @@ export * from './selfOrchestrationDenial.js';
|
|
|
85
86
|
export * from './webSearchWireCaps.js';
|
|
86
87
|
export * from './liveModelCatalog.js';
|
|
87
88
|
export * from './modelBudgetRule.js';
|
|
89
|
+
export * from './modelIdentityResolvability.js';
|
|
88
90
|
export * from './sessionModelLatch.js';
|
|
89
91
|
export * from './effortWire.js';
|
|
90
92
|
export * from './adapter/types.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type ModelIdentityLaneTuple = readonly [
|
|
2
|
+
'processEnv',
|
|
3
|
+
'settingsEnv',
|
|
4
|
+
'modelCatalogFile',
|
|
5
|
+
'followedSettingsFile',
|
|
6
|
+
'followedProviderEnv'
|
|
7
|
+
];
|
|
8
|
+
export type ModelIdentityLane = ModelIdentityLaneTuple[number];
|
|
9
|
+
export type ModelIdentityLaneReading = 'complete' | 'partial' | 'absent' | 'unreadable';
|
|
10
|
+
export type ModelIdentityLanes = {
|
|
11
|
+
[L in ModelIdentityLane]: L extends 'modelCatalogFile' ? Exclude<ModelIdentityLaneReading, 'complete'> : ModelIdentityLaneReading;
|
|
12
|
+
};
|
|
13
|
+
export type EngineAnswerObservation = 'answered' | 'not_observed' | 'unreachable';
|
|
14
|
+
export interface LocalEngineModelIdentityReading {
|
|
15
|
+
engine: 'local';
|
|
16
|
+
lanes: ModelIdentityLanes;
|
|
17
|
+
engineAnswer?: EngineAnswerObservation;
|
|
18
|
+
}
|
|
19
|
+
export interface RemoteEngineModelIdentityReading {
|
|
20
|
+
engine: 'remote';
|
|
21
|
+
engineAnswer: EngineAnswerObservation;
|
|
22
|
+
}
|
|
23
|
+
export type ModelIdentityReading = LocalEngineModelIdentityReading | RemoteEngineModelIdentityReading;
|
|
24
|
+
export type ModelIdentityResolvability = 'resolvable' | 'not_resolvable' | 'unknown';
|
|
25
|
+
export type ModelSetupDecision = 'offer_setup' | 'explain_unconfigured' | 'proceed';
|
|
26
|
+
export declare function modelIdentityResolvability(reading: ModelIdentityReading): ModelIdentityResolvability;
|
|
27
|
+
export declare function modelIdentityDetail(reading: ModelIdentityReading): string;
|
|
28
|
+
export declare function modelSetupDecision(identity: ModelIdentityResolvability, hostCanConfigureModel: boolean): ModelSetupDecision;
|
|
29
|
+
export declare function modelSetupNotice(decision: ModelSetupDecision): string | null;
|
|
30
|
+
export declare function observedEngineAnswer(baseUrl?: string | undefined): EngineAnswerObservation;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { engineCapValue } from './engineCapsCache.js';
|
|
2
|
+
import { engineWireTarget } from './engineWireTarget.js';
|
|
3
|
+
function laneOrder() {
|
|
4
|
+
return ['processEnv', 'settingsEnv', 'modelCatalogFile', 'followedSettingsFile', 'followedProviderEnv'];
|
|
5
|
+
}
|
|
6
|
+
function malformed() {
|
|
7
|
+
return { verdict: 'unknown', why: 'malformed' };
|
|
8
|
+
}
|
|
9
|
+
function own(o, key) {
|
|
10
|
+
if (!Object.hasOwn(o, key))
|
|
11
|
+
return undefined;
|
|
12
|
+
return { v: o[key] };
|
|
13
|
+
}
|
|
14
|
+
function isPlainObject(v) {
|
|
15
|
+
return v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
16
|
+
}
|
|
17
|
+
function laneState(lanes, lane) {
|
|
18
|
+
const hit = own(lanes, lane);
|
|
19
|
+
if (hit === undefined)
|
|
20
|
+
return 'not_reported';
|
|
21
|
+
const v = hit.v;
|
|
22
|
+
const _catalogPin = true;
|
|
23
|
+
void _catalogPin;
|
|
24
|
+
if (v === 'complete')
|
|
25
|
+
return lane === 'modelCatalogFile' ? 'unusable' : v;
|
|
26
|
+
return v === 'partial' || v === 'absent' || v === 'unreadable' ? v : 'unusable';
|
|
27
|
+
}
|
|
28
|
+
function analyse(reading) {
|
|
29
|
+
try {
|
|
30
|
+
if (!isPlainObject(reading))
|
|
31
|
+
return malformed();
|
|
32
|
+
const answer = own(reading, 'engineAnswer')?.v;
|
|
33
|
+
if (answer === 'answered')
|
|
34
|
+
return { verdict: 'resolvable', why: 'engine_answered' };
|
|
35
|
+
const engine = own(reading, 'engine')?.v;
|
|
36
|
+
if (engine === 'remote') {
|
|
37
|
+
return { verdict: 'unknown', why: 'remote', answer: answer === 'unreachable' ? 'unreachable' : 'not_observed' };
|
|
38
|
+
}
|
|
39
|
+
if (engine !== 'local')
|
|
40
|
+
return malformed();
|
|
41
|
+
const lanesHit = own(reading, 'lanes')?.v;
|
|
42
|
+
const order = laneOrder();
|
|
43
|
+
if (!isPlainObject(lanesHit))
|
|
44
|
+
return { verdict: 'unknown', why: 'lanes', unreadable: [], unreported: [...order], unusable: [] };
|
|
45
|
+
const partial = [];
|
|
46
|
+
const unreadable = [];
|
|
47
|
+
const unreported = [];
|
|
48
|
+
const unusable = [];
|
|
49
|
+
for (const lane of order) {
|
|
50
|
+
const s = laneState(lanesHit, lane);
|
|
51
|
+
if (s === 'complete')
|
|
52
|
+
return { verdict: 'resolvable', why: 'lane', lane };
|
|
53
|
+
if (s === 'partial')
|
|
54
|
+
partial.push(lane);
|
|
55
|
+
else if (s === 'unreadable')
|
|
56
|
+
unreadable.push(lane);
|
|
57
|
+
else if (s === 'not_reported')
|
|
58
|
+
unreported.push(lane);
|
|
59
|
+
else if (s === 'unusable')
|
|
60
|
+
unusable.push(lane);
|
|
61
|
+
}
|
|
62
|
+
if (unreadable.length > 0 || unreported.length > 0 || unusable.length > 0) {
|
|
63
|
+
return { verdict: 'unknown', why: 'lanes', unreadable, unreported, unusable };
|
|
64
|
+
}
|
|
65
|
+
return { verdict: 'not_resolvable', partial };
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return malformed();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export function modelIdentityResolvability(reading) {
|
|
72
|
+
return analyse(reading).verdict;
|
|
73
|
+
}
|
|
74
|
+
function laneLabel(lane) {
|
|
75
|
+
switch (lane) {
|
|
76
|
+
case 'processEnv':
|
|
77
|
+
return 'the environment this client was started with';
|
|
78
|
+
case 'settingsEnv':
|
|
79
|
+
return "this client's settings file";
|
|
80
|
+
case 'modelCatalogFile':
|
|
81
|
+
return 'the local model catalog file';
|
|
82
|
+
case 'followedSettingsFile':
|
|
83
|
+
return "another tool's settings file that this client follows";
|
|
84
|
+
case 'followedProviderEnv':
|
|
85
|
+
return 'the provider environment variables this client follows';
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function joinPhrases(xs) {
|
|
89
|
+
if (xs.length <= 1)
|
|
90
|
+
return xs.join('');
|
|
91
|
+
return `${xs.slice(0, -1).join(', ')} and ${xs[xs.length - 1]}`;
|
|
92
|
+
}
|
|
93
|
+
export function modelIdentityDetail(reading) {
|
|
94
|
+
const a = analyse(reading);
|
|
95
|
+
switch (a.verdict) {
|
|
96
|
+
case 'resolvable':
|
|
97
|
+
if (a.why === 'engine_answered') {
|
|
98
|
+
return 'the engine is up and answering, and it does not start without a model name, so it has one — whether its gateway accepts that name is a separate check';
|
|
99
|
+
}
|
|
100
|
+
return `${laneLabel(a.lane)} supplies a model name, so the local engine can start with it — whether its gateway accepts that name is a separate check`;
|
|
101
|
+
case 'not_resolvable':
|
|
102
|
+
if (a.partial.length > 0) {
|
|
103
|
+
const labels = joinPhrases(a.partial.map(laneLabel));
|
|
104
|
+
return `no model name is configured for the local engine — ${labels} ${a.partial.length > 1 ? 'carry' : 'carries'} part of a model configuration (such as a gateway address or a credential) but no model name, and the engine does not start without one`;
|
|
105
|
+
}
|
|
106
|
+
return 'no model name is configured for the local engine — none of the places this client reads supplies one, and the engine does not start without it';
|
|
107
|
+
case 'unknown':
|
|
108
|
+
if (a.why === 'remote') {
|
|
109
|
+
return a.answer === 'unreachable'
|
|
110
|
+
? 'the engine runs elsewhere and did not answer — it may be unreachable or may have failed to start; its model configuration lives with that deployment, so whether it has a model name is unknown'
|
|
111
|
+
: 'the engine runs elsewhere and has not been seen answering yet — its model configuration lives with that deployment, so whether it has a model name is unknown';
|
|
112
|
+
}
|
|
113
|
+
if (a.why === 'lanes') {
|
|
114
|
+
const parts = [
|
|
115
|
+
...a.unreadable.map((l) => `${laneLabel(l)} could not be read`),
|
|
116
|
+
...a.unreported.map((l) => `${laneLabel(l)} was not reported`),
|
|
117
|
+
...a.unusable.map((l) => `${laneLabel(l)} gave no usable reading`),
|
|
118
|
+
];
|
|
119
|
+
return `whether the local engine has a model name is unknown — ${joinPhrases(parts)}, and no other place this client reads provides one`;
|
|
120
|
+
}
|
|
121
|
+
return "this reading of the engine's model configuration could not be interpreted, so whether the engine has a model name is unknown";
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export function modelSetupDecision(identity, hostCanConfigureModel) {
|
|
125
|
+
if (identity !== 'not_resolvable')
|
|
126
|
+
return 'proceed';
|
|
127
|
+
if (hostCanConfigureModel === true)
|
|
128
|
+
return 'offer_setup';
|
|
129
|
+
if (hostCanConfigureModel === false)
|
|
130
|
+
return 'explain_unconfigured';
|
|
131
|
+
return 'proceed';
|
|
132
|
+
}
|
|
133
|
+
export function modelSetupNotice(decision) {
|
|
134
|
+
switch (decision) {
|
|
135
|
+
case 'offer_setup':
|
|
136
|
+
return 'no model name is configured for the engine, and it does not start without one — opening model setup';
|
|
137
|
+
case 'explain_unconfigured':
|
|
138
|
+
return 'this engine has no model configured, and it cannot be configured from this client — ask whoever runs the engine to set one up';
|
|
139
|
+
default:
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export function observedEngineAnswer(baseUrl = engineWireTarget()?.baseUrl) {
|
|
144
|
+
return engineCapValue(baseUrl, 'version').kind === 'unobserved' ? 'not_observed' : 'answered';
|
|
145
|
+
}
|
package/dist/notifications.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PlanReviewOutcomeMeta } from './hitl/planReviewWire.js';
|
|
1
2
|
export interface TaskNotificationFields {
|
|
2
3
|
taskId: string;
|
|
3
4
|
status: string;
|
|
@@ -48,12 +49,13 @@ export interface NotificationQueuePort {
|
|
|
48
49
|
priority: 'later';
|
|
49
50
|
isMeta: true;
|
|
50
51
|
workload: string;
|
|
52
|
+
_sema_planReviewOutcome?: PlanReviewOutcomeMeta;
|
|
51
53
|
}): void;
|
|
52
54
|
}
|
|
53
55
|
export declare function installNotificationQueuePort(port: NotificationQueuePort | null): void;
|
|
54
56
|
export declare function notificationQueuePortMisses(): number;
|
|
55
57
|
export declare function _resetNotificationQueuePortForTest(): void;
|
|
56
|
-
export declare function enqueuePlanReviewOutcome(value: string): boolean;
|
|
58
|
+
export declare function enqueuePlanReviewOutcome(value: string, meta?: PlanReviewOutcomeMeta): boolean;
|
|
57
59
|
export declare function dropQueuedNotificationsForRun(taskId: string): number;
|
|
58
60
|
export declare function markEngineWorkflowNotified(runId: string): void;
|
|
59
61
|
export declare function isEngineWorkflowNotified(runId: string): boolean;
|
package/dist/notifications.js
CHANGED
|
@@ -188,7 +188,7 @@ function notifiedBgCycleAtLeast(taskId, cycle) {
|
|
|
188
188
|
const high = notifiedBgCycleHigh.get(taskId);
|
|
189
189
|
return high !== undefined && high.cycle >= cycle ? high : undefined;
|
|
190
190
|
}
|
|
191
|
-
export function enqueuePlanReviewOutcome(value) {
|
|
191
|
+
export function enqueuePlanReviewOutcome(value, meta) {
|
|
192
192
|
const p = port();
|
|
193
193
|
if (!p)
|
|
194
194
|
return false;
|
|
@@ -196,7 +196,23 @@ export function enqueuePlanReviewOutcome(value) {
|
|
|
196
196
|
queuePortMisses++;
|
|
197
197
|
return false;
|
|
198
198
|
}
|
|
199
|
-
p.enqueueMetaPrompt({
|
|
199
|
+
p.enqueueMetaPrompt({
|
|
200
|
+
value,
|
|
201
|
+
mode: 'prompt',
|
|
202
|
+
priority: 'later',
|
|
203
|
+
isMeta: true,
|
|
204
|
+
workload: 'plan-review',
|
|
205
|
+
...(meta !== undefined
|
|
206
|
+
? {
|
|
207
|
+
_sema_planReviewOutcome: Object.freeze({
|
|
208
|
+
taskId: meta.taskId,
|
|
209
|
+
dispatchNo: meta.dispatchNo,
|
|
210
|
+
decision: meta.decision,
|
|
211
|
+
effect: meta.effect,
|
|
212
|
+
}),
|
|
213
|
+
}
|
|
214
|
+
: {}),
|
|
215
|
+
});
|
|
200
216
|
return true;
|
|
201
217
|
}
|
|
202
218
|
export function dropQueuedNotificationsForRun(taskId) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { isCcToolDenialKind } from './gateVocabulary.js';
|
|
2
2
|
export { flattenWireOutput as flattenToolOutput } from './adapt/wireShapes.js';
|
|
3
3
|
import { flattenWireOutput } from './adapt/wireShapes.js';
|
|
4
|
+
import { parseModelFacingBash } from './toolResult.js';
|
|
5
|
+
import { toolResultEnvelopeParts, toolResultOutcomeOf } from './adapt/toolCards.js';
|
|
4
6
|
function bashExitCodeFailed(toolName, text, structured) {
|
|
5
7
|
if (typeof toolName !== 'string' || toolName.toLowerCase() !== 'bash')
|
|
6
8
|
return false;
|
|
@@ -10,6 +12,8 @@ function bashExitCodeFailed(toolName, text, structured) {
|
|
|
10
12
|
const ec = st?.exitCode;
|
|
11
13
|
if (typeof ec === 'number')
|
|
12
14
|
return ec !== 0;
|
|
15
|
+
if (parseModelFacingBash(text)?.note !== undefined)
|
|
16
|
+
return false;
|
|
13
17
|
const m = /^exit code: (\d+)\b/.exec(text);
|
|
14
18
|
return m !== null && m[1] !== '0';
|
|
15
19
|
}
|
|
@@ -17,6 +21,14 @@ export function toolEndResultToUserFrame(arm) {
|
|
|
17
21
|
if (typeof arm.toolCallId !== 'string' || arm.toolCallId.length === 0)
|
|
18
22
|
return null;
|
|
19
23
|
const text = flattenWireOutput(arm.output);
|
|
24
|
+
const parent = typeof arm.parentToolCallId === 'string' ? arm.parentToolCallId : null;
|
|
25
|
+
const outcome = toolResultOutcomeOf(typeof arm.toolName === 'string' ? arm.toolName : '', {
|
|
26
|
+
output: arm.output,
|
|
27
|
+
structured: arm.structured,
|
|
28
|
+
truncated: arm.truncated === true,
|
|
29
|
+
isError: arm.isError === true,
|
|
30
|
+
}, undefined, parent === null ? 'leader' : 'subagent');
|
|
31
|
+
const envelope = toolResultEnvelopeParts(outcome);
|
|
20
32
|
return {
|
|
21
33
|
type: 'user',
|
|
22
34
|
message: {
|
|
@@ -30,8 +42,10 @@ export function toolEndResultToUserFrame(arm) {
|
|
|
30
42
|
},
|
|
31
43
|
],
|
|
32
44
|
},
|
|
33
|
-
parent_tool_use_id:
|
|
45
|
+
parent_tool_use_id: parent,
|
|
34
46
|
...(isCcToolDenialKind(arm._sema_denial_kind) ? { _sema_denial_kind: arm._sema_denial_kind } : {}),
|
|
47
|
+
...(Object.hasOwn(envelope, 'tool_use_result') ? { tool_use_result: envelope.tool_use_result } : {}),
|
|
48
|
+
...(Object.hasOwn(envelope, '_sema_degraded') ? { _sema_degraded: envelope._sema_degraded } : {}),
|
|
35
49
|
uuid: arm.uuid,
|
|
36
50
|
session_id: arm.session_id,
|
|
37
51
|
};
|
|
@@ -7,6 +7,18 @@ export interface ResumeRefusalDetail {
|
|
|
7
7
|
}
|
|
8
8
|
export declare function resumeRefusalFromError(err: unknown): ResumeRefusalDetail | null;
|
|
9
9
|
export declare function resumeRefusalContent(detail: ResumeRefusalDetail): string;
|
|
10
|
+
export interface ResumePolicyBlockDetail {
|
|
11
|
+
blockedBy: {
|
|
12
|
+
kind: 'named';
|
|
13
|
+
code: string;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'absent';
|
|
16
|
+
} | {
|
|
17
|
+
kind: 'unreadable';
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export declare function resumePolicyBlockFromError(err: unknown): ResumePolicyBlockDetail | null;
|
|
21
|
+
export declare function resumePolicyBlockContent(detail: ResumePolicyBlockDetail): string;
|
|
10
22
|
export interface ResumeReopenDetail {
|
|
11
23
|
code: string;
|
|
12
24
|
reason: 'env_failed' | 'tool_unavailable' | 'tool_contract_mismatch';
|
|
@@ -1,5 +1,6 @@
|
|
|
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, } 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, } from './engineErrorCodes.js';
|
|
3
|
+
import { capForDisplay } from './fleetTaskDesc.js';
|
|
3
4
|
import { resumeRetryLaterFromError } from './wireErrorTriage.js';
|
|
4
5
|
export const RESUME_REFUSAL_CODES = Object.freeze([
|
|
5
6
|
RESUME_PLACEMENT_MISMATCH,
|
|
@@ -39,6 +40,49 @@ export function resumeRefusalContent(detail) {
|
|
|
39
40
|
'The engine supplied no wait, so this refusal does not say whether the token stays redeemable');
|
|
40
41
|
return parts.join(' · ');
|
|
41
42
|
}
|
|
43
|
+
export function resumePolicyBlockFromError(err) {
|
|
44
|
+
if (typeof err !== 'object' || err === null)
|
|
45
|
+
return null;
|
|
46
|
+
const o = err;
|
|
47
|
+
let outer;
|
|
48
|
+
try {
|
|
49
|
+
outer = o['errorCode'];
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
if (outer !== RESUME_POLICY_FOLD_CODE)
|
|
55
|
+
return null;
|
|
56
|
+
const judge = (v) => ({
|
|
57
|
+
blockedBy: typeof v === 'string' && v.length > 0 ? { kind: 'named', code: v } : { kind: 'unreadable' },
|
|
58
|
+
});
|
|
59
|
+
try {
|
|
60
|
+
const top = o['blockedBy'];
|
|
61
|
+
if (top !== undefined)
|
|
62
|
+
return judge(top);
|
|
63
|
+
const extra = o['extra'];
|
|
64
|
+
if (typeof extra === 'object' && extra !== null && !Array.isArray(extra) && Object.hasOwn(extra, 'blockedBy')) {
|
|
65
|
+
return judge(extra['blockedBy']);
|
|
66
|
+
}
|
|
67
|
+
return { blockedBy: { kind: 'absent' } };
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return { blockedBy: { kind: 'unreadable' } };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function resumePolicyBlockContent(detail) {
|
|
74
|
+
const b = detail.blockedBy;
|
|
75
|
+
const reason = b.kind === 'named'
|
|
76
|
+
? `The check that refused it: ${capForDisplay(b.code, 80)}`
|
|
77
|
+
: b.kind === 'absent'
|
|
78
|
+
? 'The refusal did not name a more specific check'
|
|
79
|
+
: 'The refusal carried a more specific reason that could not be read';
|
|
80
|
+
return [
|
|
81
|
+
'The engine refused to resume this parked work at its admission check (the engine reports that its admission policy changed since the work was first accepted)',
|
|
82
|
+
reason,
|
|
83
|
+
"This refusal does not say whether anything was consumed before it or whether a retry would pass — check the task's current state before deciding again, and ask whoever operates this deployment if it keeps happening",
|
|
84
|
+
].join(' · ');
|
|
85
|
+
}
|
|
42
86
|
export function resumeReopenFromError(err) {
|
|
43
87
|
if (typeof err !== 'object' || err === null)
|
|
44
88
|
return null;
|
package/dist/seam.d.ts
CHANGED
|
@@ -130,6 +130,7 @@ export type ChromeEvent = {
|
|
|
130
130
|
engineUsage?: EngineTurnUsage;
|
|
131
131
|
usageMissing?: true;
|
|
132
132
|
stopReason?: string;
|
|
133
|
+
responseModel?: string;
|
|
133
134
|
} | {
|
|
134
135
|
kind: 'subagent_turn_usage';
|
|
135
136
|
laneProof: LaneProof;
|
|
@@ -140,6 +141,7 @@ export type ChromeEvent = {
|
|
|
140
141
|
engineUsage?: EngineTurnUsage;
|
|
141
142
|
usageMissing?: true;
|
|
142
143
|
stopReason?: string;
|
|
144
|
+
responseModel?: string;
|
|
143
145
|
} | {
|
|
144
146
|
kind: 'plan_review_park';
|
|
145
147
|
laneProof: LaneProof;
|
package/dist/toolResult.d.ts
CHANGED
|
@@ -79,8 +79,8 @@ export interface ToolResultBody {
|
|
|
79
79
|
degraded?: typeof TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT;
|
|
80
80
|
}
|
|
81
81
|
export declare function degradedToolResultBody(isError: boolean): ToolResultBody;
|
|
82
|
-
export declare function wireOutputToBody(toolName: string, output: unknown, isError: boolean, truncated: boolean, flatten: FlattenWireOutput, structured?: unknown): ToolResultBody;
|
|
83
|
-
export declare function structuredToToolUseResult(structured: unknown, modelText?: string): {
|
|
82
|
+
export declare function wireOutputToBody(toolName: string, output: unknown, isError: boolean, truncated: boolean, flatten: FlattenWireOutput, structured?: unknown, leaderLedger?: boolean): ToolResultBody;
|
|
83
|
+
export declare function structuredToToolUseResult(structured: unknown, modelText?: string, leaderLedger?: boolean): {
|
|
84
84
|
toolUseResult: unknown;
|
|
85
85
|
isError?: boolean;
|
|
86
86
|
} | null;
|
package/dist/toolResult.js
CHANGED
|
@@ -229,7 +229,7 @@ export const TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT = 'wire_carried_no_output';
|
|
|
229
229
|
export function degradedToolResultBody(isError) {
|
|
230
230
|
return { content: '', isError, degraded: TOOL_RESULT_DEGRADED_WIRE_NO_OUTPUT };
|
|
231
231
|
}
|
|
232
|
-
export function wireOutputToBody(toolName, output, isError, truncated, flatten, structured) {
|
|
232
|
+
export function wireOutputToBody(toolName, output, isError, truncated, flatten, structured, leaderLedger = true) {
|
|
233
233
|
const text = flatten(output);
|
|
234
234
|
const name = (toolName || '').toLowerCase();
|
|
235
235
|
const sType = structuredDetailType(structured);
|
|
@@ -320,7 +320,7 @@ export function wireOutputToBody(toolName, output, isError, truncated, flatten,
|
|
|
320
320
|
}
|
|
321
321
|
const wfEnvelope = parseWorkflowPollEnvelope(text);
|
|
322
322
|
if (wfEnvelope) {
|
|
323
|
-
if (WF_TERMINAL_STATUSES.has(wfEnvelope.status))
|
|
323
|
+
if (leaderLedger && WF_TERMINAL_STATUSES.has(wfEnvelope.status))
|
|
324
324
|
markEngineWorkflowNotified(wfEnvelope.taskId);
|
|
325
325
|
return wrap({
|
|
326
326
|
task_id: wfEnvelope.taskId,
|
|
@@ -340,7 +340,7 @@ export function wireOutputToBody(toolName, output, isError, truncated, flatten,
|
|
|
340
340
|
}
|
|
341
341
|
return { content: truncated ? `${text}\n…(truncated)` : text, isError };
|
|
342
342
|
}
|
|
343
|
-
export function structuredToToolUseResult(structured, modelText) {
|
|
343
|
+
export function structuredToToolUseResult(structured, modelText, leaderLedger = true) {
|
|
344
344
|
if (typeof structured !== 'object' || structured === null)
|
|
345
345
|
return null;
|
|
346
346
|
const s = structured;
|
|
@@ -348,7 +348,7 @@ export function structuredToToolUseResult(structured, modelText) {
|
|
|
348
348
|
if (typeof s[k] === 'string' && s[k].length > MAX_STRUCTURED_FIELD_CHARS)
|
|
349
349
|
return null;
|
|
350
350
|
}
|
|
351
|
-
if (s.type === 'workflow-run' && typeof s.workflowRunId === 'string') {
|
|
351
|
+
if (leaderLedger && s.type === 'workflow-run' && typeof s.workflowRunId === 'string') {
|
|
352
352
|
registerOutstandingWorkflowRun(s.workflowRunId);
|
|
353
353
|
}
|
|
354
354
|
switch (s.type) {
|
|
@@ -586,7 +586,8 @@ export function structuredToToolUseResult(structured, modelText) {
|
|
|
586
586
|
if (typeof s.description !== 'string' || typeof s.prompt !== 'string') {
|
|
587
587
|
return null;
|
|
588
588
|
}
|
|
589
|
-
|
|
589
|
+
if (leaderLedger)
|
|
590
|
+
registerOutstandingBgTask(agentId, s.description, s.prompt, receipt.seq);
|
|
590
591
|
return {
|
|
591
592
|
toolUseResult: {
|
|
592
593
|
isAsync: true,
|
|
@@ -653,7 +654,7 @@ export function structuredToToolUseResult(structured, modelText) {
|
|
|
653
654
|
const runErrorCode = typeof s.errorCode === 'string' && s.errorCode.length > 0 ? s.errorCode : undefined;
|
|
654
655
|
let output = bodyText ?? '';
|
|
655
656
|
if (taskType === 'workflow') {
|
|
656
|
-
if (WF_TERMINAL_STATUSES.has(status))
|
|
657
|
+
if (leaderLedger && WF_TERMINAL_STATUSES.has(status))
|
|
657
658
|
markEngineWorkflowNotified(taskId);
|
|
658
659
|
const jsonSrc = output.length > 0 ? output : (modelText ?? '');
|
|
659
660
|
output = projectWorkflowTaskOutput(jsonSrc);
|