/** * Run Executor * * Executes sync and action runs in a V8 isolate from compiled connector code. * Generates embeddings and streams results. */ import type { Env } from '@lobu/connector-sdk'; import type { AgentKind } from '@lobu/core/contracts/worker/device-automation'; import type { ExecutorClient, PollResponse } from './client.js'; import type { SyncExecutor } from '../executor/interface.js'; /** * Resolve the executable compiled code for a job. * * The gateway prefers omitting `compiled_code` for fleet workers and * relying on this side to find + compile the source locally from * `connector_key`. This saves the ~13 MB inline blob in poll responses * (lobu#771 postmortem trail; lobu#772 perf fix). Device workers and * DB-only user-uploaded connectors still receive `compiled_code` * directly — they don't have the connector source on disk. * * Gateway and worker images have different paths to the bundled source, * so the gateway sends only `connector_key` and each side resolves it * against its own filesystem. * * Returns `{ code }` on success or `{ error }` on failure. Callers must * surface the error to the gateway via `client.complete*` rather than * throwing — the daemon-level catch only logs, leaving runs stuck * `running` until stale-run reaping. */ type JobCodeResult = { ok: true; code: string; } | { ok: false; error: string; }; export declare function resolveJobCode(job: PollResponse): Promise; export interface ExecutorConfig { batchSize: number; heartbeatIntervalMs: number; /** Test-only override; production deliberately uses the 15-second default. */ terminalHeartbeatGraceMs?: number; generateEmbeddings: boolean; timeoutMs: number; /** Optional executor override (tests / custom runner). */ executor?: SyncExecutor; /** Daemon lifecycle signal used only by pending interactive handoffs. */ shutdownSignal?: AbortSignal; /** Local agent kind used when an Automation omits agent_kind. */ defaultAgentKind?: AgentKind; /** * Explicit per-agent binary paths for the automation arm (else PATH lookup). * Lets an operator point the daemon at a non-PATH CLI install, and is the * injection seam the automation e2e test uses to drive a fake binary. */ binaryOverrides?: Partial>; } /** * What a lane runs with when its caller overrides nothing — which is what the * fleet entrypoint (`embedded-connector-worker.ts`) does. Exported so a test * can assert what a lane does under the SHIPPED configuration instead of a * copy of these numbers that is free to drift away from them. */ export declare const DEFAULT_CONFIG: ExecutorConfig; /** * Fold the gateway's authoritative DB egress config into the worker's env. * * The gateway (which knows cloud mode authoritatively) ships `db_egress_policy` * on the poll response. The worker's own `env.LOBU_DB_EGRESS_POLICY` is derived * from the worker process's `LOBU_CLOUD_MODE`, which a fleet worker may not have * set — leaving it `allow-private` and the SSRF guard silently OFF. * * We resolve the STRICTER of the two: `block-private` wins over `allow-private` * from either side. This makes the gateway able to *raise* the boundary (a * block-private gateway forces block-private even on a worker missing the flag) * while never letting a stale/misconfigured gateway response *downgrade* a * worker that already decided block-private. The result is re-asserted as * authoritative `job.env.LOBU_DB_EGRESS_POLICY` by `buildConnectorConfig` in the * child so tenant config can't override it either. * * The gateway allow-host list replaces any worker-local value. A missing list * means no exemptions, so a worker cannot widen the gateway's boundary. * * Deployment provider credentials (`DEPLOYMENT_PROVIDER_ENV_KEYS`) follow the * run's PROVENANCE: under block-private a job that arrives with `compiled_code` * is organization-supplied (the gateway omits the bytes for connectors the * image ships, so this worker compiles those from its own image), and tenant * code never sees the operator's provider apps. The keys stay for image-shipped * code, which is how a bundled Reddit feed on a shared worker authenticates. */ export declare function resolveEffectiveEnv(env: Env, job: PollResponse): Env; /** * Execute a run (sync, action, automation, embed_backfill, or auth). * * Dispatches by `run_type` and NEVER throws: every lane reports its own * terminal state via the lane-appropriate `client.complete*` endpoint, and an * unexpected error here is likewise terminated before it can leave a claimed * run stuck `running` (the daemon's fire-and-forget `.catch` only logs). */ export declare function executeRun(client: ExecutorClient, job: PollResponse, workerEnv: Env, config?: Partial): Promise<{ itemsCollected: number; error?: string; }>; export {}; //# sourceMappingURL=executor.d.ts.map