@opengeni/worker-bundle 1.2.1-canary.37222965366001 → 1.3.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/dist/activities/codemode-dispatcher.d.ts +6 -2
- package/dist/activities/open-suffix-resume.d.ts +2 -0
- package/dist/activities/programmatic-approvals.d.ts +10 -0
- package/dist/activities/run-input.d.ts +2 -0
- package/dist/{activities-control-QSDPXLLD.js → activities-control-PEXBWKQJ.js} +2 -2
- package/dist/{activities-turn-BMY3CDKL.js → activities-turn-W27A2SBO.js} +273 -97
- package/dist/activities-turn-W27A2SBO.js.map +1 -0
- package/dist/{chunk-JKMG5ZHH.js → chunk-QUX5LT2B.js} +3 -2
- package/dist/{chunk-JKMG5ZHH.js.map → chunk-QUX5LT2B.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +21 -21
- package/src/activities/agent-turn/agent-build.ts +2 -2
- package/src/activities/agent-turn/stream-attempt.ts +66 -21
- package/src/activities/agent-turn/tool-environment.ts +1 -0
- package/src/activities/agent-turn/tool-policy.ts +1 -5
- package/src/activities/codemode-dispatcher.ts +145 -7
- package/src/activities/open-suffix-resume.ts +107 -86
- package/src/activities/programmatic-approvals.ts +26 -0
- package/src/activities/run-input.ts +4 -1
- package/dist/activities-turn-BMY3CDKL.js.map +0 -1
- /package/dist/{activities-control-QSDPXLLD.js.map → activities-control-PEXBWKQJ.js.map} +0 -0
|
@@ -248,6 +248,8 @@ export async function resultItemForOpenSuffixMember(input: {
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
export async function settleOpenSuffixResumeIfNeeded(input: {
|
|
251
|
+
additionalApprovals?: unknown[];
|
|
252
|
+
programmaticApprovalAcknowledged?: boolean;
|
|
251
253
|
db: Database;
|
|
252
254
|
agent: Agent<any, any>;
|
|
253
255
|
accountId: string;
|
|
@@ -270,7 +272,8 @@ export async function settleOpenSuffixResumeIfNeeded(input: {
|
|
|
270
272
|
}): Promise<OpenSuffixResumeOutcome> {
|
|
271
273
|
if (
|
|
272
274
|
input.trigger.type !== "user.approvalDecision" &&
|
|
273
|
-
input.trigger.type !== "user.humanInputResponse"
|
|
275
|
+
input.trigger.type !== "user.humanInputResponse" &&
|
|
276
|
+
!input.additionalApprovals?.length
|
|
274
277
|
) {
|
|
275
278
|
return { action: "continue" };
|
|
276
279
|
}
|
|
@@ -280,7 +283,7 @@ export async function settleOpenSuffixResumeIfNeeded(input: {
|
|
|
280
283
|
input.sessionId,
|
|
281
284
|
input.turnId,
|
|
282
285
|
);
|
|
283
|
-
if (rows.length === 0) {
|
|
286
|
+
if (rows.length === 0 && !input.additionalApprovals?.length) {
|
|
284
287
|
return { action: "continue" };
|
|
285
288
|
}
|
|
286
289
|
const callId = matchingOpenSuffixCallId({
|
|
@@ -288,105 +291,123 @@ export async function settleOpenSuffixResumeIfNeeded(input: {
|
|
|
288
291
|
humanInputToolCallId: input.humanInputResume?.toolCallId,
|
|
289
292
|
});
|
|
290
293
|
const target = resolveOpenSuffixResumeTarget(rows, callId);
|
|
291
|
-
if (
|
|
294
|
+
if (
|
|
295
|
+
(!target || !callId) &&
|
|
296
|
+
!input.programmaticApprovalAcknowledged &&
|
|
297
|
+
(input.trigger.type === "user.approvalDecision" ||
|
|
298
|
+
input.trigger.type === "user.humanInputResponse" ||
|
|
299
|
+
!input.additionalApprovals?.length)
|
|
300
|
+
) {
|
|
292
301
|
throw new Error("Open suffix resume event does not match an interruption");
|
|
293
302
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
303
|
+
if (target && callId) {
|
|
304
|
+
const truncationTokens =
|
|
305
|
+
input.modelToolOutputTruncationTokens ?? target.modelToolOutputTruncationTokens ?? undefined;
|
|
306
|
+
let resultItem = target.resultItem;
|
|
307
|
+
let eventOutput: unknown = resultItem?.output;
|
|
308
|
+
if (!resultItem) {
|
|
309
|
+
const member = await resultItemForOpenSuffixMember({
|
|
310
|
+
agent: input.agent,
|
|
311
|
+
row: target,
|
|
312
|
+
trigger: input.trigger,
|
|
313
|
+
humanInputResume: input.humanInputResume,
|
|
314
|
+
});
|
|
315
|
+
resultItem = member.resultItem;
|
|
316
|
+
eventOutput = member.eventOutput;
|
|
317
|
+
const recorded = await recordPendingSessionToolCallResult(input.db, {
|
|
318
|
+
accountId: input.accountId,
|
|
319
|
+
workspaceId: input.workspaceId,
|
|
320
|
+
sessionId: input.sessionId,
|
|
321
|
+
turnId: input.turnId,
|
|
322
|
+
executionGeneration: input.executionGeneration,
|
|
323
|
+
attemptId: input.attemptId,
|
|
324
|
+
callId: target.callId,
|
|
325
|
+
...(truncationTokens !== undefined
|
|
326
|
+
? { modelToolOutputTruncationTokens: truncationTokens }
|
|
327
|
+
: {}),
|
|
328
|
+
resultItem,
|
|
329
|
+
eventOutput,
|
|
330
|
+
});
|
|
331
|
+
if (!recorded.accepted) {
|
|
332
|
+
return { action: "cancelled" };
|
|
333
|
+
}
|
|
334
|
+
if (!recorded.recorded) {
|
|
335
|
+
const latest = resolveOpenSuffixResumeTarget(
|
|
336
|
+
await listTurnOpenSuffixToolCalls(
|
|
337
|
+
input.db,
|
|
338
|
+
input.workspaceId,
|
|
339
|
+
input.sessionId,
|
|
340
|
+
input.turnId,
|
|
341
|
+
),
|
|
342
|
+
callId,
|
|
343
|
+
);
|
|
344
|
+
resultItem = latest?.resultItem ?? resultItem;
|
|
345
|
+
} else if (input.publish) {
|
|
346
|
+
await input.publish([
|
|
347
|
+
{
|
|
348
|
+
type: "agent.toolCall.output",
|
|
349
|
+
payload: { id: target.callId, output: eventOutput },
|
|
350
|
+
},
|
|
351
|
+
]);
|
|
352
|
+
}
|
|
342
353
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
throw new Error(`Open suffix resume for ${target.callId} has no result item`);
|
|
346
|
-
}
|
|
347
|
-
const history = await getActiveSessionHistoryItems(input.db, input.workspaceId, input.sessionId);
|
|
348
|
-
if (
|
|
349
|
-
!openSuffixPairPresentInHistory(
|
|
350
|
-
history.map((row) => row.item),
|
|
351
|
-
callId,
|
|
352
|
-
)
|
|
353
|
-
) {
|
|
354
|
-
const historyItems = openSuffixHistoryItems(target, resultItem);
|
|
355
|
-
if (historyItems.length === 0) {
|
|
356
|
-
throw new Error(`Open suffix resume for ${target.callId} produced no paired history`);
|
|
354
|
+
if (!resultItem) {
|
|
355
|
+
throw new Error(`Open suffix resume for ${target.callId} has no result item`);
|
|
357
356
|
}
|
|
358
|
-
const
|
|
357
|
+
const history = await getActiveSessionHistoryItems(
|
|
359
358
|
input.db,
|
|
360
359
|
input.workspaceId,
|
|
361
360
|
input.sessionId,
|
|
362
361
|
);
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
362
|
+
if (
|
|
363
|
+
!openSuffixPairPresentInHistory(
|
|
364
|
+
history.map((row) => row.item),
|
|
365
|
+
callId,
|
|
366
|
+
)
|
|
367
|
+
) {
|
|
368
|
+
const historyItems = openSuffixHistoryItems(target, resultItem);
|
|
369
|
+
if (historyItems.length === 0) {
|
|
370
|
+
throw new Error(`Open suffix resume for ${target.callId} produced no paired history`);
|
|
371
|
+
}
|
|
372
|
+
const nextPosition = await nextSessionHistoryPosition(
|
|
373
|
+
input.db,
|
|
374
|
+
input.workspaceId,
|
|
375
|
+
input.sessionId,
|
|
376
|
+
);
|
|
377
|
+
const appended = await appendSessionHistoryItems(input.db, {
|
|
378
|
+
accountId: input.accountId,
|
|
379
|
+
workspaceId: input.workspaceId,
|
|
380
|
+
sessionId: input.sessionId,
|
|
381
|
+
turnId: input.turnId,
|
|
382
|
+
expectedExecutionGeneration: input.executionGeneration,
|
|
383
|
+
expectedAttemptId: input.attemptId,
|
|
384
|
+
...(truncationTokens !== undefined
|
|
385
|
+
? { modelToolOutputTruncationTokens: truncationTokens }
|
|
386
|
+
: {}),
|
|
387
|
+
items: historyItems.map((item, offset) => ({
|
|
388
|
+
position: nextPosition + offset,
|
|
389
|
+
item,
|
|
390
|
+
})),
|
|
391
|
+
});
|
|
392
|
+
if (!appended) {
|
|
393
|
+
return { action: "cancelled" };
|
|
394
|
+
}
|
|
380
395
|
}
|
|
381
396
|
}
|
|
382
397
|
const remaining = (
|
|
383
398
|
await listTurnOpenSuffixToolCalls(input.db, input.workspaceId, input.sessionId, input.turnId)
|
|
384
399
|
).filter((row) => row.resultItem == null);
|
|
385
|
-
if (remaining.length === 0) {
|
|
400
|
+
if (remaining.length === 0 && !input.additionalApprovals?.length) {
|
|
386
401
|
return { action: "continue" };
|
|
387
402
|
}
|
|
388
|
-
const requiresActionApprovals =
|
|
389
|
-
|
|
403
|
+
const requiresActionApprovals = [
|
|
404
|
+
...remainingPendingApprovalsFromSuffix(remaining),
|
|
405
|
+
...(input.additionalApprovals ?? []),
|
|
406
|
+
];
|
|
407
|
+
const pendingApprovals = [
|
|
408
|
+
...remainingRunStatePendingApprovalsFromSuffix(remaining),
|
|
409
|
+
...(input.additionalApprovals ?? []),
|
|
410
|
+
];
|
|
390
411
|
const settled = await input.settle({
|
|
391
412
|
events: [
|
|
392
413
|
...(requiresActionApprovals.length > 0
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CodemodeOperation } from "@opengeni/contracts";
|
|
2
|
+
|
|
3
|
+
/** Programmatic receipts are not open SDK calls. Exact arguments stay in protected storage. */
|
|
4
|
+
export function programmaticApproval(operation: CodemodeOperation) {
|
|
5
|
+
return {
|
|
6
|
+
id: operation.operationId,
|
|
7
|
+
name: operation.identity.toolName,
|
|
8
|
+
source: "codemode" as const,
|
|
9
|
+
operationId: operation.operationId,
|
|
10
|
+
requestId: operation.approvalRequestId,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function programmaticContinuationNote(
|
|
15
|
+
operations: readonly CodemodeOperation[],
|
|
16
|
+
): string | undefined {
|
|
17
|
+
if (operations.length === 0) return undefined;
|
|
18
|
+
return [
|
|
19
|
+
"Stored programmatic operations (durable server receipts):",
|
|
20
|
+
...operations.map(
|
|
21
|
+
(operation) =>
|
|
22
|
+
`${operation.operationId}: ${operation.state}${operation.errorCode ? ` (${operation.errorCode})` : ""}`,
|
|
23
|
+
),
|
|
24
|
+
"Approval resumes the stored operation, not the earlier program's JavaScript stack. Read results with the current Codemode client's status/resume handle. Do not resubmit arguments for completed, running, waiting, or uncertain operations.",
|
|
25
|
+
].join("\n");
|
|
26
|
+
}
|
|
@@ -81,6 +81,8 @@ export type TurnInputOptions = {
|
|
|
81
81
|
unavailableSandboxFilesNote?: string;
|
|
82
82
|
runCredentialsNote?: string;
|
|
83
83
|
mcpAvailabilityNote?: string;
|
|
84
|
+
codemodeContinuationNote?: string;
|
|
85
|
+
programmaticApprovalAcknowledged?: boolean;
|
|
84
86
|
knowledgeSourcePreparationNote?: string;
|
|
85
87
|
providerApi: HistoryProviderApi;
|
|
86
88
|
projectCanonicalHistory?: ModelHistoryAttachmentProjector;
|
|
@@ -513,6 +515,7 @@ export async function turnInput(
|
|
|
513
515
|
options.unavailableSandboxFilesNote,
|
|
514
516
|
options.runCredentialsNote,
|
|
515
517
|
options.mcpAvailabilityNote,
|
|
518
|
+
options.codemodeContinuationNote,
|
|
516
519
|
options.knowledgeSourcePreparationNote,
|
|
517
520
|
);
|
|
518
521
|
if (trigger.type === "user.message") {
|
|
@@ -606,7 +609,7 @@ async function openSuffixMessageInput(
|
|
|
606
609
|
trigger.sessionId,
|
|
607
610
|
options.turnId,
|
|
608
611
|
);
|
|
609
|
-
if (suffixRows.length === 0) {
|
|
612
|
+
if (suffixRows.length === 0 && !options.programmaticApprovalAcknowledged) {
|
|
610
613
|
throw new Error("Open suffix resume has no interruption rows");
|
|
611
614
|
}
|
|
612
615
|
if (suffixRows.some((row) => row.resultItem == null)) {
|