@maxanstey-meridian/tandem 0.1.4 → 0.1.6

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.
Files changed (155) hide show
  1. package/README.md +40 -5
  2. package/dist/index.d.ts +46 -4
  3. package/dist/index.js +144 -9
  4. package/dist/runtime/darwin-arm64/Microsoft.JavaScript.NodeApi.Generator.dll +0 -0
  5. package/dist/runtime/darwin-arm64/Tandem.Advanced.dll +0 -0
  6. package/dist/runtime/darwin-arm64/Tandem.Ledger.dll +0 -0
  7. package/dist/runtime/{Tandem.NodeApiSpike.Bridge.d.ts → darwin-arm64/Tandem.NodeApiSpike.Bridge.d.ts} +7 -0
  8. package/dist/runtime/darwin-arm64/Tandem.NodeApiSpike.Bridge.dll +0 -0
  9. package/dist/runtime/{Tandem.OpenAICompatible.dll → darwin-arm64/Tandem.OpenAICompatible.dll} +0 -0
  10. package/dist/runtime/darwin-arm64/Tandem.Terminal.dll +0 -0
  11. package/dist/runtime/darwin-arm64/Tandem.dll +0 -0
  12. package/dist/runtime/linux-x64/FluentValidation.dll +0 -0
  13. package/dist/runtime/linux-x64/Google.Protobuf.dll +0 -0
  14. package/dist/runtime/linux-x64/Humanizer.dll +0 -0
  15. package/dist/runtime/linux-x64/Json.More.dll +0 -0
  16. package/dist/runtime/linux-x64/JsonPointer.Net.dll +0 -0
  17. package/dist/runtime/linux-x64/JsonSchema.Net.Generation.dll +0 -0
  18. package/dist/runtime/linux-x64/JsonSchema.Net.dll +0 -0
  19. package/dist/runtime/linux-x64/Microsoft.Agents.AI.Abstractions.dll +0 -0
  20. package/dist/runtime/linux-x64/Microsoft.Agents.AI.Harness.dll +0 -0
  21. package/dist/runtime/linux-x64/Microsoft.Agents.AI.Tools.Shell.dll +0 -0
  22. package/dist/runtime/linux-x64/Microsoft.Agents.AI.Workflows.dll +0 -0
  23. package/dist/runtime/linux-x64/Microsoft.Agents.AI.dll +0 -0
  24. package/dist/runtime/linux-x64/Microsoft.CodeAnalysis.CSharp.dll +0 -0
  25. package/dist/runtime/linux-x64/Microsoft.CodeAnalysis.dll +0 -0
  26. package/dist/runtime/linux-x64/Microsoft.Data.Sqlite.dll +0 -0
  27. package/dist/runtime/linux-x64/Microsoft.Extensions.AI.Abstractions.dll +0 -0
  28. package/dist/runtime/linux-x64/Microsoft.Extensions.AI.Evaluation.dll +0 -0
  29. package/dist/runtime/linux-x64/Microsoft.Extensions.AI.OpenAI.dll +0 -0
  30. package/dist/runtime/linux-x64/Microsoft.Extensions.AI.dll +0 -0
  31. package/dist/runtime/linux-x64/Microsoft.Extensions.Caching.Abstractions.dll +0 -0
  32. package/dist/runtime/linux-x64/Microsoft.Extensions.Compliance.Abstractions.dll +0 -0
  33. package/dist/runtime/linux-x64/Microsoft.Extensions.Configuration.Abstractions.dll +0 -0
  34. package/dist/runtime/linux-x64/Microsoft.Extensions.DependencyInjection.Abstractions.dll +0 -0
  35. package/dist/runtime/linux-x64/Microsoft.Extensions.Diagnostics.Abstractions.dll +0 -0
  36. package/dist/runtime/linux-x64/Microsoft.Extensions.FileProviders.Abstractions.dll +0 -0
  37. package/dist/runtime/linux-x64/Microsoft.Extensions.FileSystemGlobbing.dll +0 -0
  38. package/dist/runtime/linux-x64/Microsoft.Extensions.Hosting.Abstractions.dll +0 -0
  39. package/dist/runtime/linux-x64/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
  40. package/dist/runtime/linux-x64/Microsoft.Extensions.ObjectPool.dll +0 -0
  41. package/dist/runtime/linux-x64/Microsoft.Extensions.Options.dll +0 -0
  42. package/dist/runtime/linux-x64/Microsoft.Extensions.Primitives.dll +0 -0
  43. package/dist/runtime/linux-x64/Microsoft.Extensions.VectorData.Abstractions.dll +0 -0
  44. package/dist/runtime/linux-x64/Microsoft.JavaScript.NodeApi.Generator.dll +0 -0
  45. package/dist/runtime/linux-x64/Microsoft.JavaScript.NodeApi.dll +0 -0
  46. package/dist/runtime/linux-x64/Microsoft.ML.Tokenizers.dll +0 -0
  47. package/dist/runtime/linux-x64/OpenAI.dll +0 -0
  48. package/dist/runtime/linux-x64/OpenTelemetry.Api.dll +0 -0
  49. package/dist/runtime/linux-x64/SQLitePCLRaw.batteries_v2.dll +0 -0
  50. package/dist/runtime/linux-x64/SQLitePCLRaw.core.dll +0 -0
  51. package/dist/runtime/linux-x64/SQLitePCLRaw.provider.e_sqlite3.dll +0 -0
  52. package/dist/runtime/linux-x64/Spectre.Console.Ansi.dll +0 -0
  53. package/dist/runtime/linux-x64/Spectre.Console.dll +0 -0
  54. package/dist/runtime/linux-x64/System.ClientModel.dll +0 -0
  55. package/dist/runtime/linux-x64/System.Memory.Data.dll +0 -0
  56. package/dist/runtime/linux-x64/System.Numerics.Tensors.dll +0 -0
  57. package/dist/runtime/linux-x64/System.Reflection.MetadataLoadContext.dll +0 -0
  58. package/dist/runtime/{Tandem.Advanced.dll → linux-x64/Tandem.Advanced.dll} +0 -0
  59. package/dist/runtime/linux-x64/Tandem.Ledger.dll +0 -0
  60. package/dist/runtime/linux-x64/Tandem.NodeApiSpike.Bridge.cjs +26 -0
  61. package/dist/runtime/linux-x64/Tandem.NodeApiSpike.Bridge.d.ts +30 -0
  62. package/dist/runtime/linux-x64/Tandem.NodeApiSpike.Bridge.deps.json +1157 -0
  63. package/dist/runtime/linux-x64/Tandem.NodeApiSpike.Bridge.dll +0 -0
  64. package/dist/runtime/linux-x64/Tandem.NodeApiSpike.Bridge.mjs +31 -0
  65. package/dist/runtime/linux-x64/Tandem.NodeApiSpike.Bridge.runtimeconfig.json +13 -0
  66. package/dist/runtime/linux-x64/Tandem.OpenAICompatible.dll +0 -0
  67. package/dist/runtime/linux-x64/Tandem.Terminal.dll +0 -0
  68. package/dist/runtime/linux-x64/Tandem.dll +0 -0
  69. package/dist/runtime/linux-x64/Tavily.dll +0 -0
  70. package/dist/runtime/linux-x64/import.cjs +3 -0
  71. package/dist/runtime/linux-x64/libe_sqlite3.so +0 -0
  72. package/dist/runtime/loader.mjs +8 -7
  73. package/package.json +1 -1
  74. package/dist/runtime/Tandem.Ledger.dll +0 -0
  75. package/dist/runtime/Tandem.NodeApiSpike.Bridge.dll +0 -0
  76. package/dist/runtime/Tandem.Terminal.dll +0 -0
  77. package/dist/runtime/Tandem.dll +0 -0
  78. /package/dist/runtime/{FluentValidation.dll → darwin-arm64/FluentValidation.dll} +0 -0
  79. /package/dist/runtime/{Google.Protobuf.dll → darwin-arm64/Google.Protobuf.dll} +0 -0
  80. /package/dist/runtime/{Humanizer.dll → darwin-arm64/Humanizer.dll} +0 -0
  81. /package/dist/runtime/{Json.More.dll → darwin-arm64/Json.More.dll} +0 -0
  82. /package/dist/runtime/{JsonPointer.Net.dll → darwin-arm64/JsonPointer.Net.dll} +0 -0
  83. /package/dist/runtime/{JsonSchema.Net.Generation.dll → darwin-arm64/JsonSchema.Net.Generation.dll} +0 -0
  84. /package/dist/runtime/{JsonSchema.Net.dll → darwin-arm64/JsonSchema.Net.dll} +0 -0
  85. /package/dist/runtime/{Microsoft.Agents.AI.Abstractions.dll → darwin-arm64/Microsoft.Agents.AI.Abstractions.dll} +0 -0
  86. /package/dist/runtime/{Microsoft.Agents.AI.Harness.dll → darwin-arm64/Microsoft.Agents.AI.Harness.dll} +0 -0
  87. /package/dist/runtime/{Microsoft.Agents.AI.Tools.Shell.dll → darwin-arm64/Microsoft.Agents.AI.Tools.Shell.dll} +0 -0
  88. /package/dist/runtime/{Microsoft.Agents.AI.Workflows.dll → darwin-arm64/Microsoft.Agents.AI.Workflows.dll} +0 -0
  89. /package/dist/runtime/{Microsoft.Agents.AI.dll → darwin-arm64/Microsoft.Agents.AI.dll} +0 -0
  90. /package/dist/runtime/{Microsoft.CodeAnalysis.CSharp.dll → darwin-arm64/Microsoft.CodeAnalysis.CSharp.dll} +0 -0
  91. /package/dist/runtime/{Microsoft.CodeAnalysis.dll → darwin-arm64/Microsoft.CodeAnalysis.dll} +0 -0
  92. /package/dist/runtime/{Microsoft.Data.Sqlite.dll → darwin-arm64/Microsoft.Data.Sqlite.dll} +0 -0
  93. /package/dist/runtime/{Microsoft.Extensions.AI.Abstractions.dll → darwin-arm64/Microsoft.Extensions.AI.Abstractions.dll} +0 -0
  94. /package/dist/runtime/{Microsoft.Extensions.AI.Evaluation.dll → darwin-arm64/Microsoft.Extensions.AI.Evaluation.dll} +0 -0
  95. /package/dist/runtime/{Microsoft.Extensions.AI.OpenAI.dll → darwin-arm64/Microsoft.Extensions.AI.OpenAI.dll} +0 -0
  96. /package/dist/runtime/{Microsoft.Extensions.AI.dll → darwin-arm64/Microsoft.Extensions.AI.dll} +0 -0
  97. /package/dist/runtime/{Microsoft.Extensions.Caching.Abstractions.dll → darwin-arm64/Microsoft.Extensions.Caching.Abstractions.dll} +0 -0
  98. /package/dist/runtime/{Microsoft.Extensions.Compliance.Abstractions.dll → darwin-arm64/Microsoft.Extensions.Compliance.Abstractions.dll} +0 -0
  99. /package/dist/runtime/{Microsoft.Extensions.Configuration.Abstractions.dll → darwin-arm64/Microsoft.Extensions.Configuration.Abstractions.dll} +0 -0
  100. /package/dist/runtime/{Microsoft.Extensions.DependencyInjection.Abstractions.dll → darwin-arm64/Microsoft.Extensions.DependencyInjection.Abstractions.dll} +0 -0
  101. /package/dist/runtime/{Microsoft.Extensions.Diagnostics.Abstractions.dll → darwin-arm64/Microsoft.Extensions.Diagnostics.Abstractions.dll} +0 -0
  102. /package/dist/runtime/{Microsoft.Extensions.FileProviders.Abstractions.dll → darwin-arm64/Microsoft.Extensions.FileProviders.Abstractions.dll} +0 -0
  103. /package/dist/runtime/{Microsoft.Extensions.FileSystemGlobbing.dll → darwin-arm64/Microsoft.Extensions.FileSystemGlobbing.dll} +0 -0
  104. /package/dist/runtime/{Microsoft.Extensions.Hosting.Abstractions.dll → darwin-arm64/Microsoft.Extensions.Hosting.Abstractions.dll} +0 -0
  105. /package/dist/runtime/{Microsoft.Extensions.Logging.Abstractions.dll → darwin-arm64/Microsoft.Extensions.Logging.Abstractions.dll} +0 -0
  106. /package/dist/runtime/{Microsoft.Extensions.ObjectPool.dll → darwin-arm64/Microsoft.Extensions.ObjectPool.dll} +0 -0
  107. /package/dist/runtime/{Microsoft.Extensions.Options.dll → darwin-arm64/Microsoft.Extensions.Options.dll} +0 -0
  108. /package/dist/runtime/{Microsoft.Extensions.Primitives.dll → darwin-arm64/Microsoft.Extensions.Primitives.dll} +0 -0
  109. /package/dist/runtime/{Microsoft.Extensions.VectorData.Abstractions.dll → darwin-arm64/Microsoft.Extensions.VectorData.Abstractions.dll} +0 -0
  110. /package/dist/runtime/{Microsoft.JavaScript.NodeApi.dll → darwin-arm64/Microsoft.JavaScript.NodeApi.dll} +0 -0
  111. /package/dist/runtime/{Microsoft.ML.Tokenizers.dll → darwin-arm64/Microsoft.ML.Tokenizers.dll} +0 -0
  112. /package/dist/runtime/{OpenAI.dll → darwin-arm64/OpenAI.dll} +0 -0
  113. /package/dist/runtime/{OpenTelemetry.Api.dll → darwin-arm64/OpenTelemetry.Api.dll} +0 -0
  114. /package/dist/runtime/{SQLitePCLRaw.batteries_v2.dll → darwin-arm64/SQLitePCLRaw.batteries_v2.dll} +0 -0
  115. /package/dist/runtime/{SQLitePCLRaw.core.dll → darwin-arm64/SQLitePCLRaw.core.dll} +0 -0
  116. /package/dist/runtime/{SQLitePCLRaw.provider.e_sqlite3.dll → darwin-arm64/SQLitePCLRaw.provider.e_sqlite3.dll} +0 -0
  117. /package/dist/runtime/{Spectre.Console.Ansi.dll → darwin-arm64/Spectre.Console.Ansi.dll} +0 -0
  118. /package/dist/runtime/{Spectre.Console.dll → darwin-arm64/Spectre.Console.dll} +0 -0
  119. /package/dist/runtime/{System.ClientModel.dll → darwin-arm64/System.ClientModel.dll} +0 -0
  120. /package/dist/runtime/{System.Memory.Data.dll → darwin-arm64/System.Memory.Data.dll} +0 -0
  121. /package/dist/runtime/{System.Numerics.Tensors.dll → darwin-arm64/System.Numerics.Tensors.dll} +0 -0
  122. /package/dist/runtime/{System.Reflection.MetadataLoadContext.dll → darwin-arm64/System.Reflection.MetadataLoadContext.dll} +0 -0
  123. /package/dist/runtime/{Tandem.NodeApiSpike.Bridge.cjs → darwin-arm64/Tandem.NodeApiSpike.Bridge.cjs} +0 -0
  124. /package/dist/runtime/{Tandem.NodeApiSpike.Bridge.deps.json → darwin-arm64/Tandem.NodeApiSpike.Bridge.deps.json} +0 -0
  125. /package/dist/runtime/{Tandem.NodeApiSpike.Bridge.mjs → darwin-arm64/Tandem.NodeApiSpike.Bridge.mjs} +0 -0
  126. /package/dist/runtime/{Tandem.NodeApiSpike.Bridge.runtimeconfig.json → darwin-arm64/Tandem.NodeApiSpike.Bridge.runtimeconfig.json} +0 -0
  127. /package/dist/runtime/{Tavily.dll → darwin-arm64/Tavily.dll} +0 -0
  128. /package/dist/runtime/{cs → darwin-arm64/cs}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  129. /package/dist/runtime/{cs → darwin-arm64/cs}/Microsoft.CodeAnalysis.resources.dll +0 -0
  130. /package/dist/runtime/{de → darwin-arm64/de}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  131. /package/dist/runtime/{de → darwin-arm64/de}/Microsoft.CodeAnalysis.resources.dll +0 -0
  132. /package/dist/runtime/{es → darwin-arm64/es}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  133. /package/dist/runtime/{es → darwin-arm64/es}/Microsoft.CodeAnalysis.resources.dll +0 -0
  134. /package/dist/runtime/{fr → darwin-arm64/fr}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  135. /package/dist/runtime/{fr → darwin-arm64/fr}/Microsoft.CodeAnalysis.resources.dll +0 -0
  136. /package/dist/runtime/{import.cjs → darwin-arm64/import.cjs} +0 -0
  137. /package/dist/runtime/{it → darwin-arm64/it}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  138. /package/dist/runtime/{it → darwin-arm64/it}/Microsoft.CodeAnalysis.resources.dll +0 -0
  139. /package/dist/runtime/{ja → darwin-arm64/ja}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  140. /package/dist/runtime/{ja → darwin-arm64/ja}/Microsoft.CodeAnalysis.resources.dll +0 -0
  141. /package/dist/runtime/{ko → darwin-arm64/ko}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  142. /package/dist/runtime/{ko → darwin-arm64/ko}/Microsoft.CodeAnalysis.resources.dll +0 -0
  143. /package/dist/runtime/{libe_sqlite3.dylib → darwin-arm64/libe_sqlite3.dylib} +0 -0
  144. /package/dist/runtime/{pl → darwin-arm64/pl}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  145. /package/dist/runtime/{pl → darwin-arm64/pl}/Microsoft.CodeAnalysis.resources.dll +0 -0
  146. /package/dist/runtime/{pt-BR → darwin-arm64/pt-BR}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  147. /package/dist/runtime/{pt-BR → darwin-arm64/pt-BR}/Microsoft.CodeAnalysis.resources.dll +0 -0
  148. /package/dist/runtime/{ru → darwin-arm64/ru}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  149. /package/dist/runtime/{ru → darwin-arm64/ru}/Microsoft.CodeAnalysis.resources.dll +0 -0
  150. /package/dist/runtime/{tr → darwin-arm64/tr}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  151. /package/dist/runtime/{tr → darwin-arm64/tr}/Microsoft.CodeAnalysis.resources.dll +0 -0
  152. /package/dist/runtime/{zh-Hans → darwin-arm64/zh-Hans}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  153. /package/dist/runtime/{zh-Hans → darwin-arm64/zh-Hans}/Microsoft.CodeAnalysis.resources.dll +0 -0
  154. /package/dist/runtime/{zh-Hant → darwin-arm64/zh-Hant}/Microsoft.CodeAnalysis.CSharp.resources.dll +0 -0
  155. /package/dist/runtime/{zh-Hant → darwin-arm64/zh-Hant}/Microsoft.CodeAnalysis.resources.dll +0 -0
