@ax-llm/ax 12.0.21 → 12.0.23

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/index.js CHANGED
@@ -11092,7 +11092,7 @@ var AxInstanceRegistry = class {
11092
11092
  };
11093
11093
 
11094
11094
  // dsp/program.ts
11095
- var AxProgramWithSignature = class {
11095
+ var AxProgram = class {
11096
11096
  signature;
11097
11097
  sigHash;
11098
11098
  examples;
@@ -11100,6 +11100,7 @@ var AxProgramWithSignature = class {
11100
11100
  demos;
11101
11101
  trace;
11102
11102
  usage = [];
11103
+ traceLabel;
11103
11104
  key;
11104
11105
  children;
11105
11106
  constructor(signature, options) {
@@ -11107,6 +11108,9 @@ var AxProgramWithSignature = class {
11107
11108
  if (options?.description) {
11108
11109
  this.signature.setDescription(options.description);
11109
11110
  }
11111
+ if (options?.traceLabel) {
11112
+ this.traceLabel = options.traceLabel;
11113
+ }
11110
11114
  this.signature.validate();
11111
11115
  this.sigHash = this.signature?.hash();
11112
11116
  this.children = new AxInstanceRegistry();
@@ -11212,85 +11216,6 @@ var AxProgramWithSignature = class {
11212
11216
  }
11213
11217
  }
11214
11218
  };
11215
- var AxProgram = class {
11216
- trace;
11217
- usage = [];
11218
- key;
11219
- children;
11220
- constructor() {
11221
- this.children = new AxInstanceRegistry();
11222
- this.key = { id: this.constructor.name };
11223
- }
11224
- register(prog) {
11225
- if (this.key) {
11226
- prog.setParentId(this.key.id);
11227
- }
11228
- this.children.register(prog);
11229
- }
11230
- async forward(_ai, _values, _options) {
11231
- throw new Error("forward() not implemented");
11232
- }
11233
- // biome-ignore lint/correctness/useYield: just a placeholder
11234
- async *streamingForward(_ai, _values, _options) {
11235
- throw new Error("streamingForward() not implemented");
11236
- }
11237
- setId(id) {
11238
- this.key = { id, custom: true };
11239
- for (const child of Array.from(this.children)) {
11240
- child?.setParentId(id);
11241
- }
11242
- }
11243
- setParentId(parentId) {
11244
- if (!this.key.custom) {
11245
- this.key.id = [parentId, this.key.id].join("/");
11246
- }
11247
- }
11248
- setExamples(examples, options) {
11249
- if (!("programId" in examples)) {
11250
- return;
11251
- }
11252
- for (const child of Array.from(this.children)) {
11253
- child?.setExamples(examples, options);
11254
- }
11255
- }
11256
- getTraces() {
11257
- let traces = [];
11258
- if (this.trace) {
11259
- traces.push({ trace: this.trace, programId: this.key.id });
11260
- }
11261
- for (const child of Array.from(this.children)) {
11262
- const _traces = child?.getTraces();
11263
- traces = [...traces, ..._traces ?? []];
11264
- }
11265
- return traces;
11266
- }
11267
- getUsage() {
11268
- let usage = [...this.usage ?? []];
11269
- for (const child of Array.from(this.children)) {
11270
- const cu = child?.getUsage();
11271
- usage = [...usage, ...cu ?? []];
11272
- }
11273
- return mergeProgramUsage(usage);
11274
- }
11275
- resetUsage() {
11276
- this.usage = [];
11277
- for (const child of Array.from(this.children)) {
11278
- child?.resetUsage();
11279
- }
11280
- }
11281
- setDemos(demos) {
11282
- const hasChildren = Array.from(this.children).length > 0;
11283
- const hasMatchingDemo = demos.some((demo) => demo.programId === this.key.id);
11284
- if (hasChildren && !hasMatchingDemo) {
11285
- throw new Error(
11286
- `Program with id '${this.key.id}' has children but no matching programId found in demos`
11287
- );
11288
- }
11289
- for (const child of Array.from(this.children)) {
11290
- child?.setDemos(demos);
11291
- }
11292
- }
11293
- };
11294
11219
 
11295
11220
  // dsp/samples.ts
11296
11221
  function checkForFunctionCalls(mem, sessionId) {
@@ -11405,7 +11330,7 @@ ${errors}`, {
11405
11330
  }
11406
11331
 
11407
11332
  // dsp/generate.ts
11408
- var AxGen = class extends AxProgramWithSignature {
11333
+ var AxGen = class extends AxProgram {
11409
11334
  promptTemplate;
11410
11335
  asserts;
11411
11336
  streamingAsserts;
@@ -11416,7 +11341,10 @@ var AxGen = class extends AxProgramWithSignature {
11416
11341
  excludeContentFromTrace = false;
11417
11342
  thoughtFieldName;
11418
11343
  constructor(signature, options) {
11419
- super(signature, { description: options?.description });
11344
+ super(signature, {
11345
+ description: options?.description,
11346
+ traceLabel: options?.traceLabel
11347
+ });
11420
11348
  this.options = options;
11421
11349
  this.thoughtFieldName = options?.thoughtFieldName ?? "thought";
11422
11350
  const promptTemplateOptions = {
@@ -11860,8 +11788,8 @@ var AxGen = class extends AxProgramWithSignature {
11860
11788
  ...options?.maxSteps ? { max_steps: options.maxSteps } : {},
11861
11789
  ...options?.maxRetries ? { max_retries: options.maxRetries } : {}
11862
11790
  };
11863
- const traceLabel = options.traceLabel ?? this.options?.traceLabel;
11864
- const spanName = traceLabel ? `${traceLabel} (AxGen)` : "AxGen";
11791
+ const traceLabel = this.traceLabel && options.traceLabel ? `${this.traceLabel} > ${options.traceLabel}` : options.traceLabel ?? this.traceLabel;
11792
+ const spanName = traceLabel ? `AxGen > ${traceLabel}` : "AxGen";
11865
11793
  const span = tracer.startSpan(spanName, {
11866
11794
  kind: SpanKind2.SERVER,
11867
11795
  attributes
@@ -14997,29 +14925,213 @@ var AxDockerSession = class {
14997
14925
  };
14998
14926
 
14999
14927
  // flow/flow.ts
15000
- var AxFlow = class extends AxProgramWithSignature {
14928
+ var AxFlowDependencyAnalyzer = class {
14929
+ /**
14930
+ * Analyzes a mapping function to determine which state fields it depends on
14931
+ */
14932
+ analyzeMappingDependencies(mapping, _nodeName) {
14933
+ const dependencies = [];
14934
+ const source = mapping.toString();
14935
+ const stateAccessMatches = Array.from(source.matchAll(/state\.(\w+)/g));
14936
+ for (const match of stateAccessMatches) {
14937
+ if (match[1] && !dependencies.includes(match[1])) {
14938
+ dependencies.push(match[1]);
14939
+ }
14940
+ }
14941
+ if (dependencies.length === 0) {
14942
+ try {
14943
+ const tracker = this.createDependencyTracker(dependencies);
14944
+ mapping(tracker);
14945
+ } catch {
14946
+ }
14947
+ }
14948
+ return dependencies;
14949
+ }
14950
+ createDependencyTracker(dependencies) {
14951
+ return new Proxy(
14952
+ {},
14953
+ {
14954
+ get(target, prop) {
14955
+ if (typeof prop === "string" && !dependencies.includes(prop)) {
14956
+ dependencies.push(prop);
14957
+ }
14958
+ return new Proxy(
14959
+ {},
14960
+ {
14961
+ get: () => void 0
14962
+ }
14963
+ );
14964
+ }
14965
+ }
14966
+ );
14967
+ }
14968
+ };
14969
+ var AxFlowExecutionPlanner = class {
14970
+ steps = [];
14971
+ parallelGroups = [];
14972
+ analyzer = new AxFlowDependencyAnalyzer();
14973
+ initialFields = /* @__PURE__ */ new Set();
14974
+ /**
14975
+ * Adds an execution step to the plan
14976
+ */
14977
+ addExecutionStep(stepFunction, nodeName, mapping) {
14978
+ let dependencies = [];
14979
+ let produces = [];
14980
+ let type = "other";
14981
+ if (nodeName && mapping) {
14982
+ type = "execute";
14983
+ dependencies = this.analyzer.analyzeMappingDependencies(mapping, nodeName);
14984
+ produces = [`${nodeName}Result`];
14985
+ } else if (stepFunction.toString().includes("transform(")) {
14986
+ type = "map";
14987
+ dependencies = this.getAllProducedFields();
14988
+ }
14989
+ const step = {
14990
+ type,
14991
+ nodeName,
14992
+ dependencies,
14993
+ produces,
14994
+ stepFunction,
14995
+ stepIndex: this.steps.length
14996
+ };
14997
+ this.steps.push(step);
14998
+ }
14999
+ /**
15000
+ * Sets the initial fields and rebuilds parallel groups
15001
+ */
15002
+ setInitialFields(fields) {
15003
+ this.initialFields = new Set(fields);
15004
+ this.rebuildParallelGroups();
15005
+ }
15006
+ /**
15007
+ * Rebuilds the parallel execution groups based on dependencies
15008
+ */
15009
+ rebuildParallelGroups() {
15010
+ this.parallelGroups = [];
15011
+ const processedSteps = /* @__PURE__ */ new Set();
15012
+ const availableFields = new Set(this.initialFields);
15013
+ let currentLevel = 0;
15014
+ while (processedSteps.size < this.steps.length) {
15015
+ const currentLevelSteps = [];
15016
+ for (const step of this.steps) {
15017
+ if (processedSteps.has(step.stepIndex)) continue;
15018
+ const canRun = step.dependencies.length === 0 || step.dependencies.every((dep) => availableFields.has(dep));
15019
+ if (canRun) {
15020
+ currentLevelSteps.push(step);
15021
+ processedSteps.add(step.stepIndex);
15022
+ }
15023
+ }
15024
+ if (currentLevelSteps.length > 0) {
15025
+ for (const step of currentLevelSteps) {
15026
+ step.produces.forEach((field) => availableFields.add(field));
15027
+ }
15028
+ this.parallelGroups.push({
15029
+ level: currentLevel,
15030
+ steps: currentLevelSteps
15031
+ });
15032
+ currentLevel++;
15033
+ } else {
15034
+ break;
15035
+ }
15036
+ }
15037
+ }
15038
+ /**
15039
+ * Gets all fields produced by previous steps
15040
+ */
15041
+ getAllProducedFields() {
15042
+ const fields = [];
15043
+ for (const step of this.steps) {
15044
+ fields.push(...step.produces);
15045
+ }
15046
+ return fields;
15047
+ }
15048
+ /**
15049
+ * Creates optimized execution function
15050
+ */
15051
+ createOptimizedExecution() {
15052
+ const optimizedSteps = [];
15053
+ for (const group of this.parallelGroups) {
15054
+ if (group.steps.length === 1) {
15055
+ const step = group.steps[0];
15056
+ if (step) {
15057
+ optimizedSteps.push(step.stepFunction);
15058
+ }
15059
+ } else if (group.steps.length > 1) {
15060
+ const parallelStep = async (state, context3) => {
15061
+ const promises = group.steps.map(
15062
+ (step) => step.stepFunction(state, context3)
15063
+ );
15064
+ const results = await Promise.all(promises);
15065
+ let mergedState = state;
15066
+ for (const result of results) {
15067
+ mergedState = { ...mergedState, ...result };
15068
+ }
15069
+ return mergedState;
15070
+ };
15071
+ optimizedSteps.push(parallelStep);
15072
+ }
15073
+ }
15074
+ return optimizedSteps;
15075
+ }
15076
+ /**
15077
+ * Gets execution plan info for debugging
15078
+ */
15079
+ getExecutionPlan() {
15080
+ return {
15081
+ totalSteps: this.steps.length,
15082
+ parallelGroups: this.parallelGroups.length,
15083
+ maxParallelism: Math.max(
15084
+ ...this.parallelGroups.map((g) => g.steps.length),
15085
+ 0
15086
+ ),
15087
+ steps: this.steps,
15088
+ groups: this.parallelGroups
15089
+ };
15090
+ }
15091
+ };
15092
+ var AxFlow = class extends AxProgram {
15001
15093
  nodes = /* @__PURE__ */ new Map();
15002
15094
  flowDefinition = [];
15003
15095
  nodeGenerators = /* @__PURE__ */ new Map();
15004
15096
  loopStack = [];
15005
15097
  stepLabels = /* @__PURE__ */ new Map();
15006
15098
  branchContext = null;
15007
- constructor(signature = "userInput:string -> flowOutput:string") {
15099
+ // Automatic parallelization components
15100
+ autoParallelConfig;
15101
+ executionPlanner = new AxFlowExecutionPlanner();
15102
+ constructor(signature = "userInput:string -> flowOutput:string", options) {
15008
15103
  super(signature);
15104
+ this.autoParallelConfig = {
15105
+ enabled: options?.autoParallel !== false
15106
+ // Default to true
15107
+ };
15009
15108
  }
15010
15109
  // Implementation
15011
- node(name, signatureOrAxGen, options) {
15012
- if (signatureOrAxGen instanceof AxGen) {
15110
+ node(name, signatureOrAxGenOrClass, options) {
15111
+ if (signatureOrAxGenOrClass instanceof AxGen) {
15013
15112
  this.nodes.set(name, {
15014
15113
  inputs: {},
15015
15114
  outputs: {}
15016
15115
  });
15017
15116
  this.nodeGenerators.set(
15018
15117
  name,
15019
- signatureOrAxGen
15118
+ signatureOrAxGenOrClass
15020
15119
  );
15021
- } else {
15022
- const signature = signatureOrAxGen;
15120
+ } else if (signatureOrAxGenOrClass instanceof AxSignature) {
15121
+ this.nodes.set(name, {
15122
+ inputs: {},
15123
+ outputs: {}
15124
+ });
15125
+ this.nodeGenerators.set(name, new AxGen(signatureOrAxGenOrClass, options));
15126
+ } else if (typeof signatureOrAxGenOrClass === "function" && signatureOrAxGenOrClass.prototype instanceof AxProgram) {
15127
+ this.nodes.set(name, {
15128
+ inputs: {},
15129
+ outputs: {}
15130
+ });
15131
+ const programInstance = new signatureOrAxGenOrClass();
15132
+ this.nodeGenerators.set(name, programInstance);
15133
+ } else if (typeof signatureOrAxGenOrClass === "string") {
15134
+ const signature = signatureOrAxGenOrClass;
15023
15135
  if (!signature) {
15024
15136
  throw new Error(
15025
15137
  `Invalid signature for node '${name}': signature cannot be empty`
@@ -15030,11 +15142,15 @@ var AxFlow = class extends AxProgramWithSignature {
15030
15142
  outputs: {}
15031
15143
  });
15032
15144
  this.nodeGenerators.set(name, new AxGen(signature, options));
15145
+ } else {
15146
+ throw new Error(
15147
+ `Invalid second argument for node '${name}': expected string, AxSignature, AxGen instance, or class extending AxProgram`
15148
+ );
15033
15149
  }
15034
15150
  return this;
15035
15151
  }
15036
- n(name, signatureOrAxGen, options) {
15037
- return this.node(name, signatureOrAxGen, options);
15152
+ n(name, signatureOrAxGenOrClass, options) {
15153
+ return this.node(name, signatureOrAxGenOrClass, options);
15038
15154
  }
15039
15155
  /**
15040
15156
  * Applies a synchronous transformation to the state object.
@@ -15063,6 +15179,9 @@ var AxFlow = class extends AxProgramWithSignature {
15063
15179
  );
15064
15180
  } else {
15065
15181
  this.flowDefinition.push(step);
15182
+ if (this.autoParallelConfig.enabled) {
15183
+ this.executionPlanner.addExecutionStep(step);
15184
+ }
15066
15185
  }
15067
15186
  return this;
15068
15187
  }
@@ -15117,15 +15236,19 @@ var AxFlow = class extends AxProgramWithSignature {
15117
15236
  `Node '${nodeName}' not found. Make sure to define it with .node() first.`
15118
15237
  );
15119
15238
  }
15120
- const nodeGenerator = this.nodeGenerators.get(nodeName);
15121
- if (!nodeGenerator) {
15122
- throw new Error(`Node generator for '${nodeName}' not found.`);
15239
+ const nodeProgram = this.nodeGenerators.get(nodeName);
15240
+ if (!nodeProgram) {
15241
+ throw new Error(`Node program for '${nodeName}' not found.`);
15123
15242
  }
15124
15243
  const step = async (state, context3) => {
15125
15244
  const ai = dynamicContext?.ai ?? context3.mainAi;
15126
15245
  const options = dynamicContext?.options ?? context3.mainOptions;
15127
15246
  const nodeInputs = mapping(state);
15128
- const result = await nodeGenerator.forward(ai, nodeInputs, options);
15247
+ const traceLabel = options?.traceLabel ? `Node:${nodeName} (${options.traceLabel})` : `Node:${nodeName}`;
15248
+ const result = await nodeProgram.forward(ai, nodeInputs, {
15249
+ ...options,
15250
+ traceLabel
15251
+ });
15129
15252
  return {
15130
15253
  ...state,
15131
15254
  [`${nodeName}Result`]: result
@@ -15142,6 +15265,9 @@ var AxFlow = class extends AxProgramWithSignature {
15142
15265
  );
15143
15266
  } else {
15144
15267
  this.flowDefinition.push(step);
15268
+ if (this.autoParallelConfig.enabled) {
15269
+ this.executionPlanner.addExecutionStep(step, nodeName, mapping);
15270
+ }
15145
15271
  }
15146
15272
  return this;
15147
15273
  }
@@ -15438,7 +15564,7 @@ var AxFlow = class extends AxProgramWithSignature {
15438
15564
  *
15439
15565
  * @param ai - The AI service to use as the default for all steps
15440
15566
  * @param values - The input values for the flow
15441
- * @param options - Optional forward options to use as defaults
15567
+ * @param options - Optional forward options to use as defaults (includes autoParallel override)
15442
15568
  * @returns Promise that resolves to the final output
15443
15569
  */
15444
15570
  async forward(ai, values, options) {
@@ -15447,11 +15573,36 @@ var AxFlow = class extends AxProgramWithSignature {
15447
15573
  mainAi: ai,
15448
15574
  mainOptions: options
15449
15575
  };
15450
- for (const step of this.flowDefinition) {
15451
- state = await step(state, context3);
15576
+ const useAutoParallel = options?.autoParallel !== false && this.autoParallelConfig.enabled;
15577
+ if (useAutoParallel) {
15578
+ this.executionPlanner.setInitialFields(Object.keys(values));
15579
+ const optimizedSteps = this.executionPlanner.createOptimizedExecution();
15580
+ for (const step of optimizedSteps) {
15581
+ state = await step(state, context3);
15582
+ }
15583
+ } else {
15584
+ for (const step of this.flowDefinition) {
15585
+ state = await step(state, context3);
15586
+ }
15452
15587
  }
15453
15588
  return state;
15454
15589
  }
15590
+ /**
15591
+ * Gets execution plan information for debugging automatic parallelization
15592
+ *
15593
+ * @returns Object with execution plan details
15594
+ */
15595
+ getExecutionPlan() {
15596
+ const planInfo = this.executionPlanner.getExecutionPlan();
15597
+ return {
15598
+ totalSteps: planInfo.totalSteps,
15599
+ parallelGroups: planInfo.parallelGroups,
15600
+ maxParallelism: planInfo.maxParallelism,
15601
+ autoParallelEnabled: this.autoParallelConfig.enabled,
15602
+ steps: planInfo.steps,
15603
+ groups: planInfo.groups
15604
+ };
15605
+ }
15455
15606
  };
15456
15607
  var AxFlowSubContextImpl = class {
15457
15608
  constructor(nodeGenerators) {
@@ -15459,15 +15610,19 @@ var AxFlowSubContextImpl = class {
15459
15610
  }
15460
15611
  steps = [];
15461
15612
  execute(nodeName, mapping, dynamicContext) {
15462
- const nodeGenerator = this.nodeGenerators.get(nodeName);
15463
- if (!nodeGenerator) {
15464
- throw new Error(`Node generator for '${nodeName}' not found.`);
15613
+ const nodeProgram = this.nodeGenerators.get(nodeName);
15614
+ if (!nodeProgram) {
15615
+ throw new Error(`Node program for '${nodeName}' not found.`);
15465
15616
  }
15466
15617
  this.steps.push(async (state, context3) => {
15467
15618
  const ai = dynamicContext?.ai ?? context3.mainAi;
15468
15619
  const options = dynamicContext?.options ?? context3.mainOptions;
15469
15620
  const nodeInputs = mapping(state);
15470
- const result = await nodeGenerator.forward(ai, nodeInputs, options);
15621
+ const traceLabel = options?.traceLabel ? `Node:${nodeName} (${options.traceLabel})` : `Node:${nodeName}`;
15622
+ const result = await nodeProgram.forward(ai, nodeInputs, {
15623
+ ...options,
15624
+ traceLabel
15625
+ });
15471
15626
  return {
15472
15627
  ...state,
15473
15628
  [`${nodeName}Result`]: result
@@ -15493,15 +15648,19 @@ var AxFlowTypedSubContextImpl = class {
15493
15648
  }
15494
15649
  steps = [];
15495
15650
  execute(nodeName, mapping, dynamicContext) {
15496
- const nodeGenerator = this.nodeGenerators.get(nodeName);
15497
- if (!nodeGenerator) {
15498
- throw new Error(`Node generator for '${nodeName}' not found.`);
15651
+ const nodeProgram = this.nodeGenerators.get(nodeName);
15652
+ if (!nodeProgram) {
15653
+ throw new Error(`Node program for '${nodeName}' not found.`);
15499
15654
  }
15500
15655
  this.steps.push(async (state, context3) => {
15501
15656
  const ai = dynamicContext?.ai ?? context3.mainAi;
15502
15657
  const options = dynamicContext?.options ?? context3.mainOptions;
15503
15658
  const nodeInputs = mapping(state);
15504
- const result = await nodeGenerator.forward(ai, nodeInputs, options);
15659
+ const traceLabel = options?.traceLabel ? `Node:${nodeName} (${options.traceLabel})` : `Node:${nodeName}`;
15660
+ const result = await nodeProgram.forward(ai, nodeInputs, {
15661
+ ...options,
15662
+ traceLabel
15663
+ });
15505
15664
  return {
15506
15665
  ...state,
15507
15666
  [`${nodeName}Result`]: result
@@ -16309,10 +16468,7 @@ var AxMiPRO = class extends AxBaseOptimizer {
16309
16468
  * Generates program summary for context-aware instruction generation
16310
16469
  */
16311
16470
  async generateProgramSummary(program, ai) {
16312
- let signature = "input -> output";
16313
- if ("getSignature" in program && typeof program.getSignature === "function") {
16314
- signature = program.getSignature();
16315
- }
16471
+ const signature = program.getSignature();
16316
16472
  const summaryPrompt = `
16317
16473
  Analyze this language model program and provide a concise summary of its purpose and structure.
16318
16474
 
@@ -19525,7 +19681,6 @@ export {
19525
19681
  AxMockAIService,
19526
19682
  AxMultiServiceRouter,
19527
19683
  AxProgram,
19528
- AxProgramWithSignature,
19529
19684
  AxPromptTemplate,
19530
19685
  AxRAG,
19531
19686
  AxRateLimiterTokenUsage,