deepline 0.3.200 → 0.3.202

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 (43) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +62 -1
  2. package/dist/bundling-sources/sdk/src/http.ts +55 -6
  3. package/dist/bundling-sources/sdk/src/index.ts +1 -0
  4. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  5. package/dist/bundling-sources/sdk/src/types.ts +10 -2
  6. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +4 -2
  7. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +460 -96
  8. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +11 -1
  9. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-invocation-fence.ts +6 -2
  10. package/dist/bundling-sources/shared_libs/play-runtime/fixture-behavior.ts +401 -2
  11. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +458 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/provider-no-progress.ts +40 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +7 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +25 -3
  15. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +1 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +119 -171
  17. package/dist/bundling-sources/shared_libs/play-runtime/runtime-work-counters.ts +37 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-deadline-reconciliation.ts +160 -58
  19. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +111 -6
  20. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd.ts +51 -46
  21. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +16 -7
  22. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +304 -33
  23. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +21 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-value-storage.ts +64 -15
  25. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-sandbox-capacity.ts +133 -5
  26. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +5 -5
  27. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +1 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/result-receipt-policy.ts +46 -0
  29. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +14 -5
  30. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +5 -1
  31. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +3 -9
  32. package/dist/cli/index.js +364 -39
  33. package/dist/cli/index.mjs +367 -41
  34. package/dist/index.d.mts +131 -3
  35. package/dist/index.d.ts +131 -3
  36. package/dist/index.js +64 -7
  37. package/dist/index.mjs +64 -7
  38. package/dist/install-integrity.json +3 -0
  39. package/dist/release.d.mts +1 -1
  40. package/dist/release.d.ts +1 -1
  41. package/dist/release.js +1 -1
  42. package/dist/release.mjs +1 -1
  43. package/package.json +1 -1
@@ -64,6 +64,7 @@ function schemaTables(options?: Pick<PostgresSchedulerOptions, 'schema'>) {
64
64
  leases: `${schema}."runtime_sandbox_capacity_leases"`,
65
65
  operations: `${schema}."runtime_sandbox_operations"`,
66
66
  cleanup: `${schema}."sandbox_cleanup_jobs_v2"`,
67
+ runs: `${schema}."runs"`,
67
68
  };
68
69
  }
69
70
 
