@memgrafter/flatagents 0.10.0 → 2.0.0

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.
@@ -7,6 +7,11 @@ export interface PersistenceBackend {
7
7
  load(key: string): Promise<MachineSnapshot | null>;
8
8
  delete(key: string): Promise<void>;
9
9
  list(prefix: string): Promise<string[]>;
10
+ listExecutionIds?(options?: {
11
+ event?: string;
12
+ waiting_channel?: string;
13
+ }): Promise<string[]>;
14
+ deleteExecution?(execution_id: string): Promise<void>;
10
15
  }
11
16
  export interface ResultBackend {
12
17
  write(uri: string, data: any): Promise<void>;
@@ -17,8 +22,65 @@ export interface ResultBackend {
17
22
  exists(uri: string): Promise<boolean>;
18
23
  delete(uri: string): Promise<void>;
19
24
  }
25
+ export interface AgentResult {
26
+ output?: Record<string, any> | null;
27
+ content?: string | null;
28
+ raw?: any;
29
+ usage?: UsageInfo | null;
30
+ cost?: CostInfo | number | null;
31
+ metadata?: Record<string, any> | null;
32
+ finish_reason?: string | null;
33
+ error?: AgentError | null;
34
+ rate_limit?: RateLimitState | null;
35
+ provider_data?: ProviderData | null;
36
+ }
37
+ export interface UsageInfo {
38
+ input_tokens?: number;
39
+ output_tokens?: number;
40
+ total_tokens?: number;
41
+ cache_read_tokens?: number;
42
+ cache_write_tokens?: number;
43
+ }
44
+ export interface CostInfo {
45
+ input?: number;
46
+ output?: number;
47
+ cache_read?: number;
48
+ cache_write?: number;
49
+ total?: number;
50
+ }
51
+ export interface AgentError {
52
+ code?: string;
53
+ type?: string;
54
+ message: string;
55
+ status_code?: number;
56
+ retryable?: boolean;
57
+ }
58
+ export interface RateLimitState {
59
+ limited: boolean;
60
+ retry_after?: number;
61
+ windows?: RateLimitWindow[];
62
+ }
63
+ export interface RateLimitWindow {
64
+ name: string;
65
+ resource: string;
66
+ remaining?: number;
67
+ limit?: number;
68
+ resets_in?: number;
69
+ reset_at?: number;
70
+ }
71
+ export interface ProviderData {
72
+ provider?: string;
73
+ model?: string;
74
+ request_id?: string;
75
+ raw_headers?: Record<string, string>;
76
+ [key: string]: any;
77
+ }
78
+ export interface AgentExecutor {
79
+ execute(input: Record<string, any>, context?: Record<string, any>): Promise<AgentResult>;
80
+ metadata?: Record<string, any>;
81
+ }
20
82
  export interface ExecutionType {
21
- execute<T>(fn: () => Promise<T>): Promise<T>;
83
+ execute(executor: AgentExecutor, input: Record<string, any>, context?: Record<string, any>): Promise<AgentResult>;
22
84
  }
23
85
  export interface ExecutionConfig {
24
86
  type: "default" | "retry" | "parallel" | "mdap_voting";
@@ -37,6 +99,15 @@ export interface MachineHooks {
37
99
  onError?(state: string, error: Error, context: Record<string, any>): string | null | Promise<string | null>;
38
100
  onAction?(action: string, context: Record<string, any>): Record<string, any> | Promise<Record<string, any>>;
39
101
  }
102
+ export interface HooksRegistry {
103
+ register(name: string, factory: HooksFactory): void;
104
+ resolve(ref: HooksRef): MachineHooks;
105
+ has(name: string): boolean;
106
+ }
107
+ export type HooksFactory = {
108
+ new (args?: Record<string, any>): MachineHooks;
109
+ } | ((args?: Record<string, any>) => MachineHooks);
110
+ import { HooksRef, HooksRefConfig } from "./flatmachine";
40
111
  export interface LLMBackend {
41
112
  totalCost: number;
42
113
  totalApiCalls: number;
@@ -95,6 +166,7 @@ export interface MachineSnapshot {
95
166
  total_cost?: number;
96
167
  parent_execution_id?: string;
97
168
  pending_launches?: LaunchIntent[];
169
+ waiting_channel?: string;
98
170
  }
99
171
  export interface LaunchIntent {
100
172
  execution_id: string;
@@ -149,15 +221,35 @@ export interface WorkItem {
149
221
  attempts: number;
150
222
  max_retries: number;
151
223
  }
224
+ export interface SignalBackend {
225
+ send(channel: string, data: any): Promise<string>;
226
+ consume(channel: string): Promise<Signal | null>;
227
+ peek(channel: string): Promise<Signal[]>;
228
+ channels(): Promise<string[]>;
229
+ }
230
+ export interface Signal {
231
+ id: string;
232
+ channel: string;
233
+ data: any;
234
+ created_at: string;
235
+ }
236
+ export interface TriggerBackend {
237
+ notify(channel: string): Promise<void>;
238
+ }
152
239
  export interface BackendConfig {
153
- persistence?: "memory" | "local" | "redis" | "postgres" | "s3";
154
- locking?: "none" | "local" | "redis" | "consul";
155
- results?: "memory" | "redis";
156
- registration?: "memory" | "sqlite" | "redis";
157
- work?: "memory" | "sqlite" | "redis";
240
+ persistence?: "memory" | "local" | "sqlite" | "redis" | "postgres" | "s3" | "dynamodb";
241
+ locking?: "none" | "local" | "sqlite" | "redis" | "consul" | "dynamodb";
242
+ results?: "memory" | "redis" | "dynamodb";
243
+ registration?: "memory" | "sqlite" | "redis" | "dynamodb";
244
+ work?: "memory" | "sqlite" | "redis" | "dynamodb";
245
+ signal?: "memory" | "sqlite" | "redis" | "dynamodb";
246
+ trigger?: "none" | "file" | "socket";
158
247
  sqlite_path?: string;
248
+ trigger_path?: string;
249
+ dynamodb_table?: string;
250
+ aws_region?: string;
159
251
  }
160
- export const SPEC_VERSION = "0.10.0";
252
+ export const SPEC_VERSION = "2.0.0";
161
253
  export interface SDKRuntimeWrapper {
162
254
  spec: "flatagents-runtime";
163
255
  spec_version: typeof SPEC_VERSION;
@@ -166,10 +258,13 @@ export interface SDKRuntimeWrapper {
166
258
  result_backend?: ResultBackend;
167
259
  execution_config?: ExecutionConfig;
168
260
  machine_hooks?: MachineHooks;
261
+ hooks_registry?: HooksRegistry;
169
262
  llm_backend?: LLMBackend;
170
263
  machine_invoker?: MachineInvoker;
171
264
  backend_config?: BackendConfig;
172
265
  machine_snapshot?: MachineSnapshot;
173
266
  registration_backend?: RegistrationBackend;
174
267
  work_backend?: WorkBackend;
268
+ signal_backend?: SignalBackend;
269
+ trigger_backend?: TriggerBackend;
175
270
  }
@@ -26,7 +26,7 @@
26
26
  * name - Machine identifier
27
27
  * expression_engine - "simple" (default) or "cel"
28
28
  * context - Initial context values (Jinja2 templates)
29
- * agents - Map of agent name to config file path or inline config
29
+ * agents - Map of agent name to AgentRef (path, inline config, or typed adapter ref)
30
30
  * machines - Map of machine name to config file path or inline config
31
31
  * states - Map of state name to state definition
32
32
  * settings - Optional settings (hooks, etc.)
@@ -39,6 +39,7 @@
39
39
  * execution - Execution type config: {type: "retry", backoffs: [...], jitter: 0.1}
40
40
  * on_error - Error handling: "error_state" or {default: "...", ErrorType: "..."}
41
41
  * action - Hook action to execute
42
+ * wait_for - Channel to wait for external signal (Jinja2 template)
42
43
  * input - Input mapping (Jinja2 templates)
43
44
  * output_to_context - Map agent output to context (Jinja2 templates)
44
45
  * output - Final output (for final states)
@@ -55,6 +56,10 @@
55
56
  * launch - Machine(s) to start fire-and-forget
56
57
  * launch_input - Input for launched machines
57
58
  *
59
+ * EXTERNAL SIGNALS (v1.2.0):
60
+ * --------------------------
61
+ * wait_for - Channel name (Jinja2 template) to wait for external signal
62
+ *
58
63
  * NOTE: Only `machine` supports parallel invocation (string[]), not `agent`.
59
64
  * Machines are self-healing with checkpoint/resume and error handling.
60
65
  * Agents are raw LLM calls that can fail without recovery. Wrap agents in
@@ -203,6 +208,35 @@
203
208
  * transitions:
204
209
  * - to: continue_immediately
205
210
  *
211
+ * WAIT_FOR (EXTERNAL SIGNAL) EXAMPLE:
212
+ * ------------------------------------
213
+ * Machine checkpoints and exits. Nothing running. Dispatcher resumes
214
+ * the machine when a signal arrives on the named channel.
215
+ * Signal data is available as output.* in output_to_context templates.
216
+ *
217
+ * states:
218
+ * wait_for_approval:
219
+ * wait_for: "approval/{{ context.task_id }}"
220
+ * timeout: 86400
221
+ * output_to_context:
222
+ * approved: "{{ output.approved }}"
223
+ * reviewer: "{{ output.reviewer }}"
224
+ * transitions:
225
+ * - condition: "context.approved"
226
+ * to: continue_work
227
+ * - to: rejected
228
+ *
229
+ * QUOTA-GATED EXAMPLE:
230
+ * --------------------
231
+ *
232
+ * states:
233
+ * wait_for_quota:
234
+ * wait_for: "quota/openai"
235
+ * output_to_context:
236
+ * quota_token: "{{ output }}"
237
+ * transitions:
238
+ * - to: call_api
239
+ *
206
240
  * PERSISTENCE (v0.2.0):
207
241
  * --------------------
208
242
  * MachineSnapshot - Wire format for checkpoints (execution_id, state, context, step)
@@ -249,14 +283,40 @@
249
283
  * Launch intent for outbox pattern.
250
284
  * Recorded in checkpoint before launching to ensure exactly-once semantics.
251
285
  *
286
+ * HOOKS CONFIG:
287
+ * -------------
288
+ * Hooks are referenced by name and resolved via a runtime HooksRegistry.
289
+ * This keeps machine configs language-agnostic — the same YAML works with
290
+ * Python, JavaScript, Rust, or any other SDK.
291
+ *
292
+ * String shorthand:
293
+ * hooks: "my-hooks"
294
+ *
295
+ * With constructor args:
296
+ * hooks:
297
+ * name: "my-hooks"
298
+ * args:
299
+ * working_dir: "."
300
+ *
301
+ * Composite (multiple hooks):
302
+ * hooks:
303
+ * - "logging"
304
+ * - name: "my-hooks"
305
+ * args: { working_dir: "." }
306
+ *
307
+ * The SDK's HooksRegistry maps names to implementations.
308
+ * Built-in hooks (e.g., "logging", "webhook") are pre-registered.
309
+ * Custom hooks are registered by the runner before machine execution.
310
+ *
252
311
  * MACHINE SNAPSHOT:
253
312
  * -----------------
254
313
  * Wire format for checkpoints.
255
314
  * parent_execution_id - Lineage tracking (v0.4.0)
256
315
  * pending_launches - Outbox pattern (v0.4.0)
316
+ * waiting_channel - Signal channel this machine is blocked on (v1.2.0)
257
317
  */
258
318
 
259
- export const SPEC_VERSION = "0.10.0";
319
+ export const SPEC_VERSION = "2.0.0";
260
320
 
261
321
  export interface MachineWrapper {
262
322
  spec: "flatmachine";
@@ -269,41 +329,26 @@ export interface MachineData {
269
329
  name?: string;
270
330
  expression_engine?: "simple" | "cel";
271
331
  context?: Record<string, any>;
272
- agents?: Record<string, string | AgentWrapper>;
332
+ agents?: Record<string, AgentRef>;
273
333
  machines?: Record<string, string | MachineWrapper>;
274
334
  states: Record<string, StateDefinition>;
275
335
  settings?: MachineSettings;
276
336
  persistence?: PersistenceConfig;
277
- hooks?: HooksConfig;
337
+ hooks?: HooksRef;
278
338
  }
279
339
 
280
- /**
281
- * Configuration for loading hooks from file or module.
282
- *
283
- * File-based (preferred for self-contained skills):
284
- * hooks:
285
- * file: "./hooks.py"
286
- * class: "MyHooks"
287
- * args:
288
- * working_dir: "."
289
- *
290
- * Module-based (for installed packages):
291
- * hooks:
292
- * module: "mypackage.hooks"
293
- * class: "MyHooks"
294
- * args:
295
- * api_key: "{{ input.api_key }}"
296
- *
297
- * Fields:
298
- * file - Path to Python file containing hooks class (relative to machine.yml)
299
- * module - Python module path to import
300
- * class - Class name to instantiate (required)
301
- * args - Arguments to pass to hooks constructor
302
- */
303
- export interface HooksConfig {
304
- file?: string;
305
- module?: string;
306
- class: string;
340
+ export interface AgentRefConfig {
341
+ type: string;
342
+ ref?: string;
343
+ config?: Record<string, any>;
344
+ }
345
+
346
+ export type AgentRef = string | AgentWrapper | AgentRefConfig;
347
+
348
+ export type HooksRef = string | HooksRefConfig | Array<string | HooksRefConfig>;
349
+
350
+ export interface HooksRefConfig {
351
+ name: string;
307
352
  args?: Record<string, any>;
308
353
  }
309
354
 
@@ -320,11 +365,12 @@ export interface StateDefinition {
320
365
  action?: string;
321
366
  execution?: ExecutionConfig;
322
367
  on_error?: string | Record<string, string>;
368
+ wait_for?: string;
323
369
  input?: Record<string, any>;
324
370
  output_to_context?: Record<string, any>;
325
371
  output?: Record<string, any>;
326
372
  transitions?: Transition[];
327
- tool_loop?: boolean;
373
+ tool_loop?: boolean | ToolLoopStateConfig;
328
374
  sampling?: "single" | "multi";
329
375
  foreach?: string;
330
376
  as?: string;
@@ -335,6 +381,16 @@ export interface StateDefinition {
335
381
  launch_input?: Record<string, any>;
336
382
  }
337
383
 
384
+ export interface ToolLoopStateConfig {
385
+ max_tool_calls?: number; // Total tool calls before forced stop. Default: 50
386
+ max_turns?: number; // LLM call rounds before forced stop. Default: 20
387
+ allowed_tools?: string[]; // Whitelist (if set, only these execute)
388
+ denied_tools?: string[]; // Blacklist (takes precedence over allowed)
389
+ tool_timeout?: number; // Per-tool execution timeout in seconds. Default: 30
390
+ total_timeout?: number; // Total loop timeout in seconds. Default: 600
391
+ max_cost?: number; // Cost limit in dollars
392
+ }
393
+
338
394
  export interface MachineInput {
339
395
  name: string;
340
396
  input?: Record<string, any>;
@@ -380,6 +436,13 @@ export interface MachineSnapshot {
380
436
  total_cost?: number;
381
437
  parent_execution_id?: string;
382
438
  pending_launches?: LaunchIntent[];
439
+ waiting_channel?: string;
440
+ tool_loop_state?: {
441
+ chain: Array<Record<string, any>>;
442
+ turns: number;
443
+ tool_calls_count: number;
444
+ loop_cost: number;
445
+ };
383
446
  }
384
447
 
385
448
  export interface PersistenceConfig {
@@ -45,14 +45,7 @@
45
45
  "agents": {
46
46
  "type": "object",
47
47
  "additionalProperties": {
48
- "anyOf": [
49
- {
50
- "type": "string"
51
- },
52
- {
53
- "$ref": "#/definitions/AgentWrapper"
54
- }
55
- ]
48
+ "$ref": "#/definitions/AgentRef"
56
49
  }
57
50
  },
58
51
  "machines": {
@@ -81,7 +74,7 @@
81
74
  "$ref": "#/definitions/PersistenceConfig"
82
75
  },
83
76
  "hooks": {
84
- "$ref": "#/definitions/HooksConfig"
77
+ "$ref": "#/definitions/HooksRef"
85
78
  }
86
79
  },
87
80
  "required": [
@@ -89,6 +82,19 @@
89
82
  ],
90
83
  "additionalProperties": false
91
84
  },
85
+ "AgentRef": {
86
+ "anyOf": [
87
+ {
88
+ "type": "string"
89
+ },
90
+ {
91
+ "$ref": "#/definitions/AgentWrapper"
92
+ },
93
+ {
94
+ "$ref": "#/definitions/AgentRefConfig"
95
+ }
96
+ ]
97
+ },
92
98
  "AgentWrapper": {
93
99
  "type": "object",
94
100
  "properties": {
@@ -146,6 +152,12 @@
146
152
  },
147
153
  "mcp": {
148
154
  "$ref": "#/definitions/MCPConfig"
155
+ },
156
+ "tools": {
157
+ "type": "array",
158
+ "items": {
159
+ "$ref": "#/definitions/ToolDefinition"
160
+ }
149
161
  }
150
162
  },
151
163
  "required": [
@@ -354,6 +366,56 @@
354
366
  },
355
367
  "additionalProperties": false
356
368
  },
369
+ "ToolDefinition": {
370
+ "type": "object",
371
+ "properties": {
372
+ "type": {
373
+ "type": "string",
374
+ "const": "function"
375
+ },
376
+ "function": {
377
+ "type": "object",
378
+ "properties": {
379
+ "name": {
380
+ "type": "string"
381
+ },
382
+ "description": {
383
+ "type": "string"
384
+ },
385
+ "parameters": {
386
+ "type": "object"
387
+ }
388
+ },
389
+ "required": [
390
+ "name"
391
+ ],
392
+ "additionalProperties": false
393
+ }
394
+ },
395
+ "required": [
396
+ "type",
397
+ "function"
398
+ ],
399
+ "additionalProperties": false
400
+ },
401
+ "AgentRefConfig": {
402
+ "type": "object",
403
+ "properties": {
404
+ "type": {
405
+ "type": "string"
406
+ },
407
+ "ref": {
408
+ "type": "string"
409
+ },
410
+ "config": {
411
+ "type": "object"
412
+ }
413
+ },
414
+ "required": [
415
+ "type"
416
+ ],
417
+ "additionalProperties": false
418
+ },
357
419
  "StateDefinition": {
358
420
  "type": "object",
359
421
  "properties": {
@@ -405,6 +467,9 @@
405
467
  }
406
468
  ]
407
469
  },
470
+ "wait_for": {
471
+ "type": "string"
472
+ },
408
473
  "input": {
409
474
  "type": "object"
410
475
  },
@@ -421,7 +486,14 @@
421
486
  }
422
487
  },
423
488
  "tool_loop": {
424
- "type": "boolean"
489
+ "anyOf": [
490
+ {
491
+ "type": "boolean"
492
+ },
493
+ {
494
+ "$ref": "#/definitions/ToolLoopStateConfig"
495
+ }
496
+ ]
425
497
  },
426
498
  "sampling": {
427
499
  "type": "string",
@@ -534,6 +606,39 @@
534
606
  ],
535
607
  "additionalProperties": false
536
608
  },
609
+ "ToolLoopStateConfig": {
610
+ "type": "object",
611
+ "properties": {
612
+ "max_tool_calls": {
613
+ "type": "number"
614
+ },
615
+ "max_turns": {
616
+ "type": "number"
617
+ },
618
+ "allowed_tools": {
619
+ "type": "array",
620
+ "items": {
621
+ "type": "string"
622
+ }
623
+ },
624
+ "denied_tools": {
625
+ "type": "array",
626
+ "items": {
627
+ "type": "string"
628
+ }
629
+ },
630
+ "tool_timeout": {
631
+ "type": "number"
632
+ },
633
+ "total_timeout": {
634
+ "type": "number"
635
+ },
636
+ "max_cost": {
637
+ "type": "number"
638
+ }
639
+ },
640
+ "additionalProperties": false
641
+ },
537
642
  "MachineSettings": {
538
643
  "type": "object",
539
644
  "properties": {
@@ -570,16 +675,33 @@
570
675
  "backend"
571
676
  ]
572
677
  },
573
- "HooksConfig": {
574
- "type": "object",
575
- "properties": {
576
- "file": {
678
+ "HooksRef": {
679
+ "anyOf": [
680
+ {
577
681
  "type": "string"
578
682
  },
579
- "module": {
580
- "type": "string"
683
+ {
684
+ "$ref": "#/definitions/HooksRefConfig"
581
685
  },
582
- "class": {
686
+ {
687
+ "type": "array",
688
+ "items": {
689
+ "anyOf": [
690
+ {
691
+ "type": "string"
692
+ },
693
+ {
694
+ "$ref": "#/definitions/HooksRefConfig"
695
+ }
696
+ ]
697
+ }
698
+ }
699
+ ]
700
+ },
701
+ "HooksRefConfig": {
702
+ "type": "object",
703
+ "properties": {
704
+ "name": {
583
705
  "type": "string"
584
706
  },
585
707
  "args": {
@@ -587,10 +709,9 @@
587
709
  }
588
710
  },
589
711
  "required": [
590
- "class"
712
+ "name"
591
713
  ],
592
- "additionalProperties": false,
593
- "description": "Configuration for loading hooks from file or module.\n\nFile-based (preferred for self-contained skills): hooks: file: \"./hooks.py\" class: \"MyHooks\" args: working_dir: \".\"\n\nModule-based (for installed packages): hooks: module: \"mypackage.hooks\" class: \"MyHooks\" args: api_key: \"{{ input.api_key }}\"\n\nFields: file - Path to Python file containing hooks class (relative to machine.yml) module - Python module path to import class - Class name to instantiate (required) args - Arguments to pass to hooks constructor"
714
+ "additionalProperties": false
594
715
  }
595
716
  }
596
717
  }
@@ -1,4 +1,4 @@
1
- export const SPEC_VERSION = "0.10.0";
1
+ export const SPEC_VERSION = "2.0.0";
2
2
  export interface MachineWrapper {
3
3
  spec: "flatmachine";
4
4
  spec_version: string;
@@ -9,17 +9,22 @@ export interface MachineData {
9
9
  name?: string;
10
10
  expression_engine?: "simple" | "cel";
11
11
  context?: Record<string, any>;
12
- agents?: Record<string, string | AgentWrapper>;
12
+ agents?: Record<string, AgentRef>;
13
13
  machines?: Record<string, string | MachineWrapper>;
14
14
  states: Record<string, StateDefinition>;
15
15
  settings?: MachineSettings;
16
16
  persistence?: PersistenceConfig;
17
- hooks?: HooksConfig;
17
+ hooks?: HooksRef;
18
18
  }
19
- export interface HooksConfig {
20
- file?: string;
21
- module?: string;
22
- class: string;
19
+ export interface AgentRefConfig {
20
+ type: string;
21
+ ref?: string;
22
+ config?: Record<string, any>;
23
+ }
24
+ export type AgentRef = string | AgentWrapper | AgentRefConfig;
25
+ export type HooksRef = string | HooksRefConfig | Array<string | HooksRefConfig>;
26
+ export interface HooksRefConfig {
27
+ name: string;
23
28
  args?: Record<string, any>;
24
29
  }
25
30
  export interface MachineSettings {
@@ -34,11 +39,12 @@ export interface StateDefinition {
34
39
  action?: string;
35
40
  execution?: ExecutionConfig;
36
41
  on_error?: string | Record<string, string>;
42
+ wait_for?: string;
37
43
  input?: Record<string, any>;
38
44
  output_to_context?: Record<string, any>;
39
45
  output?: Record<string, any>;
40
46
  transitions?: Transition[];
41
- tool_loop?: boolean;
47
+ tool_loop?: boolean | ToolLoopStateConfig;
42
48
  sampling?: "single" | "multi";
43
49
  foreach?: string;
44
50
  as?: string;
@@ -48,6 +54,15 @@ export interface StateDefinition {
48
54
  launch?: string | string[];
49
55
  launch_input?: Record<string, any>;
50
56
  }
57
+ export interface ToolLoopStateConfig {
58
+ max_tool_calls?: number;
59
+ max_turns?: number;
60
+ allowed_tools?: string[];
61
+ denied_tools?: string[];
62
+ tool_timeout?: number;
63
+ total_timeout?: number;
64
+ max_cost?: number;
65
+ }
51
66
  export interface MachineInput {
52
67
  name: string;
53
68
  input?: Record<string, any>;
@@ -87,6 +102,13 @@ export interface MachineSnapshot {
87
102
  total_cost?: number;
88
103
  parent_execution_id?: string;
89
104
  pending_launches?: LaunchIntent[];
105
+ waiting_channel?: string;
106
+ tool_loop_state?: {
107
+ chain: Array<Record<string, any>>;
108
+ turns: number;
109
+ tool_calls_count: number;
110
+ loop_cost: number;
111
+ };
90
112
  }
91
113
  export interface PersistenceConfig {
92
114
  enabled: boolean;
@@ -108,7 +108,7 @@
108
108
  * stream - Enable streaming responses (default: false)
109
109
  */
110
110
 
111
- export const SPEC_VERSION = "0.10.0";
111
+ export const SPEC_VERSION = "2.0.0";
112
112
 
113
113
  export interface ProfilesWrapper {
114
114
  spec: "flatprofiles";
@@ -1,4 +1,4 @@
1
- export const SPEC_VERSION = "0.10.0";
1
+ export const SPEC_VERSION = "2.0.0";
2
2
  export interface ProfilesWrapper {
3
3
  spec: "flatprofiles";
4
4
  spec_version: string;