@deepnoodle/mobius 0.0.21 → 0.0.22

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/worker.d.ts CHANGED
@@ -1,190 +1,92 @@
1
1
  import { Client } from "./client.js";
2
2
  export type InstanceIDSource = "configured" | "cloud_run_revision_instance" | "hostname" | "fly_machine_id" | "railway_replica_id" | "render_instance_id" | "system_hostname" | "generated_uuid";
3
- /**
4
- * Resolve a per-process `worker_instance_id` from the runtime
5
- * environment. Order: explicit → Cloud Run K_REVISION + metadata →
6
- * HOSTNAME env → FLY_MACHINE_ID → RAILWAY_REPLICA_ID →
7
- * RENDER_INSTANCE_ID → `os.hostname()` suffixed with a per-boot
8
- * random tag (laptops and bare metal) → generated UUID.
9
- *
10
- * The system_hostname rung carries a random suffix because
11
- * `os.hostname()` identifies the host, not the process — two
12
- * processes started on the same machine would otherwise auto-detect
13
- * the same identifier and collide on the server's conflict detector.
14
- * Set {@link WorkerConfig.workerInstanceId} explicitly only when a
15
- * stable identity across restarts is desired (named singleton
16
- * workers).
17
- *
18
- * The returned source is informational only — workers log it once at
19
- * startup so operators can confirm the right platform was picked up.
20
- */
21
3
  export declare function resolveInstanceID(explicit: string | undefined): Promise<{
22
4
  id: string;
23
5
  source: InstanceIDSource;
24
6
  }>;
25
- /**
26
- * Logger interface used by Worker for status and error output. Compatible with
27
- * the global `console` object, so `console` is a valid logger. Pass `null` to
28
- * `WorkerConfig.logger` to silence all output.
29
- */
30
7
  export interface Logger {
31
8
  info(...args: unknown[]): void;
32
9
  warn(...args: unknown[]): void;
33
10
  error(...args: unknown[]): void;
34
11
  }
12
+ export interface ModelCapability {
13
+ provider: string;
14
+ model: string;
15
+ }
35
16
  export interface WorkerConfig {
36
- /**
37
- * Identifier for this worker process. Leave omitted for the
38
- * common case: the SDK auto-detects an identifier that is unique
39
- * per running process. Resolution prefers platform-native IDs
40
- * that are unique-per-replica by design (Cloud Run revision
41
- * instance, Kubernetes HOSTNAME, Fly machine, Railway replica,
42
- * Render instance), then falls back to OS hostname plus a
43
- * per-boot random suffix so two processes on the same host
44
- * (back-to-back tests, parallel CI workers) cannot collide.
45
- *
46
- * Set this explicitly only when you want a stable identity
47
- * across restarts of a named singleton worker. Two live
48
- * processes using the same explicit value in the same project
49
- * will collide and the second will fail with
50
- * {@link WorkerInstanceConflictError}.
51
- */
52
17
  workerInstanceId?: string;
53
- /**
54
- * Maximum number of jobs this worker holds in flight simultaneously.
55
- * Defaults to 1; raise to claim several jobs from one worker process
56
- * while still surfacing as a single row on the workers page.
57
- */
58
18
  concurrency?: number;
59
- /** Human-readable name reported to Mobius (e.g. "billing-worker"). */
60
19
  name?: string;
61
- /** Version string reported to Mobius (e.g. "1.0.0"). */
62
20
  version?: string;
63
- /**
64
- * Queue names this worker subscribes to. Empty (or omitted) means claim
65
- * jobs from any queue in the project. Runs default to the "default"
66
- * queue.
67
- */
68
21
  queues?: string[];
69
- /**
70
- * Optional filter of action names this worker will claim. When empty the
71
- * worker will only claim jobs for actions it has registered.
72
- */
73
22
  actions?: string[];
74
- /** Long-poll window per claim request in seconds (0–30). Defaults to 20. */
75
- pollWaitSeconds?: number;
76
- /**
77
- * Heartbeat interval in milliseconds. When unset, the SDK uses the interval
78
- * advertised by the server in the claim response, falling back to 10_000.
79
- */
23
+ models?: ModelCapability[];
24
+ reconnectDelayMs?: number;
80
25
  heartbeatIntervalMs?: number;
81
- /**
82
- * Logger for worker status and error output. Defaults to `console`. Pass
83
- * `null` to silence all worker output, or supply a custom {@link Logger}
84
- * (e.g. pino, winston) to route messages elsewhere.
85
- */
86
26
  logger?: Logger | null;
87
- /** Max buffered custom events per in-flight job before dropping oldest. */
88
- eventQueueSize?: number;
89
- /** Max custom events per HTTP batch. Defaults to 20. */
90
- eventBatchSize?: number;
91
27
  }
92
- /**
93
- * ActionFn implements a single Mobius action. Receives the JSON-decoded
94
- * parameters delivered with the job claim and returns a JSON-serialisable
95
- * result.
96
- */
97
- export type ActionFn = (params: Record<string, unknown>, signal: AbortSignal, ctx: ActionContext) => Promise<unknown>;
98
28
  export interface ActionContext {
99
29
  jobId: string;
100
- runId: string;
30
+ runId?: string;
31
+ sessionId?: string;
32
+ agentTurnId?: string;
33
+ toolCallId?: string;
101
34
  projectId?: string;
102
35
  workerInstanceId: string;
103
36
  attempt: number;
104
37
  queue?: string;
105
- workflowName?: string;
106
- stepName?: string;
38
+ stepId?: string;
107
39
  action?: string;
108
40
  emitEvent(type: string, payload: Record<string, unknown>): void;
109
41
  }