@@ -266,7 +267,7 @@ export async function reserveRuntimeSandboxCapacityLease(
266
267
  > {
267
268
  const orgId = assertId(input.orgId, 'orgId');
268
269
  const runId = assertId(input.runId, 'runId');
269
- const { cache, leases, operations } = schemaTables(options);
270
+ const { cache, leases, operations, runs } = schemaTables(options);
270
271
  // This is deliberately a soft admission check: concurrent workers may both
271
272
  // observe space and insert. Avoid locks and long transactions; the provider
272
273
  // has its own global safety cap and the 50-minute lease bounds crashes.
@@ -469,13 +470,21 @@ export async function reserveRuntimeSandboxCapacityLease(
469
470
  }
470
471
  await client.query(
471
472
  `
472
- WITH reserved_lease AS (
473
+ WITH active_run AS MATERIALIZED (
474
+ SELECT run_id FROM ${runs}
475
+ WHERE run_id = $3 AND status IN ('queued', 'running', 'waiting')
476
+ AND NOT EXISTS (
477
+ SELECT 1 FROM ${quoteIdent(options?.schema ?? 'runtime_scheduler')}."control"
478
+ WHERE key = 'runtime_cancel:' || $3::text
479
+ )
480
+ FOR UPDATE
481
+ ), reserved_lease AS (
473
482
  INSERT INTO ${leases} (
474
483
  lease_id, org_id, run_id, provider, expires_at
475
- ) VALUES (
476
- $1, $2, $3, $4,
477
- clock_timestamp() + ($5::integer * interval '1 millisecond')
478
484
  )
485
+ SELECT $1, $2, $3, $4,
486
+ clock_timestamp() + ($5::integer * interval '1 millisecond')
487
+ WHERE $6::integer IS NULL OR EXISTS (SELECT 1 FROM active_run)
479
488
  ON CONFLICT (lease_id) DO NOTHING
480
489
  RETURNING lease_id
481
490
  )
@@ -726,6 +735,125 @@ export async function abandonRuntimeSandboxOperationReservation(
726
735
  return result.rows.length === 1;
727
736
  }
728
737
 
738
+ export async function readReservedDaytonaCancellationOperation(
739
+ client: PostgresSchedulerQueryClient,
740
+ environment: 'preview' | 'production',
741
+ options?: Pick<PostgresSchedulerOptions, 'schema'>,
742
+ ): Promise<{
743
+ operationKey: string;
744
+ providerOperationToken: string;
745
+ createdAtMs: number;
746
+ } | null> {
747
+ const { operations } = schemaTables(options);
748
+ const schema = quoteIdent(options?.schema ?? 'runtime_scheduler');
749
+ const rows = await client.query<{
750
+ operation_key: string;
751
+ provider_operation_token: string | null;
752
+ created_at_ms: number;
753
+ }>(
754
+ `WITH candidate AS (
755
+ SELECT operation.operation_key
756
+ FROM ${operations} AS operation
757
+ JOIN ${schema}."control" AS request
758
+ ON request.key = 'runtime_cancel:' || operation.run_id
759
+ WHERE operation.provider = 'daytona'
760
+ AND operation.environment = $1
761
+ AND operation.state = 'reserved'
762
+ ORDER BY operation.updated_at ASC, operation.operation_key ASC
763
+ LIMIT 1
764
+ FOR UPDATE OF operation SKIP LOCKED
765
+ )
766
+ UPDATE ${operations} AS operation
767
+ SET updated_at = clock_timestamp()
768
+ FROM candidate
769
+ WHERE operation.operation_key = candidate.operation_key
770
+ RETURNING operation.operation_key, operation.provider_operation_token,
771
+ floor(extract(epoch FROM operation.created_at) * 1000)::bigint AS created_at_ms`,
772
+ [environment],
773
+ );
774
+ const row = rows.rows[0];
775
+ if (!row) return null;
776
+ if (!row.provider_operation_token) {
777
+ throw new Error(
778
+ `Reserved Daytona cancellation operation ${row.operation_key} lacks its provider token.`,
779
+ );
780
+ }
781
+ return {
782
+ operationKey: row.operation_key,
783
+ providerOperationToken: row.provider_operation_token,
784
+ createdAtMs: Number(row.created_at_ms),
785
+ };
786
+ }
787
+
788
+ export async function recordRecoveredDaytonaCancellationSandbox(
789
+ client: PostgresSchedulerQueryClient,
790
+ input: { operationKey: string; sandboxId: string; routingDomain: string },
791
+ options?: Pick<PostgresSchedulerOptions, 'schema'>,
792
+ ): Promise<boolean> {
793
+ const { operations, leases, cleanup } = schemaTables(options);
794
+ const schema = quoteIdent(options?.schema ?? 'runtime_scheduler');
795
+ const recorded = await client.query<{ operation_key: string }>(
796
+ `WITH promoted AS (
797
+ UPDATE ${operations} AS operation
798
+ SET state = 'deleting',
799
+ sandbox_id = $2,
800
+ routing_domain = $3,
801
+ provider_created_at = clock_timestamp(),
802
+ updated_at = clock_timestamp()
803
+ WHERE operation.operation_key = $1
804
+ AND operation.provider = 'daytona'
805
+ AND operation.state = 'reserved'
806
+ RETURNING operation.operation_key, operation.run_id, operation.attempt,
807
+ operation.environment, operation.created_at
808
+ ), resource AS (
809
+ SELECT promoted.*,
810
+ jsonb_build_object(
811
+ 'kind', 'daytona_sandbox',
812
+ 'sandboxId', $2::text,
813
+ 'runtimeEnvironment', promoted.environment,
814
+ 'daytonaOrganizationId', $3::text,
815
+ 'billingStartedAt', extract(epoch FROM promoted.created_at) * 1000,
816
+ 'sandboxCapacityLeaseId', promoted.operation_key,
817
+ 'lateAcquired', true
818
+ ) AS value
819
+ FROM promoted
820
+ ), recorded_attempt AS (
821
+ UPDATE ${schema}."attempts" AS attempt
822
+ SET resource_json = CASE
823
+ WHEN attempt.resource_json IS NULL THEN jsonb_build_array(resource.value)
824
+ WHEN jsonb_typeof(attempt.resource_json) = 'array'
825
+ THEN attempt.resource_json || jsonb_build_array(resource.value)
826
+ ELSE jsonb_build_array(attempt.resource_json, resource.value)
827
+ END,
828
+ updated_at = clock_timestamp()
829
+ FROM resource
830
+ WHERE attempt.run_id = resource.run_id
831
+ AND attempt.attempt = resource.attempt
832
+ RETURNING attempt.run_id
833
+ ), bound AS (
834
+ UPDATE ${leases} AS lease
835
+ SET sandbox_id = $2, routing_domain = $3
836
+ FROM promoted
837
+ WHERE lease.lease_id = promoted.operation_key
838
+ AND lease.released_at IS NULL
839
+ RETURNING lease.lease_id
840
+ ), queued AS (
841
+ INSERT INTO ${cleanup} (
842
+ provider, sandbox_id, run_id, attempt, environment, routing_domain
843
+ )
844
+ SELECT 'daytona', $2, promoted.run_id, promoted.attempt,
845
+ promoted.environment, $3
846
+ FROM promoted
847
+ ON CONFLICT (provider, sandbox_id, routing_domain_key) DO NOTHING
848
+ )
849
+ SELECT promoted.operation_key FROM promoted
850
+ JOIN recorded_attempt ON recorded_attempt.run_id = promoted.run_id
851
+ JOIN bound ON bound.lease_id = promoted.operation_key`,
852
+ [input.operationKey, input.sandboxId, input.routingDomain],
853
+ );
854
+ return recorded.rows.length === 1;
855
+ }
856
+
729
857
  /** Release only after the provider confirms deletion (or already absent). */
730
858
  export async function releaseRuntimeSandboxCapacityLeaseForSandbox(
731
859
  client: PostgresSchedulerQueryClient,
@@ -41,11 +41,11 @@ export function releasableRuntimeSheetAttemptFenceSql(
41
41
  }
42
42
 
43
43
  /**
44
- * Predicate for durable replay idempotency: matches rows that are already
45
- * terminal (enriched or failed) from the same attempt owner + epoch. Used to
46
- * suppress same-version conflicts when a worker restarts and re-runs map rows
47
- * that it already completed. First terminal state wins; payload/error drift on
48
- * replay is accepted as a no-op rather than rejected as a conflict.
44
+ * Predicate for callers that need to identify a terminal row from the same
45
+ * attempt owner + epoch. Runtime map persistence now enforces first-terminal
46
+ * idempotency inline because its write-version and row-key context are also
47
+ * required; keep this helper exported for compatibility with external
48
+ * conformance checks and integrations.
49
49
  */
50
50
  export function sameOwnerTerminalAttemptEpochSql(
51
51
  tableAlias: string,
@@ -35,6 +35,7 @@ export {
35
35
  type AlwaysFreshToolCall,
36
36
  type AlwaysFreshToolCallInput,
37
37
  } from './always-fresh-adapter';
38
+ export { resolveToolCallResultReceiptPolicy } from './result-receipt-policy';
38
39
 
39
40
  export type {
40
41
  ToolCallCompatibilityIdentity,
@@ -0,0 +1,46 @@
1
+ import { scopeToolReceiptToInvocation } from '../durable-call-cache';
2
+
3
+ /**
4
+ * Freshness chooses which completed results a run may reuse. It never turns
5
+ * off durable progress inside that run. A forced invocation gets an immutable
6
+ * result of its own; a scheduler retry reads it like any other completed key.
7
+ *
8
+ * The canonical key already binds payload, authorization, action and response
9
+ * semantics. Keep it in the derivation so a changed input cannot recover an
10
+ * unrelated result. Provider operation identities and public receipt metadata
11
+ * remain canonical and are deliberately outside this storage policy.
12
+ */
13
+ export function resolveToolCallResultReceiptPolicy(input: {
14
+ orgId?: string | null;
15
+ toolId: string;
16
+ resultReceiptKey: string;
17
+ runId: string;
18
+ logicalCallId: string;
19
+ force: boolean;
20
+ /** Historical local contexts may have no durable result store. */
21
+ canStoreResult?: boolean;
22
+ }): { resultReceiptKey: string; force: boolean } {
23
+ if (!input.resultReceiptKey.trim()) {
24
+ throw new Error('Tool Call result policy requires a result receipt key.');
25
+ }
26
+ if (!input.force) {
27
+ return { resultReceiptKey: input.resultReceiptKey, force: false };
28
+ }
29
+ if (input.canStoreResult === false) {
30
+ return { resultReceiptKey: input.resultReceiptKey, force: true };
31
+ }
32
+ if (!input.runId.trim() || !input.logicalCallId.trim()) {
33
+ throw new Error(
34
+ 'Forced Tool Call requires stable run and call identities.',
35
+ );
36
+ }
37
+ return {
38
+ resultReceiptKey: scopeToolReceiptToInvocation({
39
+ orgId: input.orgId,
40
+ toolId: input.toolId,
41
+ receiptKey: input.resultReceiptKey,
42
+ invocationIdentity: `forced-result:${input.runId}:${input.logicalCallId}`,
43
+ }),
44
+ force: false,
45
+ };
46
+ }
@@ -425,20 +425,29 @@ export function createToolExecuteHttpFailureAttemptTracker(): ToolExecuteHttpFai
425
425
  };
426
426
  }
427
427
 
428
- export function parseToolExecuteRetryAfterMs(
428
+ // Keep expired absolute deadlines intact: durable response replay must not
429
+ // turn old provider feedback into a new AIMD throttle episode.
430
+ export function parseToolExecuteRetryAtMs(
429
431
  header: string | null | undefined,
430
432
  nowMs = Date.now(),
431
433
  ): number {
432
- if (!header) return TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
434
+ if (!header) return nowMs + TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
433
435
  const seconds = Number(header);
434
436
  if (Number.isFinite(seconds) && seconds >= 0) {
435
- return Math.ceil(seconds * 1000);
437
+ return nowMs + Math.ceil(seconds * 1000);
436
438
  }
437
439
  const retryAt = Date.parse(header);
438
440
  if (Number.isFinite(retryAt)) {
439
- return Math.max(0, retryAt - nowMs);
441
+ return retryAt;
440
442
  }
441
- return TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
443
+ return nowMs + TOOL_EXECUTE_RETRY_DELAY_FALLBACK_MS;
444
+ }
445
+
446
+ export function parseToolExecuteRetryAfterMs(
447
+ header: string | null | undefined,
448
+ nowMs = Date.now(),
449
+ ): number {
450
+ return Math.max(0, parseToolExecuteRetryAtMs(header, nowMs) - nowMs);
442
451
  }
443
452
 
444
453
  export function classifyToolExecuteHttpFailure(input: {
@@ -265,7 +265,11 @@ function receiptFailureKindForToolErrorPayload(
265
265
  // A credential connection can be added or replaced between play runs. Keep
266
266
  // the failure terminal within its owning run, but let a later run reclaim
267
267
  // the durable receipt instead of replaying stale authorization state.
268
- return code === 'INTEGRATION_CREDENTIALS_MISSING' ? 'repairable' : 'terminal';
268
+ if (code === 'INTEGRATION_CREDENTIALS_MISSING') return 'repairable';
269
+ // Managed AI has billing evidence for completed model steps, but no stored
270
+ // responses from which to resume the later rate-limited step. Its 409 stops
271
+ // automatic replay; an explicit later run may intentionally repeat work.
272
+ return code === 'UPSTREAM_PARTIAL_EXECUTION' ? 'repairable' : 'terminal';
269
273
  }
270
274
 
271
275
  function formatHardBillingFailureMessage(input: {
@@ -246,17 +246,11 @@ export function decideWorkReceiptClaim(input: {
246
246
  const sameLogicalRun =
247
247
  normalize(input.claimantRunId) !== null &&
248
248
  normalize(input.claimantRunId) === normalize(input.receipt.runId);
249
- const sameRunNewerLeaseAttempt =
250
- state.reusable &&
251
- state.lease.kind === 'active' &&
252
- state.lease.ownerRunId === normalize(input.claimantRunId) &&
253
- state.lease.ownerAttempt < normalizeAttempt(input.claimantRunAttempt);
254
249
  // Force refresh means new intent across runs. Within one run it is a replay,
255
250
  // so reuse terminal output instead of creating a second terminal payload
256
- // under the run's existing Runtime Sheet write version. A newer lease
257
- // generation is the exception: it is a new attempt and retains the existing
258
- // stale-owner fence semantics.
259
- if (state.reusable && sameLogicalRun && !sameRunNewerLeaseAttempt) {
251
+ // under the run's existing Runtime Sheet write version. A scheduler resume
252
+ // increases the attempt number but does not create another refresh intent.
253
+ if (state.reusable && sameLogicalRun) {
260
254
  return { kind: 'reuse_terminal' };
261
255
  }
262
256
  if (state.reusable && input.forceRefresh !== true) {