@x12i/optimixer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +96 -0
  3. package/dist/Optimixer.d.ts +22 -0
  4. package/dist/Optimixer.d.ts.map +1 -0
  5. package/dist/Optimixer.js +78 -0
  6. package/dist/Optimixer.js.map +1 -0
  7. package/dist/adapters/standalone-activix.d.ts +8 -0
  8. package/dist/adapters/standalone-activix.d.ts.map +1 -0
  9. package/dist/adapters/standalone-activix.js +23 -0
  10. package/dist/adapters/standalone-activix.js.map +1 -0
  11. package/dist/contracts/optimixer-types.d.ts +68 -0
  12. package/dist/contracts/optimixer-types.d.ts.map +1 -0
  13. package/dist/contracts/optimixer-types.js +3 -0
  14. package/dist/contracts/optimixer-types.js.map +1 -0
  15. package/dist/index.d.ts +6 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +5 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/persistence/activix-writer.d.ts +26 -0
  20. package/dist/persistence/activix-writer.d.ts.map +1 -0
  21. package/dist/persistence/activix-writer.js +72 -0
  22. package/dist/persistence/activix-writer.js.map +1 -0
  23. package/dist/pipelines/ai-max-tokens-v1.d.ts +18 -0
  24. package/dist/pipelines/ai-max-tokens-v1.d.ts.map +1 -0
  25. package/dist/pipelines/ai-max-tokens-v1.js +96 -0
  26. package/dist/pipelines/ai-max-tokens-v1.js.map +1 -0
  27. package/dist/state/bucket-store.d.ts +14 -0
  28. package/dist/state/bucket-store.d.ts.map +1 -0
  29. package/dist/state/bucket-store.js +24 -0
  30. package/dist/state/bucket-store.js.map +1 -0
  31. package/dist/state/quantile-stats.d.ts +12 -0
  32. package/dist/state/quantile-stats.d.ts.map +1 -0
  33. package/dist/state/quantile-stats.js +48 -0
  34. package/dist/state/quantile-stats.js.map +1 -0
  35. package/dist-cjs/Optimixer.d.ts +22 -0
  36. package/dist-cjs/Optimixer.d.ts.map +1 -0
  37. package/dist-cjs/Optimixer.js +82 -0
  38. package/dist-cjs/Optimixer.js.map +1 -0
  39. package/dist-cjs/adapters/standalone-activix.d.ts +8 -0
  40. package/dist-cjs/adapters/standalone-activix.d.ts.map +1 -0
  41. package/dist-cjs/adapters/standalone-activix.js +26 -0
  42. package/dist-cjs/adapters/standalone-activix.js.map +1 -0
  43. package/dist-cjs/contracts/optimixer-types.d.ts +68 -0
  44. package/dist-cjs/contracts/optimixer-types.d.ts.map +1 -0
  45. package/dist-cjs/contracts/optimixer-types.js +6 -0
  46. package/dist-cjs/contracts/optimixer-types.js.map +1 -0
  47. package/dist-cjs/index.d.ts +6 -0
  48. package/dist-cjs/index.d.ts.map +1 -0
  49. package/dist-cjs/index.js +15 -0
  50. package/dist-cjs/index.js.map +1 -0
  51. package/dist-cjs/package.json +3 -0
  52. package/dist-cjs/persistence/activix-writer.d.ts +26 -0
  53. package/dist-cjs/persistence/activix-writer.d.ts.map +1 -0
  54. package/dist-cjs/persistence/activix-writer.js +77 -0
  55. package/dist-cjs/persistence/activix-writer.js.map +1 -0
  56. package/dist-cjs/pipelines/ai-max-tokens-v1.d.ts +18 -0
  57. package/dist-cjs/pipelines/ai-max-tokens-v1.d.ts.map +1 -0
  58. package/dist-cjs/pipelines/ai-max-tokens-v1.js +101 -0
  59. package/dist-cjs/pipelines/ai-max-tokens-v1.js.map +1 -0
  60. package/dist-cjs/state/bucket-store.d.ts +14 -0
  61. package/dist-cjs/state/bucket-store.d.ts.map +1 -0
  62. package/dist-cjs/state/bucket-store.js +29 -0
  63. package/dist-cjs/state/bucket-store.js.map +1 -0
  64. package/dist-cjs/state/quantile-stats.d.ts +12 -0
  65. package/dist-cjs/state/quantile-stats.d.ts.map +1 -0
  66. package/dist-cjs/state/quantile-stats.js +53 -0
  67. package/dist-cjs/state/quantile-stats.js.map +1 -0
  68. package/package.json +62 -0
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Athenix License
2
+
3
+ Copyright (c) Athenices. All rights reserved.
4
+
5
+ This software is proprietary. Redistribution, modification, and use are permitted only under a separate written agreement with Athenices.
6
+
7
+ For licensing inquiries, contact the rights holder.
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # @x12i/optimixer
2
+
3
+ Prediction and learning layer for AI workloads. First pipeline: **`ai.max_tokens.v1`** (recommended max completion tokens from historical usage).
4
+
5
+ Uses `@x12i/activix-contracts` for record agreement. Persists prediction/evidence through an Activix-compatible client.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @x12i/optimixer @x12i/activix-contracts
11
+ # Optional for standalone mode:
12
+ npm install @x12i/activix
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Embedded mode (caller owns Activix)
18
+
19
+ ```typescript
20
+ import { Activix } from '@x12i/activix';
21
+ import { Optimixer } from '@x12i/optimixer';
22
+
23
+ const activix = await Activix.create({
24
+ collection: 'ai-gateway-activities',
25
+ mongoUri: process.env.MONGO_URI,
26
+ });
27
+
28
+ const optimixer = await Optimixer.create({
29
+ activixClient: activix,
30
+ activixCollection: 'ai-gateway-activities',
31
+ pipelines: { aiMaxTokens: { enabled: true } },
32
+ });
33
+
34
+ const prediction = await optimixer.predictAiMaxTokens({
35
+ actionTypeId: 'summarize',
36
+ inputSize: 1200,
37
+ contextSize: 800,
38
+ acceptableRisk: 'medium',
39
+ runContext: { sessionId: 'sess-1', jobId: 'job-1' },
40
+ });
41
+
42
+ // Use prediction.recommendedMaxTokens for the AI call
43
+
44
+ await optimixer.completeAiMaxTokensPrediction({
45
+ requestId: prediction.requestId,
46
+ actual: {
47
+ promptTokens: 900,
48
+ completionTokens: 420,
49
+ totalTokens: 1320,
50
+ finishReason: 'stop',
51
+ latencyMs: 800,
52
+ },
53
+ });
54
+ ```
55
+
56
+ ### Standalone mode
57
+
58
+ ```typescript
59
+ const optimixer = await Optimixer.create({
60
+ activix: {
61
+ collection: 'optimixer-activities',
62
+ mongoUri: process.env.MONGO_URI,
63
+ storageMode: 'automatic',
64
+ },
65
+ });
66
+ ```
67
+
68
+ Requires peer `@x12i/activix`.
69
+
70
+ ## Flow
71
+
72
+ ```
73
+ AI wrapper
74
+ → Optimixer.predictAiMaxTokens (creates Activix record)
75
+ → AI call with recommendedMaxTokens
76
+ → Optimixer.completeAiMaxTokensPrediction (updates record + in-memory stats)
77
+ ```
78
+
79
+ `requestId` equals the Activix `activityId` from `startRecord`.
80
+
81
+ ## Record conventions
82
+
83
+ Optimixer writes Activix rows with:
84
+
85
+ - `outer.input` — prediction request
86
+ - `outer.output` — prediction result, then actual usage + learning on complete
87
+ - `outer.metadata.kind` — `optimixer:prediction`
88
+ - `outer.metadata.pipelineId` — `ai.max_tokens.v1`
89
+
90
+ ## Warmup
91
+
92
+ On `create()`, Optimixer loads recent completed prediction rows via `findRecords` (when the client supports it) to repopulate in-memory quantile stats.
93
+
94
+ ## Version
95
+
96
+ Pre-1.0 (`0.1.0`) while pipelines evolve.
@@ -0,0 +1,22 @@
1
+ import type { AiMaxTokensCompleteInput, AiMaxTokensPredictionInput, AiMaxTokensPredictionResult, OptimixerCreateOptions } from './contracts/optimixer-types.js';
2
+ export declare class Optimixer {
3
+ private readonly client;
4
+ private readonly collection?;
5
+ private readonly bucketStore;
6
+ private readonly aiMaxTokensEnabled;
7
+ private readonly aiMaxTokensConfig;
8
+ private readonly writer;
9
+ private readonly closeHook?;
10
+ private constructor();
11
+ static create(options: OptimixerCreateOptions): Promise<Optimixer>;
12
+ close(): Promise<void>;
13
+ warmup(limit?: number): Promise<number>;
14
+ predictAiMaxTokens(input: AiMaxTokensPredictionInput): Promise<AiMaxTokensPredictionResult>;
15
+ completeAiMaxTokensPrediction(input: AiMaxTokensCompleteInput): Promise<{
16
+ learning: {
17
+ bucketKey: string;
18
+ observedCompletionTokens: number;
19
+ };
20
+ }>;
21
+ }
22
+ //# sourceMappingURL=Optimixer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Optimixer.d.ts","sourceRoot":"","sources":["../src/Optimixer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,sBAAsB,EACvB,MAAM,gCAAgC,CAAC;AAgBxC,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAU;IAC7C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAsB;IAEjD,OAAO;WAgBM,MAAM,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,SAAS,CAAC;IAoBlE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB,MAAM,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBpC,kBAAkB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,2BAA2B,CAAC;IAQ3F,6BAA6B,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC;QAC5E,QAAQ,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,wBAAwB,EAAE,MAAM,CAAA;SAAE,CAAC;KACnE,CAAC;CASH"}
@@ -0,0 +1,78 @@
1
+ import { createStandaloneActivixClient } from './adapters/standalone-activix.js';
2
+ import { AI_MAX_TOKENS_V1_ALGORITHM_VERSION, AI_MAX_TOKENS_V1_PIPELINE_ID, } from './contracts/optimixer-types.js';
3
+ import { completeAiMaxTokensPredictionV1, predictAiMaxTokensV1, recordAiMaxTokensPrediction, } from './pipelines/ai-max-tokens-v1.js';
4
+ import { ActivixOptimixerWriter, warmupBucketStoreFromActivix, } from './persistence/activix-writer.js';
5
+ import { BucketStore } from './state/bucket-store.js';
6
+ export class Optimixer {
7
+ client;
8
+ collection;
9
+ bucketStore = new BucketStore();
10
+ aiMaxTokensEnabled;
11
+ aiMaxTokensConfig;
12
+ writer;
13
+ closeHook;
14
+ constructor(client, options) {
15
+ this.client = client;
16
+ this.collection = options.collection ?? options.activixCollection;
17
+ this.aiMaxTokensEnabled = options.pipelines?.aiMaxTokens?.enabled !== false;
18
+ this.aiMaxTokensConfig = options.pipelines?.aiMaxTokens;
19
+ this.closeHook = options.closeHook;
20
+ this.writer = new ActivixOptimixerWriter(client, {
21
+ collection: this.collection,
22
+ pipelineId: AI_MAX_TOKENS_V1_PIPELINE_ID,
23
+ algorithmVersion: AI_MAX_TOKENS_V1_ALGORITHM_VERSION,
24
+ });
25
+ }
26
+ static async create(options) {
27
+ let client = options.activixClient;
28
+ let collection = options.activixCollection ?? options.activix?.collection;
29
+ let closeHook;
30
+ if (!client) {
31
+ if (!options.activix) {
32
+ throw new Error('Optimixer.create requires activixClient or activix standalone config');
33
+ }
34
+ const standalone = await createStandaloneActivixClient(options.activix);
35
+ client = standalone.client;
36
+ collection = standalone.collection;
37
+ closeHook = standalone.close;
38
+ }
39
+ const optimixer = new Optimixer(client, { ...options, collection, closeHook });
40
+ await optimixer.warmup(options.warmupLimit ?? options.pipelines?.aiMaxTokens?.warmupLimit ?? 500);
41
+ return optimixer;
42
+ }
43
+ async close() {
44
+ if (this.closeHook) {
45
+ await this.closeHook();
46
+ }
47
+ }
48
+ async warmup(limit = 500) {
49
+ if (!this.aiMaxTokensEnabled) {
50
+ return 0;
51
+ }
52
+ return warmupBucketStoreFromActivix(this.client, {
53
+ collection: this.collection,
54
+ pipelineId: AI_MAX_TOKENS_V1_PIPELINE_ID,
55
+ limit,
56
+ onObservation: (actionTypeId, provider, model, completionTokens) => {
57
+ this.bucketStore.observe(`${actionTypeId}|${provider ?? '*'}|${model ?? '*'}`, completionTokens);
58
+ },
59
+ });
60
+ }
61
+ async predictAiMaxTokens(input) {
62
+ if (!this.aiMaxTokensEnabled) {
63
+ throw new Error('Optimixer ai.max_tokens.v1 pipeline is disabled');
64
+ }
65
+ const prediction = predictAiMaxTokensV1(input, this.bucketStore, this.aiMaxTokensConfig);
66
+ return recordAiMaxTokensPrediction(this.writer, input, prediction);
67
+ }
68
+ async completeAiMaxTokensPrediction(input) {
69
+ if (!this.aiMaxTokensEnabled) {
70
+ throw new Error('Optimixer ai.max_tokens.v1 pipeline is disabled');
71
+ }
72
+ return completeAiMaxTokensPredictionV1(this.client, this.writer, this.bucketStore, {
73
+ ...input,
74
+ collection: this.collection,
75
+ });
76
+ }
77
+ }
78
+ //# sourceMappingURL=Optimixer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Optimixer.js","sourceRoot":"","sources":["../src/Optimixer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ActivixActivityClient } from '@x12i/activix-contracts';
2
+ import type { OptimixerStandaloneActivixConfig } from '../contracts/optimixer-types.js';
3
+ export declare function createStandaloneActivixClient(config: OptimixerStandaloneActivixConfig): Promise<{
4
+ client: ActivixActivityClient;
5
+ collection: string;
6
+ close?: () => Promise<void>;
7
+ }>;
8
+ //# sourceMappingURL=standalone-activix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone-activix.d.ts","sourceRoot":"","sources":["../../src/adapters/standalone-activix.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,iCAAiC,CAAC;AAExF,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,gCAAgC,GACvC,OAAO,CAAC;IAAE,MAAM,EAAE,qBAAqB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAwB7F"}
@@ -0,0 +1,23 @@
1
+ export async function createStandaloneActivixClient(config) {
2
+ let ActivixCtor;
3
+ try {
4
+ ({ Activix: ActivixCtor } = await import('@x12i/activix'));
5
+ }
6
+ catch {
7
+ throw new Error('Optimixer standalone mode requires optional peer dependency @x12i/activix. Install it or pass activixClient instead.');
8
+ }
9
+ const ax = await ActivixCtor.create({
10
+ collection: config.collection,
11
+ mongoUri: config.mongoUri,
12
+ storageMode: config.storageMode ?? 'automatic',
13
+ playground: config.playground,
14
+ collectionRegistry: false,
15
+ autoCost: false,
16
+ });
17
+ return {
18
+ client: ax,
19
+ collection: config.collection,
20
+ close: () => ax.close(),
21
+ };
22
+ }
23
+ //# sourceMappingURL=standalone-activix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standalone-activix.js","sourceRoot":"","sources":["../../src/adapters/standalone-activix.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,MAAwC;IAExC,IAAI,WAAmD,CAAC;IACxD,IAAI,CAAC;QACH,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,sHAAsH,CACvH,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC;QAClC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,WAAW;QAC9C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,kBAAkB,EAAE,KAAK;QACzB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,EAAE,EAAsC;QAC9C,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,68 @@
1
+ import type { ActivixRunContext } from '@x12i/activix-contracts';
2
+ export type OptimixerPipelineId = 'ai.max_tokens.v1' | (string & {});
3
+ export declare const AI_MAX_TOKENS_V1_PIPELINE_ID: OptimixerPipelineId;
4
+ export declare const AI_MAX_TOKENS_V1_ALGORITHM_VERSION = "1.0.0";
5
+ export type OptimixerAcceptableRisk = 'very-low' | 'low' | 'medium' | 'high' | number;
6
+ export type OptimixerPredictionRecord = {
7
+ requestId: string;
8
+ pipelineId: OptimixerPipelineId;
9
+ algorithmVersion: string;
10
+ prediction: unknown;
11
+ actual?: unknown;
12
+ learning?: unknown;
13
+ };
14
+ export type AiMaxTokensPredictionInput = {
15
+ runContext?: ActivixRunContext;
16
+ actionTypeId: string;
17
+ inputSize: number;
18
+ contextSize: number;
19
+ plannedTools?: string[];
20
+ acceptableRisk: OptimixerAcceptableRisk;
21
+ provider?: string;
22
+ model?: string;
23
+ };
24
+ export type AiMaxTokensActualUsage = {
25
+ promptTokens: number;
26
+ completionTokens: number;
27
+ totalTokens: number;
28
+ finishReason?: string;
29
+ latencyMs?: number;
30
+ };
31
+ export type AiMaxTokensPredictionResult = {
32
+ requestId: string;
33
+ pipelineId: typeof AI_MAX_TOKENS_V1_PIPELINE_ID;
34
+ algorithmVersion: string;
35
+ recommendedMaxTokens: number;
36
+ confidence: 'cold-start' | 'warm';
37
+ bucketKey: string;
38
+ riskLevel: OptimixerAcceptableRisk;
39
+ };
40
+ export type AiMaxTokensCompleteInput = {
41
+ requestId: string;
42
+ actual: AiMaxTokensActualUsage;
43
+ };
44
+ export type OptimixerPipelineConfig = {
45
+ enabled?: boolean;
46
+ warmupLimit?: number;
47
+ defaultMaxTokens?: number;
48
+ };
49
+ export type OptimixerPipelinesConfig = {
50
+ aiMaxTokens?: OptimixerPipelineConfig;
51
+ };
52
+ export type OptimixerStandaloneActivixConfig = {
53
+ collection: string;
54
+ mongoUri?: string;
55
+ storageMode?: 'automatic' | 'database' | 'local';
56
+ playground?: {
57
+ outputDir?: string;
58
+ runId?: string;
59
+ };
60
+ };
61
+ export type OptimixerCreateOptions = {
62
+ activixClient?: import('@x12i/activix-contracts').ActivixActivityClient;
63
+ activix?: OptimixerStandaloneActivixConfig;
64
+ activixCollection?: string;
65
+ pipelines?: OptimixerPipelinesConfig;
66
+ warmupLimit?: number;
67
+ };
68
+ //# sourceMappingURL=optimixer-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimixer-types.d.ts","sourceRoot":"","sources":["../../src/contracts/optimixer-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,MAAM,mBAAmB,GAAG,kBAAkB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAErE,eAAO,MAAM,4BAA4B,EAAE,mBAAwC,CAAC;AAEpF,eAAO,MAAM,kCAAkC,UAAU,CAAC;AAE1D,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEtF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,mBAAmB,CAAC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,uBAAuB,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,4BAA4B,CAAC;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,EAAE,YAAY,GAAG,MAAM,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,uBAAuB,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;IACjD,UAAU,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,aAAa,CAAC,EAAE,OAAO,yBAAyB,EAAE,qBAAqB,CAAC;IACxE,OAAO,CAAC,EAAE,gCAAgC,CAAC;IAC3C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,wBAAwB,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export const AI_MAX_TOKENS_V1_PIPELINE_ID = 'ai.max_tokens.v1';
2
+ export const AI_MAX_TOKENS_V1_ALGORITHM_VERSION = '1.0.0';
3
+ //# sourceMappingURL=optimixer-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"optimixer-types.js","sourceRoot":"","sources":["../../src/contracts/optimixer-types.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,4BAA4B,GAAwB,kBAAkB,CAAC;AAEpF,MAAM,CAAC,MAAM,kCAAkC,GAAG,OAAO,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { Optimixer } from './Optimixer.js';
2
+ export type { AiMaxTokensActualUsage, AiMaxTokensCompleteInput, AiMaxTokensPredictionInput, AiMaxTokensPredictionResult, OptimixerAcceptableRisk, OptimixerCreateOptions, OptimixerPipelineConfig, OptimixerPipelineId, OptimixerPipelinesConfig, OptimixerPredictionRecord, OptimixerStandaloneActivixConfig, } from './contracts/optimixer-types.js';
3
+ export { AI_MAX_TOKENS_V1_ALGORITHM_VERSION, AI_MAX_TOKENS_V1_PIPELINE_ID, } from './contracts/optimixer-types.js';
4
+ export { BucketStore, buildBucketKey } from './state/bucket-store.js';
5
+ export { QuantileStats, riskToPercentile } from './state/quantile-stats.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,YAAY,EACV,sBAAsB,EACtB,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,gCAAgC,GACjC,MAAM,gCAAgC,CAAC;AAExC,OAAO,EACL,kCAAkC,EAClC,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { Optimixer } from './Optimixer.js';
2
+ export { AI_MAX_TOKENS_V1_ALGORITHM_VERSION, AI_MAX_TOKENS_V1_PIPELINE_ID, } from './contracts/optimixer-types.js';
3
+ export { BucketStore, buildBucketKey } from './state/bucket-store.js';
4
+ export { QuantileStats, riskToPercentile } from './state/quantile-stats.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAgB3C,OAAO,EACL,kCAAkC,EAClC,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { ActivixActivityClient, ActivixActivityRecord, ActivixRunContext } from '@x12i/activix-contracts';
2
+ export type ActivixWriterOptions = {
3
+ collection?: string;
4
+ pipelineId: string;
5
+ algorithmVersion: string;
6
+ };
7
+ export declare class ActivixOptimixerWriter {
8
+ private readonly client;
9
+ private readonly options;
10
+ constructor(client: ActivixActivityClient, options: ActivixWriterOptions);
11
+ startPredictionRecord(input: {
12
+ runContext?: ActivixRunContext;
13
+ outerInput: unknown;
14
+ outerOutput: unknown;
15
+ outerMetadata?: Record<string, unknown>;
16
+ }): Promise<string>;
17
+ completePredictionRecord(activityId: string, updates: Partial<ActivixActivityRecord>): Promise<void>;
18
+ patchPredictionRecord(activityId: string, fields: Partial<ActivixActivityRecord>): Promise<void>;
19
+ }
20
+ export declare function warmupBucketStoreFromActivix(client: ActivixActivityClient, opts: {
21
+ collection?: string;
22
+ pipelineId: string;
23
+ limit: number;
24
+ onObservation: (actionTypeId: string, provider: string | undefined, model: string | undefined, completionTokens: number) => void;
25
+ }): Promise<number>;
26
+ //# sourceMappingURL=activix-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activix-writer.d.ts","sourceRoot":"","sources":["../../src/persistence/activix-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAMjC,MAAM,MAAM,oBAAoB,GAAG;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,qBAAa,sBAAsB;IAE/B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,oBAAoB;IAG1C,qBAAqB,CAAC,KAAK,EAAE;QACjC,UAAU,CAAC,EAAE,iBAAiB,CAAC;QAC/B,UAAU,EAAE,OAAO,CAAC;QACpB,WAAW,EAAE,OAAO,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACzC,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBb,wBAAwB,CAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC;IAMV,qBAAqB,CACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACrC,OAAO,CAAC,IAAI,CAAC;CAWjB;AAED,wBAAsB,4BAA4B,CAChD,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE;IACJ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,gBAAgB,EAAE,MAAM,KAAK,IAAI,CAAC;CAClI,GACA,OAAO,CAAC,MAAM,CAAC,CAqCjB"}
@@ -0,0 +1,72 @@
1
+ import { ACTIVIX_METADATA_KIND_OPTIMIXER_PREDICTION, ACTIVIX_METADATA_OPTIMIZER_OPTIMIXER, } from '@x12i/activix-contracts';
2
+ export class ActivixOptimixerWriter {
3
+ client;
4
+ options;
5
+ constructor(client, options) {
6
+ this.client = client;
7
+ this.options = options;
8
+ }
9
+ async startPredictionRecord(input) {
10
+ const result = await this.client.startRecord({
11
+ runContext: input.runContext,
12
+ outer: {
13
+ input: input.outerInput,
14
+ output: input.outerOutput,
15
+ metadata: {
16
+ kind: ACTIVIX_METADATA_KIND_OPTIMIXER_PREDICTION,
17
+ optimizer: ACTIVIX_METADATA_OPTIMIZER_OPTIMIXER,
18
+ pipelineId: this.options.pipelineId,
19
+ algorithmVersion: this.options.algorithmVersion,
20
+ ...(input.outerMetadata ?? {}),
21
+ },
22
+ },
23
+ }, { collection: this.options.collection });
24
+ return result.activityId;
25
+ }
26
+ async completePredictionRecord(activityId, updates) {
27
+ await this.client.completeRecord(activityId, updates, {
28
+ collection: this.options.collection,
29
+ });
30
+ }
31
+ async patchPredictionRecord(activityId, fields) {
32
+ if (this.client.patchRecord) {
33
+ await this.client.patchRecord(activityId, fields, {
34
+ collection: this.options.collection,
35
+ });
36
+ return;
37
+ }
38
+ await this.client.completeRecord(activityId, fields, {
39
+ collection: this.options.collection,
40
+ });
41
+ }
42
+ }
43
+ export async function warmupBucketStoreFromActivix(client, opts) {
44
+ if (!client.findRecords) {
45
+ return 0;
46
+ }
47
+ const rows = await client.findRecords({
48
+ 'outer.metadata.pipelineId': opts.pipelineId,
49
+ 'outer.metadata.optimizer': ACTIVIX_METADATA_OPTIMIZER_OPTIMIXER,
50
+ status: 'completed',
51
+ }, {
52
+ collection: opts.collection,
53
+ limit: opts.limit,
54
+ sort: { startTime: -1 },
55
+ });
56
+ let loaded = 0;
57
+ for (const row of rows) {
58
+ const outer = row.outer;
59
+ const input = outer?.input;
60
+ const output = outer?.output;
61
+ const actual = (output?.actual ?? output);
62
+ const completionTokens = actual?.completionTokens ?? actual?.completion_tokens;
63
+ const actionTypeId = input?.actionTypeId;
64
+ if (typeof actionTypeId !== 'string' || typeof completionTokens !== 'number' || !input) {
65
+ continue;
66
+ }
67
+ opts.onObservation(actionTypeId, typeof input.provider === 'string' ? input.provider : undefined, typeof input.model === 'string' ? input.model : undefined, completionTokens);
68
+ loaded += 1;
69
+ }
70
+ return loaded;
71
+ }
72
+ //# sourceMappingURL=activix-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activix-writer.js","sourceRoot":"","sources":["../../src/persistence/activix-writer.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,0CAA0C,EAC1C,oCAAoC,GACrC,MAAM,yBAAyB,CAAC;AAQjC,MAAM,OAAO,sBAAsB;IAEd;IACA;IAFnB,YACmB,MAA6B,EAC7B,OAA6B;QAD7B,WAAM,GAAN,MAAM,CAAuB;QAC7B,YAAO,GAAP,OAAO,CAAsB;IAC7C,CAAC;IAEJ,KAAK,CAAC,qBAAqB,CAAC,KAK3B;QACC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAC1C;YACE,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,KAAK,EAAE;gBACL,KAAK,EAAE,KAAK,CAAC,UAAU;gBACvB,MAAM,EAAE,KAAK,CAAC,WAAW;gBACzB,QAAQ,EAAE;oBACR,IAAI,EAAE,0CAA0C;oBAChD,SAAS,EAAE,oCAAoC;oBAC/C,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;oBACnC,gBAAgB,EAAE,IAAI,CAAC,OAAO,CAAC,gBAAgB;oBAC/C,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,EAAE,CAAC;iBAC/B;aACF;SACF,EACD,EAAE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CACxC,CAAC;QACF,OAAO,MAAM,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,wBAAwB,CAC5B,UAAkB,EAClB,OAAuC;QAEvC,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE;YACpD,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;SACpC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,qBAAqB,CACzB,UAAkB,EAClB,MAAsC;QAEtC,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAC5B,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE;gBAChD,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;aACpC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE;YACnD,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;SACpC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,MAA6B,EAC7B,IAKC;IAED,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CACnC;QACE,2BAA2B,EAAE,IAAI,CAAC,UAAU;QAC5C,0BAA0B,EAAE,oCAAoC;QAChE,MAAM,EAAE,WAAW;KACpB,EACD;QACE,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE;KACxB,CACF,CAAC;IAEF,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,EAAE,KAA4C,CAAC;QAClE,MAAM,MAAM,GAAG,KAAK,EAAE,MAA6C,CAAC;QACpE,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,IAAI,MAAM,CAAwC,CAAC;QACjF,MAAM,gBAAgB,GAAG,MAAM,EAAE,gBAAgB,IAAI,MAAM,EAAE,iBAAiB,CAAC;QAC/E,MAAM,YAAY,GAAG,KAAK,EAAE,YAAY,CAAC;QACzC,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;YACvF,SAAS;QACX,CAAC;QACD,IAAI,CAAC,aAAa,CAChB,YAAY,EACZ,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAC/D,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EACzD,gBAAgB,CACjB,CAAC;QACF,MAAM,IAAI,CAAC,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ActivixActivityClient } from '@x12i/activix-contracts';
2
+ import type { AiMaxTokensActualUsage, AiMaxTokensPredictionInput, AiMaxTokensPredictionResult, OptimixerAcceptableRisk, OptimixerPipelineConfig } from '../contracts/optimixer-types.js';
3
+ import { ActivixOptimixerWriter } from '../persistence/activix-writer.js';
4
+ import { type BucketStore } from '../state/bucket-store.js';
5
+ export declare function predictAiMaxTokensV1(input: AiMaxTokensPredictionInput, bucketStore: BucketStore, config?: OptimixerPipelineConfig): Omit<AiMaxTokensPredictionResult, 'requestId'>;
6
+ export declare function recordAiMaxTokensPrediction(writer: ActivixOptimixerWriter, input: AiMaxTokensPredictionInput, prediction: Omit<AiMaxTokensPredictionResult, 'requestId'>): Promise<AiMaxTokensPredictionResult>;
7
+ export declare function completeAiMaxTokensPredictionV1(client: ActivixActivityClient, writer: ActivixOptimixerWriter, bucketStore: BucketStore, input: {
8
+ requestId: string;
9
+ actual: AiMaxTokensActualUsage;
10
+ collection?: string;
11
+ acceptableRisk?: OptimixerAcceptableRisk;
12
+ }): Promise<{
13
+ learning: {
14
+ bucketKey: string;
15
+ observedCompletionTokens: number;
16
+ };
17
+ }>;
18
+ //# sourceMappingURL=ai-max-tokens-v1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-max-tokens-v1.d.ts","sourceRoot":"","sources":["../../src/pipelines/ai-max-tokens-v1.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAErE,OAAO,KAAK,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,uBAAuB,EACvB,uBAAuB,EACxB,MAAM,iCAAiC,CAAC;AAKzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAO5E,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,0BAA0B,EACjC,WAAW,EAAE,WAAW,EACxB,MAAM,CAAC,EAAE,uBAAuB,GAC/B,IAAI,CAAC,2BAA2B,EAAE,WAAW,CAAC,CAuChD;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,sBAAsB,EAC9B,KAAK,EAAE,0BAA0B,EACjC,UAAU,EAAE,IAAI,CAAC,2BAA2B,EAAE,WAAW,CAAC,GACzD,OAAO,CAAC,2BAA2B,CAAC,CAgBtC;AAED,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,sBAAsB,EAC9B,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE;IACL,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,uBAAuB,CAAC;CAC1C,GACA,OAAO,CAAC;IAAE,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,wBAAwB,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC,CA4ChF"}
@@ -0,0 +1,96 @@
1
+ import { normalizeToActivixCostShape } from '@x12i/activix-contracts';
2
+ import { AI_MAX_TOKENS_V1_ALGORITHM_VERSION, AI_MAX_TOKENS_V1_PIPELINE_ID, } from '../contracts/optimixer-types.js';
3
+ import { buildBucketKey } from '../state/bucket-store.js';
4
+ import { riskToPercentile } from '../state/quantile-stats.js';
5
+ const DEFAULT_MAX_TOKENS = 4096;
6
+ const MIN_MAX_TOKENS = 64;
7
+ const HEADROOM_RATIO = 1.15;
8
+ export function predictAiMaxTokensV1(input, bucketStore, config) {
9
+ const bucketKey = buildBucketKey({
10
+ actionTypeId: input.actionTypeId,
11
+ provider: input.provider,
12
+ model: input.model,
13
+ });
14
+ const stats = bucketStore.statsFor(bucketKey);
15
+ const defaultMax = config?.defaultMaxTokens ?? DEFAULT_MAX_TOKENS;
16
+ if (!stats || stats.count === 0) {
17
+ const baseline = Math.max(MIN_MAX_TOKENS, Math.ceil((input.inputSize + input.contextSize) * 0.25) + 256);
18
+ return {
19
+ pipelineId: AI_MAX_TOKENS_V1_PIPELINE_ID,
20
+ algorithmVersion: AI_MAX_TOKENS_V1_ALGORITHM_VERSION,
21
+ recommendedMaxTokens: Math.min(defaultMax, baseline),
22
+ confidence: 'cold-start',
23
+ bucketKey,
24
+ riskLevel: input.acceptableRisk,
25
+ };
26
+ }
27
+ const percentile = riskToPercentile(input.acceptableRisk);
28
+ const observed = stats.percentile(percentile) ?? stats.max() ?? defaultMax;
29
+ const recommended = Math.max(MIN_MAX_TOKENS, Math.ceil(observed * HEADROOM_RATIO));
30
+ return {
31
+ pipelineId: AI_MAX_TOKENS_V1_PIPELINE_ID,
32
+ algorithmVersion: AI_MAX_TOKENS_V1_ALGORITHM_VERSION,
33
+ recommendedMaxTokens: Math.min(defaultMax, recommended),
34
+ confidence: 'warm',
35
+ bucketKey,
36
+ riskLevel: input.acceptableRisk,
37
+ };
38
+ }
39
+ export async function recordAiMaxTokensPrediction(writer, input, prediction) {
40
+ const requestId = await writer.startPredictionRecord({
41
+ runContext: input.runContext,
42
+ outerInput: input,
43
+ outerOutput: {
44
+ recommendedMaxTokens: prediction.recommendedMaxTokens,
45
+ confidence: prediction.confidence,
46
+ bucketKey: prediction.bucketKey,
47
+ riskLevel: prediction.riskLevel,
48
+ },
49
+ outerMetadata: {
50
+ actionTypeId: input.actionTypeId,
51
+ },
52
+ });
53
+ return { ...prediction, requestId };
54
+ }
55
+ export async function completeAiMaxTokensPredictionV1(client, writer, bucketStore, input) {
56
+ const existing = await client.getRecord(input.requestId, {
57
+ collection: input.collection,
58
+ });
59
+ const outerInput = (existing?.outer?.input ?? {});
60
+ const actionTypeId = typeof outerInput.actionTypeId === 'string' ? outerInput.actionTypeId : 'unknown';
61
+ const bucketKey = buildBucketKey({
62
+ actionTypeId,
63
+ provider: typeof outerInput.provider === 'string' ? outerInput.provider : undefined,
64
+ model: typeof outerInput.model === 'string' ? outerInput.model : undefined,
65
+ });
66
+ bucketStore.observe(bucketKey, input.actual.completionTokens);
67
+ const cost = normalizeToActivixCostShape({
68
+ prompt_tokens: input.actual.promptTokens,
69
+ completion_tokens: input.actual.completionTokens,
70
+ total_tokens: input.actual.totalTokens,
71
+ provider: outerInput.provider,
72
+ model: outerInput.model,
73
+ });
74
+ await writer.completePredictionRecord(input.requestId, {
75
+ outer: {
76
+ input: existing?.outer?.input ?? outerInput,
77
+ output: {
78
+ ...existing?.outer?.output,
79
+ actual: input.actual,
80
+ learning: {
81
+ bucketKey,
82
+ observedCompletionTokens: input.actual.completionTokens,
83
+ },
84
+ },
85
+ metadata: existing?.outer?.metadata ?? {},
86
+ ...(cost ? { cost } : {}),
87
+ },
88
+ });
89
+ return {
90
+ learning: {
91
+ bucketKey,
92
+ observedCompletionTokens: input.actual.completionTokens,
93
+ },
94
+ };
95
+ }
96
+ //# sourceMappingURL=ai-max-tokens-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-max-tokens-v1.js","sourceRoot":"","sources":["../../src/pipelines/ai-max-tokens-v1.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { QuantileStats } from './quantile-stats.js';
2
+ export type BucketKeyParts = {
3
+ actionTypeId: string;
4
+ provider?: string;
5
+ model?: string;
6
+ };
7
+ export declare function buildBucketKey(parts: BucketKeyParts): string;
8
+ export declare class BucketStore {
9
+ private readonly buckets;
10
+ getOrCreate(key: string): QuantileStats;
11
+ observe(key: string, completionTokens: number): void;
12
+ statsFor(key: string): QuantileStats | undefined;
13
+ }
14
+ //# sourceMappingURL=bucket-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bucket-store.d.ts","sourceRoot":"","sources":["../../src/state/bucket-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAI5D;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAE5D,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa;IASvC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAIpD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;CAGjD"}