@ax-llm/ax 16.0.6 → 16.0.8

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.d.cts CHANGED
@@ -680,6 +680,16 @@ type AxAIServiceOptions = {
680
680
  * Currently supported by: Google Gemini/Vertex AI
681
681
  */
682
682
  contextCache?: AxContextCacheOptions;
683
+ /**
684
+ * When true, examples/demos are embedded in system prompt (legacy).
685
+ * When false (default), they are rendered as alternating user/assistant message pairs.
686
+ */
687
+ examplesInSystem?: boolean;
688
+ /**
689
+ * Custom labels to include in OpenTelemetry metrics.
690
+ * These labels are merged with axGlobals.customLabels (service-level overrides global).
691
+ */
692
+ customLabels?: Record<string, string>;
683
693
  };
684
694
  interface AxAIService<TModel = unknown, TEmbedModel = unknown, TModelKey = string> {
685
695
  getId(): string;
@@ -813,14 +823,14 @@ declare class AxSignatureBuilder<_TInput extends Record<string, any> = {}, _TOut
813
823
  * @param fieldInfo - Field type created with f.string(), f.number(), etc.
814
824
  * @param prepend - If true, adds field to the beginning of input fields
815
825
  */
816
- input<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<AddFieldToShape<_TInput, K, T>, _TOutput>;
826
+ input<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<AddFieldToShape<_TInput, K, T>, _TOutput>;
817
827
  /**
818
828
  * Add an output field to the signature
819
829
  * @param name - Field name
820
830
  * @param fieldInfo - Field type created with f.string(), f.number(), etc.
821
831
  * @param prepend - If true, adds field to the beginning of output fields
822
832
  */
823
- output<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<_TInput, AddFieldToShape<_TOutput, K, T>>;
833
+ output<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<_TInput, AddFieldToShape<_TOutput, K, T>>;
824
834
  /**
825
835
  * Set the description for the signature
826
836
  * @param description - Description text
@@ -835,13 +845,14 @@ declare class AxSignatureBuilder<_TInput extends Record<string, any> = {}, _TOut
835
845
  */
836
846
  build(): AxSignature<_TInput, _TOutput>;
837
847
  }