110
- /**
111
- * Worker claims jobs from Mobius and dispatches each to the corresponding
112
- * registered action function. A *job* is a single action invocation on
113
- * behalf of a workflow run; the backend owns the workflow engine.
114
- *
115
- * With `concurrency > 1` the worker holds up to N jobs in flight
116
- * simultaneously, all reporting the same `worker_instance_id` and
117
- * session token; the admin UI shows one row with a saturation bar
118
- * rather than N independent rows.
119
- */
42
+ export type ActionFn = (params: Record<string, unknown>, signal: AbortSignal, ctx: ActionContext) => Promise<unknown>;
43
+ export interface GenerationJob {
44
+ jobId: string;
45
+ runId?: string;
46
+ sessionId?: string;
47
+ agentTurnId?: string;
48
+ toolCallId?: string;
49
+ provider?: string;
50
+ model?: string;
51
+ spec: Record<string, unknown>;
52
+ }
53
+ export type GenerationEmitter = (delta: Record<string, unknown>) => void;
54
+ export type GenerationFn = (ctx: ActionContext, job: GenerationJob, emit: GenerationEmitter) => Promise<Record<string, unknown>>;
120
55
  export declare class Worker {
121
56
  private readonly client;
122
57
  private readonly config;
123
58
  private readonly logger;
124
59
  private readonly actions;
125
- private readonly sessionToken;
126
- private instanceIDResolved;
127
- private abortController;
128
- private authRevoked;
129
- constructor(client: Client, config: WorkerConfig, actions?: Map<string, ActionFn>);
130
- /** Register an action function under the given name. */
60
+ private readonly generators;
61
+ private sessionToken;
62
+ private stopping;
63
+ private readonly stopController;
64
+ constructor(client: Client, config?: WorkerConfig, actions?: Map<string, ActionFn>);
131
65
  register(name: string, fn: ActionFn): this;
132
- /**
133
- * Start the claim loop. Returns a promise that resolves when the worker is
134
- * stopped via {@link stop} or the given signal is aborted. Throws
135
- * {@link AuthRevokedError} when the credential is revoked mid-flight
136
- * and {@link WorkerInstanceConflictError} when another live process
137
- * has already registered this worker_instance_id.
138
- *
139
- * Cancellation has two distinct shapes:
140
- *
141
- * - {@link stop} aborts the claim loop only — in-flight jobs continue
142
- * to run to natural completion and the returned promise resolves
143
- * once they all settle. This is graceful drain.
144
- * - The caller's `signal`, when aborted, propagates into both the
145
- * claim loop and every running action. This is the emergency-stop
146
- * path (e.g. SIGTERM with a hard deadline).
147
- */
148
- run(signal?: AbortSignal): Promise<void>;
149
- /** Gracefully stop the worker after in-flight jobs complete. */
66
+ registerGenerator(provider: string, model: string, fn: GenerationFn): this;
150
67
  stop(): void;
68
+ run(signal?: AbortSignal): Promise<void>;
69
+ private runSocket;
70
+ private registerFrame;
71
+ private claim;
72
+ private modelCapabilities;
151
73
  private executeJob;
152
- private heartbeatInterval;
153
- private failJob;
74
+ private generator;
75
+ private actionContext;
76
+ private report;
154
77
  }
155
78
  export interface WorkerPoolConfig extends Omit<WorkerConfig, "workerInstanceId"> {
156
- /** Number of worker instances to run. Defaults to 1. */
157
79
  count?: number;
158
- /**
159
- * Prefix used to derive child instance IDs as `<prefix>-<index>`.
160
- * When omitted, the SDK generates a per-boot prefix; child workers
161
- * each get their own session token, so a pool of N produces N rows
162
- * on the workers page.
163
- */
164
80
  workerInstanceIdPrefix?: string;
165
81
  }
166
- /**
167
- * Runs multiple worker instances in one process. Most callers do not
168
- * need a pool — to run several jobs from one process, set
169
- * {@link WorkerConfig.concurrency} on a single {@link Worker} and the
170
- * admin UI will show one row with a saturation bar. Reach for a pool
171
- * only when each child should surface as its own row on the workers
172
- * page (independent draining, in-flight isolation).
173
- */
174
82
  export declare class WorkerPool {
175
83
  private readonly client;
176
84
  private readonly config;
177
85
  private readonly actions;
178
- private abortController;
86
+ private readonly generators;
179
87
  constructor(client: Client, config: WorkerPoolConfig);
180
- /** Register an action function under the given name for every pool worker. */
181
88
  register(name: string, fn: ActionFn): this;
182
- /**
183
- * Start all workers in the pool. Rejects with AuthRevokedError if any child
184
- * worker sees credential revocation.
185
- */
89
+ registerGenerator(provider: string, model: string, fn: GenerationFn): this;
186
90
  run(signal?: AbortSignal): Promise<void>;
187
- /** Gracefully stop every worker in the pool after in-flight jobs complete. */
188
- stop(): void;
189
91
  }
190
92
  //# sourceMappingURL=worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}