flatmachines 1.0.0__py3-none-any.whl
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.
- flatmachines/__init__.py +136 -0
- flatmachines/actions.py +408 -0
- flatmachines/adapters/__init__.py +38 -0
- flatmachines/adapters/flatagent.py +86 -0
- flatmachines/adapters/pi_agent_bridge.py +127 -0
- flatmachines/adapters/pi_agent_runner.mjs +99 -0
- flatmachines/adapters/smolagents.py +125 -0
- flatmachines/agents.py +144 -0
- flatmachines/assets/MACHINES.md +141 -0
- flatmachines/assets/README.md +11 -0
- flatmachines/assets/__init__.py +0 -0
- flatmachines/assets/flatagent.d.ts +219 -0
- flatmachines/assets/flatagent.schema.json +271 -0
- flatmachines/assets/flatagent.slim.d.ts +58 -0
- flatmachines/assets/flatagents-runtime.d.ts +523 -0
- flatmachines/assets/flatagents-runtime.schema.json +281 -0
- flatmachines/assets/flatagents-runtime.slim.d.ts +187 -0
- flatmachines/assets/flatmachine.d.ts +403 -0
- flatmachines/assets/flatmachine.schema.json +620 -0
- flatmachines/assets/flatmachine.slim.d.ts +106 -0
- flatmachines/assets/profiles.d.ts +140 -0
- flatmachines/assets/profiles.schema.json +93 -0
- flatmachines/assets/profiles.slim.d.ts +26 -0
- flatmachines/backends.py +222 -0
- flatmachines/distributed.py +835 -0
- flatmachines/distributed_hooks.py +351 -0
- flatmachines/execution.py +638 -0
- flatmachines/expressions/__init__.py +60 -0
- flatmachines/expressions/cel.py +101 -0
- flatmachines/expressions/simple.py +166 -0
- flatmachines/flatmachine.py +1263 -0
- flatmachines/hooks.py +381 -0
- flatmachines/locking.py +69 -0
- flatmachines/monitoring.py +505 -0
- flatmachines/persistence.py +213 -0
- flatmachines/run.py +117 -0
- flatmachines/utils.py +166 -0
- flatmachines/validation.py +79 -0
- flatmachines-1.0.0.dist-info/METADATA +390 -0
- flatmachines-1.0.0.dist-info/RECORD +41 -0
- flatmachines-1.0.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlatAgents Runtime Interface Spec
|
|
3
|
+
* ==================================
|
|
4
|
+
*
|
|
5
|
+
* This file defines the runtime interfaces that SDKs MUST implement
|
|
6
|
+
* to be considered compliant. These are NOT configuration schemas
|
|
7
|
+
* (see flatagent.d.ts and flatmachine.d.ts for those).
|
|
8
|
+
*
|
|
9
|
+
* REQUIRED IMPLEMENTATIONS:
|
|
10
|
+
* -------------------------
|
|
11
|
+
* - ExecutionLock: NoOpLock (MUST), LocalFileLock (SHOULD)
|
|
12
|
+
* - PersistenceBackend: MemoryBackend (MUST), LocalFileBackend (SHOULD)
|
|
13
|
+
* - ResultBackend: InMemoryResultBackend (MUST)
|
|
14
|
+
* - ExecutionType: Default, Retry, Parallel, MDAPVoting (MUST)
|
|
15
|
+
* - MachineHooks: Base interface (MUST)
|
|
16
|
+
* - RegistrationBackend: SQLiteRegistrationBackend (MUST), MemoryRegistrationBackend (SHOULD)
|
|
17
|
+
* - WorkBackend: SQLiteWorkBackend (MUST), MemoryWorkBackend (SHOULD)
|
|
18
|
+
*
|
|
19
|
+
* OPTIONAL IMPLEMENTATIONS:
|
|
20
|
+
* -------------------------
|
|
21
|
+
* - Distributed backends (Redis, Postgres, etc.)
|
|
22
|
+
* - LLMBackend (SDK may use native provider SDKs)
|
|
23
|
+
*
|
|
24
|
+
* EXECUTION LOCKING:
|
|
25
|
+
* ------------------
|
|
26
|
+
* Prevents concurrent execution of the same machine instance.
|
|
27
|
+
*
|
|
28
|
+
* SDKs MUST provide:
|
|
29
|
+
* - NoOpLock: For when locking is handled externally or disabled
|
|
30
|
+
*
|
|
31
|
+
* SDKs SHOULD provide:
|
|
32
|
+
* - LocalFileLock: For single-node deployments using fcntl/flock
|
|
33
|
+
*
|
|
34
|
+
* Distributed deployments should implement Redis/Consul/etcd locks.
|
|
35
|
+
*
|
|
36
|
+
* PERSISTENCE BACKEND:
|
|
37
|
+
* --------------------
|
|
38
|
+
* Storage backend for machine checkpoints.
|
|
39
|
+
*
|
|
40
|
+
* SDKs MUST provide:
|
|
41
|
+
* - MemoryBackend: For testing and ephemeral runs
|
|
42
|
+
*
|
|
43
|
+
* SDKs SHOULD provide:
|
|
44
|
+
* - LocalFileBackend: For durable local storage with atomic writes
|
|
45
|
+
*
|
|
46
|
+
* RESULT BACKEND:
|
|
47
|
+
* ---------------
|
|
48
|
+
* Inter-machine communication via URI-addressed results.
|
|
49
|
+
*
|
|
50
|
+
* URI format: flatagents://{execution_id}/{path}
|
|
51
|
+
* - path is typically "result" or "checkpoint"
|
|
52
|
+
*
|
|
53
|
+
* SDKs MUST provide:
|
|
54
|
+
* - InMemoryResultBackend: For single-process execution
|
|
55
|
+
*
|
|
56
|
+
* EXECUTION TYPES:
|
|
57
|
+
* ----------------
|
|
58
|
+
* Execution strategy for agent calls.
|
|
59
|
+
*
|
|
60
|
+
* SDKs MUST implement all four types:
|
|
61
|
+
* - default: Single call, no retry
|
|
62
|
+
* - retry: Configurable backoffs with jitter
|
|
63
|
+
* - parallel: Run N samples, return all successes
|
|
64
|
+
* - mdap_voting: Multi-sample with consensus voting
|
|
65
|
+
*
|
|
66
|
+
* MACHINE HOOKS:
|
|
67
|
+
* --------------
|
|
68
|
+
* Extension points for machine execution.
|
|
69
|
+
* All methods are optional and can be sync or async.
|
|
70
|
+
*
|
|
71
|
+
* SDKs SHOULD provide:
|
|
72
|
+
* - WebhookHooks: Send events to HTTP endpoint
|
|
73
|
+
* - CompositeHooks: Combine multiple hook implementations
|
|
74
|
+
*
|
|
75
|
+
* LLM BACKEND (OPTIONAL):
|
|
76
|
+
* -----------------------
|
|
77
|
+
* Abstraction over LLM providers.
|
|
78
|
+
*
|
|
79
|
+
* This interface is OPTIONAL - SDKs may use provider SDKs directly.
|
|
80
|
+
* Useful for:
|
|
81
|
+
* - Unified retry/monitoring across providers
|
|
82
|
+
* - Provider-agnostic code
|
|
83
|
+
* - Testing with mock backends
|
|
84
|
+
*
|
|
85
|
+
* MACHINE INVOKER:
|
|
86
|
+
* ----------------
|
|
87
|
+
* Interface for invoking peer machines.
|
|
88
|
+
* Used internally by FlatMachine for `machine:` and `launch:` states.
|
|
89
|
+
*
|
|
90
|
+
* BACKEND CONFIGURATION:
|
|
91
|
+
* ----------------------
|
|
92
|
+
* Backend configuration for machine settings.
|
|
93
|
+
*
|
|
94
|
+
* Example in YAML:
|
|
95
|
+
* settings:
|
|
96
|
+
* backends:
|
|
97
|
+
* persistence: local
|
|
98
|
+
* locking: none
|
|
99
|
+
* results: memory
|
|
100
|
+
*/
|
|
101
|
+
|
|
102
|
+
export interface ExecutionLock {
|
|
103
|
+
/**
|
|
104
|
+
* Attempt to acquire exclusive lock for the given key.
|
|
105
|
+
* MUST be non-blocking - returns immediately.
|
|
106
|
+
*
|
|
107
|
+
* @param key - Typically the execution_id
|
|
108
|
+
* @returns true if lock acquired, false if already held by another process
|
|
109
|
+
*/
|
|
110
|
+
acquire(key: string): Promise<boolean>;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Release the lock for the given key.
|
|
114
|
+
* Safe to call even if lock not held.
|
|
115
|
+
*/
|
|
116
|
+
release(key: string): Promise<void>;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface PersistenceBackend {
|
|
120
|
+
/**
|
|
121
|
+
* Save a checkpoint snapshot.
|
|
122
|
+
* MUST be atomic - either fully written or not at all.
|
|
123
|
+
*
|
|
124
|
+
* @param key - Checkpoint identifier (e.g., "{execution_id}/step_{step}")
|
|
125
|
+
* @param snapshot - The machine state to persist
|
|
126
|
+
*/
|
|
127
|
+
save(key: string, snapshot: MachineSnapshot): Promise<void>;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Load a checkpoint snapshot.
|
|
131
|
+
* @returns The snapshot, or null if not found
|
|
132
|
+
*/
|
|
133
|
+
load(key: string): Promise<MachineSnapshot | null>;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Delete a checkpoint.
|
|
137
|
+
* Safe to call if key doesn't exist.
|
|
138
|
+
*/
|
|
139
|
+
delete(key: string): Promise<void>;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* List all keys matching a prefix.
|
|
143
|
+
* Used to find all checkpoints for an execution.
|
|
144
|
+
*
|
|
145
|
+
* @param prefix - Key prefix to match (e.g., "{execution_id}/")
|
|
146
|
+
* @returns Array of matching keys, sorted lexicographically
|
|
147
|
+
*/
|
|
148
|
+
list(prefix: string): Promise<string[]>;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface ResultBackend {
|
|
152
|
+
/**
|
|
153
|
+
* Write data to a URI.
|
|
154
|
+
* MUST notify any blocked readers.
|
|
155
|
+
*/
|
|
156
|
+
write(uri: string, data: any): Promise<void>;
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Read data from a URI.
|
|
160
|
+
*
|
|
161
|
+
* @param uri - The flatagents:// URI
|
|
162
|
+
* @param options.block - If true, wait until data is available
|
|
163
|
+
* @param options.timeout - Max ms to wait (undefined = forever)
|
|
164
|
+
* @returns The data, or undefined if not found and block=false
|
|
165
|
+
* @throws TimeoutError if timeout expires while blocking
|
|
166
|
+
*/
|
|
167
|
+
read(uri: string, options?: {
|
|
168
|
+
block?: boolean;
|
|
169
|
+
timeout?: number;
|
|
170
|
+
}): Promise<any>;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Check if data exists at a URI without reading it.
|
|
174
|
+
*/
|
|
175
|
+
exists(uri: string): Promise<boolean>;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Delete data at a URI.
|
|
179
|
+
* Safe to call if URI doesn't exist.
|
|
180
|
+
*/
|
|
181
|
+
delete(uri: string): Promise<void>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export interface AgentResult {
|
|
185
|
+
output?: Record<string, any> | null;
|
|
186
|
+
content?: string | null;
|
|
187
|
+
raw?: any;
|
|
188
|
+
usage?: Record<string, any> | null;
|
|
189
|
+
cost?: number | null;
|
|
190
|
+
metadata?: Record<string, any> | null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export interface AgentExecutor {
|
|
194
|
+
execute(input: Record<string, any>, context?: Record<string, any>): Promise<AgentResult>;
|
|
195
|
+
metadata?: Record<string, any>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export interface ExecutionType {
|
|
199
|
+
/**
|
|
200
|
+
* Execute an agent with this strategy.
|
|
201
|
+
*/
|
|
202
|
+
execute(executor: AgentExecutor, input: Record<string, any>, context?: Record<string, any>): Promise<AgentResult>;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface ExecutionConfig {
|
|
206
|
+
type: "default" | "retry" | "parallel" | "mdap_voting";
|
|
207
|
+
|
|
208
|
+
// retry options
|
|
209
|
+
backoffs?: number[]; // seconds between retries
|
|
210
|
+
jitter?: number; // random factor (0-1)
|
|
211
|
+
|
|
212
|
+
// parallel/mdap options
|
|
213
|
+
n_samples?: number; // number of parallel calls
|
|
214
|
+
k_margin?: number; // mdap consensus threshold
|
|
215
|
+
max_candidates?: number;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export interface MachineHooks {
|
|
219
|
+
/** Called once at machine start. Can modify initial context. */
|
|
220
|
+
onMachineStart?(context: Record<string, any>): Record<string, any> | Promise<Record<string, any>>;
|
|
221
|
+
|
|
222
|
+
/** Called once at machine end. Can modify final output. */
|
|
223
|
+
onMachineEnd?(context: Record<string, any>, output: any): any | Promise<any>;
|
|
224
|
+
|
|
225
|
+
/** Called before each state execution. Can modify context. */
|
|
226
|
+
onStateEnter?(state: string, context: Record<string, any>): Record<string, any> | Promise<Record<string, any>>;
|
|
227
|
+
|
|
228
|
+
/** Called after each state execution. Can modify output. */
|
|
229
|
+
onStateExit?(state: string, context: Record<string, any>, output: any): any | Promise<any>;
|
|
230
|
+
|
|
231
|
+
/** Called before transition. Can redirect to different state. */
|
|
232
|
+
onTransition?(from: string, to: string, context: Record<string, any>): string | Promise<string>;
|
|
233
|
+
|
|
234
|
+
/** Called on error. Return state name to recover, null to propagate. */
|
|
235
|
+
onError?(state: string, error: Error, context: Record<string, any>): string | null | Promise<string | null>;
|
|
236
|
+
|
|
237
|
+
/** Called for custom actions defined in state config. */
|
|
238
|
+
onAction?(action: string, context: Record<string, any>): Record<string, any> | Promise<Record<string, any>>;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export interface LLMBackend {
|
|
242
|
+
/** Total cost accumulated across all calls. */
|
|
243
|
+
totalCost: number;
|
|
244
|
+
|
|
245
|
+
/** Total API calls made. */
|
|
246
|
+
totalApiCalls: number;
|
|
247
|
+
|
|
248
|
+
/** Call LLM and return content string. */
|
|
249
|
+
call(messages: Message[], options?: LLMOptions): Promise<string>;
|
|
250
|
+
|
|
251
|
+
/** Call LLM and return raw provider response. */
|
|
252
|
+
callRaw(messages: Message[], options?: LLMOptions): Promise<any>;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface Message {
|
|
256
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
257
|
+
content: string;
|
|
258
|
+
tool_call_id?: string;
|
|
259
|
+
tool_calls?: ToolCall[];
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export interface ToolCall {
|
|
263
|
+
id: string;
|
|
264
|
+
type: "function";
|
|
265
|
+
function: {
|
|
266
|
+
name: string;
|
|
267
|
+
arguments: string; // JSON string
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface LLMOptions {
|
|
272
|
+
temperature?: number;
|
|
273
|
+
max_tokens?: number;
|
|
274
|
+
tools?: ToolDefinition[];
|
|
275
|
+
response_format?: { type: "json_object" } | { type: "text" };
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export interface ToolDefinition {
|
|
279
|
+
type: "function";
|
|
280
|
+
function: {
|
|
281
|
+
name: string;
|
|
282
|
+
description?: string;
|
|
283
|
+
parameters?: Record<string, any>; // JSON Schema
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export interface MachineInvoker {
|
|
288
|
+
/**
|
|
289
|
+
* Invoke a machine and wait for result.
|
|
290
|
+
*/
|
|
291
|
+
invoke(
|
|
292
|
+
machineName: string,
|
|
293
|
+
input: Record<string, any>,
|
|
294
|
+
options?: { timeout?: number }
|
|
295
|
+
): Promise<Record<string, any>>;
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Launch a machine fire-and-forget style.
|
|
299
|
+
* @returns The execution_id of the launched machine
|
|
300
|
+
*/
|
|
301
|
+
launch(
|
|
302
|
+
machineName: string,
|
|
303
|
+
input: Record<string, any>
|
|
304
|
+
): Promise<string>;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
export interface MachineSnapshot {
|
|
308
|
+
execution_id: string;
|
|
309
|
+
machine_name: string;
|
|
310
|
+
spec_version: string;
|
|
311
|
+
current_state: string;
|
|
312
|
+
context: Record<string, any>;
|
|
313
|
+
step: number;
|
|
314
|
+
created_at: string;
|
|
315
|
+
event?: string;
|
|
316
|
+
output?: Record<string, any>;
|
|
317
|
+
total_api_calls?: number;
|
|
318
|
+
total_cost?: number;
|
|
319
|
+
parent_execution_id?: string;
|
|
320
|
+
pending_launches?: LaunchIntent[];
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export interface LaunchIntent {
|
|
324
|
+
execution_id: string;
|
|
325
|
+
machine: string;
|
|
326
|
+
input: Record<string, any>;
|
|
327
|
+
launched: boolean;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* REGISTRATION BACKEND:
|
|
332
|
+
* ---------------------
|
|
333
|
+
* Worker lifecycle management for distributed execution.
|
|
334
|
+
*
|
|
335
|
+
* SDKs MUST provide:
|
|
336
|
+
* - SQLiteRegistrationBackend: For local deployments
|
|
337
|
+
*
|
|
338
|
+
* SDKs SHOULD provide:
|
|
339
|
+
* - MemoryRegistrationBackend: For testing
|
|
340
|
+
*
|
|
341
|
+
* Implementation notes:
|
|
342
|
+
* - Time units: Python reference SDK uses seconds for all interval values
|
|
343
|
+
* - Stale threshold: SDKs SHOULD default to 2× heartbeat_interval if not specified
|
|
344
|
+
*/
|
|
345
|
+
export interface RegistrationBackend {
|
|
346
|
+
/**
|
|
347
|
+
* Register a new worker.
|
|
348
|
+
* Creates a new worker record with status "active".
|
|
349
|
+
*/
|
|
350
|
+
register(worker: WorkerRegistration): Promise<WorkerRecord>;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Update worker's last_heartbeat timestamp.
|
|
354
|
+
* Can optionally update metadata.
|
|
355
|
+
*/
|
|
356
|
+
heartbeat(worker_id: string, metadata?: Record<string, any>): Promise<void>;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Update worker status.
|
|
360
|
+
* Status values (string, not enum for extensibility):
|
|
361
|
+
* - "active": Worker is running and healthy
|
|
362
|
+
* - "terminating": Worker received shutdown signal
|
|
363
|
+
* - "terminated": Worker exited cleanly
|
|
364
|
+
* - "lost": Worker failed heartbeat, presumed dead
|
|
365
|
+
*/
|
|
366
|
+
updateStatus(worker_id: string, status: string): Promise<void>;
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Get a worker record by ID.
|
|
370
|
+
* @returns The worker record, or null if not found
|
|
371
|
+
*/
|
|
372
|
+
get(worker_id: string): Promise<WorkerRecord | null>;
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* List workers matching filter criteria.
|
|
376
|
+
*/
|
|
377
|
+
list(filter?: WorkerFilter): Promise<WorkerRecord[]>;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export interface WorkerRegistration {
|
|
381
|
+
worker_id: string;
|
|
382
|
+
host?: string;
|
|
383
|
+
pid?: number;
|
|
384
|
+
capabilities?: string[]; // e.g., ["gpu", "paper-analysis"]
|
|
385
|
+
pool_id?: string; // Worker pool grouping
|
|
386
|
+
started_at: string;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export interface WorkerRecord extends WorkerRegistration {
|
|
390
|
+
status: string; // See status values in RegistrationBackend.updateStatus
|
|
391
|
+
last_heartbeat: string;
|
|
392
|
+
current_task_id?: string;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
export interface WorkerFilter {
|
|
396
|
+
status?: string | string[];
|
|
397
|
+
capability?: string;
|
|
398
|
+
pool_id?: string;
|
|
399
|
+
stale_threshold_seconds?: number; // Filter workers with old heartbeats
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* WORK BACKEND:
|
|
404
|
+
* -------------
|
|
405
|
+
* Work distribution via named pools with atomic claim.
|
|
406
|
+
*
|
|
407
|
+
* SDKs MUST provide:
|
|
408
|
+
* - SQLiteWorkBackend: For local deployments
|
|
409
|
+
*
|
|
410
|
+
* SDKs SHOULD provide:
|
|
411
|
+
* - MemoryWorkBackend: For testing
|
|
412
|
+
*
|
|
413
|
+
* Implementation notes:
|
|
414
|
+
* - Atomic claim: SDKs MUST ensure no two workers can claim the same job
|
|
415
|
+
* - Test requirements: Include concurrent claim race condition tests
|
|
416
|
+
*/
|
|
417
|
+
export interface WorkBackend {
|
|
418
|
+
/**
|
|
419
|
+
* Get a named work pool.
|
|
420
|
+
* Creates the pool if it doesn't exist.
|
|
421
|
+
*/
|
|
422
|
+
pool(name: string): WorkPool;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
export interface WorkPool {
|
|
426
|
+
/**
|
|
427
|
+
* Add work item to the pool.
|
|
428
|
+
* @param item - The work data (will be JSON serialized)
|
|
429
|
+
* @param options.max_retries - Max retry attempts before poisoning (default: 3)
|
|
430
|
+
* @returns The item ID
|
|
431
|
+
*/
|
|
432
|
+
push(item: any, options?: { max_retries?: number }): Promise<string>;
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Atomically claim next available item.
|
|
436
|
+
* MUST be atomic - no two workers can claim the same job.
|
|
437
|
+
* @returns The claimed item, or null if pool is empty
|
|
438
|
+
*/
|
|
439
|
+
claim(worker_id: string): Promise<WorkItem | null>;
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Mark item as complete.
|
|
443
|
+
* Sets status to "done" and stores result.
|
|
444
|
+
*/
|
|
445
|
+
complete(item_id: string, result?: any): Promise<void>;
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Mark item as failed.
|
|
449
|
+
* Increments attempts. If attempts >= max_retries, marks as "poisoned".
|
|
450
|
+
* Otherwise returns to "pending" status for retry.
|
|
451
|
+
*/
|
|
452
|
+
fail(item_id: string, error?: string): Promise<void>;
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Get pool depth (unclaimed pending items).
|
|
456
|
+
*/
|
|
457
|
+
size(): Promise<number>;
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Release all jobs claimed by a worker.
|
|
461
|
+
* Used for stale worker cleanup.
|
|
462
|
+
* @returns Number of jobs released
|
|
463
|
+
*/
|
|
464
|
+
releaseByWorker(worker_id: string): Promise<number>;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export interface WorkItem {
|
|
468
|
+
id: string;
|
|
469
|
+
data: any;
|
|
470
|
+
claimed_by?: string;
|
|
471
|
+
claimed_at?: string;
|
|
472
|
+
attempts: number;
|
|
473
|
+
max_retries: number; // default: 3
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Job status values (string):
|
|
477
|
+
// - "pending": Available for claim
|
|
478
|
+
// - "claimed": Currently being processed
|
|
479
|
+
// - "done": Successfully completed
|
|
480
|
+
// - "poisoned": Failed max_retries times, will not be retried
|
|
481
|
+
|
|
482
|
+
export interface BackendConfig {
|
|
483
|
+
/** Checkpoint storage. Default: memory */
|
|
484
|
+
persistence?: "memory" | "local" | "redis" | "postgres" | "s3";
|
|
485
|
+
|
|
486
|
+
/** Execution locking. Default: none */
|
|
487
|
+
locking?: "none" | "local" | "redis" | "consul";
|
|
488
|
+
|
|
489
|
+
/** Inter-machine results. Default: memory */
|
|
490
|
+
results?: "memory" | "redis";
|
|
491
|
+
|
|
492
|
+
/** Worker registration. Default: memory */
|
|
493
|
+
registration?: "memory" | "sqlite" | "redis";
|
|
494
|
+
|
|
495
|
+
/** Work pool. Default: memory */
|
|
496
|
+
work?: "memory" | "sqlite" | "redis";
|
|
497
|
+
|
|
498
|
+
/** Path for sqlite backends (registration and work share this) */
|
|
499
|
+
sqlite_path?: string;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export const SPEC_VERSION = "1.0.0";
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Wrapper interface for JSON schema generation.
|
|
506
|
+
* Groups all runtime interfaces that SDKs must implement.
|
|
507
|
+
*/
|
|
508
|
+
export interface SDKRuntimeWrapper {
|
|
509
|
+
spec: "flatagents-runtime";
|
|
510
|
+
spec_version: typeof SPEC_VERSION;
|
|
511
|
+
execution_lock?: ExecutionLock;
|
|
512
|
+
persistence_backend?: PersistenceBackend;
|
|
513
|
+
result_backend?: ResultBackend;
|
|
514
|
+
execution_config?: ExecutionConfig;
|
|
515
|
+
machine_hooks?: MachineHooks;
|
|
516
|
+
llm_backend?: LLMBackend;
|
|
517
|
+
machine_invoker?: MachineInvoker;
|
|
518
|
+
backend_config?: BackendConfig;
|
|
519
|
+
machine_snapshot?: MachineSnapshot;
|
|
520
|
+
registration_backend?: RegistrationBackend;
|
|
521
|
+
work_backend?: WorkBackend;
|
|
522
|
+
}
|
|
523
|
+
|