838
- declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] | undefined = undefined, TIsOptional extends boolean = false, TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined> implements AxFieldType {
848
+ declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] | undefined = undefined, TIsOptional extends boolean = false, TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined, TIsCached extends boolean = false> implements AxFieldType {
839
849
  readonly type: TType;
840
850
  readonly isArray: TIsArray;
841
851
  readonly options?: TOptions;
842
852
  readonly description?: string;
843
853
  readonly isOptional: TIsOptional;
844
854
  readonly isInternal: TIsInternal;
855
+ readonly isCached: TIsCached;
845
856
  readonly fields?: any;
846
857
  readonly minLength?: number;
847
858
  readonly maxLength?: number;
@@ -859,6 +870,7 @@ declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType[
859
870
  itemDescription?: string;
860
871
  isOptional: TIsOptional;
861
872
  isInternal: TIsInternal;
873
+ isCached: TIsCached;
862
874
  fields?: TFields;
863
875
  minLength?: number;
864
876
  maxLength?: number;
@@ -868,39 +880,45 @@ declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType[
868
880
  patternDescription?: string;
869
881
  format?: string;
870
882
  });
871
- optional(): AxFluentFieldType<TType, TIsArray, TOptions, true, TIsInternal, TFields>;
872
- array(desc?: string): AxFluentFieldType<TType, true, TOptions, TIsOptional, TIsInternal, TFields>;
873
- internal(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, true, TFields>;
883
+ optional(): AxFluentFieldType<TType, TIsArray, TOptions, true, TIsInternal, TFields, TIsCached>;
884
+ array(desc?: string): AxFluentFieldType<TType, true, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
885
+ internal(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, true, TFields, TIsCached>;
886
+ /**
887
+ * Mark this input field for caching. When contextCache is enabled,
888
+ * cached fields are rendered in a separate user message with cache: true,
889
+ * allowing them to be cached by the LLM provider.
890
+ */
891
+ cache(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, true>;
874
892
  /**
875
893
  * Set minimum value for numbers or minimum length for strings
876
894
  */
877
- min(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
895
+ min(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
878
896
  /**
879
897
  * Set maximum value for numbers or maximum length for strings
880
898
  */
881
- max(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
899
+ max(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
882
900
  /**
883
901
  * Set email format validation for strings
884
902
  */
885
- email(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
903
+ email(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
886
904
  /**
887
905
  * Set URL/URI format validation for strings
888
906
  */
889
- url(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
907
+ url(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
890
908
  /**
891
909
  * Set regex pattern validation for strings
892
910
  * @param pattern - Regular expression pattern to match
893
911
  * @param description - Human-readable description of what the pattern validates (e.g., "Must be a valid username with only lowercase letters, numbers, and underscores")
894
912
  */
895
- regex(pattern: string, description: string): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
913
+ regex(pattern: string, description: string): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
896
914
  /**
897
915
  * Set date format validation for strings
898
916
  */
899
- date(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
917
+ date(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
900
918
  /**
901
919
  * Set datetime format validation for strings
902
920
  */
903
- datetime(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
921
+ datetime(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
904
922
  }
905
923
  type ValidateNoMediaTypes<TFields> = {
906
924
  [K in keyof TFields]: TFields[K] extends {
@@ -915,20 +933,20 @@ type ValidateNoMediaTypes<TFields> = {
915
933
  } : TFields[K] : TFields[K] : TFields[K];
916
934
  };
917
935
  declare const f: (() => AxSignatureBuilder) & {
918
- string: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined>;
919
- number: (desc?: string) => AxFluentFieldType<"number", false, undefined, false, false, undefined>;
920
- boolean: (desc?: string) => AxFluentFieldType<"boolean", false, undefined, false, false, undefined>;
921
- json: (desc?: string) => AxFluentFieldType<"json", false, undefined, false, false, undefined>;
922
- datetime: (desc?: string) => AxFluentFieldType<"datetime", false, undefined, false, false, undefined>;
923
- date: (desc?: string) => AxFluentFieldType<"date", false, undefined, false, false, undefined>;
924
- class: <const TOptions extends readonly string[]>(options: TOptions, desc?: string) => AxFluentFieldType<"class", false, TOptions, false, false, undefined>;
925
- image: (desc?: string) => AxFluentFieldType<"image", false, undefined, false, false, undefined>;
926
- audio: (desc?: string) => AxFluentFieldType<"audio", false, undefined, false, false, undefined>;
927
- file: (desc?: string) => AxFluentFieldType<"file", false, undefined, false, false, undefined>;
928
- url: (desc?: string) => AxFluentFieldType<"url", false, undefined, false, false, undefined>;
929
- email: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined>;
930
- code: (language?: string, desc?: string) => AxFluentFieldType<"code", false, undefined, false, false, undefined>;
931
- object: <TFields extends Record<string, AxFluentFieldInfo<any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any>>>(fields: TFields & ValidateNoMediaTypes<TFields>, desc?: string) => AxFluentFieldType<"object", false, undefined, false, false, TFields>;
936
+ string: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined, false>;
937
+ number: (desc?: string) => AxFluentFieldType<"number", false, undefined, false, false, undefined, false>;
938
+ boolean: (desc?: string) => AxFluentFieldType<"boolean", false, undefined, false, false, undefined, false>;
939
+ json: (desc?: string) => AxFluentFieldType<"json", false, undefined, false, false, undefined, false>;
940
+ datetime: (desc?: string) => AxFluentFieldType<"datetime", false, undefined, false, false, undefined, false>;
941
+ date: (desc?: string) => AxFluentFieldType<"date", false, undefined, false, false, undefined, false>;
942
+ class: <const TOptions extends readonly string[]>(options: TOptions, desc?: string) => AxFluentFieldType<"class", false, TOptions, false, false, undefined, false>;
943
+ image: (desc?: string) => AxFluentFieldType<"image", false, undefined, false, false, undefined, false>;
944
+ audio: (desc?: string) => AxFluentFieldType<"audio", false, undefined, false, false, undefined, false>;
945
+ file: (desc?: string) => AxFluentFieldType<"file", false, undefined, false, false, undefined, false>;
946
+ url: (desc?: string) => AxFluentFieldType<"url", false, undefined, false, false, undefined, false>;
947
+ email: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined, false>;
948
+ code: (language?: string, desc?: string) => AxFluentFieldType<"code", false, undefined, false, false, undefined, false>;
949
+ object: <TFields extends Record<string, AxFluentFieldInfo<any, any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any, any>>>(fields: TFields & ValidateNoMediaTypes<TFields>, desc?: string) => AxFluentFieldType<"object", false, undefined, false, false, TFields, false>;
932
950
  };
933
951
  interface AxField {
934
952
  name: string;
@@ -950,6 +968,7 @@ interface AxField {
950
968
  };
951
969
  isOptional?: boolean;
952
970
  isInternal?: boolean;
971
+ isCached?: boolean;
953
972
  }
954
973
  type AxIField = Omit<AxField, 'title'> & {
955
974
  title: string;
@@ -985,7 +1004,7 @@ type InferFieldValueType<T> = T extends AxFieldType | AxFluentFieldType ? T['typ
985
1004
  }[] : {
986
1005
  [K in keyof F]: InferFluentType<F[K]>;
987
1006
  } : any : any : any : any;
988
- interface AxFluentFieldInfo<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] = readonly string[], TIsOptional extends boolean = false, _TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined> {
1007
+ interface AxFluentFieldInfo<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] = readonly string[], TIsOptional extends boolean = false, _TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined, _TIsCached extends boolean = false> {
989
1008
  readonly type: TType;
990
1009
  readonly isArray?: TIsArray;
991
1010
  readonly options?: TOptions;
@@ -994,6 +1013,7 @@ interface AxFluentFieldInfo<TType extends AxFieldType['type'] = AxFieldType['typ
994
1013
  readonly itemDescription?: string;
995
1014
  readonly isOptional?: TIsOptional;
996
1015
  readonly isInternal?: boolean;
1016
+ readonly isCached?: boolean;
997
1017
  readonly minLength?: number;
998
1018
  readonly maxLength?: number;
999
1019
  readonly minimum?: number;
@@ -1509,6 +1529,11 @@ interface AxCompileOptions {
1509
1529
  skipPerfectScore?: boolean;
1510
1530
  perfectScore?: number;
1511
1531
  maxMetricCalls?: number;
1532
+ /**
1533
+ * Custom labels to include in OpenTelemetry metrics.
1534
+ * These labels are merged with axGlobals.customLabels and AI service customLabels.
1535
+ */
1536
+ customLabels?: Record<string, string>;
1512
1537
  }
1513
1538
 
1514
1539
  interface AxOptimizerMetricsConfig {
@@ -1780,6 +1805,11 @@ declare abstract class AxBaseOptimizer implements AxOptimizer {
1780
1805
  protected readonly metricsInstruments?: AxOptimizerMetricsInstruments;
1781
1806
  private resultExplainer?;
1782
1807
  constructor(args: Readonly<AxOptimizerArgs>);
1808
+ /**
1809
+ * Get merged custom labels from globals, AI services, and compile options.
1810
+ * Labels are merged with later sources overriding earlier ones.
1811
+ */
1812
+ protected getMergedCustomLabels(options?: AxCompileOptions): Record<string, string>;
1783
1813
  /**
1784
1814
  * Initialize the result explanation generator
1785
1815
  * FIXME: Disabled due to circular dependency with ax() function
@@ -1808,7 +1838,7 @@ declare abstract class AxBaseOptimizer implements AxOptimizer {
1808
1838
  /**
1809
1839
  * Trigger early stopping with appropriate callbacks
1810
1840
  */
1811
- protected triggerEarlyStopping(reason: string, bestScoreRound: number): void;
1841
+ protected triggerEarlyStopping(reason: string, bestScoreRound: number, options?: AxCompileOptions): void;
1812
1842
  /**
1813
1843
  * Validate that examples meet minimum requirements for optimization
1814
1844
  * @param examples Examples to validate
@@ -1934,35 +1964,35 @@ declare abstract class AxBaseOptimizer implements AxOptimizer {
1934
1964
  /**
1935
1965
  * Record optimization start metrics
1936
1966
  */
1937
- protected recordOptimizationStart(optimizerType: string, programSignature?: string): void;
1967
+ protected recordOptimizationStart(optimizerType: string, programSignature?: string, options?: AxCompileOptions): void;
1938
1968
  /**
1939
1969
  * Record optimization completion metrics
1940
1970
  */
1941
- protected recordOptimizationComplete(duration: number, success: boolean, optimizerType: string, programSignature?: string): void;
1971
+ protected recordOptimizationComplete(duration: number, success: boolean, optimizerType: string, programSignature?: string, options?: AxCompileOptions): void;
1942
1972
  /**
1943
1973
  * Record convergence metrics
1944
1974
  */
1945
- protected recordConvergenceMetrics(rounds: number, currentScore: number, improvement: number, stagnationRounds: number, optimizerType: string): void;
1975
+ protected recordConvergenceMetrics(rounds: number, currentScore: number, improvement: number, stagnationRounds: number, optimizerType: string, options?: AxCompileOptions): void;
1946
1976
  /**
1947
1977
  * Record early stopping metrics
1948
1978
  */
1949
- protected recordEarlyStoppingMetrics(reason: string, optimizerType: string): void;
1979
+ protected recordEarlyStoppingMetrics(reason: string, optimizerType: string, options?: AxCompileOptions): void;
1950
1980
  /**
1951
1981
  * Record teacher-student interaction metrics
1952
1982
  */
1953
- protected recordTeacherStudentMetrics(latency: number, scoreImprovement: number, optimizerType: string): void;
1983
+ protected recordTeacherStudentMetrics(latency: number, scoreImprovement: number, optimizerType: string, options?: AxCompileOptions): void;
1954
1984
  /**
1955
1985
  * Record checkpoint metrics
1956
1986
  */
1957
- protected recordCheckpointMetrics(operation: 'save' | 'load', latency: number, success: boolean, optimizerType: string): void;
1987
+ protected recordCheckpointMetrics(operation: 'save' | 'load', latency: number, success: boolean, optimizerType: string, options?: AxCompileOptions): void;
1958
1988
  /**
1959
1989
  * Record Pareto optimization metrics
1960
1990
  */
1961
- protected recordParetoMetrics(frontSize: number, solutionsGenerated: number, optimizerType: string, hypervolume?: number): void;
1991
+ protected recordParetoMetrics(frontSize: number, solutionsGenerated: number, optimizerType: string, hypervolume?: number, options?: AxCompileOptions): void;
1962
1992
  /**
1963
1993
  * Record performance metrics
1964
1994
  */
1965
- protected recordPerformanceMetrics(metricType: 'evaluation' | 'demo_generation' | 'metric_computation', duration: number, optimizerType: string): void;
1995
+ protected recordPerformanceMetrics(metricType: 'evaluation' | 'demo_generation' | 'metric_computation', duration: number, optimizerType: string, options?: AxCompileOptions): void;
1966
1996
  protected isOptimizerLoggingEnabled(options?: AxCompileOptions): boolean;
1967
1997
  protected getOptimizerLogger(options?: AxCompileOptions): AxOptimizerLoggerFunction | undefined;
1968
1998
  getStats(): AxOptimizationStats;
@@ -2055,6 +2085,7 @@ declare class AxGen<IN = any, OUT extends AxGenOut = any> extends AxProgram<IN,
2055
2085
  getInstruction(): string | undefined;
2056
2086
  private getSignatureName;
2057
2087
  private getMetricsInstruments;
2088
+ private getMergedCustomLabels;
2058
2089
  updateMeter(meter?: Meter): void;
2059
2090
  private createStates;
2060
2091
  addAssert: (fn: AxAssertion<OUT>["fn"], message?: string) => void;
@@ -2118,6 +2149,8 @@ interface AxPromptTemplateOptions {
2118
2149
  contextCache?: AxContextCacheOptions;
2119
2150
  /** When true, examples/demos are embedded in system prompt (legacy). When false (default), they are rendered as alternating user/assistant message pairs. */
2120
2151
  examplesInSystem?: boolean;
2152
+ /** When true, cacheBreakpoint is ignored and cache is applied to all positions (for providers with auto-lookback like Anthropic) */
2153
+ ignoreBreakpoints?: boolean;
2121
2154
  }
2122
2155
  type AxChatRequestChatPrompt = Writeable<AxChatRequest['chatPrompt'][0]>;
2123
2156
  type ChatRequestUserMessage = Exclude<Extract<AxChatRequestChatPrompt, {
@@ -2135,7 +2168,13 @@ declare class AxPromptTemplate {
2135
2168
  private readonly functions?;
2136
2169
  private readonly contextCache?;
2137
2170
  private readonly examplesInSystem;
2171
+ private readonly ignoreBreakpoints;
2138
2172
  constructor(sig: Readonly<AxSignature>, options?: Readonly<AxPromptTemplateOptions>, fieldTemplates?: Record<string, AxFieldTemplateFn>);
2173
+ /**
2174
+ * Sort fields so that cached fields come first.
2175
+ * Uses stable sort to preserve relative order among cached and non-cached fields.
2176
+ */
2177
+ private sortFieldsCachedFirst;
2139
2178
  /**
2140
2179
  * Build legacy prompt format (backward compatible)
2141
2180
  */
@@ -2627,6 +2666,8 @@ interface AxAIFeatures {
2627
2666
  supported: boolean;
2628
2667
  /** Types of caching available */
2629
2668
  types: ('ephemeral' | 'persistent')[];
2669
+ /** Whether explicit cache breakpoints are needed. If false, provider has automatic lookback and cache_control is always applied to system and last tool when caching is detected. Defaults to true. */
2670
+ cacheBreakpoints?: boolean;
2630
2671
  };
2631
2672
  /** Whether the provider supports thinking/reasoning modes */
2632
2673
  thinking: boolean;
@@ -2662,6 +2703,7 @@ declare class AxBaseAI<TModel, TEmbedModel, TChatRequest, TEmbedRequest, TChatRe
2662
2703
  private logger;
2663
2704
  private corsProxy?;
2664
2705
  private retry?;
2706
+ private customLabels?;
2665
2707
  private modelInfo;
2666
2708
  private modelUsage?;
2667
2709
  private embedModelUsage?;
@@ -2685,6 +2727,7 @@ declare class AxBaseAI<TModel, TEmbedModel, TChatRequest, TEmbedRequest, TChatRe
2685
2727
  setOptions(options: Readonly<AxAIServiceOptions>): void;
2686
2728
  getOptions(): Readonly<AxAIServiceOptions>;
2687
2729
  getLogger(): AxLoggerFunction;
2730
+ private getMergedCustomLabels;
2688
2731
  getModelList(): ({
2689
2732
  readonly key: TModelKey;
2690
2733
  readonly description: string;
@@ -6138,6 +6181,7 @@ declare const axGlobals: {
6138
6181
  optimizerLogger: AxOptimizerLoggerFunction | undefined;
6139
6182
  debug: boolean | undefined;
6140
6183
  abortSignal: AbortSignal | undefined;
6184
+ customLabels: Record<string, string> | undefined;
6141
6185
  cachingFunction: ((key: string, value?: AxGenOut) => AxGenOut | undefined | Promise<AxGenOut | undefined>) | undefined;
6142
6186
  functionResultFormatter: AxFunctionResultFormatter;
6143
6187
  };
package/index.d.ts CHANGED
@@ -680,6 +680,16 @@ type AxAIServiceOptions = {
680
680
  * Currently supported by: Google Gemini/Vertex AI
681
681
  */
682
682
  contextCache?: AxContextCacheOptions;
683
+ /**
684
+ * When true, examples/demos are embedded in system prompt (legacy).
685
+ * When false (default), they are rendered as alternating user/assistant message pairs.
686
+ */
687
+ examplesInSystem?: boolean;
688
+ /**
689
+ * Custom labels to include in OpenTelemetry metrics.
690
+ * These labels are merged with axGlobals.customLabels (service-level overrides global).
691
+ */
692
+ customLabels?: Record<string, string>;
683
693
  };
684
694
  interface AxAIService<TModel = unknown, TEmbedModel = unknown, TModelKey = string> {
685
695
  getId(): string;
@@ -813,14 +823,14 @@ declare class AxSignatureBuilder<_TInput extends Record<string, any> = {}, _TOut
813
823
  * @param fieldInfo - Field type created with f.string(), f.number(), etc.
814
824
  * @param prepend - If true, adds field to the beginning of input fields
815
825
  */
816
- input<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<AddFieldToShape<_TInput, K, T>, _TOutput>;
826
+ input<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<AddFieldToShape<_TInput, K, T>, _TOutput>;
817
827
  /**
818
828
  * Add an output field to the signature
819
829
  * @param name - Field name
820
830
  * @param fieldInfo - Field type created with f.string(), f.number(), etc.
821
831
  * @param prepend - If true, adds field to the beginning of output fields
822
832
  */
823
- output<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<_TInput, AddFieldToShape<_TOutput, K, T>>;
833
+ output<K extends string, T extends AxFluentFieldInfo<any, any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any, any>>(name: K, fieldInfo: T, prepend?: boolean): AxSignatureBuilder<_TInput, AddFieldToShape<_TOutput, K, T>>;
824
834
  /**
825
835
  * Set the description for the signature
826
836
  * @param description - Description text
@@ -835,13 +845,14 @@ declare class AxSignatureBuilder<_TInput extends Record<string, any> = {}, _TOut
835
845
  */
836
846
  build(): AxSignature<_TInput, _TOutput>;
837
847
  }
838
- declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] | undefined = undefined, TIsOptional extends boolean = false, TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined> implements AxFieldType {
848
+ declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] | undefined = undefined, TIsOptional extends boolean = false, TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined, TIsCached extends boolean = false> implements AxFieldType {
839
849
  readonly type: TType;
840
850
  readonly isArray: TIsArray;
841
851
  readonly options?: TOptions;
842
852
  readonly description?: string;
843
853
  readonly isOptional: TIsOptional;
844
854
  readonly isInternal: TIsInternal;
855
+ readonly isCached: TIsCached;
845
856
  readonly fields?: any;
846
857
  readonly minLength?: number;
847
858
  readonly maxLength?: number;
@@ -859,6 +870,7 @@ declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType[
859
870
  itemDescription?: string;
860
871
  isOptional: TIsOptional;
861
872
  isInternal: TIsInternal;
873
+ isCached: TIsCached;
862
874
  fields?: TFields;
863
875
  minLength?: number;
864
876
  maxLength?: number;
@@ -868,39 +880,45 @@ declare class AxFluentFieldType<TType extends AxFieldType['type'] = AxFieldType[
868
880
  patternDescription?: string;
869
881
  format?: string;
870
882
  });
871
- optional(): AxFluentFieldType<TType, TIsArray, TOptions, true, TIsInternal, TFields>;
872
- array(desc?: string): AxFluentFieldType<TType, true, TOptions, TIsOptional, TIsInternal, TFields>;
873
- internal(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, true, TFields>;
883
+ optional(): AxFluentFieldType<TType, TIsArray, TOptions, true, TIsInternal, TFields, TIsCached>;
884
+ array(desc?: string): AxFluentFieldType<TType, true, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
885
+ internal(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, true, TFields, TIsCached>;
886
+ /**
887
+ * Mark this input field for caching. When contextCache is enabled,
888
+ * cached fields are rendered in a separate user message with cache: true,
889
+ * allowing them to be cached by the LLM provider.
890
+ */
891
+ cache(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, true>;
874
892
  /**
875
893
  * Set minimum value for numbers or minimum length for strings
876
894
  */
877
- min(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
895
+ min(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
878
896
  /**
879
897
  * Set maximum value for numbers or maximum length for strings
880
898
  */
881
- max(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
899
+ max(value: number): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
882
900
  /**
883
901
  * Set email format validation for strings
884
902
  */
885
- email(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
903
+ email(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
886
904
  /**
887
905
  * Set URL/URI format validation for strings
888
906
  */
889
- url(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
907
+ url(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
890
908
  /**
891
909
  * Set regex pattern validation for strings
892
910
  * @param pattern - Regular expression pattern to match
893
911
  * @param description - Human-readable description of what the pattern validates (e.g., "Must be a valid username with only lowercase letters, numbers, and underscores")
894
912
  */
895
- regex(pattern: string, description: string): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
913
+ regex(pattern: string, description: string): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
896
914
  /**
897
915
  * Set date format validation for strings
898
916
  */
899
- date(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
917
+ date(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
900
918
  /**
901
919
  * Set datetime format validation for strings
902
920
  */
903
- datetime(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields>;
921
+ datetime(): AxFluentFieldType<TType, TIsArray, TOptions, TIsOptional, TIsInternal, TFields, TIsCached>;
904
922
  }
905
923
  type ValidateNoMediaTypes<TFields> = {
906
924
  [K in keyof TFields]: TFields[K] extends {
@@ -915,20 +933,20 @@ type ValidateNoMediaTypes<TFields> = {
915
933
  } : TFields[K] : TFields[K] : TFields[K];
916
934
  };
917
935
  declare const f: (() => AxSignatureBuilder) & {
918
- string: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined>;
919
- number: (desc?: string) => AxFluentFieldType<"number", false, undefined, false, false, undefined>;
920
- boolean: (desc?: string) => AxFluentFieldType<"boolean", false, undefined, false, false, undefined>;
921
- json: (desc?: string) => AxFluentFieldType<"json", false, undefined, false, false, undefined>;
922
- datetime: (desc?: string) => AxFluentFieldType<"datetime", false, undefined, false, false, undefined>;
923
- date: (desc?: string) => AxFluentFieldType<"date", false, undefined, false, false, undefined>;
924
- class: <const TOptions extends readonly string[]>(options: TOptions, desc?: string) => AxFluentFieldType<"class", false, TOptions, false, false, undefined>;
925
- image: (desc?: string) => AxFluentFieldType<"image", false, undefined, false, false, undefined>;
926
- audio: (desc?: string) => AxFluentFieldType<"audio", false, undefined, false, false, undefined>;
927
- file: (desc?: string) => AxFluentFieldType<"file", false, undefined, false, false, undefined>;
928
- url: (desc?: string) => AxFluentFieldType<"url", false, undefined, false, false, undefined>;
929
- email: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined>;
930
- code: (language?: string, desc?: string) => AxFluentFieldType<"code", false, undefined, false, false, undefined>;
931
- object: <TFields extends Record<string, AxFluentFieldInfo<any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any>>>(fields: TFields & ValidateNoMediaTypes<TFields>, desc?: string) => AxFluentFieldType<"object", false, undefined, false, false, TFields>;
936
+ string: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined, false>;
937
+ number: (desc?: string) => AxFluentFieldType<"number", false, undefined, false, false, undefined, false>;
938
+ boolean: (desc?: string) => AxFluentFieldType<"boolean", false, undefined, false, false, undefined, false>;
939
+ json: (desc?: string) => AxFluentFieldType<"json", false, undefined, false, false, undefined, false>;
940
+ datetime: (desc?: string) => AxFluentFieldType<"datetime", false, undefined, false, false, undefined, false>;
941
+ date: (desc?: string) => AxFluentFieldType<"date", false, undefined, false, false, undefined, false>;
942
+ class: <const TOptions extends readonly string[]>(options: TOptions, desc?: string) => AxFluentFieldType<"class", false, TOptions, false, false, undefined, false>;
943
+ image: (desc?: string) => AxFluentFieldType<"image", false, undefined, false, false, undefined, false>;
944
+ audio: (desc?: string) => AxFluentFieldType<"audio", false, undefined, false, false, undefined, false>;
945
+ file: (desc?: string) => AxFluentFieldType<"file", false, undefined, false, false, undefined, false>;
946
+ url: (desc?: string) => AxFluentFieldType<"url", false, undefined, false, false, undefined, false>;
947
+ email: (desc?: string) => AxFluentFieldType<"string", false, undefined, false, false, undefined, false>;
948
+ code: (language?: string, desc?: string) => AxFluentFieldType<"code", false, undefined, false, false, undefined, false>;
949
+ object: <TFields extends Record<string, AxFluentFieldInfo<any, any, any, any, any, any, any> | AxFluentFieldType<any, any, any, any, any, any, any>>>(fields: TFields & ValidateNoMediaTypes<TFields>, desc?: string) => AxFluentFieldType<"object", false, undefined, false, false, TFields, false>;
932
950
  };
933
951
  interface AxField {
934
952
  name: string;
@@ -950,6 +968,7 @@ interface AxField {
950
968
  };
951
969
  isOptional?: boolean;
952
970
  isInternal?: boolean;
971
+ isCached?: boolean;
953
972
  }
954
973
  type AxIField = Omit<AxField, 'title'> & {
955
974
  title: string;
@@ -985,7 +1004,7 @@ type InferFieldValueType<T> = T extends AxFieldType | AxFluentFieldType ? T['typ
985
1004
  }[] : {
986
1005
  [K in keyof F]: InferFluentType<F[K]>;
987
1006
  } : any : any : any : any;
988
- interface AxFluentFieldInfo<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] = readonly string[], TIsOptional extends boolean = false, _TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined> {
1007
+ interface AxFluentFieldInfo<TType extends AxFieldType['type'] = AxFieldType['type'], TIsArray extends boolean = false, TOptions extends readonly string[] = readonly string[], TIsOptional extends boolean = false, _TIsInternal extends boolean = false, TFields extends Record<string, AxFluentFieldInfo | AxFluentFieldType> | undefined = undefined, _TIsCached extends boolean = false> {
989
1008
  readonly type: TType;
990
1009
  readonly isArray?: TIsArray;
991
1010
  readonly options?: TOptions;
@@ -994,6 +1013,7 @@ interface AxFluentFieldInfo<TType extends AxFieldType['type'] = AxFieldType['typ
994
1013
  readonly itemDescription?: string;
995
1014
  readonly isOptional?: TIsOptional;
996
1015
  readonly isInternal?: boolean;
1016
+ readonly isCached?: boolean;
997
1017
  readonly minLength?: number;
998
1018
  readonly maxLength?: number;
999
1019
  readonly minimum?: number;
@@ -1509,6 +1529,11 @@ interface AxCompileOptions {
1509
1529
  skipPerfectScore?: boolean;
1510
1530
  perfectScore?: number;
1511
1531
  maxMetricCalls?: number;
1532
+ /**
1533
+ * Custom labels to include in OpenTelemetry metrics.
1534
+ * These labels are merged with axGlobals.customLabels and AI service customLabels.
1535
+ */
1536
+ customLabels?: Record<string, string>;
1512
1537
  }
1513
1538
 
1514
1539
  interface AxOptimizerMetricsConfig {
@@ -1780,6 +1805,11 @@ declare abstract class AxBaseOptimizer implements AxOptimizer {
1780
1805
  protected readonly metricsInstruments?: AxOptimizerMetricsInstruments;
1781
1806
  private resultExplainer?;
1782
1807
  constructor(args: Readonly<AxOptimizerArgs>);
1808
+ /**
1809
+ * Get merged custom labels from globals, AI services, and compile options.
1810
+ * Labels are merged with later sources overriding earlier ones.
1811
+ */
1812
+ protected getMergedCustomLabels(options?: AxCompileOptions): Record<string, string>;
1783
1813
  /**
1784
1814
  * Initialize the result explanation generator
1785
1815
  * FIXME: Disabled due to circular dependency with ax() function
@@ -1808,7 +1838,7 @@ declare abstract class AxBaseOptimizer implements AxOptimizer {
1808
1838
  /**
1809
1839
  * Trigger early stopping with appropriate callbacks
1810
1840
  */
1811
- protected triggerEarlyStopping(reason: string, bestScoreRound: number): void;
1841
+ protected triggerEarlyStopping(reason: string, bestScoreRound: number, options?: AxCompileOptions): void;
1812
1842
  /**
1813
1843
  * Validate that examples meet minimum requirements for optimization
1814
1844
  * @param examples Examples to validate
@@ -1934,35 +1964,35 @@ declare abstract class AxBaseOptimizer implements AxOptimizer {
1934
1964
  /**
1935
1965
  * Record optimization start metrics
1936
1966
  */
1937
- protected recordOptimizationStart(optimizerType: string, programSignature?: string): void;
1967
+ protected recordOptimizationStart(optimizerType: string, programSignature?: string, options?: AxCompileOptions): void;
1938
1968
  /**
1939
1969
  * Record optimization completion metrics
1940
1970
  */
1941
- protected recordOptimizationComplete(duration: number, success: boolean, optimizerType: string, programSignature?: string): void;
1971
+ protected recordOptimizationComplete(duration: number, success: boolean, optimizerType: string, programSignature?: string, options?: AxCompileOptions): void;
1942
1972
  /**
1943
1973
  * Record convergence metrics
1944
1974
  */
1945
- protected recordConvergenceMetrics(rounds: number, currentScore: number, improvement: number, stagnationRounds: number, optimizerType: string): void;
1975
+ protected recordConvergenceMetrics(rounds: number, currentScore: number, improvement: number, stagnationRounds: number, optimizerType: string, options?: AxCompileOptions): void;
1946
1976
  /**
1947
1977
  * Record early stopping metrics
1948
1978
  */
1949
- protected recordEarlyStoppingMetrics(reason: string, optimizerType: string): void;
1979
+ protected recordEarlyStoppingMetrics(reason: string, optimizerType: string, options?: AxCompileOptions): void;
1950
1980
  /**
1951
1981
  * Record teacher-student interaction metrics
1952
1982
  */
1953
- protected recordTeacherStudentMetrics(latency: number, scoreImprovement: number, optimizerType: string): void;
1983
+ protected recordTeacherStudentMetrics(latency: number, scoreImprovement: number, optimizerType: string, options?: AxCompileOptions): void;
1954
1984
  /**
1955
1985
  * Record checkpoint metrics
1956
1986
  */
1957
- protected recordCheckpointMetrics(operation: 'save' | 'load', latency: number, success: boolean, optimizerType: string): void;
1987
+ protected recordCheckpointMetrics(operation: 'save' | 'load', latency: number, success: boolean, optimizerType: string, options?: AxCompileOptions): void;
1958
1988
  /**
1959
1989
  * Record Pareto optimization metrics
1960
1990
  */
1961
- protected recordParetoMetrics(frontSize: number, solutionsGenerated: number, optimizerType: string, hypervolume?: number): void;
1991
+ protected recordParetoMetrics(frontSize: number, solutionsGenerated: number, optimizerType: string, hypervolume?: number, options?: AxCompileOptions): void;
1962
1992
  /**
1963
1993
  * Record performance metrics
1964
1994
  */
1965
- protected recordPerformanceMetrics(metricType: 'evaluation' | 'demo_generation' | 'metric_computation', duration: number, optimizerType: string): void;
1995
+ protected recordPerformanceMetrics(metricType: 'evaluation' | 'demo_generation' | 'metric_computation', duration: number, optimizerType: string, options?: AxCompileOptions): void;
1966
1996
  protected isOptimizerLoggingEnabled(options?: AxCompileOptions): boolean;
1967
1997
  protected getOptimizerLogger(options?: AxCompileOptions): AxOptimizerLoggerFunction | undefined;
1968
1998
  getStats(): AxOptimizationStats;
@@ -2055,6 +2085,7 @@ declare class AxGen<IN = any, OUT extends AxGenOut = any> extends AxProgram<IN,
2055
2085
  getInstruction(): string | undefined;
2056
2086
  private getSignatureName;
2057
2087
  private getMetricsInstruments;
2088
+ private getMergedCustomLabels;
2058
2089
  updateMeter(meter?: Meter): void;
2059
2090
  private createStates;
2060
2091
  addAssert: (fn: AxAssertion<OUT>["fn"], message?: string) => void;
@@ -2118,6 +2149,8 @@ interface AxPromptTemplateOptions {
2118
2149
  contextCache?: AxContextCacheOptions;
2119
2150
  /** When true, examples/demos are embedded in system prompt (legacy). When false (default), they are rendered as alternating user/assistant message pairs. */
2120
2151
  examplesInSystem?: boolean;
2152
+ /** When true, cacheBreakpoint is ignored and cache is applied to all positions (for providers with auto-lookback like Anthropic) */
2153
+ ignoreBreakpoints?: boolean;
2121
2154
  }
2122
2155
  type AxChatRequestChatPrompt = Writeable<AxChatRequest['chatPrompt'][0]>;
2123
2156
  type ChatRequestUserMessage = Exclude<Extract<AxChatRequestChatPrompt, {
@@ -2135,7 +2168,13 @@ declare class AxPromptTemplate {
2135
2168
  private readonly functions?;
2136
2169
  private readonly contextCache?;
2137
2170
  private readonly examplesInSystem;
2171
+ private readonly ignoreBreakpoints;
2138
2172
  constructor(sig: Readonly<AxSignature>, options?: Readonly<AxPromptTemplateOptions>, fieldTemplates?: Record<string, AxFieldTemplateFn>);
2173
+ /**
2174
+ * Sort fields so that cached fields come first.
2175
+ * Uses stable sort to preserve relative order among cached and non-cached fields.
2176
+ */
2177
+ private sortFieldsCachedFirst;
2139
2178
  /**
2140
2179
  * Build legacy prompt format (backward compatible)
2141
2180
  */
@@ -2627,6 +2666,8 @@ interface AxAIFeatures {
2627
2666
  supported: boolean;
2628
2667
  /** Types of caching available */
2629
2668
  types: ('ephemeral' | 'persistent')[];
2669
+ /** Whether explicit cache breakpoints are needed. If false, provider has automatic lookback and cache_control is always applied to system and last tool when caching is detected. Defaults to true. */
2670
+ cacheBreakpoints?: boolean;
2630
2671
  };
2631
2672
  /** Whether the provider supports thinking/reasoning modes */
2632
2673
  thinking: boolean;
@@ -2662,6 +2703,7 @@ declare class AxBaseAI<TModel, TEmbedModel, TChatRequest, TEmbedRequest, TChatRe
2662
2703
  private logger;
2663
2704
  private corsProxy?;
2664
2705
  private retry?;
2706
+ private customLabels?;
2665
2707
  private modelInfo;
2666
2708
  private modelUsage?;
2667
2709
  private embedModelUsage?;
@@ -2685,6 +2727,7 @@ declare class AxBaseAI<TModel, TEmbedModel, TChatRequest, TEmbedRequest, TChatRe
2685
2727
  setOptions(options: Readonly<AxAIServiceOptions>): void;
2686
2728
  getOptions(): Readonly<AxAIServiceOptions>;
2687
2729
  getLogger(): AxLoggerFunction;
2730
+ private getMergedCustomLabels;
2688
2731
  getModelList(): ({
2689
2732
  readonly key: TModelKey;
2690
2733
  readonly description: string;
@@ -6138,6 +6181,7 @@ declare const axGlobals: {
6138
6181
  optimizerLogger: AxOptimizerLoggerFunction | undefined;
6139
6182
  debug: boolean | undefined;
6140
6183
  abortSignal: AbortSignal | undefined;
6184
+ customLabels: Record<string, string> | undefined;
6141
6185
  cachingFunction: ((key: string, value?: AxGenOut) => AxGenOut | undefined | Promise<AxGenOut | undefined>) | undefined;
6142
6186
  functionResultFormatter: AxFunctionResultFormatter;
6143
6187
  };