package/README.md CHANGED
@@ -5,7 +5,7 @@ agentic pipeline SDK running on .NET and Microsoft Agent Framework.
5
5
 
6
6
  ## Requirements
7
7
 
8
- - macOS on Apple silicon
8
+ - macOS on Apple silicon or Linux x64
9
9
  - Node.js 22 or newer
10
10
  - .NET 10 runtime
11
11
 
@@ -15,8 +15,8 @@ agentic pipeline SDK running on .NET and Microsoft Agent Framework.
15
15
  npm install @maxanstey-meridian/tandem zod
16
16
  ```
17
17
 
18
- The package includes compiled JavaScript, TypeScript declarations, and the macOS Apple silicon
19
- bridge runtime. Installation does not compile the SDK or download a bridge.
18
+ The package includes compiled JavaScript, TypeScript declarations, and bridge runtimes for
19
+ macOS Apple silicon and Linux x64. Installation does not compile the SDK or download a bridge.
20
20
 
21
21
  ## Quick Start
22
22
 
@@ -77,5 +77,40 @@ npm pack
77
77
  ```
78
78
 
79
79
  `npm pack` and `npm publish` build fresh output before packaging. The npm package contains
80
- `dist`, including one copy of the vendored bridge in `dist/runtime`. Update `runtime` from
81
- a tested Tandem bridge build before releasing runtime changes.
80
+ `dist`, including the vendored platform bridge bundles in `dist/runtime`. Update each runtime
81
+ bundle from a tested Tandem bridge build before releasing runtime changes.
82
+
83
+ ## Runtime-sized collections
84
+
85
+ Use `collection` for a list whose size is known at execution time. Declare its
86
+ item/result schemas and agents, select items from state, and apply the ordered
87
+ results. Native Tandem owns scheduling through `max`; zero and one item need no
88
+ special graph.
89
+
90
+ `taskAgent<Input, Output>` defines a model participant with validated input and
91
+ output. Inside a collection, `context.run(agent, input)` invokes only agents
92
+ declared on that collection. Await each call before the next. Scope use after
93
+ completion and sibling parallel agent calls are rejected. Operational failure
94
+ fails the collection, drains active work, and skips application of results.
95
+
96
+ ```ts
97
+ const canonicalise = collection({
98
+ id: "canonicalise",
99
+ item: Proposition,
100
+ result: Claim,
101
+ agents: [canonicaliser],
102
+ max: 6,
103
+ items: (state: SourceState) => state.propositions,
104
+ execute: (proposition, context) => context.run(canonicaliser, proposition),
105
+ apply: (state, claims) => ({ ...state, claims }),
106
+ });
107
+ ```
108
+
109
+ The executable [collection example](tests/collection-child.ts) includes
110
+ conditional recovery, persistence, cancellation and concurrent source runs.
111
+ Agent visits remain in the source run's native observations and ledger.
112
+
113
+ Agent definitions may be reused across collections. Native Tandem binds each under
114
+ its collection name. Scoped observations and accepted ledger values carry a
115
+ `visitId` so concurrent calls can be correlated without changing their semantic
116
+ `stepId`.
package/dist/index.d.ts CHANGED
@@ -55,7 +55,7 @@ export interface Parallel<TState> extends Participant<TState> {
55
55
  export interface Terminal<TState> extends Participant<TState> {
56
56
  readonly kind: "terminal";
57
57
  }
58
- type Node<TState> = Stage<TState> | Interaction<TState, unknown, unknown> | Agent<TState> | Parallel<TState> | Terminal<TState>;
58
+ type Node<TState> = Collection<TState> | Stage<TState> | Interaction<TState, unknown, unknown> | Agent<TState> | Parallel<TState> | Terminal<TState>;
59
59
  export declare function stage<TState>(definition: {
60
60
  id: string;
61
61
  execute: (state: TState, context: {
@@ -63,6 +63,44 @@ export declare function stage<TState>(definition: {
63
63
  }) => TState | Promise<TState>;
64
64
  persist?: boolean;
65
65
  }): Stage<TState>;
66
+ declare const taskAgentBrand: unique symbol;
67
+ export interface TaskAgentReference {
68
+ readonly id: string;
69
+ readonly [taskAgentBrand]: true;
70
+ }
71
+ export interface TaskAgent<TInput, TOutput> extends TaskAgentReference {
72
+ readonly input: z.ZodType<TInput>;
73
+ readonly result: z.ZodType<TOutput>;
74
+ }
75
+ export interface CollectionContext {
76
+ readonly signal: AbortSignal;
77
+ run<TInput, TOutput>(agent: TaskAgent<TInput, TOutput>, input: NoInfer<TInput>): Promise<TOutput>;
78
+ }
79
+ export interface Collection<TState> extends Participant<TState> {
80
+ readonly kind: "collection";
81
+ }
82
+ export interface TaskAgentDefinition<TInput, TOutput> extends Omit<AgentDefinition<TInput, TOutput>, "output" | "capabilities" | "workspace" | "checkpoint"> {
83
+ input: z.ZodType<TInput>;
84
+ result: z.ZodType<TOutput>;
85
+ output: Omit<Extract<NonNullable<AgentDefinition<TInput, TOutput>["output"]>, {
86
+ schema: unknown;
87
+ }>, "apply"> | Omit<Extract<NonNullable<AgentDefinition<TInput, TOutput>["output"]>, {
88
+ raw: true;
89
+ }>, "apply">;
90
+ }
91
+ export declare function taskAgent<TInput, TOutput>(definition: TaskAgentDefinition<TInput, TOutput>): TaskAgent<TInput, TOutput>;
92
+ interface CollectionDefinition<TState, TItem, TResult> {
93
+ id: string;
94
+ item: z.ZodType<TItem>;
95
+ result: z.ZodType<TResult>;
96
+ items: (state: TState) => readonly TItem[];
97
+ agents: readonly TaskAgentReference[];
98
+ execute: (item: TItem, context: CollectionContext) => Promise<TResult> | TResult;
99
+ apply: (state: TState, results: readonly TResult[]) => TState;
100
+ max: number;
101
+ persist?: boolean;
102
+ }
103
+ export declare function collection<TState, TItem, TResult>(definition: CollectionDefinition<TState, TItem, TResult>): Collection<TState>;
66
104
  export declare function interaction<TState, TRequest, TResponse>(definition: {
67
105
  id: string;
68
106
  requestSchema: z.ZodType<TRequest>;
@@ -221,7 +259,7 @@ export declare function output<TState>(definition: {
221
259
  persist?: boolean;
222
260
  }): Terminal<TState>;
223
261
  export interface OrdinaryRoute<TState> {
224
- readonly from: Stage<TState> | Interaction<TState, unknown, unknown>;
262
+ readonly from: Stage<TState> | Collection<TState> | Interaction<TState, unknown, unknown>;
225
263
  readonly to: Node<TState>;
226
264
  readonly label: string;
227
265
  readonly outcome?: never;
@@ -275,7 +313,8 @@ export interface InspectedRoute {
275
313
  }
276
314
  export interface InspectedNode {
277
315
  readonly id: string;
278
- readonly kind: "stage" | "interaction" | "agent" | "parallel" | "completion" | "failure";
316
+ readonly kind: "stage" | "interaction" | "agent" | "parallel" | "collection" | "completion" | "failure";
317
+ readonly agents?: readonly string[];
279
318
  readonly persist?: boolean;
280
319
  readonly interaction?: {
281
320
  readonly requestSchema: unknown;
@@ -304,6 +343,8 @@ export interface RunResult<TState> {
304
343
  readonly summary: string | null;
305
344
  }
306
345
  export type RunObservation = {
346
+ readonly visitId?: string | null;
347
+ } & ({
307
348
  readonly version: 1;
308
349
  readonly kind: "stepStarted";
309
350
  readonly stepId: string;
@@ -354,7 +395,7 @@ export type RunObservation = {
354
395
  readonly message: string;
355
396
  }[];
356
397
  readonly rawResponse: string;
357
- };
398
+ });
358
399
  export interface TerminalPresentationOptions {
359
400
  readonly truncatedToolNames?: readonly string[];
360
401
  }
@@ -377,6 +418,7 @@ export type AcceptedValue = {
377
418
  readonly version: 1;
378
419
  readonly kind: K;
379
420
  readonly stepId: string;
421
+ readonly visitId?: string | null;
380
422
  readonly valueType: string | null;
381
423
  readonly payload: unknown | null;
382
424
  };
package/dist/index.js CHANGED
@@ -332,6 +332,55 @@ class StageImplementation extends NodeImplementation {
332
332
  export function stage(definition) {
333
333
  return new StageImplementation(definition.id, definition.persist, definition.execute);
334
334
  }
335
+ const taskAgentBrand = Symbol("taskAgent");
336
+ class TaskAgentImplementation {
337
+ id;
338
+ input;
339
+ result;
340
+ [taskAgentBrand] = true;
341
+ state;
342
+ participant;
343
+ constructor(id, input, result, definition) {
344
+ this.id = id;
345
+ this.input = input;
346
+ this.result = result;
347
+ this.state = z.object({ input, output: z.object({ value: result }).nullable() });
348
+ this.participant = agent({
349
+ ...definition,
350
+ message: (state) => definition.message(state.input),
351
+ output: {
352
+ ...definition.output,
353
+ validateFor: definition.output.validateFor
354
+ ? (state, value) => definition.output.validateFor(state.input, value)
355
+ : undefined,
356
+ apply: (state, value) => ({
357
+ ...state,
358
+ output: { value },
359
+ }),
360
+ },
361
+ });
362
+ }
363
+ }
364
+ export function taskAgent(definition) {
365
+ return new TaskAgentImplementation(definition.id, definition.input, definition.result, definition);
366
+ }
367
+ class CollectionImplementation extends NodeImplementation {
368
+ definition;
369
+ kind = "collection";
370
+ constructor(definition) {
371
+ super(definition.id, definition.persist);
372
+ this.definition = definition;
373
+ }
374
+ }
375
+ export function collection(definition) {
376
+ if (!Number.isInteger(definition.max) || definition.max < 1 || definition.max > 2147483647) {
377
+ throw new TandemError("Collection max must be a positive 32-bit integer.");
378
+ }
379
+ if (new Set(definition.agents.map((agent) => agent.id)).size !== definition.agents.length) {
380
+ throw new TandemError("Collection agent IDs must be unique.");
381
+ }
382
+ return new CollectionImplementation(definition);
383
+ }
335
384
  class InteractionImplementation extends NodeImplementation {
336
385
  requestSchema;
337
386
  responseSchema;
@@ -823,6 +872,15 @@ export function inspectPipeline(graph) {
823
872
  const inspectNode = (node) => {
824
873
  const implementation = node;
825
874
  const persist = implementation.persist;
875
+ if (implementation instanceof CollectionImplementation) {
876
+ return {
877
+ id: node.id,
878
+ kind: "collection",
879
+ persist,
880
+ max: implementation.definition.max,
881
+ agents: implementation.definition.agents.map((agent) => node.id + "/" + agent.id),
882
+ };
883
+ }
826
884
  if (node.kind === "interaction") {
827
885
  const interaction = implementation;
828
886
  return {
@@ -892,19 +950,35 @@ export function inspectPipeline(graph) {
892
950
  }
893
951
  const runObservationSchema = z.discriminatedUnion("kind", [
894
952
  z
895
- .object({ version: z.literal(1), kind: z.literal("stepStarted"), stepId: z.string().min(1) })
953
+ .object({
954
+ version: z.literal(1),
955
+ kind: z.literal("stepStarted"),
956
+ stepId: z.string().min(1),
957
+ visitId: z.string().nullable().optional(),
958
+ })
896
959
  .strict(),
897
960
  z
898
- .object({ version: z.literal(1), kind: z.literal("stepCompleted"), stepId: z.string().min(1) })
961
+ .object({
962
+ version: z.literal(1),
963
+ kind: z.literal("stepCompleted"),
964
+ stepId: z.string().min(1),
965
+ visitId: z.string().nullable().optional(),
966
+ })
899
967
  .strict(),
900
968
  z
901
- .object({ version: z.literal(1), kind: z.literal("stepCancelled"), stepId: z.string().min(1) })
969
+ .object({
970
+ version: z.literal(1),
971
+ kind: z.literal("stepCancelled"),
972
+ stepId: z.string().min(1),
973
+ visitId: z.string().nullable().optional(),
974
+ })
902
975
  .strict(),
903
976
  z
904
977
  .object({
905
978
  version: z.literal(1),
906
979
  kind: z.literal("stepFaulted"),
907
980
  stepId: z.string().min(1),
981
+ visitId: z.string().nullable().optional(),
908
982
  error: z.string(),
909
983
  })
910
984
  .strict(),
@@ -913,6 +987,7 @@ const runObservationSchema = z.discriminatedUnion("kind", [
913
987
  version: z.literal(1),
914
988
  kind: z.literal("agentText"),
915
989
  stepId: z.string().min(1),
990
+ visitId: z.string().nullable().optional(),
916
991
  text: z.string(),
917
992
  })
918
993
  .strict(),
@@ -921,6 +996,7 @@ const runObservationSchema = z.discriminatedUnion("kind", [
921
996
  version: z.literal(1),
922
997
  kind: z.literal("agentModelSelected"),
923
998
  stepId: z.string().min(1),
999
+ visitId: z.string().nullable().optional(),
924
1000
  modelId: z.string().min(1),
925
1001
  })
926
1002
  .strict(),
@@ -929,6 +1005,7 @@ const runObservationSchema = z.discriminatedUnion("kind", [
929
1005
  version: z.literal(1),
930
1006
  kind: z.literal("agentReasoning"),
931
1007
  stepId: z.string().min(1),
1008
+ visitId: z.string().nullable().optional(),
932
1009
  text: z.string(),
933
1010
  })
934
1011
  .strict(),
@@ -937,6 +1014,7 @@ const runObservationSchema = z.discriminatedUnion("kind", [
937
1014
  version: z.literal(1),
938
1015
  kind: z.literal("agentUsage"),
939
1016
  stepId: z.string().min(1),
1017
+ visitId: z.string().nullable().optional(),
940
1018
  inputTokens: z.number().int().nonnegative(),
941
1019
  outputTokens: z.number().int().nonnegative(),
942
1020
  reasoningTokens: z.number().int().nonnegative(),
@@ -949,6 +1027,7 @@ const runObservationSchema = z.discriminatedUnion("kind", [
949
1027
  version: z.literal(1),
950
1028
  kind: z.literal("structuredOutputRejected"),
951
1029
  stepId: z.string().min(1),
1030
+ visitId: z.string().nullable().optional(),
952
1031
  attempt: z.number().int().positive(),
953
1032
  problems: z.array(z.object({ field: z.string(), message: z.string().min(1) }).strict()),
954
1033
  rawResponse: z.string(),
@@ -965,6 +1044,7 @@ const acceptedKinds = [
965
1044
  const acceptedValueSchema = z
966
1045
  .object({
967
1046
  kind: z.enum(acceptedKinds),
1047
+ visitId: z.string().nullable().optional(),
968
1048
  stepId: z.string().min(1),
969
1049
  valueType: z.string().min(1).nullable(),
970
1050
  payload: z.unknown().nullable(),
@@ -989,6 +1069,7 @@ export async function inspectAccepted(options) {
989
1069
  version: 1,
990
1070
  kind: value.kind,
991
1071
  stepId: value.stepId,
1072
+ ...(value.visitId == null ? {} : { visitId: value.visitId }),
992
1073
  valueType: value.valueType,
993
1074
  payload: value.payload,
994
1075
  }));
@@ -1137,6 +1218,64 @@ function interactionHandlerEntries(handlers) {
1137
1218
  function compileNode(node, stateSchema, callbacks) {
1138
1219
  const implementation = node;
1139
1220
  const base = { id: node.id, persist: implementation.persist };
1221
+ if (implementation instanceof CollectionImplementation) {
1222
+ const definition = implementation.definition;
1223
+ const agents = definition.agents.map((value) => {
1224
+ if (!(value instanceof TaskAgentImplementation))
1225
+ throw new TandemError("Use taskAgent to declare collection agents.");
1226
+ return compileNode(value.participant, value.state, callbacks);
1227
+ });
1228
+ const itemsCallback = callbacks.registerSync((state) => serializeBoundary(z.array(definition.item), definition.items(parseJson(stateSchema, state, node.id + " state")), node.id + " items"));
1229
+ const runCallback = callbacks.registerAsync(async (item, scopeId, signal) => {
1230
+ let active = false;
1231
+ let closed = false;
1232
+ const context = {
1233
+ signal,
1234
+ async run(value, input) {
1235
+ if (closed)
1236
+ throw new TandemError("Collection scope has ended.");
1237
+ if (active)
1238
+ throw new TandemError("Collection item agents must be awaited serially.");
1239
+ if (!definition.agents.includes(value) || !(value instanceof TaskAgentImplementation)) {
1240
+ throw new TandemError("Agent is not declared in this collection.");
1241
+ }
1242
+ signal.throwIfAborted();
1243
+ active = true;
1244
+ try {
1245
+ const { runCollectionAgentAsync } = await import("./runtime/loader.mjs");
1246
+ const response = await runCollectionAgentAsync(scopeId, value.id, serializeBoundary(value.state, { input, output: null }, value.id + " input"));
1247
+ const state = parseJson(value.state, response, value.id + " output");
1248
+ if (state.output === null)
1249
+ throw new TandemError("Agent returned no output.");
1250
+ return parse(value.result, state.output.value, value.id + " result");
1251
+ }
1252
+ finally {
1253
+ active = false;
1254
+ }
1255
+ },
1256
+ };
1257
+ try {
1258
+ const result = await definition.execute(parseJson(definition.item, item, node.id + " item"), context);
1259
+ if (active)
1260
+ throw new TandemError("Collection item returned before its agent completed.");
1261
+ signal.throwIfAborted();
1262
+ return serializeBoundary(definition.result, result, node.id + " result");
1263
+ }
1264
+ finally {
1265
+ closed = true;
1266
+ }
1267
+ });
1268
+ const applyCallback = callbacks.registerSync((state, results) => serializeBoundary(stateSchema, definition.apply(parseJson(stateSchema, state, node.id + " state"), parseJson(z.array(definition.result), results, node.id + " results")), node.id + " output"));
1269
+ return {
1270
+ ...base,
1271
+ kind: "collection",
1272
+ agents,
1273
+ max: definition.max,
1274
+ itemsCallback,
1275
+ runCallback,
1276
+ applyCallback,
1277
+ };
1278
+ }
1140
1279
  if (implementation instanceof StageImplementation) {
1141
1280
  const run = callbacks.registerAsync(async (state, _, signal) => serializeBoundary(stateSchema, await implementation.execute(parseJson(stateSchema, state, `${node.id} input`), {
1142
1281
  signal,
@@ -1326,13 +1465,9 @@ function compileAgentOutput(id, output, stateSchema, callbacks) {
1326
1465
  ? callbacks.registerSync((_, input) => issuesParsed(z.unknown(), output.parse(JSON.parse(input))))
1327
1466
  : callbacks.registerSync((_, input) => issues(output.schema, input));
1328
1467
  const validateFor = output.validateFor
1329
- ? callbacks.registerSync((state, input) => validationProblems(output.validateFor(parseJson(stateSchema, state, `${id} state`), raw
1330
- ? JSON.parse(input)
1331
- : parseJson(output.schema, input, `${id} output`)), `${id} output contextual validation`))
1468
+ ? callbacks.registerSync((state, input) => validationProblems(output.validateFor(parseJson(stateSchema, state, `${id} state`), raw ? JSON.parse(input) : parseJson(output.schema, input, `${id} output`)), `${id} output contextual validation`))
1332
1469
  : undefined;
1333
- const apply = callbacks.registerSync((state, input) => serializeBoundary(stateSchema, output.apply(parseJson(stateSchema, state, `${id} state`), raw
1334
- ? JSON.parse(input)
1335
- : parseJson(output.schema, input, `${id} output`)), `${id} applied state`));
1470
+ const apply = callbacks.registerSync((state, input) => serializeBoundary(stateSchema, output.apply(parseJson(stateSchema, state, `${id} state`), raw ? JSON.parse(input) : parseJson(output.schema, input, `${id} output`)), `${id} applied state`));
1336
1471
  return {
1337
1472
  instructions: output.instructions,
1338
1473
  ...(raw
@@ -7,6 +7,13 @@ import './System.Runtime';
7
7
 
8
8
  /** Adapts JavaScript-authored participants to the Tandem runtime. */
9
9
  export namespace NodePipelineBridge {
10
+ /** Executes a declared agent within an active collection item. */
11
+ export function runCollectionAgentAsync(
12
+ scopeId: string,
13
+ agentId: string,
14
+ state: string,
15
+ ): Promise<string>;
16
+
10
17
  /** Reads accepted semantic journal values from a packaged SQLite ledger. */
11
18
  export function inspectAcceptedAsync(
12
19
  ledgerPath: string,
@@ -0,0 +1,26 @@
1
+ // Generated for: Tandem.NodeApiSpike.Bridge 0.1.0.0
2
+ // Generated by: Microsoft.JavaScript.NodeApi.Generator 0.9.0.0
3
+ /* eslint-disable */
4
+
5
+ const dotnet = require('node-api-dotnet/net10.0');
6
+ const path = require('node:path');
7
+ // @ts-ignore - https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/65252
8
+ const { dlopen, platform, arch } = require('node:process');
9
+
10
+ const moduleName = path.basename(__filename, __filename.match(/(\.[cm]?js)?$/)[0]);
11
+ module.exports = dotnet ? importDotnetModule(moduleName) : importAotModule(moduleName);
12
+
13
+ function importDotnetModule(moduleName) {
14
+ const moduleFilePath = path.join(__dirname, moduleName + '.dll');
15
+ return dotnet.require(moduleFilePath);
16
+ }
17
+
18
+ function importAotModule(moduleName) {
19
+ const ridPlatform = platform === 'win32' ? 'win' : platform === 'darwin' ? 'osx' : platform;
20
+ const ridArch = arch === 'ia32' ? 'x86' : arch;
21
+ const rid = `${ridPlatform}-${ridArch}`;
22
+ const moduleFilePath = path.join(__dirname, rid, moduleName + '.node');
23
+ const module = { exports: {} };
24
+ dlopen(module, moduleFilePath);
25
+ return module.exports;
26
+ }
@@ -0,0 +1,30 @@
1
+ // Generated for: Tandem.NodeApiSpike.Bridge 0.1.0.0
2
+ // Generated by: Microsoft.JavaScript.NodeApi.Generator 0.9.0.0
3
+ /* eslint-disable */
4
+
5
+ import './System.Runtime';
6
+
7
+
8
+ /** Adapts JavaScript-authored participants to the Tandem runtime. */
9
+ export namespace NodePipelineBridge {
10
+ /** Executes a declared agent within an active collection item. */
11
+ export function runCollectionAgentAsync(
12
+ scopeId: string,
13
+ agentId: string,
14
+ state: string,
15
+ ): Promise<string>;
16
+
17
+ /** Reads accepted semantic journal values from a packaged SQLite ledger. */
18
+ export function inspectAcceptedAsync(
19
+ ledgerPath: string,
20
+ runId: string,
21
+ ): Promise<string>;
22
+
23
+ /** Registers and runs a complete JavaScript-authored Tandem graph. */
24
+ export function runRegisteredGraphAsync(
25
+ definitionJson: string,
26
+ invokeSyncCallback: Func$4<string, string, string, string>,
27
+ invokeAsyncCallback: Func$5<string, string, string, AbortSignal, Promise<string>>,
28
+ cancellationToken?: AbortSignal,
29
+ ): Promise<string>;
30
+ }