@opengeni/worker-bundle 2.0.3 → 2.1.0-canary.36239117573001
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/agent-turn/agent-build.d.ts +2 -0
- package/dist/activities/agent-turn/code-search.d.ts +60 -0
- package/dist/activities/agent-turn/codex-capacity.d.ts +13 -0
- package/dist/activities/agent-turn/errors.d.ts +12 -1
- package/dist/activities/agent-turn/governance-model.d.ts +2 -0
- package/dist/activities/agent-turn/session-title.d.ts +32 -2
- package/dist/activities/agent-turn/tool-environment.d.ts +4 -0
- package/dist/activities/context-compaction.d.ts +10 -2
- package/dist/activities/knowledge-indexing.d.ts +19 -0
- package/dist/{activities-control-IVTL723D.js → activities-control-I72CRMAE.js} +81 -14
- package/dist/activities-control-I72CRMAE.js.map +1 -0
- package/dist/{activities-turn-EZEDZTEZ.js → activities-turn-CSDKK4N3.js} +425 -46
- package/dist/activities-turn-CSDKK4N3.js.map +1 -0
- package/dist/artifact-outbox-entry.js +3 -0
- package/dist/artifact-outbox-entry.js.map +1 -1
- package/dist/{chunk-JMO5ZUW3.js → chunk-7M6G2SCF.js} +159 -11
- package/dist/chunk-7M6G2SCF.js.map +1 -0
- package/dist/{chunk-I7HKKMUJ.js → chunk-DSPP6CZL.js} +48 -3
- package/dist/chunk-DSPP6CZL.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/observability-metrics.d.ts +11 -1
- package/dist/sandbox-resume.d.ts +46 -0
- package/dist/workflow-bundle.js +77 -2
- package/dist/workflows/session.d.ts +30 -0
- package/package.json +20 -19
- package/src/activities/agent-turn/agent-build.ts +4 -0
- package/src/activities/agent-turn/code-search.ts +275 -0
- package/src/activities/agent-turn/codex-capacity.ts +37 -2
- package/src/activities/agent-turn/compaction-prep.ts +52 -16
- package/src/activities/agent-turn/errors.ts +59 -1
- package/src/activities/agent-turn/governance-model.ts +17 -1
- package/src/activities/agent-turn/run.ts +4 -0
- package/src/activities/agent-turn/sandbox-establish.ts +12 -1
- package/src/activities/agent-turn/session-title.ts +73 -3
- package/src/activities/agent-turn/stream-attempt.ts +14 -13
- package/src/activities/agent-turn/tool-environment.ts +65 -0
- package/src/activities/context-compaction.ts +49 -14
- package/src/activities/knowledge-indexing.ts +107 -9
- package/src/activities/scheduled-tasks.ts +18 -2
- package/src/activity-services.ts +16 -4
- package/src/editable-artifact-hint-broker.ts +3 -0
- package/src/index.ts +2 -2
- package/src/observability-metrics.ts +70 -1
- package/src/personal-github-git-credentials.ts +2 -0
- package/src/sandbox-resume.ts +205 -5
- package/src/workflows/session.ts +102 -6
- package/dist/activities-control-IVTL723D.js.map +0 -1
- package/dist/activities-turn-EZEDZTEZ.js.map +0 -1
- package/dist/chunk-I7HKKMUJ.js.map +0 -1
- package/dist/chunk-JMO5ZUW3.js.map +0 -1
|
@@ -130,6 +130,9 @@ async function connectEditableArtifactHintBroker(input) {
|
|
|
130
130
|
name,
|
|
131
131
|
reconnect: true,
|
|
132
132
|
maxReconnectAttempts: -1,
|
|
133
|
+
// Same policy as the event bus: a broker or auth-callout restart must not
|
|
134
|
+
// permanently close this connection after two identical auth errors.
|
|
135
|
+
ignoreAuthErrorAbort: true,
|
|
133
136
|
reconnectTimeWait: 2e3,
|
|
134
137
|
reconnectJitter: 1e3,
|
|
135
138
|
reconnectJitterTLS: 1e3,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/editable-artifact-outbox-service.ts","../src/editable-artifact-outbox-dispatcher.ts","../src/editable-artifact-hint-broker.ts","../src/artifact-outbox-entry.ts"],"sourcesContent":["import {\n dbSearchPath,\n getArtifactOutboxSettings,\n resolveNatsControlPlaneAuth,\n type ArtifactOutboxSettings,\n} from \"@opengeni/config\";\nimport type { EditableArtifactOutboxDispatchSummary } from \"@opengeni/core\";\nimport { createObservability, type Observability } from \"@opengeni/observability\";\n\nimport {\n EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV,\n EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE,\n createEditableArtifactOutboxWorker,\n type EditableArtifactOutboxWorkerRuntime,\n} from \"./editable-artifact-outbox-dispatcher\";\nimport type { EditableArtifactHintNatsAuth } from \"./editable-artifact-hint-broker\";\n\nexport type EditableArtifactOutboxServiceState =\n | \"starting\"\n | \"ready\"\n | \"draining\"\n | \"stopped\"\n | \"failed\";\n\nexport interface EditableArtifactOutboxRuntimePort {\n start(): Promise<void>;\n drain(): boolean;\n stop(): Promise<void>;\n check(signal?: AbortSignal): Promise<void>;\n readonly dispatcher: Readonly<{\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n }>;\n}\n\nexport type EditableArtifactOutboxService = Readonly<{\n state(): EditableArtifactOutboxServiceState;\n run(): Promise<void>;\n drain(reason?: string): boolean;\n close(): Promise<void>;\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n fetch(request: Request): Promise<Response>;\n}>;\n\nexport type CreateEditableArtifactOutboxServiceInput = Readonly<{\n runtime: EditableArtifactOutboxRuntimePort;\n observability: Observability;\n serviceName: string;\n environment: string;\n deploymentRevision?: string;\n readinessTimeoutMs?: number;\n}>;\n\nexport type ProductionEditableArtifactOutboxServiceOptions = Readonly<{\n settings: ArtifactOutboxSettings;\n databaseUrl: string;\n declaredDatabaseRole: string;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner: string;\n databasePoolSize?: number;\n batchSize?: number;\n concurrency?: number;\n leaseDurationMs?: number;\n leaseRenewIntervalMs?: number;\n pollIntervalMs?: number;\n publishTimeoutMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n}>;\n\n/** Compose the independently supervised production outbox dispatcher. */\nexport async function createProductionEditableArtifactOutboxService(\n options: ProductionEditableArtifactOutboxServiceOptions,\n): Promise<EditableArtifactOutboxService> {\n if (options.declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"Artifact outbox dispatcher database role declaration is invalid\");\n }\n const observability = createObservability(options.settings, {\n component: \"artifact-outbox-dispatcher\",\n });\n const databaseSearchPath = dbSearchPath(options.settings);\n const runtime = await createEditableArtifactOutboxWorker({\n dispatcherDatabaseUrl: options.databaseUrl,\n ...(databaseSearchPath ? { databaseSearchPath } : {}),\n ...(options.databasePoolSize === undefined\n ? {}\n : { databasePoolSize: options.databasePoolSize }),\n natsUrl: options.natsUrl,\n natsAuth: options.natsAuth,\n owner: options.owner,\n dispatcher: {\n ...(options.batchSize === undefined ? {} : { batchSize: options.batchSize }),\n ...(options.concurrency === undefined ? {} : { concurrency: options.concurrency }),\n ...(options.leaseDurationMs === undefined\n ? {}\n : { leaseDurationMs: options.leaseDurationMs }),\n ...(options.leaseRenewIntervalMs === undefined\n ? {}\n : { leaseRenewIntervalMs: options.leaseRenewIntervalMs }),\n ...(options.pollIntervalMs === undefined ? {} : { pollIntervalMs: options.pollIntervalMs }),\n ...(options.publishTimeoutMs === undefined\n ? {}\n : { publishTimeoutMs: options.publishTimeoutMs }),\n ...(options.retryBaseMs === undefined ? {} : { retryBaseMs: options.retryBaseMs }),\n ...(options.retryMaxMs === undefined ? {} : { retryMaxMs: options.retryMaxMs }),\n },\n metrics: {\n increment(outcome, count = 1) {\n observability.incrementCounter({\n name: \"opengeni_artifact_outbox_dispatch_total\",\n help: \"Editable artifact outbox dispatch actions by closed outcome.\",\n labels: { outcome },\n amount: count,\n });\n },\n observePublishSeconds(outcome, seconds) {\n observability.observeHistogram({\n name: \"opengeni_artifact_outbox_publish_seconds\",\n help: \"Editable artifact broker publication latency by closed outcome.\",\n labels: { outcome },\n value: seconds,\n });\n },\n },\n logger: {\n warn(message, attributes) {\n observability.warn(message, {\n errorClass: \"WorkerOperationError\",\n errorCode: \"worker_operation_failed\",\n origin: \"worker\",\n outcome: typeof attributes.code === \"string\" ? attributes.code : \"unknown\",\n });\n },\n },\n });\n return createEditableArtifactOutboxService({\n runtime,\n observability,\n serviceName: options.settings.serviceName,\n environment: options.settings.environment,\n deploymentRevision: options.settings.deploymentRevision,\n });\n}\n\nexport function createEditableArtifactOutboxService(\n input: CreateEditableArtifactOutboxServiceInput,\n): EditableArtifactOutboxService {\n let state: EditableArtifactOutboxServiceState = \"starting\";\n let runPromise: Promise<void> | null = null;\n let closePromise: Promise<void> | null = null;\n let readinessPromise: Promise<void> | null = null;\n const readinessTimeoutMs = input.readinessTimeoutMs ?? 2_000;\n\n const ready = (): Promise<void> => {\n if (readinessPromise) return readinessPromise;\n const abort = new AbortController();\n const check = withTimeout(input.runtime.check(abort.signal), readinessTimeoutMs, abort);\n readinessPromise = check;\n void check.then(\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n );\n return check;\n };\n\n const run = (): Promise<void> => {\n if (runPromise) return runPromise;\n if (state !== \"starting\") {\n return Promise.reject(new Error(\"Artifact outbox dispatcher service cannot be restarted\"));\n }\n runPromise = (async () => {\n try {\n await ready();\n if ((state as EditableArtifactOutboxServiceState) === \"draining\") {\n state = \"stopped\";\n return;\n }\n const running = input.runtime.start();\n state = \"ready\";\n await running;\n const exitWasDraining = (state as EditableArtifactOutboxServiceState) === \"draining\";\n state = exitWasDraining ? \"stopped\" : \"failed\";\n if (!exitWasDraining) {\n throw new Error(\"Artifact outbox dispatcher exited without a drain request\");\n }\n } catch (error) {\n const caughtState = state as EditableArtifactOutboxServiceState;\n if (caughtState !== \"draining\" && caughtState !== \"stopped\") state = \"failed\";\n throw error;\n }\n })();\n return runPromise;\n };\n\n const drain = (_reason = \"shutdown\"): boolean => {\n if (state === \"draining\" || state === \"stopped\" || state === \"failed\") return false;\n state = \"draining\";\n input.runtime.drain();\n return true;\n };\n\n const close = (): Promise<void> => {\n if (closePromise) return closePromise;\n closePromise = (async () => {\n drain(\"close\");\n if (runPromise) await runPromise.catch(() => undefined);\n await input.runtime.stop();\n if (state !== \"failed\") state = \"stopped\";\n })();\n return closePromise;\n };\n\n const fetch = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n if (request.method !== \"GET\") {\n return Response.json({ error: \"method_not_allowed\" }, { status: 405 });\n }\n if (url.pathname === \"/healthz\") {\n const ok = state !== \"failed\" && state !== \"stopped\";\n return Response.json(\n {\n service: input.serviceName,\n component: \"artifact-outbox-dispatcher\",\n environment: input.environment,\n ...(input.deploymentRevision ? { deploymentRevision: input.deploymentRevision } : {}),\n state,\n ok,\n },\n { status: ok ? 200 : 503 },\n );\n }\n if (url.pathname === \"/readyz\") {\n if (state !== \"ready\") {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n try {\n await ready();\n return Response.json({\n ok: true,\n state,\n checks: { databaseRole: { ok: true }, nats: { ok: true } },\n });\n } catch {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n }\n if (url.pathname === \"/metrics\") {\n return new Response(await input.observability.prometheusMetrics(), {\n status: 200,\n headers: { \"content-type\": \"text/plain; version=0.0.4; charset=utf-8\" },\n });\n }\n return Response.json({ error: \"not_found\" }, { status: 404 });\n };\n\n return Object.freeze({\n state: () => state,\n run,\n drain,\n close,\n dispatchOnce: async () => await input.runtime.dispatcher.dispatchOnce(),\n fetch,\n });\n}\n\nexport type EditableArtifactOutboxSidecarEnvironment = Readonly<{\n databaseUrl: string;\n declaredDatabaseRole: string;\n owner: string;\n httpPort: number;\n databasePoolSize: number;\n batchSize: number;\n concurrency: number;\n leaseDurationMs: number;\n leaseRenewIntervalMs: number;\n pollIntervalMs: number;\n publishTimeoutMs: number;\n retryBaseMs: number;\n retryMaxMs: number;\n}>;\n\nexport function readEditableArtifactOutboxSidecarEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): EditableArtifactOutboxSidecarEnvironment | null {\n if (environment.OPENGENI_ARTIFACT_OUTBOX_ENABLED !== \"true\") return null;\n const declaredDatabaseRole = required(environment, \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE\");\n if (declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE is invalid\");\n }\n const result = {\n databaseUrl: required(environment, EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV),\n declaredDatabaseRole,\n owner:\n environment.OPENGENI_ARTIFACT_OUTBOX_OWNER?.trim() ||\n `artifact-outbox-${process.pid}-${crypto.randomUUID()}`,\n httpPort: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_HTTP_PORT\", 9466, 1, 65_535),\n databasePoolSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_DB_POOL_SIZE\", 4, 1, 8),\n batchSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_BATCH_SIZE\", 32, 1, 1_000),\n concurrency: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_CONCURRENCY\", 8, 1, 128),\n leaseDurationMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_LEASE_MS\",\n 30_000,\n 1_000,\n 86_400_000,\n ),\n leaseRenewIntervalMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS\",\n 10_000,\n 100,\n 43_199_999,\n ),\n pollIntervalMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_POLL_MS\", 500, 10, 60_000),\n publishTimeoutMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_PUBLISH_TIMEOUT_MS\",\n 5_000,\n 100,\n 60_000,\n ),\n retryBaseMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS\", 500, 10, 60_000),\n retryMaxMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RETRY_MAX_MS\",\n 60_000,\n 10,\n 86_400_000,\n ),\n } as const;\n if (result.leaseRenewIntervalMs >= result.leaseDurationMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS must be less than lease duration\");\n }\n if (result.retryBaseMs > result.retryMaxMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS must not exceed retry max\");\n }\n return Object.freeze(result);\n}\n\nexport async function createOutboxSidecarFromEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<Readonly<{ service: EditableArtifactOutboxService; httpPort: number }> | null> {\n const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);\n if (!sidecar) return null;\n const settings = getArtifactOutboxSettings(environment);\n const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);\n const natsAuth: EditableArtifactHintNatsAuth = controlPlaneAuth\n ? {\n kind: \"user-password\",\n user: controlPlaneAuth.user,\n pass: controlPlaneAuth.password,\n }\n : { kind: \"anonymous\" };\n const service = await createProductionEditableArtifactOutboxService({\n settings,\n databaseUrl: sidecar.databaseUrl,\n declaredDatabaseRole: sidecar.declaredDatabaseRole,\n natsUrl: settings.natsUrl,\n natsAuth,\n owner: sidecar.owner,\n databasePoolSize: sidecar.databasePoolSize,\n batchSize: sidecar.batchSize,\n concurrency: sidecar.concurrency,\n leaseDurationMs: sidecar.leaseDurationMs,\n leaseRenewIntervalMs: sidecar.leaseRenewIntervalMs,\n pollIntervalMs: sidecar.pollIntervalMs,\n publishTimeoutMs: sidecar.publishTimeoutMs,\n retryBaseMs: sidecar.retryBaseMs,\n retryMaxMs: sidecar.retryMaxMs,\n });\n return Object.freeze({ service, httpPort: sidecar.httpPort });\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n milliseconds: number,\n abort: AbortController,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n abort.abort();\n reject(new Error(\"readiness check timed out\"));\n }, milliseconds);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction required(environment: NodeJS.ProcessEnv, name: string): string {\n const value = environment[name]?.trim();\n if (!value) throw new Error(`${name} is required when artifact outbox dispatch is enabled`);\n return value;\n}\n\nfunction integer(\n environment: NodeJS.ProcessEnv,\n name: string,\n fallback: number,\n minimum: number,\n maximum: number,\n): number {\n const raw = environment[name];\n const value = raw === undefined ? fallback : Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n throw new Error(`${name} is outside its allowed range`);\n }\n return value;\n}\n\n// Compile-time assurance that production composition satisfies the service port.\nconst _runtimePort: EditableArtifactOutboxRuntimePort | undefined = undefined as\n | EditableArtifactOutboxWorkerRuntime\n | undefined;\nvoid _runtimePort;\n","import {\n EditableArtifactLiveOutboxDispatcher,\n MathEditableArtifactOutboxRandom,\n SystemEditableArtifactLiveClock,\n SystemEditableArtifactLiveScheduler,\n type EditableArtifactOutboxDispatcherOptions,\n type EditableArtifactOutboxLoggerPort,\n type EditableArtifactOutboxMetricsPort,\n type EditableArtifactOutboxDispatcherStorePort,\n type EditableArtifactLiveOutboxRecord,\n} from \"@opengeni/core\";\nimport {\n PostgresEditableArtifactStore,\n createDb,\n dbSql,\n type Database,\n type DbClient,\n} from \"@opengeni/db\";\n\nimport {\n connectEditableArtifactHintBroker,\n type ConfirmedNatsEditableArtifactHintBroker,\n type EditableArtifactHintNatsAuth,\n} from \"./editable-artifact-hint-broker\";\n\nexport const EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE =\n \"opengeni_artifact_outbox_dispatcher\";\nexport const EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV = \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_URL\";\n\nexport type EditableArtifactOutboxWorkerOptions = Readonly<{\n /** Must authenticate as the dedicated dispatcher role, never the generic app role. */\n dispatcherDatabaseUrl: string;\n databaseSearchPath?: string;\n databasePoolSize?: number;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner?: string;\n dispatcher?: Omit<EditableArtifactOutboxDispatcherOptions, \"owner\">;\n metrics?: EditableArtifactOutboxMetricsPort;\n logger?: EditableArtifactOutboxLoggerPort;\n}>;\n\n/** Explicit lifecycle handle; hosts supervise `start()` and await `stop()` on drain. */\nexport class EditableArtifactOutboxWorkerRuntime {\n private readonly abort = new AbortController();\n private running: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(\n readonly dispatcher: EditableArtifactLiveOutboxDispatcher,\n private readonly broker: ConfirmedNatsEditableArtifactHintBroker,\n private readonly database: DbClient,\n ) {}\n\n start(): Promise<void> {\n if (this.closing) return Promise.reject(new Error(\"Artifact outbox worker is stopping\"));\n this.running ??= this.dispatcher.run(this.abort.signal);\n return this.running;\n }\n\n drain(): boolean {\n if (this.abort.signal.aborted) return false;\n this.abort.abort();\n return true;\n }\n\n async check(signal?: AbortSignal): Promise<void> {\n if (this.abort.signal.aborted || this.closing) {\n throw new Error(\"Artifact outbox worker is stopping\");\n }\n await Promise.all([\n assertDedicatedOutboxDispatcherDatabaseRole(this.database.db),\n this.broker.check(signal),\n ]);\n }\n\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n this.closing = this.stopOnce();\n return this.closing;\n }\n\n private async stopOnce(): Promise<void> {\n this.drain();\n const running = this.running ? await Promise.allSettled([this.running]) : [];\n const cleanup = await Promise.allSettled([this.broker.close(), this.database.close()]);\n const failure = [...running, ...cleanup].find(\n (result): result is PromiseRejectedResult => result.status === \"rejected\",\n );\n if (failure) throw failure.reason;\n }\n}\n\n/**\n * Production composition. DB grants make the role a narrow capability: it can\n * execute only lease-fenced dispatcher functions and cannot read artifact rows.\n */\nexport async function createEditableArtifactOutboxWorker(\n options: EditableArtifactOutboxWorkerOptions,\n): Promise<EditableArtifactOutboxWorkerRuntime> {\n const dispatcherDatabaseUrl = dedicatedDispatcherDatabaseUrl(options.dispatcherDatabaseUrl);\n const databasePoolSize = options.databasePoolSize ?? 2;\n if (!Number.isSafeInteger(databasePoolSize) || databasePoolSize < 1 || databasePoolSize > 8) {\n throw new TypeError(\"Artifact outbox dispatcher DB pool size must be 1-8\");\n }\n const database = createDb(dispatcherDatabaseUrl, {\n max: databasePoolSize,\n ...(options.databaseSearchPath ? { searchPath: options.databaseSearchPath } : {}),\n });\n let broker: ConfirmedNatsEditableArtifactHintBroker;\n try {\n await assertDedicatedOutboxDispatcherDatabaseRole(database.db);\n broker = await connectEditableArtifactHintBroker({\n natsUrl: options.natsUrl,\n auth: options.natsAuth,\n });\n } catch (error) {\n await database.close();\n throw error;\n }\n const persistence = new PostgresEditableArtifactStore(database.db);\n const store = dispatcherStore(persistence);\n const dispatcher = new EditableArtifactLiveOutboxDispatcher(\n {\n store,\n broker,\n clock: new SystemEditableArtifactLiveClock(),\n scheduler: new SystemEditableArtifactLiveScheduler(),\n random: new MathEditableArtifactOutboxRandom(),\n ...(options.metrics ? { metrics: options.metrics } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n },\n {\n owner: options.owner ?? `artifact-outbox:${crypto.randomUUID()}`,\n ...options.dispatcher,\n },\n );\n return new EditableArtifactOutboxWorkerRuntime(dispatcher, broker, database);\n}\n\n/**\n * Verify the database identity and its negative capability at runtime. A DSN\n * username check alone is insufficient because PostgreSQL role inheritance,\n * SET ROLE, or a mis-provisioned grant could otherwise widen this worker.\n */\nexport async function assertDedicatedOutboxDispatcherDatabaseRole(db: Database): Promise<void> {\n const raw = await db.execute<{\n current_role: string;\n session_role: string;\n can_access_any_relation: boolean;\n can_access_any_sequence: boolean;\n }>(dbSql`\n select\n current_user::text as current_role,\n session_user::text as session_role,\n exists (\n select 1\n from pg_catalog.pg_class relation_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = relation_row.relnamespace\n where namespace_row.nspname = current_schema()\n and relation_row.relkind in ('r', 'p', 'v', 'm', 'f')\n and (\n has_table_privilege(current_user, relation_row.oid, 'SELECT')\n or has_table_privilege(current_user, relation_row.oid, 'INSERT')\n or has_table_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_table_privilege(current_user, relation_row.oid, 'DELETE')\n or has_table_privilege(current_user, relation_row.oid, 'TRUNCATE')\n or has_table_privilege(current_user, relation_row.oid, 'REFERENCES')\n or has_table_privilege(current_user, relation_row.oid, 'TRIGGER')\n or has_any_column_privilege(current_user, relation_row.oid, 'SELECT')\n or has_any_column_privilege(current_user, relation_row.oid, 'INSERT')\n or has_any_column_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_any_column_privilege(current_user, relation_row.oid, 'REFERENCES')\n )\n ) as can_access_any_relation,\n exists (\n select 1\n from pg_catalog.pg_class sequence_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = sequence_row.relnamespace\n where namespace_row.nspname = current_schema()\n and sequence_row.relkind = 'S'\n and (\n has_sequence_privilege(current_user, sequence_row.oid, 'USAGE')\n or has_sequence_privilege(current_user, sequence_row.oid, 'SELECT')\n or has_sequence_privilege(current_user, sequence_row.oid, 'UPDATE')\n )\n ) as can_access_any_sequence\n `);\n const rows = Array.isArray(raw) ? raw : ((raw as unknown as { rows?: unknown[] }).rows ?? []);\n const row = rows[0] as\n | {\n current_role?: unknown;\n session_role?: unknown;\n can_access_any_relation?: unknown;\n can_access_any_sequence?: unknown;\n }\n | undefined;\n if (\n row?.current_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.session_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.can_access_any_relation !== false ||\n row.can_access_any_sequence !== false\n ) {\n throw new Error(\"Artifact outbox dispatcher database connection has an unsafe role posture\");\n }\n}\n\nfunction dispatcherStore(\n persistence: PostgresEditableArtifactStore,\n): EditableArtifactOutboxDispatcherStorePort {\n return {\n claimLiveOutbox: async (input) =>\n (await persistence.claimLiveOutbox(\n input,\n )) as unknown as readonly EditableArtifactLiveOutboxRecord[],\n renewLiveOutbox: async (input) => await persistence.renewLiveOutbox(input),\n markLiveOutboxPublished: async (input) => await persistence.markLiveOutboxPublished(input),\n retryLiveOutbox: async (input) => await persistence.retryLiveOutbox(input),\n deadLetterLiveOutbox: async (input) => await persistence.deadLetterLiveOutbox(input),\n };\n}\n\nexport function dedicatedDispatcherDatabaseUrl(raw: string): string {\n if (typeof raw !== \"string\" || raw.length > 8_192 || raw.trim() !== raw) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`);\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch (cause) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`, { cause });\n }\n if (\n (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") ||\n decodeURIComponent(url.username) !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE\n ) {\n throw new TypeError(\n `${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} must authenticate as ${EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE}`,\n );\n }\n return raw;\n}\n","import {\n EDITABLE_ARTIFACT_HINT_MAX_BYTES,\n type EditableArtifactHintBrokerPort,\n} from \"@opengeni/core\";\nimport { connect, type NatsConnection } from \"@opengeni/events\";\n\nconst DEFAULT_CONNECTION_NAME = \"opengeni-editable-artifact-outbox\";\n\nexport type EditableArtifactHintNatsAuth =\n | Readonly<{ kind: \"user-password\"; user: string; pass: string }>\n | Readonly<{ kind: \"token\"; token: string }>\n | Readonly<{ kind: \"anonymous\" }>;\n\nexport type EditableArtifactHintNatsBrokerOptions = Readonly<{\n maxHintBytes?: number;\n}>;\n\nexport type EditableArtifactHintNatsConnection = Pick<\n NatsConnection,\n \"publish\" | \"flush\" | \"drain\" | \"close\" | \"closed\" | \"isClosed\" | \"isDraining\"\n>;\n\n/**\n * Core-NATS adapter for the durable outbox. A publish resolves only after a\n * server round-trip flush ACK. Reconnect buffering may create duplicates after\n * a timeout; hints are intentionally idempotent wakeups for durable gap-fill.\n */\nexport class ConfirmedNatsEditableArtifactHintBroker implements EditableArtifactHintBrokerPort {\n private readonly maxHintBytes: number;\n\n constructor(\n private readonly connection: EditableArtifactHintNatsConnection,\n options: EditableArtifactHintNatsBrokerOptions = {},\n ) {\n this.maxHintBytes = options.maxHintBytes ?? EDITABLE_ARTIFACT_HINT_MAX_BYTES;\n if (\n !Number.isSafeInteger(this.maxHintBytes) ||\n this.maxHintBytes < 1 ||\n this.maxHintBytes > EDITABLE_ARTIFACT_HINT_MAX_BYTES\n ) {\n throw new TypeError(\"Editable artifact NATS hint byte limit is invalid\");\n }\n }\n\n async publish(\n input: Readonly<{\n subject: string;\n payload: Uint8Array;\n signal: AbortSignal;\n }>,\n ): Promise<void> {\n assertSubject(input.subject);\n if (\n !(input.payload instanceof Uint8Array) ||\n input.payload.byteLength < 1 ||\n input.payload.byteLength > this.maxHintBytes\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact hint exceeds the NATS envelope\",\n );\n }\n if (input.signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is closed\",\n );\n }\n try {\n this.connection.publish(input.subject, input.payload);\n await abortable(this.connection.flush(), input.signal);\n } catch (error) {\n if (input.signal.aborted) throw abortedPublish();\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was not acknowledged\",\n { cause: error },\n );\n }\n }\n\n /**\n * A readiness probe must prove the server is reachable, not merely that the\n * client object has not observed closure yet. `flush()` is a bounded NATS\n * round trip and has the same acknowledgement semantics as publication.\n */\n async check(signal: AbortSignal = new AbortController().signal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is unavailable\",\n );\n }\n try {\n await abortable(this.connection.flush(), signal);\n } catch (error) {\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS readiness round trip failed\",\n { cause: error },\n );\n }\n }\n\n async close(drainTimeoutMs = 5_000): Promise<void> {\n if (!Number.isSafeInteger(drainTimeoutMs) || drainTimeoutMs < 1 || drainTimeoutMs > 30_000) {\n throw new TypeError(\"Editable artifact NATS drain timeout is invalid\");\n }\n if (this.connection.isClosed()) return;\n if (this.connection.isDraining()) {\n await this.connection.closed();\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = this.connection.drain();\n const outcome = await Promise.race([\n drain.then(\n () => \"drained\" as const,\n () => \"failed\" as const,\n ),\n new Promise<\"timed_out\">((resolve) => {\n timer = setTimeout(() => resolve(\"timed_out\"), drainTimeoutMs);\n }),\n ]);\n if (timer) clearTimeout(timer);\n if (outcome !== \"drained\" && !this.connection.isClosed()) {\n await this.connection.close();\n }\n }\n}\n\nexport class EditableArtifactNatsHintPublishError extends Error {\n constructor(\n readonly code: \"broker_unavailable\" | \"broker_backpressure\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"EditableArtifactNatsHintPublishError\";\n }\n}\n\n/** Opens one resilient dispatcher identity; callers own `broker.close()`. */\nexport async function connectEditableArtifactHintBroker(\n input: Readonly<{\n natsUrl: string;\n auth: EditableArtifactHintNatsAuth;\n name?: string;\n maxHintBytes?: number;\n }>,\n): Promise<ConfirmedNatsEditableArtifactHintBroker> {\n const natsUrl = boundedText(input.natsUrl, \"NATS URL\", 2_048);\n const name = boundedText(input.name ?? DEFAULT_CONNECTION_NAME, \"NATS connection name\", 128);\n const auth = natsAuthOptions(input.auth);\n const connection = await connect({\n servers: natsUrl,\n name,\n reconnect: true,\n maxReconnectAttempts: -1,\n reconnectTimeWait: 2_000,\n reconnectJitter: 1_000,\n reconnectJitterTLS: 1_000,\n waitOnFirstConnect: true,\n pingInterval: 20_000,\n maxPingOut: 3,\n ...auth,\n });\n return new ConfirmedNatsEditableArtifactHintBroker(connection, {\n ...(input.maxHintBytes === undefined ? {} : { maxHintBytes: input.maxHintBytes }),\n });\n}\n\nfunction natsAuthOptions(auth: EditableArtifactHintNatsAuth): {\n user?: string;\n pass?: string;\n token?: string;\n} {\n if (auth.kind === \"anonymous\") return {};\n if (auth.kind === \"token\") return { token: boundedText(auth.token, \"NATS token\", 4_096) };\n return {\n user: boundedText(auth.user, \"NATS user\", 256),\n pass: boundedText(auth.pass, \"NATS password\", 4_096),\n };\n}\n\nfunction assertSubject(subject: string): void {\n const bytes = new TextEncoder().encode(subject).byteLength;\n if (\n bytes < 1 ||\n bytes > 1_024 ||\n subject.startsWith(\".\") ||\n subject.endsWith(\".\") ||\n subject.includes(\"..\") ||\n /[\\s*>]/u.test(subject)\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact NATS subject is malformed\",\n );\n }\n}\n\nfunction boundedText(value: string, label: string, maxBytes: number): string {\n const bytes = new TextEncoder().encode(value).byteLength;\n if (bytes < 1 || bytes > maxBytes || value.trim() !== value) {\n throw new TypeError(`${label} is malformed`);\n }\n return value;\n}\n\nfunction abortedPublish(): EditableArtifactNatsHintPublishError {\n return new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was aborted\",\n );\n}\n\nasync function abortable(operation: Promise<void>, signal: AbortSignal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n let remove: () => void = () => undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n const onAbort = () => reject(abortedPublish());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n remove = () => signal.removeEventListener(\"abort\", onAbort);\n });\n try {\n await Promise.race([operation, aborted]);\n } finally {\n remove();\n }\n}\n","import { createOutboxSidecarFromEnvironment } from \"./editable-artifact-outbox-service\";\n\n/** Dedicated process: no Temporal/control worker is created or imported here. */\nexport async function runEditableArtifactOutboxSidecar(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const configured = await createOutboxSidecarFromEnvironment(environment);\n if (!configured) throw new Error(\"Editable artifact outbox sidecar is disabled\");\n const server = Bun.serve({\n hostname: \"0.0.0.0\",\n port: configured.httpPort,\n fetch: configured.service.fetch,\n });\n const stop = () => configured.service.drain(\"process signal\");\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGINT\", stop);\n try {\n await configured.service.run();\n } finally {\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGINT\", stop);\n server.stop(true);\n await configured.service.close();\n }\n}\n\nif (import.meta.main) {\n await runEditableArtifactOutboxSidecar();\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/editable-artifact-outbox-service.ts","../src/editable-artifact-outbox-dispatcher.ts","../src/editable-artifact-hint-broker.ts","../src/artifact-outbox-entry.ts"],"sourcesContent":["import {\n dbSearchPath,\n getArtifactOutboxSettings,\n resolveNatsControlPlaneAuth,\n type ArtifactOutboxSettings,\n} from \"@opengeni/config\";\nimport type { EditableArtifactOutboxDispatchSummary } from \"@opengeni/core\";\nimport { createObservability, type Observability } from \"@opengeni/observability\";\n\nimport {\n EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV,\n EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE,\n createEditableArtifactOutboxWorker,\n type EditableArtifactOutboxWorkerRuntime,\n} from \"./editable-artifact-outbox-dispatcher\";\nimport type { EditableArtifactHintNatsAuth } from \"./editable-artifact-hint-broker\";\n\nexport type EditableArtifactOutboxServiceState =\n | \"starting\"\n | \"ready\"\n | \"draining\"\n | \"stopped\"\n | \"failed\";\n\nexport interface EditableArtifactOutboxRuntimePort {\n start(): Promise<void>;\n drain(): boolean;\n stop(): Promise<void>;\n check(signal?: AbortSignal): Promise<void>;\n readonly dispatcher: Readonly<{\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n }>;\n}\n\nexport type EditableArtifactOutboxService = Readonly<{\n state(): EditableArtifactOutboxServiceState;\n run(): Promise<void>;\n drain(reason?: string): boolean;\n close(): Promise<void>;\n dispatchOnce(): Promise<EditableArtifactOutboxDispatchSummary>;\n fetch(request: Request): Promise<Response>;\n}>;\n\nexport type CreateEditableArtifactOutboxServiceInput = Readonly<{\n runtime: EditableArtifactOutboxRuntimePort;\n observability: Observability;\n serviceName: string;\n environment: string;\n deploymentRevision?: string;\n readinessTimeoutMs?: number;\n}>;\n\nexport type ProductionEditableArtifactOutboxServiceOptions = Readonly<{\n settings: ArtifactOutboxSettings;\n databaseUrl: string;\n declaredDatabaseRole: string;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner: string;\n databasePoolSize?: number;\n batchSize?: number;\n concurrency?: number;\n leaseDurationMs?: number;\n leaseRenewIntervalMs?: number;\n pollIntervalMs?: number;\n publishTimeoutMs?: number;\n retryBaseMs?: number;\n retryMaxMs?: number;\n}>;\n\n/** Compose the independently supervised production outbox dispatcher. */\nexport async function createProductionEditableArtifactOutboxService(\n options: ProductionEditableArtifactOutboxServiceOptions,\n): Promise<EditableArtifactOutboxService> {\n if (options.declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"Artifact outbox dispatcher database role declaration is invalid\");\n }\n const observability = createObservability(options.settings, {\n component: \"artifact-outbox-dispatcher\",\n });\n const databaseSearchPath = dbSearchPath(options.settings);\n const runtime = await createEditableArtifactOutboxWorker({\n dispatcherDatabaseUrl: options.databaseUrl,\n ...(databaseSearchPath ? { databaseSearchPath } : {}),\n ...(options.databasePoolSize === undefined\n ? {}\n : { databasePoolSize: options.databasePoolSize }),\n natsUrl: options.natsUrl,\n natsAuth: options.natsAuth,\n owner: options.owner,\n dispatcher: {\n ...(options.batchSize === undefined ? {} : { batchSize: options.batchSize }),\n ...(options.concurrency === undefined ? {} : { concurrency: options.concurrency }),\n ...(options.leaseDurationMs === undefined\n ? {}\n : { leaseDurationMs: options.leaseDurationMs }),\n ...(options.leaseRenewIntervalMs === undefined\n ? {}\n : { leaseRenewIntervalMs: options.leaseRenewIntervalMs }),\n ...(options.pollIntervalMs === undefined ? {} : { pollIntervalMs: options.pollIntervalMs }),\n ...(options.publishTimeoutMs === undefined\n ? {}\n : { publishTimeoutMs: options.publishTimeoutMs }),\n ...(options.retryBaseMs === undefined ? {} : { retryBaseMs: options.retryBaseMs }),\n ...(options.retryMaxMs === undefined ? {} : { retryMaxMs: options.retryMaxMs }),\n },\n metrics: {\n increment(outcome, count = 1) {\n observability.incrementCounter({\n name: \"opengeni_artifact_outbox_dispatch_total\",\n help: \"Editable artifact outbox dispatch actions by closed outcome.\",\n labels: { outcome },\n amount: count,\n });\n },\n observePublishSeconds(outcome, seconds) {\n observability.observeHistogram({\n name: \"opengeni_artifact_outbox_publish_seconds\",\n help: \"Editable artifact broker publication latency by closed outcome.\",\n labels: { outcome },\n value: seconds,\n });\n },\n },\n logger: {\n warn(message, attributes) {\n observability.warn(message, {\n errorClass: \"WorkerOperationError\",\n errorCode: \"worker_operation_failed\",\n origin: \"worker\",\n outcome: typeof attributes.code === \"string\" ? attributes.code : \"unknown\",\n });\n },\n },\n });\n return createEditableArtifactOutboxService({\n runtime,\n observability,\n serviceName: options.settings.serviceName,\n environment: options.settings.environment,\n deploymentRevision: options.settings.deploymentRevision,\n });\n}\n\nexport function createEditableArtifactOutboxService(\n input: CreateEditableArtifactOutboxServiceInput,\n): EditableArtifactOutboxService {\n let state: EditableArtifactOutboxServiceState = \"starting\";\n let runPromise: Promise<void> | null = null;\n let closePromise: Promise<void> | null = null;\n let readinessPromise: Promise<void> | null = null;\n const readinessTimeoutMs = input.readinessTimeoutMs ?? 2_000;\n\n const ready = (): Promise<void> => {\n if (readinessPromise) return readinessPromise;\n const abort = new AbortController();\n const check = withTimeout(input.runtime.check(abort.signal), readinessTimeoutMs, abort);\n readinessPromise = check;\n void check.then(\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n () => {\n if (readinessPromise === check) readinessPromise = null;\n },\n );\n return check;\n };\n\n const run = (): Promise<void> => {\n if (runPromise) return runPromise;\n if (state !== \"starting\") {\n return Promise.reject(new Error(\"Artifact outbox dispatcher service cannot be restarted\"));\n }\n runPromise = (async () => {\n try {\n await ready();\n if ((state as EditableArtifactOutboxServiceState) === \"draining\") {\n state = \"stopped\";\n return;\n }\n const running = input.runtime.start();\n state = \"ready\";\n await running;\n const exitWasDraining = (state as EditableArtifactOutboxServiceState) === \"draining\";\n state = exitWasDraining ? \"stopped\" : \"failed\";\n if (!exitWasDraining) {\n throw new Error(\"Artifact outbox dispatcher exited without a drain request\");\n }\n } catch (error) {\n const caughtState = state as EditableArtifactOutboxServiceState;\n if (caughtState !== \"draining\" && caughtState !== \"stopped\") state = \"failed\";\n throw error;\n }\n })();\n return runPromise;\n };\n\n const drain = (_reason = \"shutdown\"): boolean => {\n if (state === \"draining\" || state === \"stopped\" || state === \"failed\") return false;\n state = \"draining\";\n input.runtime.drain();\n return true;\n };\n\n const close = (): Promise<void> => {\n if (closePromise) return closePromise;\n closePromise = (async () => {\n drain(\"close\");\n if (runPromise) await runPromise.catch(() => undefined);\n await input.runtime.stop();\n if (state !== \"failed\") state = \"stopped\";\n })();\n return closePromise;\n };\n\n const fetch = async (request: Request): Promise<Response> => {\n const url = new URL(request.url);\n if (request.method !== \"GET\") {\n return Response.json({ error: \"method_not_allowed\" }, { status: 405 });\n }\n if (url.pathname === \"/healthz\") {\n const ok = state !== \"failed\" && state !== \"stopped\";\n return Response.json(\n {\n service: input.serviceName,\n component: \"artifact-outbox-dispatcher\",\n environment: input.environment,\n ...(input.deploymentRevision ? { deploymentRevision: input.deploymentRevision } : {}),\n state,\n ok,\n },\n { status: ok ? 200 : 503 },\n );\n }\n if (url.pathname === \"/readyz\") {\n if (state !== \"ready\") {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n try {\n await ready();\n return Response.json({\n ok: true,\n state,\n checks: { databaseRole: { ok: true }, nats: { ok: true } },\n });\n } catch {\n return Response.json(\n {\n ok: false,\n state,\n checks: { databaseRole: { ok: false }, nats: { ok: false } },\n },\n { status: 503 },\n );\n }\n }\n if (url.pathname === \"/metrics\") {\n return new Response(await input.observability.prometheusMetrics(), {\n status: 200,\n headers: { \"content-type\": \"text/plain; version=0.0.4; charset=utf-8\" },\n });\n }\n return Response.json({ error: \"not_found\" }, { status: 404 });\n };\n\n return Object.freeze({\n state: () => state,\n run,\n drain,\n close,\n dispatchOnce: async () => await input.runtime.dispatcher.dispatchOnce(),\n fetch,\n });\n}\n\nexport type EditableArtifactOutboxSidecarEnvironment = Readonly<{\n databaseUrl: string;\n declaredDatabaseRole: string;\n owner: string;\n httpPort: number;\n databasePoolSize: number;\n batchSize: number;\n concurrency: number;\n leaseDurationMs: number;\n leaseRenewIntervalMs: number;\n pollIntervalMs: number;\n publishTimeoutMs: number;\n retryBaseMs: number;\n retryMaxMs: number;\n}>;\n\nexport function readEditableArtifactOutboxSidecarEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): EditableArtifactOutboxSidecarEnvironment | null {\n if (environment.OPENGENI_ARTIFACT_OUTBOX_ENABLED !== \"true\") return null;\n const declaredDatabaseRole = required(environment, \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE\");\n if (declaredDatabaseRole !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_DATABASE_ROLE is invalid\");\n }\n const result = {\n databaseUrl: required(environment, EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV),\n declaredDatabaseRole,\n owner:\n environment.OPENGENI_ARTIFACT_OUTBOX_OWNER?.trim() ||\n `artifact-outbox-${process.pid}-${crypto.randomUUID()}`,\n httpPort: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_HTTP_PORT\", 9466, 1, 65_535),\n databasePoolSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_DB_POOL_SIZE\", 4, 1, 8),\n batchSize: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_BATCH_SIZE\", 32, 1, 1_000),\n concurrency: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_CONCURRENCY\", 8, 1, 128),\n leaseDurationMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_LEASE_MS\",\n 30_000,\n 1_000,\n 86_400_000,\n ),\n leaseRenewIntervalMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS\",\n 10_000,\n 100,\n 43_199_999,\n ),\n pollIntervalMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_POLL_MS\", 500, 10, 60_000),\n publishTimeoutMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_PUBLISH_TIMEOUT_MS\",\n 5_000,\n 100,\n 60_000,\n ),\n retryBaseMs: integer(environment, \"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS\", 500, 10, 60_000),\n retryMaxMs: integer(\n environment,\n \"OPENGENI_ARTIFACT_OUTBOX_RETRY_MAX_MS\",\n 60_000,\n 10,\n 86_400_000,\n ),\n } as const;\n if (result.leaseRenewIntervalMs >= result.leaseDurationMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RENEW_MS must be less than lease duration\");\n }\n if (result.retryBaseMs > result.retryMaxMs) {\n throw new Error(\"OPENGENI_ARTIFACT_OUTBOX_RETRY_BASE_MS must not exceed retry max\");\n }\n return Object.freeze(result);\n}\n\nexport async function createOutboxSidecarFromEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<Readonly<{ service: EditableArtifactOutboxService; httpPort: number }> | null> {\n const sidecar = readEditableArtifactOutboxSidecarEnvironment(environment);\n if (!sidecar) return null;\n const settings = getArtifactOutboxSettings(environment);\n const controlPlaneAuth = resolveNatsControlPlaneAuth(settings);\n const natsAuth: EditableArtifactHintNatsAuth = controlPlaneAuth\n ? {\n kind: \"user-password\",\n user: controlPlaneAuth.user,\n pass: controlPlaneAuth.password,\n }\n : { kind: \"anonymous\" };\n const service = await createProductionEditableArtifactOutboxService({\n settings,\n databaseUrl: sidecar.databaseUrl,\n declaredDatabaseRole: sidecar.declaredDatabaseRole,\n natsUrl: settings.natsUrl,\n natsAuth,\n owner: sidecar.owner,\n databasePoolSize: sidecar.databasePoolSize,\n batchSize: sidecar.batchSize,\n concurrency: sidecar.concurrency,\n leaseDurationMs: sidecar.leaseDurationMs,\n leaseRenewIntervalMs: sidecar.leaseRenewIntervalMs,\n pollIntervalMs: sidecar.pollIntervalMs,\n publishTimeoutMs: sidecar.publishTimeoutMs,\n retryBaseMs: sidecar.retryBaseMs,\n retryMaxMs: sidecar.retryMaxMs,\n });\n return Object.freeze({ service, httpPort: sidecar.httpPort });\n}\n\nasync function withTimeout<T>(\n promise: Promise<T>,\n milliseconds: number,\n abort: AbortController,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n promise,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n abort.abort();\n reject(new Error(\"readiness check timed out\"));\n }, milliseconds);\n }),\n ]);\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\nfunction required(environment: NodeJS.ProcessEnv, name: string): string {\n const value = environment[name]?.trim();\n if (!value) throw new Error(`${name} is required when artifact outbox dispatch is enabled`);\n return value;\n}\n\nfunction integer(\n environment: NodeJS.ProcessEnv,\n name: string,\n fallback: number,\n minimum: number,\n maximum: number,\n): number {\n const raw = environment[name];\n const value = raw === undefined ? fallback : Number(raw);\n if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {\n throw new Error(`${name} is outside its allowed range`);\n }\n return value;\n}\n\n// Compile-time assurance that production composition satisfies the service port.\nconst _runtimePort: EditableArtifactOutboxRuntimePort | undefined = undefined as\n | EditableArtifactOutboxWorkerRuntime\n | undefined;\nvoid _runtimePort;\n","import {\n EditableArtifactLiveOutboxDispatcher,\n MathEditableArtifactOutboxRandom,\n SystemEditableArtifactLiveClock,\n SystemEditableArtifactLiveScheduler,\n type EditableArtifactOutboxDispatcherOptions,\n type EditableArtifactOutboxLoggerPort,\n type EditableArtifactOutboxMetricsPort,\n type EditableArtifactOutboxDispatcherStorePort,\n type EditableArtifactLiveOutboxRecord,\n} from \"@opengeni/core\";\nimport {\n PostgresEditableArtifactStore,\n createDb,\n dbSql,\n type Database,\n type DbClient,\n} from \"@opengeni/db\";\n\nimport {\n connectEditableArtifactHintBroker,\n type ConfirmedNatsEditableArtifactHintBroker,\n type EditableArtifactHintNatsAuth,\n} from \"./editable-artifact-hint-broker\";\n\nexport const EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE =\n \"opengeni_artifact_outbox_dispatcher\";\nexport const EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV = \"OPENGENI_ARTIFACT_OUTBOX_DATABASE_URL\";\n\nexport type EditableArtifactOutboxWorkerOptions = Readonly<{\n /** Must authenticate as the dedicated dispatcher role, never the generic app role. */\n dispatcherDatabaseUrl: string;\n databaseSearchPath?: string;\n databasePoolSize?: number;\n natsUrl: string;\n natsAuth: EditableArtifactHintNatsAuth;\n owner?: string;\n dispatcher?: Omit<EditableArtifactOutboxDispatcherOptions, \"owner\">;\n metrics?: EditableArtifactOutboxMetricsPort;\n logger?: EditableArtifactOutboxLoggerPort;\n}>;\n\n/** Explicit lifecycle handle; hosts supervise `start()` and await `stop()` on drain. */\nexport class EditableArtifactOutboxWorkerRuntime {\n private readonly abort = new AbortController();\n private running: Promise<void> | null = null;\n private closing: Promise<void> | null = null;\n\n constructor(\n readonly dispatcher: EditableArtifactLiveOutboxDispatcher,\n private readonly broker: ConfirmedNatsEditableArtifactHintBroker,\n private readonly database: DbClient,\n ) {}\n\n start(): Promise<void> {\n if (this.closing) return Promise.reject(new Error(\"Artifact outbox worker is stopping\"));\n this.running ??= this.dispatcher.run(this.abort.signal);\n return this.running;\n }\n\n drain(): boolean {\n if (this.abort.signal.aborted) return false;\n this.abort.abort();\n return true;\n }\n\n async check(signal?: AbortSignal): Promise<void> {\n if (this.abort.signal.aborted || this.closing) {\n throw new Error(\"Artifact outbox worker is stopping\");\n }\n await Promise.all([\n assertDedicatedOutboxDispatcherDatabaseRole(this.database.db),\n this.broker.check(signal),\n ]);\n }\n\n stop(): Promise<void> {\n if (this.closing) return this.closing;\n this.closing = this.stopOnce();\n return this.closing;\n }\n\n private async stopOnce(): Promise<void> {\n this.drain();\n const running = this.running ? await Promise.allSettled([this.running]) : [];\n const cleanup = await Promise.allSettled([this.broker.close(), this.database.close()]);\n const failure = [...running, ...cleanup].find(\n (result): result is PromiseRejectedResult => result.status === \"rejected\",\n );\n if (failure) throw failure.reason;\n }\n}\n\n/**\n * Production composition. DB grants make the role a narrow capability: it can\n * execute only lease-fenced dispatcher functions and cannot read artifact rows.\n */\nexport async function createEditableArtifactOutboxWorker(\n options: EditableArtifactOutboxWorkerOptions,\n): Promise<EditableArtifactOutboxWorkerRuntime> {\n const dispatcherDatabaseUrl = dedicatedDispatcherDatabaseUrl(options.dispatcherDatabaseUrl);\n const databasePoolSize = options.databasePoolSize ?? 2;\n if (!Number.isSafeInteger(databasePoolSize) || databasePoolSize < 1 || databasePoolSize > 8) {\n throw new TypeError(\"Artifact outbox dispatcher DB pool size must be 1-8\");\n }\n const database = createDb(dispatcherDatabaseUrl, {\n max: databasePoolSize,\n ...(options.databaseSearchPath ? { searchPath: options.databaseSearchPath } : {}),\n });\n let broker: ConfirmedNatsEditableArtifactHintBroker;\n try {\n await assertDedicatedOutboxDispatcherDatabaseRole(database.db);\n broker = await connectEditableArtifactHintBroker({\n natsUrl: options.natsUrl,\n auth: options.natsAuth,\n });\n } catch (error) {\n await database.close();\n throw error;\n }\n const persistence = new PostgresEditableArtifactStore(database.db);\n const store = dispatcherStore(persistence);\n const dispatcher = new EditableArtifactLiveOutboxDispatcher(\n {\n store,\n broker,\n clock: new SystemEditableArtifactLiveClock(),\n scheduler: new SystemEditableArtifactLiveScheduler(),\n random: new MathEditableArtifactOutboxRandom(),\n ...(options.metrics ? { metrics: options.metrics } : {}),\n ...(options.logger ? { logger: options.logger } : {}),\n },\n {\n owner: options.owner ?? `artifact-outbox:${crypto.randomUUID()}`,\n ...options.dispatcher,\n },\n );\n return new EditableArtifactOutboxWorkerRuntime(dispatcher, broker, database);\n}\n\n/**\n * Verify the database identity and its negative capability at runtime. A DSN\n * username check alone is insufficient because PostgreSQL role inheritance,\n * SET ROLE, or a mis-provisioned grant could otherwise widen this worker.\n */\nexport async function assertDedicatedOutboxDispatcherDatabaseRole(db: Database): Promise<void> {\n const raw = await db.execute<{\n current_role: string;\n session_role: string;\n can_access_any_relation: boolean;\n can_access_any_sequence: boolean;\n }>(dbSql`\n select\n current_user::text as current_role,\n session_user::text as session_role,\n exists (\n select 1\n from pg_catalog.pg_class relation_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = relation_row.relnamespace\n where namespace_row.nspname = current_schema()\n and relation_row.relkind in ('r', 'p', 'v', 'm', 'f')\n and (\n has_table_privilege(current_user, relation_row.oid, 'SELECT')\n or has_table_privilege(current_user, relation_row.oid, 'INSERT')\n or has_table_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_table_privilege(current_user, relation_row.oid, 'DELETE')\n or has_table_privilege(current_user, relation_row.oid, 'TRUNCATE')\n or has_table_privilege(current_user, relation_row.oid, 'REFERENCES')\n or has_table_privilege(current_user, relation_row.oid, 'TRIGGER')\n or has_any_column_privilege(current_user, relation_row.oid, 'SELECT')\n or has_any_column_privilege(current_user, relation_row.oid, 'INSERT')\n or has_any_column_privilege(current_user, relation_row.oid, 'UPDATE')\n or has_any_column_privilege(current_user, relation_row.oid, 'REFERENCES')\n )\n ) as can_access_any_relation,\n exists (\n select 1\n from pg_catalog.pg_class sequence_row\n join pg_catalog.pg_namespace namespace_row\n on namespace_row.oid = sequence_row.relnamespace\n where namespace_row.nspname = current_schema()\n and sequence_row.relkind = 'S'\n and (\n has_sequence_privilege(current_user, sequence_row.oid, 'USAGE')\n or has_sequence_privilege(current_user, sequence_row.oid, 'SELECT')\n or has_sequence_privilege(current_user, sequence_row.oid, 'UPDATE')\n )\n ) as can_access_any_sequence\n `);\n const rows = Array.isArray(raw) ? raw : ((raw as unknown as { rows?: unknown[] }).rows ?? []);\n const row = rows[0] as\n | {\n current_role?: unknown;\n session_role?: unknown;\n can_access_any_relation?: unknown;\n can_access_any_sequence?: unknown;\n }\n | undefined;\n if (\n row?.current_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.session_role !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE ||\n row.can_access_any_relation !== false ||\n row.can_access_any_sequence !== false\n ) {\n throw new Error(\"Artifact outbox dispatcher database connection has an unsafe role posture\");\n }\n}\n\nfunction dispatcherStore(\n persistence: PostgresEditableArtifactStore,\n): EditableArtifactOutboxDispatcherStorePort {\n return {\n claimLiveOutbox: async (input) =>\n (await persistence.claimLiveOutbox(\n input,\n )) as unknown as readonly EditableArtifactLiveOutboxRecord[],\n renewLiveOutbox: async (input) => await persistence.renewLiveOutbox(input),\n markLiveOutboxPublished: async (input) => await persistence.markLiveOutboxPublished(input),\n retryLiveOutbox: async (input) => await persistence.retryLiveOutbox(input),\n deadLetterLiveOutbox: async (input) => await persistence.deadLetterLiveOutbox(input),\n };\n}\n\nexport function dedicatedDispatcherDatabaseUrl(raw: string): string {\n if (typeof raw !== \"string\" || raw.length > 8_192 || raw.trim() !== raw) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`);\n }\n let url: URL;\n try {\n url = new URL(raw);\n } catch (cause) {\n throw new TypeError(`${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} is malformed`, { cause });\n }\n if (\n (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") ||\n decodeURIComponent(url.username) !== EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE\n ) {\n throw new TypeError(\n `${EDITABLE_ARTIFACT_OUTBOX_DATABASE_URL_ENV} must authenticate as ${EDITABLE_ARTIFACT_OUTBOX_DISPATCHER_DATABASE_ROLE}`,\n );\n }\n return raw;\n}\n","import {\n EDITABLE_ARTIFACT_HINT_MAX_BYTES,\n type EditableArtifactHintBrokerPort,\n} from \"@opengeni/core\";\nimport { connect, type NatsConnection } from \"@opengeni/events\";\n\nconst DEFAULT_CONNECTION_NAME = \"opengeni-editable-artifact-outbox\";\n\nexport type EditableArtifactHintNatsAuth =\n | Readonly<{ kind: \"user-password\"; user: string; pass: string }>\n | Readonly<{ kind: \"token\"; token: string }>\n | Readonly<{ kind: \"anonymous\" }>;\n\nexport type EditableArtifactHintNatsBrokerOptions = Readonly<{\n maxHintBytes?: number;\n}>;\n\nexport type EditableArtifactHintNatsConnection = Pick<\n NatsConnection,\n \"publish\" | \"flush\" | \"drain\" | \"close\" | \"closed\" | \"isClosed\" | \"isDraining\"\n>;\n\n/**\n * Core-NATS adapter for the durable outbox. A publish resolves only after a\n * server round-trip flush ACK. Reconnect buffering may create duplicates after\n * a timeout; hints are intentionally idempotent wakeups for durable gap-fill.\n */\nexport class ConfirmedNatsEditableArtifactHintBroker implements EditableArtifactHintBrokerPort {\n private readonly maxHintBytes: number;\n\n constructor(\n private readonly connection: EditableArtifactHintNatsConnection,\n options: EditableArtifactHintNatsBrokerOptions = {},\n ) {\n this.maxHintBytes = options.maxHintBytes ?? EDITABLE_ARTIFACT_HINT_MAX_BYTES;\n if (\n !Number.isSafeInteger(this.maxHintBytes) ||\n this.maxHintBytes < 1 ||\n this.maxHintBytes > EDITABLE_ARTIFACT_HINT_MAX_BYTES\n ) {\n throw new TypeError(\"Editable artifact NATS hint byte limit is invalid\");\n }\n }\n\n async publish(\n input: Readonly<{\n subject: string;\n payload: Uint8Array;\n signal: AbortSignal;\n }>,\n ): Promise<void> {\n assertSubject(input.subject);\n if (\n !(input.payload instanceof Uint8Array) ||\n input.payload.byteLength < 1 ||\n input.payload.byteLength > this.maxHintBytes\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact hint exceeds the NATS envelope\",\n );\n }\n if (input.signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is closed\",\n );\n }\n try {\n this.connection.publish(input.subject, input.payload);\n await abortable(this.connection.flush(), input.signal);\n } catch (error) {\n if (input.signal.aborted) throw abortedPublish();\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was not acknowledged\",\n { cause: error },\n );\n }\n }\n\n /**\n * A readiness probe must prove the server is reachable, not merely that the\n * client object has not observed closure yet. `flush()` is a bounded NATS\n * round trip and has the same acknowledgement semantics as publication.\n */\n async check(signal: AbortSignal = new AbortController().signal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n if (this.connection.isClosed() || this.connection.isDraining()) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS connection is unavailable\",\n );\n }\n try {\n await abortable(this.connection.flush(), signal);\n } catch (error) {\n if (error instanceof EditableArtifactNatsHintPublishError) throw error;\n throw new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS readiness round trip failed\",\n { cause: error },\n );\n }\n }\n\n async close(drainTimeoutMs = 5_000): Promise<void> {\n if (!Number.isSafeInteger(drainTimeoutMs) || drainTimeoutMs < 1 || drainTimeoutMs > 30_000) {\n throw new TypeError(\"Editable artifact NATS drain timeout is invalid\");\n }\n if (this.connection.isClosed()) return;\n if (this.connection.isDraining()) {\n await this.connection.closed();\n return;\n }\n let timer: ReturnType<typeof setTimeout> | undefined;\n const drain = this.connection.drain();\n const outcome = await Promise.race([\n drain.then(\n () => \"drained\" as const,\n () => \"failed\" as const,\n ),\n new Promise<\"timed_out\">((resolve) => {\n timer = setTimeout(() => resolve(\"timed_out\"), drainTimeoutMs);\n }),\n ]);\n if (timer) clearTimeout(timer);\n if (outcome !== \"drained\" && !this.connection.isClosed()) {\n await this.connection.close();\n }\n }\n}\n\nexport class EditableArtifactNatsHintPublishError extends Error {\n constructor(\n readonly code: \"broker_unavailable\" | \"broker_backpressure\",\n message: string,\n options?: ErrorOptions,\n ) {\n super(message, options);\n this.name = \"EditableArtifactNatsHintPublishError\";\n }\n}\n\n/** Opens one resilient dispatcher identity; callers own `broker.close()`. */\nexport async function connectEditableArtifactHintBroker(\n input: Readonly<{\n natsUrl: string;\n auth: EditableArtifactHintNatsAuth;\n name?: string;\n maxHintBytes?: number;\n }>,\n): Promise<ConfirmedNatsEditableArtifactHintBroker> {\n const natsUrl = boundedText(input.natsUrl, \"NATS URL\", 2_048);\n const name = boundedText(input.name ?? DEFAULT_CONNECTION_NAME, \"NATS connection name\", 128);\n const auth = natsAuthOptions(input.auth);\n const connection = await connect({\n servers: natsUrl,\n name,\n reconnect: true,\n maxReconnectAttempts: -1,\n // Same policy as the event bus: a broker or auth-callout restart must not\n // permanently close this connection after two identical auth errors.\n ignoreAuthErrorAbort: true,\n reconnectTimeWait: 2_000,\n reconnectJitter: 1_000,\n reconnectJitterTLS: 1_000,\n waitOnFirstConnect: true,\n pingInterval: 20_000,\n maxPingOut: 3,\n ...auth,\n });\n return new ConfirmedNatsEditableArtifactHintBroker(connection, {\n ...(input.maxHintBytes === undefined ? {} : { maxHintBytes: input.maxHintBytes }),\n });\n}\n\nfunction natsAuthOptions(auth: EditableArtifactHintNatsAuth): {\n user?: string;\n pass?: string;\n token?: string;\n} {\n if (auth.kind === \"anonymous\") return {};\n if (auth.kind === \"token\") return { token: boundedText(auth.token, \"NATS token\", 4_096) };\n return {\n user: boundedText(auth.user, \"NATS user\", 256),\n pass: boundedText(auth.pass, \"NATS password\", 4_096),\n };\n}\n\nfunction assertSubject(subject: string): void {\n const bytes = new TextEncoder().encode(subject).byteLength;\n if (\n bytes < 1 ||\n bytes > 1_024 ||\n subject.startsWith(\".\") ||\n subject.endsWith(\".\") ||\n subject.includes(\"..\") ||\n /[\\s*>]/u.test(subject)\n ) {\n throw new EditableArtifactNatsHintPublishError(\n \"broker_backpressure\",\n \"Editable artifact NATS subject is malformed\",\n );\n }\n}\n\nfunction boundedText(value: string, label: string, maxBytes: number): string {\n const bytes = new TextEncoder().encode(value).byteLength;\n if (bytes < 1 || bytes > maxBytes || value.trim() !== value) {\n throw new TypeError(`${label} is malformed`);\n }\n return value;\n}\n\nfunction abortedPublish(): EditableArtifactNatsHintPublishError {\n return new EditableArtifactNatsHintPublishError(\n \"broker_unavailable\",\n \"Editable artifact NATS publish was aborted\",\n );\n}\n\nasync function abortable(operation: Promise<void>, signal: AbortSignal): Promise<void> {\n if (signal.aborted) throw abortedPublish();\n let remove: () => void = () => undefined;\n const aborted = new Promise<never>((_resolve, reject) => {\n const onAbort = () => reject(abortedPublish());\n signal.addEventListener(\"abort\", onAbort, { once: true });\n remove = () => signal.removeEventListener(\"abort\", onAbort);\n });\n try {\n await Promise.race([operation, aborted]);\n } finally {\n remove();\n }\n}\n","import { createOutboxSidecarFromEnvironment } from \"./editable-artifact-outbox-service\";\n\n/** Dedicated process: no Temporal/control worker is created or imported here. */\nexport async function runEditableArtifactOutboxSidecar(\n environment: NodeJS.ProcessEnv = process.env,\n): Promise<void> {\n const configured = await createOutboxSidecarFromEnvironment(environment);\n if (!configured) throw new Error(\"Editable artifact outbox sidecar is disabled\");\n const server = Bun.serve({\n hostname: \"0.0.0.0\",\n port: configured.httpPort,\n fetch: configured.service.fetch,\n });\n const stop = () => configured.service.drain(\"process signal\");\n process.on(\"SIGTERM\", stop);\n process.on(\"SIGINT\", stop);\n try {\n await configured.service.run();\n } finally {\n process.off(\"SIGTERM\", stop);\n process.off(\"SIGINT\", stop);\n server.stop(true);\n await configured.service.close();\n }\n}\n\nif (import.meta.main) {\n await runEditableArtifactOutboxSidecar();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
2
|
+
observabilityEventBusOptions
|
|
3
|
+
} from "./chunk-DSPP6CZL.js";
|
|
4
4
|
|
|
5
5
|
// src/activity-services.ts
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
codeSearchDeploymentPolicy,
|
|
8
|
+
dbSearchPath,
|
|
9
|
+
getSettings,
|
|
10
|
+
resolveNatsControlPlaneAuth
|
|
11
|
+
} from "@opengeni/config";
|
|
12
|
+
import {
|
|
13
|
+
configureChildLifecycleNotices,
|
|
14
|
+
configureCodeSearchDeploymentPolicy,
|
|
15
|
+
createDb
|
|
16
|
+
} from "@opengeni/db";
|
|
8
17
|
import { createNatsEventBus } from "@opengeni/events";
|
|
9
18
|
import { createObservability } from "@opengeni/observability";
|
|
10
19
|
import { resolveCatalogSettings } from "@opengeni/core";
|
|
@@ -403,6 +412,7 @@ function createSharedActivityServices(dependencies) {
|
|
|
403
412
|
const db = dependencies.db ?? dbClient.db;
|
|
404
413
|
const resolvedSettings = (await resolveCatalogSettings(db, settings)).settings;
|
|
405
414
|
configureChildLifecycleNotices({ enabled: settings.childLifecycleNoticesEnabled });
|
|
415
|
+
configureCodeSearchDeploymentPolicy(codeSearchDeploymentPolicy(settings));
|
|
406
416
|
return {
|
|
407
417
|
settings: resolvedSettings,
|
|
408
418
|
catalogSourceSettings: settings,
|
|
@@ -410,7 +420,7 @@ function createSharedActivityServices(dependencies) {
|
|
|
410
420
|
bus: dependencies.bus ?? await createNatsEventBus(
|
|
411
421
|
settings.natsUrl,
|
|
412
422
|
controlPlaneAuth ? { user: controlPlaneAuth.user, pass: controlPlaneAuth.password } : void 0,
|
|
413
|
-
|
|
423
|
+
observabilityEventBusOptions(observability)
|
|
414
424
|
),
|
|
415
425
|
objectStorage: dependencies.objectStorage ?? createObjectStorage(settings),
|
|
416
426
|
observability,
|
|
@@ -5191,6 +5201,42 @@ var SandboxSiblingWarmingTimeoutError = class extends SandboxWarmingTimeoutError
|
|
|
5191
5201
|
this.name = "SandboxSiblingWarmingTimeoutError";
|
|
5192
5202
|
}
|
|
5193
5203
|
};
|
|
5204
|
+
var disposedUnreadyFreshSandboxErrors = /* @__PURE__ */ new WeakSet();
|
|
5205
|
+
function isReplaceableFreshSandboxReadinessTimeout(error) {
|
|
5206
|
+
return error instanceof SandboxExecReadinessTimeoutError && disposedUnreadyFreshSandboxErrors.has(error);
|
|
5207
|
+
}
|
|
5208
|
+
var FRESH_SANDBOX_READINESS_REPLACEMENT_BASE_DELAY_MS = 2e3;
|
|
5209
|
+
var FRESH_SANDBOX_READINESS_REPLACEMENT_JITTER_MS = 8e3;
|
|
5210
|
+
function freshSandboxReadinessReplacementDelayMs(random = Math.random) {
|
|
5211
|
+
const sample = random();
|
|
5212
|
+
const unit = Number.isFinite(sample) ? Math.min(Math.max(sample, 0), 1 - Number.EPSILON) : 0;
|
|
5213
|
+
return FRESH_SANDBOX_READINESS_REPLACEMENT_BASE_DELAY_MS + Math.floor(unit * FRESH_SANDBOX_READINESS_REPLACEMENT_JITTER_MS);
|
|
5214
|
+
}
|
|
5215
|
+
var FRESH_SANDBOX_READINESS_REPLACEMENTS_PER_TURN_ATTEMPT = 1;
|
|
5216
|
+
function createFreshSandboxReadinessReplacementBudget() {
|
|
5217
|
+
return { remaining: FRESH_SANDBOX_READINESS_REPLACEMENTS_PER_TURN_ATTEMPT };
|
|
5218
|
+
}
|
|
5219
|
+
function recordFreshSandboxReadinessReplacement(metrics, backend, outcome) {
|
|
5220
|
+
try {
|
|
5221
|
+
metrics?.onSandboxReadinessReplacement?.({ backend, outcome });
|
|
5222
|
+
} catch {
|
|
5223
|
+
}
|
|
5224
|
+
}
|
|
5225
|
+
async function sleepUnlessCancelled(ms, signal) {
|
|
5226
|
+
if (signal?.aborted) return false;
|
|
5227
|
+
if (ms <= 0) return true;
|
|
5228
|
+
return await new Promise((resolve) => {
|
|
5229
|
+
const onAbort = () => {
|
|
5230
|
+
clearTimeout(timer);
|
|
5231
|
+
resolve(false);
|
|
5232
|
+
};
|
|
5233
|
+
const timer = setTimeout(() => {
|
|
5234
|
+
signal?.removeEventListener("abort", onAbort);
|
|
5235
|
+
resolve(true);
|
|
5236
|
+
}, ms);
|
|
5237
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
5238
|
+
});
|
|
5239
|
+
}
|
|
5194
5240
|
var SandboxLeaseInstanceLostError = class extends SandboxLeaseSupersededError {
|
|
5195
5241
|
constructor(sandboxGroupId, leaseEpoch, lostInstanceId) {
|
|
5196
5242
|
super(sandboxGroupId, leaseEpoch);
|
|
@@ -5640,6 +5686,69 @@ async function persistWarmWorkspaceSnapshot(services, ids, session, leaseEpoch,
|
|
|
5640
5686
|
}
|
|
5641
5687
|
}
|
|
5642
5688
|
async function resumeBoxForTurn(services, ids, kind, holderId) {
|
|
5689
|
+
try {
|
|
5690
|
+
return await resumeBoxForTurnOnce(services, ids, kind, holderId);
|
|
5691
|
+
} catch (error) {
|
|
5692
|
+
if (!isReplaceableFreshSandboxReadinessTimeout(error)) throw error;
|
|
5693
|
+
const readiness = error;
|
|
5694
|
+
const warn = (message, fields) => {
|
|
5695
|
+
if (services.observability) services.observability.warn(message, fields);
|
|
5696
|
+
else console.warn(message, fields);
|
|
5697
|
+
};
|
|
5698
|
+
const identity = {
|
|
5699
|
+
workspaceId: ids.workspaceId,
|
|
5700
|
+
sessionId: ids.sessionId,
|
|
5701
|
+
sandboxGroupId: ids.sandboxGroupId,
|
|
5702
|
+
backend: readiness.backend,
|
|
5703
|
+
instanceId: readiness.instanceId,
|
|
5704
|
+
readinessTimeoutMs: readiness.timeoutMs
|
|
5705
|
+
};
|
|
5706
|
+
const budget = services.freshSandboxReadinessReplacementBudget ?? createFreshSandboxReadinessReplacementBudget();
|
|
5707
|
+
if (budget.remaining <= 0) {
|
|
5708
|
+
recordFreshSandboxReadinessReplacement(
|
|
5709
|
+
services.sandboxMetrics,
|
|
5710
|
+
readiness.backend,
|
|
5711
|
+
"budget_spent"
|
|
5712
|
+
);
|
|
5713
|
+
warn(
|
|
5714
|
+
"sandbox command-readiness timed out on a fresh box; this turn attempt already used its replacement",
|
|
5715
|
+
identity
|
|
5716
|
+
);
|
|
5717
|
+
throw error;
|
|
5718
|
+
}
|
|
5719
|
+
budget.remaining -= 1;
|
|
5720
|
+
const delayMs = await (services.freshSandboxReadinessReplacementDelayMs ?? freshSandboxReadinessReplacementDelayMs)();
|
|
5721
|
+
warn("sandbox command-readiness timed out on a fresh box; replacing it once after jitter", {
|
|
5722
|
+
...identity,
|
|
5723
|
+
replacementDelayMs: delayMs
|
|
5724
|
+
});
|
|
5725
|
+
if (!await sleepUnlessCancelled(delayMs, services.cancellationSignal)) {
|
|
5726
|
+
recordFreshSandboxReadinessReplacement(
|
|
5727
|
+
services.sandboxMetrics,
|
|
5728
|
+
readiness.backend,
|
|
5729
|
+
"cancelled"
|
|
5730
|
+
);
|
|
5731
|
+
throw error;
|
|
5732
|
+
}
|
|
5733
|
+
try {
|
|
5734
|
+
const replaced = await resumeBoxForTurnOnce(services, ids, kind, holderId);
|
|
5735
|
+
recordFreshSandboxReadinessReplacement(
|
|
5736
|
+
services.sandboxMetrics,
|
|
5737
|
+
readiness.backend,
|
|
5738
|
+
"replaced"
|
|
5739
|
+
);
|
|
5740
|
+
return replaced;
|
|
5741
|
+
} catch (replacementError) {
|
|
5742
|
+
recordFreshSandboxReadinessReplacement(
|
|
5743
|
+
services.sandboxMetrics,
|
|
5744
|
+
readiness.backend,
|
|
5745
|
+
services.cancellationSignal?.aborted ? "cancelled" : replacementError instanceof SandboxExecReadinessTimeoutError ? "failed_again" : "replacement_failed"
|
|
5746
|
+
);
|
|
5747
|
+
throw replacementError;
|
|
5748
|
+
}
|
|
5749
|
+
}
|
|
5750
|
+
}
|
|
5751
|
+
async function resumeBoxForTurnOnce(services, ids, kind, holderId) {
|
|
5643
5752
|
const { db, settings } = services;
|
|
5644
5753
|
const os = ids.os ?? "linux";
|
|
5645
5754
|
const leaseTtlMs = settings.sandboxLeaseTtlMs;
|
|
@@ -6080,9 +6189,15 @@ async function resumeBoxForTurn(services, ids, kind, holderId) {
|
|
|
6080
6189
|
});
|
|
6081
6190
|
createdEstablished = established;
|
|
6082
6191
|
throwIfReleasedOrCancelled();
|
|
6083
|
-
|
|
6084
|
-
|
|
6085
|
-
|
|
6192
|
+
if (services.verifySpawnedSandboxReadiness) {
|
|
6193
|
+
await services.verifySpawnedSandboxReadiness(established, {
|
|
6194
|
+
sandboxGroupId: ids.sandboxGroupId
|
|
6195
|
+
});
|
|
6196
|
+
} else {
|
|
6197
|
+
await waitForSandboxExecReadiness(established, MODAL_EXEC_READINESS_TIMEOUT_MS, {
|
|
6198
|
+
sandboxGroupId: ids.sandboxGroupId
|
|
6199
|
+
});
|
|
6200
|
+
}
|
|
6086
6201
|
await maybeRenewProviderExpiration(true);
|
|
6087
6202
|
throwIfReleasedOrCancelled();
|
|
6088
6203
|
const resumeEnvelope = requirePersistableReplacementSandboxEnvelope(
|
|
@@ -6176,6 +6291,9 @@ async function resumeBoxForTurn(services, ids, kind, holderId) {
|
|
|
6176
6291
|
}
|
|
6177
6292
|
await release();
|
|
6178
6293
|
recordSandboxWarmingTimeout(services.sandboxMetrics, error);
|
|
6294
|
+
if (terminated && createdEstablished && error instanceof SandboxExecReadinessTimeoutError && error.instanceId === createdEstablished.instanceId && (createdEstablished.origin === "created" || createdEstablished.origin === "restored") && !createdEstablished.providerContinuity) {
|
|
6295
|
+
disposedUnreadyFreshSandboxErrors.add(error);
|
|
6296
|
+
}
|
|
6179
6297
|
throw sandboxProvisionStageError(rematerialization ? "archive_recovery" : "create", error);
|
|
6180
6298
|
}
|
|
6181
6299
|
}
|
|
@@ -8696,6 +8814,9 @@ import {
|
|
|
8696
8814
|
RoutingWorkspaceRootChangedError,
|
|
8697
8815
|
SandboxMaterializationVerificationError,
|
|
8698
8816
|
materializationVerificationDiagnostic,
|
|
8817
|
+
PROVIDER_QUOTA_EXHAUSTED_CODE,
|
|
8818
|
+
classifyProviderQuotaError,
|
|
8819
|
+
providerQuotaExhaustedMessage,
|
|
8699
8820
|
SelfhostedWorkspaceRootChangedError,
|
|
8700
8821
|
UNKNOWN_MODEL_FINISH_REASON_CODE
|
|
8701
8822
|
} from "@opengeni/runtime";
|
|
@@ -9213,6 +9334,7 @@ function sandboxFilePath(resource, file) {
|
|
|
9213
9334
|
|
|
9214
9335
|
// src/activities/agent-turn/errors.ts
|
|
9215
9336
|
import {
|
|
9337
|
+
CODEX_USAGE_LIMIT_ERROR_TYPE,
|
|
9216
9338
|
CodexReloginRequired,
|
|
9217
9339
|
classifyCodexEncryptedArtifactRejection,
|
|
9218
9340
|
classifyCodexResponseTimeoutError,
|
|
@@ -9496,6 +9618,12 @@ function compactionFailureReasonFromError(error) {
|
|
|
9496
9618
|
`the model provider rejected the compaction request (${describeCompactionProviderRejection(rejection)}). Active history was preserved. ${COMPACTION_PROVIDER_REJECTION_GUIDANCE}`
|
|
9497
9619
|
);
|
|
9498
9620
|
}
|
|
9621
|
+
const quota = classifyProviderQuotaExhaustionError(error);
|
|
9622
|
+
if (quota) {
|
|
9623
|
+
return compactionFailureReason(
|
|
9624
|
+
`${providerQuotaExhaustedMessage(quota.scope)} Active history was preserved.`
|
|
9625
|
+
);
|
|
9626
|
+
}
|
|
9499
9627
|
if (error instanceof CompactionProviderResponseError || error instanceof EmptyCompactionSummaryError) {
|
|
9500
9628
|
return compactionFailureReason(error.message);
|
|
9501
9629
|
}
|
|
@@ -9504,13 +9632,15 @@ function compactionFailureReasonFromError(error) {
|
|
|
9504
9632
|
}
|
|
9505
9633
|
function compactionFailureTurnEventPayload(error, overrides = {}) {
|
|
9506
9634
|
const rejection = compactionProviderRejection(error);
|
|
9635
|
+
const quota = rejection ? null : classifyProviderQuotaExhaustionError(error);
|
|
9507
9636
|
return {
|
|
9508
9637
|
error: overrides.error ?? compactionFailureReasonFromError(error),
|
|
9509
9638
|
code: "context_compaction_failed",
|
|
9510
9639
|
retryable: false,
|
|
9511
9640
|
recovery: "user_message",
|
|
9512
9641
|
compacted: false,
|
|
9513
|
-
...rejection ? { providerRejection: rejection } : {}
|
|
9642
|
+
...rejection ? { providerRejection: rejection } : {},
|
|
9643
|
+
...quota ? { quotaScope: quota.scope } : {}
|
|
9514
9644
|
};
|
|
9515
9645
|
}
|
|
9516
9646
|
function isCompactionSummaryFailure(error) {
|
|
@@ -9614,6 +9744,13 @@ function isTransientProviderError(error) {
|
|
|
9614
9744
|
message
|
|
9615
9745
|
);
|
|
9616
9746
|
}
|
|
9747
|
+
function hasCodexUsageLimitType(error) {
|
|
9748
|
+
return collectErrorStrings(error).some((value) => value.includes(CODEX_USAGE_LIMIT_ERROR_TYPE));
|
|
9749
|
+
}
|
|
9750
|
+
function classifyProviderQuotaExhaustionError(error) {
|
|
9751
|
+
if (isCodexTransportError(error) || isXaiSubscriptionTransportError(error)) return null;
|
|
9752
|
+
return classifyProviderQuotaError(error);
|
|
9753
|
+
}
|
|
9617
9754
|
function classifyXaiCredentialFailure(error) {
|
|
9618
9755
|
if (isProviderSafetyRefusal(error)) return null;
|
|
9619
9756
|
let relogin = error;
|
|
@@ -9790,7 +9927,7 @@ function baseAgentRunFailurePayload(error, options = {}) {
|
|
|
9790
9927
|
};
|
|
9791
9928
|
}
|
|
9792
9929
|
const usageLimit = classifyCodexUsageLimitError(error);
|
|
9793
|
-
if (usageLimit) {
|
|
9930
|
+
if (usageLimit && (isCodexTransportError(error) || hasCodexUsageLimitType(error))) {
|
|
9794
9931
|
return codexUsageLimitFailurePayload(usageLimit, message);
|
|
9795
9932
|
}
|
|
9796
9933
|
const codexTimeout = classifyCodexResponseTimeoutError(error, {
|
|
@@ -9835,6 +9972,16 @@ function baseAgentRunFailurePayload(error, options = {}) {
|
|
|
9835
9972
|
retryable: true
|
|
9836
9973
|
};
|
|
9837
9974
|
}
|
|
9975
|
+
const quota = classifyProviderQuotaExhaustionError(error);
|
|
9976
|
+
if (quota) {
|
|
9977
|
+
return {
|
|
9978
|
+
error: providerQuotaExhaustedMessage(quota.scope),
|
|
9979
|
+
code: PROVIDER_QUOTA_EXHAUSTED_CODE,
|
|
9980
|
+
retryable: false,
|
|
9981
|
+
quotaScope: quota.scope,
|
|
9982
|
+
...message ? { detail: message } : {}
|
|
9983
|
+
};
|
|
9984
|
+
}
|
|
9838
9985
|
if (status === 429 || code === "rate_limit_exceeded" || /(?:too many requests|rate.?limit|\b429\b)/i.test(message)) {
|
|
9839
9986
|
return {
|
|
9840
9987
|
error: "Model provider rate limit hit. Try again in a minute or lower the reasoning effort.",
|
|
@@ -9990,6 +10137,7 @@ export {
|
|
|
9990
10137
|
persistWorkspaceArchiveCandidate,
|
|
9991
10138
|
putVersion1TarArchiveOrInline,
|
|
9992
10139
|
sandboxLeaseHolderIdForAttempt,
|
|
10140
|
+
createFreshSandboxReadinessReplacementBudget,
|
|
9993
10141
|
waitForWarmSnapshot,
|
|
9994
10142
|
maybePersistWarmWorkspaceSnapshot,
|
|
9995
10143
|
resumeBoxForTurn,
|
|
@@ -10071,4 +10219,4 @@ export {
|
|
|
10071
10219
|
codexUsageLimitFailurePayload,
|
|
10072
10220
|
CODEX_USAGE_LIMIT_MAX_RESUME_MS
|
|
10073
10221
|
};
|
|
10074
|
-
//# sourceMappingURL=chunk-
|
|
10222
|
+
//# sourceMappingURL=chunk-7M6G2SCF.js.map
|