@opengeni/worker-bundle 2.0.0 → 2.0.1-canary.35916963870001

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.
Files changed (33) hide show
  1. package/dist/activities/agent-turn/agent-build.d.ts +1 -0
  2. package/dist/activities/agent-turn/failure-settlement.d.ts +1 -1
  3. package/dist/activities/agent-turn/tool-environment.d.ts +34 -0
  4. package/dist/activities/codemode-dispatcher.d.ts +3 -1
  5. package/dist/activities/sandbox-lease.d.ts +3 -4
  6. package/dist/{activities-control-BOLIY3H4.js → activities-control-UF2CR2LB.js} +199 -23
  7. package/dist/activities-control-UF2CR2LB.js.map +1 -0
  8. package/dist/{activities-turn-2B3WMHBB.js → activities-turn-KBLXHBWS.js} +109 -25
  9. package/dist/activities-turn-KBLXHBWS.js.map +1 -0
  10. package/dist/{chunk-TVEE2UUC.js → chunk-K3BPAI4R.js} +12 -6
  11. package/dist/chunk-K3BPAI4R.js.map +1 -0
  12. package/dist/index.js +7 -2
  13. package/dist/index.js.map +1 -1
  14. package/dist/workflow-bundle.js +4 -1
  15. package/package.json +19 -19
  16. package/src/activities/agent-turn/agent-build.ts +5 -1
  17. package/src/activities/agent-turn/claim.ts +12 -2
  18. package/src/activities/agent-turn/errors.ts +1 -0
  19. package/src/activities/agent-turn/failure-settlement.ts +40 -8
  20. package/src/activities/agent-turn/run.ts +1 -0
  21. package/src/activities/agent-turn/sandbox-runtime.ts +25 -9
  22. package/src/activities/agent-turn/stream-attempt.ts +14 -1
  23. package/src/activities/agent-turn/tool-environment.ts +5 -0
  24. package/src/activities/codemode-dispatcher.ts +6 -0
  25. package/src/activities/knowledge-indexing.ts +124 -6
  26. package/src/activities/retained-screenshots.ts +42 -4
  27. package/src/activities/sandbox-lease.ts +141 -21
  28. package/src/sandbox-resume.ts +6 -0
  29. package/src/sandbox-routing.ts +7 -3
  30. package/src/workflows/activities.ts +14 -1
  31. package/dist/activities-control-BOLIY3H4.js.map +0 -1
  32. package/dist/activities-turn-2B3WMHBB.js.map +0 -1
  33. package/dist/chunk-TVEE2UUC.js.map +0 -1
@@ -86,7 +86,7 @@ import {
86
86
  withFirstPartyTools,
87
87
  wrapLazyTurnBoxWithRouting,
88
88
  wrapTurnBoxWithRouting
89
- } from "./chunk-TVEE2UUC.js";
89
+ } from "./chunk-K3BPAI4R.js";
90
90
  import {
91
91
  StreamTimingMetrics,
92
92
  makeMachineOpObserver,
@@ -1450,6 +1450,7 @@ import {
1450
1450
  import {
1451
1451
  RetainedScreenshotQuotaExceededError,
1452
1452
  getRetainedScreenshotArtifact,
1453
+ getRetainedScreenshotArtifactForToolCall,
1453
1454
  isDatabasePersistenceFailure,
1454
1455
  isSessionEventPersistenceError,
1455
1456
  prepareRetainedScreenshotArtifact,
@@ -2005,6 +2006,20 @@ async function materializeRetainedScreenshotHistory(input) {
2005
2006
  }
2006
2007
  async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
2007
2008
  const now = input.now ?? /* @__PURE__ */ new Date();
2009
+ const receiptForMarker = async (marker, callId) => {
2010
+ if (!isRetainedImageMarker(marker)) return null;
2011
+ const receipt = retainedReceipt(marker.artifact);
2012
+ if (receipt) return receipt;
2013
+ if (!callId) throw new Error("Retained screenshot receipt has no tool call identity");
2014
+ const artifact = await getRetainedScreenshotArtifactForToolCall(
2015
+ input.db,
2016
+ input.workspaceId,
2017
+ input.sessionId,
2018
+ callId
2019
+ );
2020
+ if (!artifact) throw new Error("Retained screenshot receipt cannot be recovered");
2021
+ return reference(artifact);
2022
+ };
2008
2023
  const dataUrlForReceipt = async (receipt) => {
2009
2024
  let dataUrl = cache.get(receipt.artifactId);
2010
2025
  if (!dataUrl) {
@@ -2045,15 +2060,17 @@ async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
2045
2060
  }
2046
2061
  return dataUrl;
2047
2062
  };
2048
- const materializeEntry = async (entry) => {
2049
- const receipt = retainedReceiptFromImageContent(entry);
2063
+ const materializeEntry = async (entry, callId) => {
2064
+ const image = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.image : null;
2065
+ const receipt = await receiptForMarker(image, callId);
2050
2066
  if (!receipt) return entry;
2051
2067
  const dataUrl = await dataUrlForReceipt(receipt);
2052
2068
  return { ...entry, image: dataUrl };
2053
2069
  };
2054
2070
  const materialized = [];
2055
2071
  for (const item of input.history) {
2056
- const directReceipt = retainedReceiptFromDirectOutput(item.output);
2072
+ const callId = historyCallId(item);
2073
+ const directReceipt = await receiptForMarker(item.output, callId);
2057
2074
  if (directReceipt) {
2058
2075
  materialized.push({
2059
2076
  ...item,
@@ -2070,7 +2087,7 @@ async function materializeRetainedScreenshotHistoryWithCache(input, cache) {
2070
2087
  let changed = false;
2071
2088
  const output = [];
2072
2089
  for (const entry of outputEntries) {
2073
- const next = await materializeEntry(entry);
2090
+ const next = await materializeEntry(entry, callId);
2074
2091
  changed ||= next !== entry;
2075
2092
  output.push(next);
2076
2093
  }
@@ -2166,6 +2183,11 @@ function retainedReceiptFromImageContent(entry) {
2166
2183
  if (marker.type !== RETAINED_IMAGE_MARKER) return null;
2167
2184
  return retainedReceipt(marker.artifact);
2168
2185
  }
2186
+ function isRetainedImageMarker(value) {
2187
+ return Boolean(
2188
+ value && typeof value === "object" && !Array.isArray(value) && value.type === RETAINED_IMAGE_MARKER
2189
+ );
2190
+ }
2169
2191
  function retainedReceiptFromDirectOutput(output) {
2170
2192
  if (!output || typeof output !== "object" || Array.isArray(output)) return null;
2171
2193
  const marker = output;
@@ -5110,7 +5132,8 @@ import {
5110
5132
  } from "@opengeni/db";
5111
5133
  import { publishDurableSessionEvents as publishDurableSessionEvents2 } from "@opengeni/events";
5112
5134
  import { maxTurnsExceededRunState } from "@opengeni/runtime";
5113
- import { CancelledFailure } from "@temporalio/activity";
5135
+ import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
5136
+ import { TurnExecutionPolicyDefinitionMismatchError } from "@opengeni/config";
5114
5137
  import {
5115
5138
  classifyCodexEncryptedArtifactRejection,
5116
5139
  classifyCodexUsageLimitError,
@@ -6853,10 +6876,11 @@ async function settleTurnFailure(deps) {
6853
6876
  return claimedResult({ status: "recovering" });
6854
6877
  }
6855
6878
  }
6856
- let failure = agentRunFailurePayload(error51, {
6879
+ const earlyDefinitionMismatch = error51 instanceof TurnExecutionPolicyDefinitionMismatchError && !attempt.modelRequestStarted && !eventing.turnStartedPublished && !!attempt.turnId && !!attempt.triggerEventId && attempt.executionGeneration > 0;
6880
+ let failure = earlyDefinitionMismatch ? { error: error51.message, code: error51.code, retryable: true } : agentRunFailurePayload(error51, {
6857
6881
  isCodexTurn: billingState.isCodexTurn
6858
6882
  });
6859
- if (failure.retryable && eventing.publish && attempt.turnId && eventing.turnStartedPublished) {
6883
+ if (attempt.turnId && (earlyDefinitionMismatch || failure.retryable && eventing.publish && eventing.turnStartedPublished)) {
6860
6884
  const nextProviderRecoveryCount = attempt.providerRecoveryCount + 1;
6861
6885
  const recoveryResult = providerRecoveryResult({
6862
6886
  failureCode: failure.code,
@@ -6865,8 +6889,10 @@ async function settleTurnFailure(deps) {
6865
6889
  });
6866
6890
  try {
6867
6891
  if (recoveryResult.status === "recovering") {
6868
- await flushRuntimeBatcher();
6869
- await historySink.reconcileConversationTruth({ requireDurable: true });
6892
+ if (!earlyDefinitionMismatch) {
6893
+ await flushRuntimeBatcher();
6894
+ await historySink.reconcileConversationTruth({ requireDurable: true });
6895
+ }
6870
6896
  const recovery = await requestSessionTurnRecovery(db, input.workspaceId, {
6871
6897
  sessionId: input.sessionId,
6872
6898
  turnId: attempt.turnId,
@@ -6894,6 +6920,16 @@ async function settleTurnFailure(deps) {
6894
6920
  return claimedResult(recoveryResult);
6895
6921
  }
6896
6922
  failure = providerRecoveryExhaustedFailure(failure, recoveryResult);
6923
+ if (earlyDefinitionMismatch) {
6924
+ control.activityStatus = "failed";
6925
+ control.turnMetricOutcome = "failed";
6926
+ control.activityError = error51;
6927
+ throw ApplicationFailure.create({
6928
+ message: `${error51.message}. Automatic same-turn configuration recovery exhausted after ${recoveryResult.providerRecoveryCount} retries.`,
6929
+ type: "TurnExecutionPolicyDefinitionMismatchError",
6930
+ nonRetryable: true
6931
+ });
6932
+ }
6897
6933
  } catch (recoveryError) {
6898
6934
  const escaped = recoveryResult.status === "recovering" ? escapedMcpTimeoutRecoveryFailure({
6899
6935
  failureCode: failure.code,
@@ -6994,6 +7030,7 @@ import { publishDurableSessionEvents as publishDurableSessionEvents3 } from "@op
6994
7030
  import {
6995
7031
  normalizeModelCallUsage as normalizeModelCallUsage2,
6996
7032
  normalizeSdkEvent,
7033
+ withMcpToolDisplayMetadata,
6997
7034
  extractOpenSuffixFromRunState,
6998
7035
  assertOpenSuffixResumable,
6999
7036
  interruptionKindForCallItem,
@@ -8824,6 +8861,11 @@ async function runTurnStreamAttempt(deps) {
8824
8861
  } : {}
8825
8862
  );
8826
8863
  for (const event of normalized) {
8864
+ if (event.type === "agent.toolCall.created")
8865
+ event.payload = withMcpToolDisplayMetadata(
8866
+ eventing.preparedTools?.mcpServers ?? [],
8867
+ event.payload
8868
+ );
8827
8869
  streamTiming.onEvent(event.type);
8828
8870
  await eventing.batcher.push(event);
8829
8871
  }
@@ -9113,7 +9155,14 @@ async function runTurnStreamAttempt(deps) {
9113
9155
  ...approvals.length > 0 ? [
9114
9156
  {
9115
9157
  type: "session.requiresAction",
9116
- payload: { approvals }
9158
+ payload: {
9159
+ approvals: approvals.map(
9160
+ (approval) => withMcpToolDisplayMetadata(
9161
+ eventing.preparedTools?.mcpServers ?? [],
9162
+ approval
9163
+ )
9164
+ )
9165
+ }
9117
9166
  }
9118
9167
  ] : [],
9119
9168
  {
@@ -9407,6 +9456,7 @@ import { appendAndPublishTurnEventsFenced as appendAndPublishTurnEventsFenced2,
9407
9456
  import { linkCurrentSpanToAdmission, turnExecutionTelemetryKey } from "@opengeni/observability";
9408
9457
  import {
9409
9458
  assertTurnExecutionPolicyMatchesConfigV1,
9459
+ settingsForAcceptedSubscriptionTurn,
9410
9460
  resolveTurnExecutionPolicyV1 as resolveTurnExecutionPolicyV12
9411
9461
  } from "@opengeni/config";
9412
9462
 
@@ -9730,7 +9780,7 @@ async function claimTurnAttempt(deps) {
9730
9780
  gatewaySettings,
9731
9781
  claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model
9732
9782
  );
9733
- const capabilitySettings = await settingsWithOrganizationProviderCredentials(
9783
+ let capabilitySettings = await settingsWithOrganizationProviderCredentials(
9734
9784
  db,
9735
9785
  input.accountId,
9736
9786
  input.workspaceId,
@@ -9738,7 +9788,6 @@ async function claimTurnAttempt(deps) {
9738
9788
  claimedPolicy.kind === "valid" ? claimedPolicy.policy.productModelId : turn.model
9739
9789
  );
9740
9790
  const codexAppsCredentialId = capabilitySettings.codexConnectedAppsEnabled ? await resolveCodexAppsCredentialIdForRun(db, input.workspaceId) : null;
9741
- runtime.configure(capabilitySettings);
9742
9791
  const policyForAbsent = claimedPolicy.kind === "valid" ? claimedPolicy.policy : resolveTurnExecutionPolicyV12(capabilitySettings, legacyTurnExecutionPolicyInput(turn));
9743
9792
  const installedPolicy = await installOrReadTurnExecutionPolicyForAttempt(db, {
9744
9793
  accountId: input.accountId,
@@ -9752,6 +9801,16 @@ async function claimTurnAttempt(deps) {
9752
9801
  if (!installedPolicy.accepted) {
9753
9802
  throw new TurnAttemptFencedError(`turn execution policy was fenced: ${installedPolicy.reason}`);
9754
9803
  }
9804
+ capabilitySettings = settingsForAcceptedSubscriptionTurn(
9805
+ capabilitySettings,
9806
+ installedPolicy.policy,
9807
+ {
9808
+ modelId: turn.model,
9809
+ reasoningEffort: turn.reasoningEffort,
9810
+ latencyMode: turn.latencyMode
9811
+ }
9812
+ );
9813
+ runtime.configure(capabilitySettings);
9755
9814
  const verifiedExecutionPolicy = assertTurnExecutionPolicyMatchesConfigV1(
9756
9815
  capabilitySettings,
9757
9816
  installedPolicy.policy,
@@ -11981,7 +12040,7 @@ async function runPostAgentCompaction(deps) {
11981
12040
  import {
11982
12041
  advanceWorkspaceGeneration,
11983
12042
  verifyWorkspaceMutationSettlement,
11984
- heartbeatLeaseHolder,
12043
+ heartbeatLeaseHolderStatus,
11985
12044
  readLease as readLease2,
11986
12045
  accrueWarmSeconds,
11987
12046
  SandboxWorkspaceMutationFencedError
@@ -12289,21 +12348,29 @@ function createSandboxTurnRuntime(deps) {
12289
12348
  const heartbeatEpoch = sandbox.leaseEpoch;
12290
12349
  const heartbeatHolderId = sandboxState.sandboxHolderId;
12291
12350
  const heartbeatGroupId = sandboxState.sandboxGroupId;
12292
- const warmRate = sandboxWarmRateMicrosPerSecond(
12351
+ const warmRate = settings.sandboxWarmBillingMode === "usage_only" ? 0 : sandboxWarmRateMicrosPerSecond(
12293
12352
  settings,
12294
12353
  warmBackend ?? sandbox.established.backendId
12295
12354
  );
12296
12355
  sandboxState.leaseHeartbeatTimer = setInterval(() => {
12297
- void heartbeatLeaseHolder(db, {
12356
+ void heartbeatLeaseHolderStatus(db, {
12298
12357
  accountId: input.accountId,
12299
12358
  workspaceId: input.workspaceId,
12300
12359
  sandboxGroupId: heartbeatGroupId,
12301
12360
  kind: "turn",
12302
12361
  holderId: heartbeatHolderId,
12303
12362
  leaseTtlMs: settings.sandboxLeaseTtlMs,
12304
- expectedEpoch: heartbeatEpoch
12305
- }).then(async (alive) => {
12306
- if (alive) return;
12363
+ expectedEpoch: heartbeatEpoch,
12364
+ billingMode: settings.sandboxWarmBillingMode
12365
+ }).then(async (status) => {
12366
+ if (status.fence === "funding") {
12367
+ stopLeaseHeartbeat();
12368
+ sandboxRotationController.abort(
12369
+ new Error("Insufficient OpenGeni credits to extend paid sandbox compute")
12370
+ );
12371
+ return;
12372
+ }
12373
+ if (status.leaseExtended) return;
12307
12374
  const rotation = await beginRotationPreemption(sandbox, heartbeatEpoch, heartbeatGroupId);
12308
12375
  if (rotation === "not_rotating") {
12309
12376
  stopLeaseHeartbeat();
@@ -12315,8 +12382,13 @@ function createSandboxTurnRuntime(deps) {
12315
12382
  sandboxGroupId: heartbeatGroupId,
12316
12383
  expectedEpoch: heartbeatEpoch,
12317
12384
  warmRateMicrosPerSecond: warmRate,
12385
+ billingMode: settings.sandboxWarmBillingMode,
12318
12386
  subjectId: input.sessionId
12319
- }).then((result) => recordCreditMicros(observability, "usage", result.costMicros)).catch(() => void 0);
12387
+ }).then((result) => {
12388
+ if (settings.sandboxWarmBillingMode === "credits") {
12389
+ recordCreditMicros(observability, "usage", result.costMicros);
12390
+ }
12391
+ }).catch(() => void 0);
12320
12392
  const snapshotSession = sandboxState.setupBoxSession;
12321
12393
  const snapshotTurnId = attempt.turnId;
12322
12394
  if (snapshotSession && snapshotTurnId && shouldStartPeriodicWorkspaceSnapshot({
@@ -14684,7 +14756,8 @@ import {
14684
14756
  } from "@opengeni/db";
14685
14757
  import { publishDurableSessionEvents as publishDurableSessionEvents9 } from "@opengeni/events";
14686
14758
  import {
14687
- createFirstPartyInteractionAttemptToolDefinitions
14759
+ createFirstPartyInteractionAttemptToolDefinitions,
14760
+ mcpToolDisplayMetadata
14688
14761
  } from "@opengeni/runtime";
14689
14762
 
14690
14763
  // src/activities/google-drive-publication.ts
@@ -30932,13 +31005,14 @@ import {
30932
31005
  publishDurableSessionEvents as publishDurableSessionEvents8
30933
31006
  } from "@opengeni/events";
30934
31007
  var CodemodeAttemptDispatcher = class {
30935
- constructor(db, bus, environment, scope, turnSignal, maxConcurrentCalls = CODEMODE_MAX_CONCURRENT_CALLS_PER_ATTEMPT, timings = {}) {
31008
+ constructor(db, bus, environment, scope, turnSignal, maxConcurrentCalls = CODEMODE_MAX_CONCURRENT_CALLS_PER_ATTEMPT, timings = {}, toolDisplayMetadata) {
30936
31009
  this.db = db;
30937
31010
  this.bus = bus;
30938
31011
  this.environment = environment;
30939
31012
  this.scope = scope;
30940
31013
  this.turnSignal = turnSignal;
30941
31014
  this.maxConcurrentCalls = maxConcurrentCalls;
31015
+ this.toolDisplayMetadata = toolDisplayMetadata;
30942
31016
  if (environment.catalog.accountId !== scope.accountId || environment.catalog.workspaceId !== scope.workspaceId || environment.catalog.sessionId !== scope.sessionId || environment.catalog.turnId !== scope.turnId || environment.catalog.attemptId !== scope.attemptId || environment.catalog.executionGeneration !== scope.executionGeneration) {
30943
31017
  throw new Error("Codemode dispatcher scope does not match its tool environment");
30944
31018
  }
@@ -31196,6 +31270,10 @@ var CodemodeAttemptDispatcher = class {
31196
31270
  payload: {
31197
31271
  id: operation.operationId,
31198
31272
  name: entry.modelName,
31273
+ display: this.toolDisplayMetadata?.(entry.modelName) ?? {
31274
+ toolName: entry.identity.toolName,
31275
+ ...entry.title ? { title: entry.title } : {}
31276
+ },
31199
31277
  arguments: operation.arguments,
31200
31278
  origin: "codemode",
31201
31279
  subjectId: operation.caller.subjectId,
@@ -32957,7 +33035,10 @@ async function prepareTurnToolRuntime(deps) {
32957
33035
  attemptId: input.attemptId,
32958
33036
  executionGeneration: attempt.executionGeneration
32959
33037
  },
32960
- cancellationSignal
33038
+ cancellationSignal,
33039
+ void 0,
33040
+ {},
33041
+ (name) => mcpToolDisplayMetadata(tools.mcpServers, name)
32961
33042
  );
32962
33043
  eventing.codemodeDispatcher.start();
32963
33044
  };
@@ -32973,6 +33054,7 @@ async function prepareTurnToolRuntime(deps) {
32973
33054
  return {
32974
33055
  attemptConnectorActionBindings,
32975
33056
  connectorActionPolicy,
33057
+ mcpServers: runSettings.mcpServers,
32976
33058
  generateSessionTitleInParallel: titleToolPlan.generateTitleInParallel,
32977
33059
  postToolPreparationStartedAt,
32978
33060
  preparationIndependentToolNames: [
@@ -34348,6 +34430,7 @@ async function resolveVideoReferenceSandboxAccess(request, sandboxState, sdkOwne
34348
34430
  // src/activities/agent-turn/agent-build.ts
34349
34431
  async function buildTurnAgent(deps) {
34350
34432
  const {
34433
+ mcpServers,
34351
34434
  input,
34352
34435
  db,
34353
34436
  runtime,
@@ -34765,7 +34848,7 @@ async function buildTurnAgent(deps) {
34765
34848
  const agentConstructionStartedAt = performance.now();
34766
34849
  let agentConstructionOutcome = "completed";
34767
34850
  try {
34768
- return runtime.buildAgent(eventing.modelRunSettings, runtimeResources, {
34851
+ return runtime.buildAgent({ ...eventing.modelRunSettings, mcpServers }, runtimeResources, {
34769
34852
  ...linkedToolAuthority ? {
34770
34853
  authorizeAttemptExecution: async () => {
34771
34854
  const current = await getSessionTurnForAttempt2(
@@ -35942,6 +36025,7 @@ These are publication receipts for the human's earlier answer. Do not call the r
35942
36025
  } = toolRuntime;
35943
36026
  const builtAgent = await buildTurnAgent({
35944
36027
  skillCatalog: toolRuntime.skillCatalog,
36028
+ mcpServers: toolRuntime.mcpServers,
35945
36029
  input,
35946
36030
  db,
35947
36031
  runtime,
@@ -37498,4 +37582,4 @@ export {
37498
37582
  createTurnActivities,
37499
37583
  createTurnActivitiesFromServices
37500
37584
  };
37501
- //# sourceMappingURL=activities-turn-2B3WMHBB.js.map
37585
+ //# sourceMappingURL=activities-turn-KBLXHBWS.js.map