@posthog/wizard 1.33.0 → 1.35.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 (104) hide show
  1. package/dist/bin.js +9 -0
  2. package/dist/bin.js.map +1 -1
  3. package/dist/src/javascript-node/javascript-node-wizard-agent.d.ts +4 -0
  4. package/dist/src/javascript-node/javascript-node-wizard-agent.js +61 -0
  5. package/dist/src/javascript-node/javascript-node-wizard-agent.js.map +1 -0
  6. package/dist/src/javascript-web/javascript-web-wizard-agent.d.ts +3 -0
  7. package/dist/src/javascript-web/javascript-web-wizard-agent.js +150 -0
  8. package/dist/src/javascript-web/javascript-web-wizard-agent.js.map +1 -0
  9. package/dist/src/javascript-web/utils.d.ts +23 -0
  10. package/dist/src/javascript-web/utils.js +99 -0
  11. package/dist/src/javascript-web/utils.js.map +1 -0
  12. package/dist/src/lib/__tests__/agent-interface.test.js +1 -0
  13. package/dist/src/lib/__tests__/agent-interface.test.js.map +1 -1
  14. package/dist/src/lib/agent-interface.d.ts +5 -0
  15. package/dist/src/lib/agent-interface.js +19 -2
  16. package/dist/src/lib/agent-interface.js.map +1 -1
  17. package/dist/src/lib/agent-runner.js +8 -4
  18. package/dist/src/lib/agent-runner.js.map +1 -1
  19. package/dist/src/lib/api.js +3 -0
  20. package/dist/src/lib/api.js.map +1 -1
  21. package/dist/src/lib/constants.d.ts +6 -1
  22. package/dist/src/lib/constants.js +15 -1
  23. package/dist/src/lib/constants.js.map +1 -1
  24. package/dist/src/lib/middleware/benchmark.d.ts +54 -0
  25. package/dist/src/lib/middleware/benchmark.js +49 -0
  26. package/dist/src/lib/middleware/benchmark.js.map +1 -0
  27. package/dist/src/lib/middleware/benchmarks/cache-tracker.d.ts +44 -0
  28. package/dist/src/lib/middleware/benchmarks/cache-tracker.js +81 -0
  29. package/dist/src/lib/middleware/benchmarks/cache-tracker.js.map +1 -0
  30. package/dist/src/lib/middleware/benchmarks/compaction-tracker.d.ts +29 -0
  31. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js +60 -0
  32. package/dist/src/lib/middleware/benchmarks/compaction-tracker.js.map +1 -0
  33. package/dist/src/lib/middleware/benchmarks/context-size-tracker.d.ts +26 -0
  34. package/dist/src/lib/middleware/benchmarks/context-size-tracker.js +56 -0
  35. package/dist/src/lib/middleware/benchmarks/context-size-tracker.js.map +1 -0
  36. package/dist/src/lib/middleware/benchmarks/cost-tracker.d.ts +16 -0
  37. package/dist/src/lib/middleware/benchmarks/cost-tracker.js +76 -0
  38. package/dist/src/lib/middleware/benchmarks/cost-tracker.js.map +1 -0
  39. package/dist/src/lib/middleware/benchmarks/duration-tracker.d.ts +20 -0
  40. package/dist/src/lib/middleware/benchmarks/duration-tracker.js +40 -0
  41. package/dist/src/lib/middleware/benchmarks/duration-tracker.js.map +1 -0
  42. package/dist/src/lib/middleware/benchmarks/index.d.ts +9 -0
  43. package/dist/src/lib/middleware/benchmarks/index.js +60 -0
  44. package/dist/src/lib/middleware/benchmarks/index.js.map +1 -0
  45. package/dist/src/lib/middleware/benchmarks/json-writer.d.ts +15 -0
  46. package/dist/src/lib/middleware/benchmarks/json-writer.js +145 -0
  47. package/dist/src/lib/middleware/benchmarks/json-writer.js.map +1 -0
  48. package/dist/src/lib/middleware/benchmarks/summary.d.ts +9 -0
  49. package/dist/src/lib/middleware/benchmarks/summary.js +106 -0
  50. package/dist/src/lib/middleware/benchmarks/summary.js.map +1 -0
  51. package/dist/src/lib/middleware/benchmarks/token-tracker.d.ts +40 -0
  52. package/dist/src/lib/middleware/benchmarks/token-tracker.js +77 -0
  53. package/dist/src/lib/middleware/benchmarks/token-tracker.js.map +1 -0
  54. package/dist/src/lib/middleware/benchmarks/turn-counter.d.ts +34 -0
  55. package/dist/src/lib/middleware/benchmarks/turn-counter.js +59 -0
  56. package/dist/src/lib/middleware/benchmarks/turn-counter.js.map +1 -0
  57. package/dist/src/lib/middleware/config.d.ts +24 -0
  58. package/dist/src/lib/middleware/config.js +78 -0
  59. package/dist/src/lib/middleware/config.js.map +1 -0
  60. package/dist/src/lib/middleware/index.d.ts +11 -0
  61. package/dist/src/lib/middleware/index.js +18 -0
  62. package/dist/src/lib/middleware/index.js.map +1 -0
  63. package/dist/src/lib/middleware/phase-detector.d.ts +7 -0
  64. package/dist/src/lib/middleware/phase-detector.js +64 -0
  65. package/dist/src/lib/middleware/phase-detector.js.map +1 -0
  66. package/dist/src/lib/middleware/pipeline.d.ts +29 -0
  67. package/dist/src/lib/middleware/pipeline.js +82 -0
  68. package/dist/src/lib/middleware/pipeline.js.map +1 -0
  69. package/dist/src/lib/middleware/types.d.ts +40 -0
  70. package/dist/src/lib/middleware/types.js +9 -0
  71. package/dist/src/lib/middleware/types.js.map +1 -0
  72. package/dist/src/lib/package-manager-detection.d.ts +1 -0
  73. package/dist/src/lib/package-manager-detection.js +17 -0
  74. package/dist/src/lib/package-manager-detection.js.map +1 -1
  75. package/dist/src/lib/registry.js +8 -0
  76. package/dist/src/lib/registry.js.map +1 -1
  77. package/dist/src/python/python-wizard-agent.js +1 -78
  78. package/dist/src/python/python-wizard-agent.js.map +1 -1
  79. package/dist/src/rails/rails-wizard-agent.d.ts +8 -0
  80. package/dist/src/rails/rails-wizard-agent.js +90 -0
  81. package/dist/src/rails/rails-wizard-agent.js.map +1 -0
  82. package/dist/src/rails/utils.d.ts +37 -0
  83. package/dist/src/rails/utils.js +187 -0
  84. package/dist/src/rails/utils.js.map +1 -0
  85. package/dist/src/ruby/ruby-wizard-agent.d.ts +7 -0
  86. package/dist/src/ruby/ruby-wizard-agent.js +113 -0
  87. package/dist/src/ruby/ruby-wizard-agent.js.map +1 -0
  88. package/dist/src/ruby/utils.d.ts +25 -0
  89. package/dist/src/ruby/utils.js +158 -0
  90. package/dist/src/ruby/utils.js.map +1 -0
  91. package/dist/src/run.d.ts +2 -0
  92. package/dist/src/run.js +8 -0
  93. package/dist/src/run.js.map +1 -1
  94. package/dist/src/utils/clack-utils.d.ts +1 -1
  95. package/dist/src/utils/clack-utils.js +26 -7
  96. package/dist/src/utils/clack-utils.js.map +1 -1
  97. package/dist/src/utils/debug.d.ts +11 -3
  98. package/dist/src/utils/debug.js +25 -6
  99. package/dist/src/utils/debug.js.map +1 -1
  100. package/dist/src/utils/oauth.js +1 -0
  101. package/dist/src/utils/oauth.js.map +1 -1
  102. package/dist/src/utils/types.d.ts +11 -0
  103. package/dist/src/utils/types.js.map +1 -1
  104. package/package.json +2 -2
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ /**
3
+ * Plugin registry and factory.
4
+ *
5
+ * Maps plugin names to constructors and creates the ordered plugin list
6
+ * from a BenchmarkConfig.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createPluginsFromConfig = createPluginsFromConfig;
10
+ const turn_counter_1 = require("./turn-counter");
11
+ const token_tracker_1 = require("./token-tracker");
12
+ const cache_tracker_1 = require("./cache-tracker");
13
+ const compaction_tracker_1 = require("./compaction-tracker");
14
+ const context_size_tracker_1 = require("./context-size-tracker");
15
+ const cost_tracker_1 = require("./cost-tracker");
16
+ const duration_tracker_1 = require("./duration-tracker");
17
+ const summary_1 = require("./summary");
18
+ const json_writer_1 = require("./json-writer");
19
+ const PLUGIN_REGISTRY = {
20
+ turns: () => new turn_counter_1.TurnCounterPlugin(),
21
+ tokens: () => new token_tracker_1.TokenTrackerPlugin(),
22
+ cache: () => new cache_tracker_1.CacheTrackerPlugin(),
23
+ compactions: () => new compaction_tracker_1.CompactionTrackerPlugin(),
24
+ contextSize: () => new context_size_tracker_1.ContextSizeTrackerPlugin(),
25
+ cost: () => new cost_tracker_1.CostTrackerPlugin(),
26
+ duration: () => new duration_tracker_1.DurationTrackerPlugin(),
27
+ summary: (opts) => new summary_1.SummaryPlugin(opts.spinner),
28
+ jsonWriter: (opts) => new json_writer_1.JsonWriterPlugin(opts.outputPath),
29
+ };
30
+ /**
31
+ * Execution order — data producers before consumers:
32
+ * turns (dedup) -> tokens -> cache -> compactions -> contextSize -> cost -> duration -> summary -> jsonWriter
33
+ */
34
+ const PLUGIN_ORDER = [
35
+ 'turns',
36
+ 'tokens',
37
+ 'cache',
38
+ 'compactions',
39
+ 'contextSize',
40
+ 'cost',
41
+ 'duration',
42
+ 'summary',
43
+ 'jsonWriter',
44
+ ];
45
+ function createPluginsFromConfig(config, opts) {
46
+ const resolvedOpts = {
47
+ ...opts,
48
+ outputPath: opts.outputPath ?? config.output.benchmarkPath,
49
+ };
50
+ // If suppressWizardLogs is set, disable the summary plugin
51
+ const effectivePlugins = { ...config.plugins };
52
+ if (config.output.suppressWizardLogs) {
53
+ effectivePlugins.summary = false;
54
+ }
55
+ return PLUGIN_ORDER.filter((name) => effectivePlugins[name] !== false)
56
+ .map((name) => PLUGIN_REGISTRY[name])
57
+ .filter(Boolean)
58
+ .map((factory) => factory(resolvedOpts));
59
+ }
60
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/lib/middleware/benchmarks/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;AA4CH,0DAmBC;AA3DD,iDAAmD;AACnD,mDAAqD;AACrD,mDAAqD;AACrD,6DAA+D;AAC/D,iEAAkE;AAClE,iDAAmD;AACnD,yDAA2D;AAC3D,uCAA0C;AAC1C,+CAAiD;AAIjD,MAAM,eAAe,GAAkC;IACrD,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,gCAAiB,EAAE;IACpC,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,kCAAkB,EAAE;IACtC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,kCAAkB,EAAE;IACrC,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,4CAAuB,EAAE;IAChD,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI,+CAAwB,EAAE;IACjD,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,gCAAiB,EAAE;IACnC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,wCAAqB,EAAE;IAC3C,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,uBAAa,CAAC,IAAI,CAAC,OAAQ,CAAC;IACnD,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,8BAAgB,CAAC,IAAI,CAAC,UAAW,CAAC;CAC7D,CAAC;AAEF;;;GAGG;AACH,MAAM,YAAY,GAAG;IACnB,OAAO;IACP,QAAQ;IACR,OAAO;IACP,aAAa;IACb,aAAa;IACb,MAAM;IACN,UAAU;IACV,SAAS;IACT,YAAY;CACb,CAAC;AAEF,SAAgB,uBAAuB,CACrC,MAAuB,EACvB,IAA8B;IAE9B,MAAM,YAAY,GAA6B;QAC7C,GAAG,IAAI;QACP,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,MAAM,CAAC,aAAa;KAC3D,CAAC;IAEF,2DAA2D;IAC3D,MAAM,gBAAgB,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IAC/C,IAAI,MAAM,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACrC,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC;IACnC,CAAC;IAED,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC;SACnE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;SACpC,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;AAC7C,CAAC","sourcesContent":["/**\n * Plugin registry and factory.\n *\n * Maps plugin names to constructors and creates the ordered plugin list\n * from a BenchmarkConfig.\n */\n\nimport type { Middleware, MiddlewareFactoryOptions } from '../types';\nimport type { BenchmarkConfig } from '../config';\nimport { TurnCounterPlugin } from './turn-counter';\nimport { TokenTrackerPlugin } from './token-tracker';\nimport { CacheTrackerPlugin } from './cache-tracker';\nimport { CompactionTrackerPlugin } from './compaction-tracker';\nimport { ContextSizeTrackerPlugin } from './context-size-tracker';\nimport { CostTrackerPlugin } from './cost-tracker';\nimport { DurationTrackerPlugin } from './duration-tracker';\nimport { SummaryPlugin } from './summary';\nimport { JsonWriterPlugin } from './json-writer';\n\ntype PluginFactory = (opts: MiddlewareFactoryOptions) => Middleware;\n\nconst PLUGIN_REGISTRY: Record<string, PluginFactory> = {\n turns: () => new TurnCounterPlugin(),\n tokens: () => new TokenTrackerPlugin(),\n cache: () => new CacheTrackerPlugin(),\n compactions: () => new CompactionTrackerPlugin(),\n contextSize: () => new ContextSizeTrackerPlugin(),\n cost: () => new CostTrackerPlugin(),\n duration: () => new DurationTrackerPlugin(),\n summary: (opts) => new SummaryPlugin(opts.spinner!),\n jsonWriter: (opts) => new JsonWriterPlugin(opts.outputPath!),\n};\n\n/**\n * Execution order — data producers before consumers:\n * turns (dedup) -> tokens -> cache -> compactions -> contextSize -> cost -> duration -> summary -> jsonWriter\n */\nconst PLUGIN_ORDER = [\n 'turns',\n 'tokens',\n 'cache',\n 'compactions',\n 'contextSize',\n 'cost',\n 'duration',\n 'summary',\n 'jsonWriter',\n];\n\nexport function createPluginsFromConfig(\n config: BenchmarkConfig,\n opts: MiddlewareFactoryOptions,\n): Middleware[] {\n const resolvedOpts: MiddlewareFactoryOptions = {\n ...opts,\n outputPath: opts.outputPath ?? config.output.benchmarkPath,\n };\n\n // If suppressWizardLogs is set, disable the summary plugin\n const effectivePlugins = { ...config.plugins };\n if (config.output.suppressWizardLogs) {\n effectivePlugins.summary = false;\n }\n\n return PLUGIN_ORDER.filter((name) => effectivePlugins[name] !== false)\n .map((name) => PLUGIN_REGISTRY[name])\n .filter(Boolean)\n .map((factory) => factory(resolvedOpts));\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * JSON file output plugin.
3
+ *
4
+ * Assembles the BenchmarkData structure from all upstream plugin data
5
+ * and writes it to a JSON file. Returns the BenchmarkData for backward compat.
6
+ */
7
+ import type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';
8
+ import type { BenchmarkData } from '../benchmark';
9
+ export declare class JsonWriterPlugin implements Middleware {
10
+ readonly name = "jsonWriter";
11
+ private outputPath;
12
+ constructor(outputPath: string);
13
+ onFinalize(resultMessage: any, totalDurationMs: number, ctx: MiddlewareContext, _store: MiddlewareStore): BenchmarkData;
14
+ private writeBenchmarkData;
15
+ }
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ /**
3
+ * JSON file output plugin.
4
+ *
5
+ * Assembles the BenchmarkData structure from all upstream plugin data
6
+ * and writes it to a JSON file. Returns the BenchmarkData for backward compat.
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.JsonWriterPlugin = void 0;
13
+ const fs_1 = __importDefault(require("fs"));
14
+ const clack_1 = __importDefault(require("../../../utils/clack"));
15
+ const chalk_1 = __importDefault(require("chalk"));
16
+ const debug_1 = require("../../../utils/debug");
17
+ const agent_interface_1 = require("../../agent-interface");
18
+ /**
19
+ * Sum token usage across all models from the SDK's modelUsage field.
20
+ */
21
+ function sumModelUsage(modelUsage) {
22
+ let input_tokens = 0;
23
+ let output_tokens = 0;
24
+ let cache_creation_input_tokens = 0;
25
+ let cache_read_input_tokens = 0;
26
+ for (const model of Object.values(modelUsage)) {
27
+ input_tokens += model.inputTokens ?? 0;
28
+ output_tokens += model.outputTokens ?? 0;
29
+ cache_creation_input_tokens += model.cacheCreationInputTokens ?? 0;
30
+ cache_read_input_tokens += model.cacheReadInputTokens ?? 0;
31
+ }
32
+ return {
33
+ input_tokens,
34
+ output_tokens,
35
+ cache_creation_input_tokens,
36
+ cache_read_input_tokens,
37
+ };
38
+ }
39
+ class JsonWriterPlugin {
40
+ name = 'jsonWriter';
41
+ outputPath;
42
+ constructor(outputPath) {
43
+ this.outputPath = outputPath;
44
+ }
45
+ onFinalize(resultMessage, totalDurationMs, ctx, _store) {
46
+ const tokens = ctx.get('tokens');
47
+ const cache = ctx.get('cache');
48
+ const turns = ctx.get('turns');
49
+ const cost = ctx.get('cost');
50
+ const duration = ctx.get('duration');
51
+ const compactions = ctx.get('compactions');
52
+ const contextSize = ctx.get('contextSize');
53
+ const modelUsage = resultMessage?.modelUsage ?? {};
54
+ const aggregateUsage = sumModelUsage(modelUsage);
55
+ const phaseCount = duration?.phaseSnapshots.length ?? 0;
56
+ const steps = [];
57
+ for (let i = 0; i < phaseCount; i++) {
58
+ const dur = duration.phaseSnapshots[i];
59
+ const tokenSnap = tokens?.phaseSnapshots[i];
60
+ const cacheSnap = cache?.phaseSnapshots[i];
61
+ const turnSnap = turns?.phaseSnapshots[i];
62
+ const costSnap = cost?.phaseCosts[i];
63
+ const compSnap = compactions?.phaseSnapshots[i];
64
+ const ctxSnap = contextSize?.phaseSnapshots[i];
65
+ const step = {
66
+ name: dur.phase,
67
+ usage: {
68
+ input_tokens: tokenSnap?.inputTokens ?? 0,
69
+ output_tokens: tokenSnap?.outputTokens ?? 0,
70
+ cache_creation_input_tokens: cacheSnap?.cacheCreationTokens ?? 0,
71
+ cache_read_input_tokens: cacheSnap?.cacheReadTokens ?? 0,
72
+ ...((cacheSnap?.cacheCreation5m ?? 0) +
73
+ (cacheSnap?.cacheCreation1h ?? 0) >
74
+ 0 && {
75
+ cache_creation: {
76
+ ephemeral_5m_input_tokens: cacheSnap?.cacheCreation5m ?? 0,
77
+ ephemeral_1h_input_tokens: cacheSnap?.cacheCreation1h ?? 0,
78
+ },
79
+ }),
80
+ },
81
+ modelUsage: {},
82
+ totalCostUsd: costSnap?.cost ?? 0,
83
+ durationMs: dur.durationMs,
84
+ durationApiMs: 0,
85
+ numTurns: turnSnap?.turns ?? 0,
86
+ ...(ctxSnap?.contextTokensIn !== undefined && {
87
+ contextTokensIn: ctxSnap.contextTokensIn,
88
+ }),
89
+ ...(ctxSnap?.contextTokensOut !== undefined && {
90
+ contextTokensOut: ctxSnap.contextTokensOut,
91
+ }),
92
+ ...(compSnap && compSnap.compactions > 0
93
+ ? {
94
+ compactions: compSnap.compactions,
95
+ compactionPreTokens: compSnap.preTokens,
96
+ }
97
+ : {}),
98
+ };
99
+ steps.push(step);
100
+ }
101
+ const totalTurns = turns?.totalTurns ?? 0;
102
+ const totalCost = cost?.totalCost ?? 0;
103
+ const totalCompactions = compactions?.totalCompactions ?? 0;
104
+ const fromModelUsage = aggregateUsage.input_tokens +
105
+ aggregateUsage.cache_read_input_tokens +
106
+ aggregateUsage.cache_creation_input_tokens;
107
+ const inputTokens = fromModelUsage > 0
108
+ ? fromModelUsage
109
+ : (tokens?.totalInput ?? 0) +
110
+ (cache?.totalRead ?? 0) +
111
+ (cache?.totalCreation ?? 0);
112
+ const outputTokens = aggregateUsage.output_tokens > 0
113
+ ? aggregateUsage.output_tokens
114
+ : tokens?.totalOutput ?? 0;
115
+ const benchmark = {
116
+ timestamp: new Date().toISOString(),
117
+ steps,
118
+ totals: {
119
+ totalCostUsd: totalCost,
120
+ durationMs: totalDurationMs,
121
+ inputTokens,
122
+ outputTokens,
123
+ numTurns: resultMessage?.num_turns ?? totalTurns,
124
+ totalCompactions,
125
+ totalCacheReadTokens: cache?.totalRead ?? 0,
126
+ totalCacheCreation5mTokens: cache?.totalCreation5m ?? 0,
127
+ totalCacheCreation1hTokens: cache?.totalCreation1h ?? 0,
128
+ },
129
+ };
130
+ this.writeBenchmarkData(benchmark);
131
+ return benchmark;
132
+ }
133
+ writeBenchmarkData(data) {
134
+ try {
135
+ fs_1.default.writeFileSync(this.outputPath, JSON.stringify(data, null, 2));
136
+ (0, debug_1.logToFile)(`Benchmark data written to ${this.outputPath}`);
137
+ clack_1.default.log.info(`${chalk_1.default.blue('●')} ${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} Results written to ${this.outputPath}`);
138
+ }
139
+ catch (error) {
140
+ (0, debug_1.logToFile)('Failed to write benchmark data:', error);
141
+ }
142
+ }
143
+ }
144
+ exports.JsonWriterPlugin = JsonWriterPlugin;
145
+ //# sourceMappingURL=json-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-writer.js","sourceRoot":"","sources":["../../../../../src/lib/middleware/benchmarks/json-writer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * JSON file output plugin.\n *\n * Assembles the BenchmarkData structure from all upstream plugin data\n * and writes it to a JSON file. Returns the BenchmarkData for backward compat.\n */\n\nimport fs from 'fs';\nimport clack from '../../../utils/clack';\nimport chalk from 'chalk';\nimport { logToFile } from '../../../utils/debug';\nimport { AgentSignals } from '../../agent-interface';\nimport type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';\nimport type { TokenData } from './token-tracker';\nimport type { CacheData } from './cache-tracker';\nimport type { TurnData } from './turn-counter';\nimport type { CostData } from './cost-tracker';\nimport type { DurationData } from './duration-tracker';\nimport type { CompactionData } from './compaction-tracker';\nimport type { ContextSizeData } from './context-size-tracker';\nimport type { BenchmarkData, StepUsage } from '../benchmark';\n\n/**\n * Sum token usage across all models from the SDK's modelUsage field.\n */\nfunction sumModelUsage(modelUsage: Record<string, any>): {\n input_tokens: number;\n output_tokens: number;\n cache_creation_input_tokens: number;\n cache_read_input_tokens: number;\n} {\n let input_tokens = 0;\n let output_tokens = 0;\n let cache_creation_input_tokens = 0;\n let cache_read_input_tokens = 0;\n\n for (const model of Object.values(modelUsage)) {\n input_tokens += model.inputTokens ?? 0;\n output_tokens += model.outputTokens ?? 0;\n cache_creation_input_tokens += model.cacheCreationInputTokens ?? 0;\n cache_read_input_tokens += model.cacheReadInputTokens ?? 0;\n }\n\n return {\n input_tokens,\n output_tokens,\n cache_creation_input_tokens,\n cache_read_input_tokens,\n };\n}\n\nexport class JsonWriterPlugin implements Middleware {\n readonly name = 'jsonWriter';\n\n private outputPath: string;\n\n constructor(outputPath: string) {\n this.outputPath = outputPath;\n }\n\n onFinalize(\n resultMessage: any,\n totalDurationMs: number,\n ctx: MiddlewareContext,\n _store: MiddlewareStore,\n ): BenchmarkData {\n const tokens = ctx.get<TokenData>('tokens');\n const cache = ctx.get<CacheData>('cache');\n const turns = ctx.get<TurnData>('turns');\n const cost = ctx.get<CostData>('cost');\n const duration = ctx.get<DurationData>('duration');\n const compactions = ctx.get<CompactionData>('compactions');\n const contextSize = ctx.get<ContextSizeData>('contextSize');\n\n const modelUsage = resultMessage?.modelUsage ?? {};\n const aggregateUsage = sumModelUsage(modelUsage);\n\n const phaseCount = duration?.phaseSnapshots.length ?? 0;\n const steps: StepUsage[] = [];\n\n for (let i = 0; i < phaseCount; i++) {\n const dur = duration!.phaseSnapshots[i];\n const tokenSnap = tokens?.phaseSnapshots[i];\n const cacheSnap = cache?.phaseSnapshots[i];\n const turnSnap = turns?.phaseSnapshots[i];\n const costSnap = cost?.phaseCosts[i];\n const compSnap = compactions?.phaseSnapshots[i];\n const ctxSnap = contextSize?.phaseSnapshots[i];\n\n const step: StepUsage = {\n name: dur.phase,\n usage: {\n input_tokens: tokenSnap?.inputTokens ?? 0,\n output_tokens: tokenSnap?.outputTokens ?? 0,\n cache_creation_input_tokens: cacheSnap?.cacheCreationTokens ?? 0,\n cache_read_input_tokens: cacheSnap?.cacheReadTokens ?? 0,\n ...((cacheSnap?.cacheCreation5m ?? 0) +\n (cacheSnap?.cacheCreation1h ?? 0) >\n 0 && {\n cache_creation: {\n ephemeral_5m_input_tokens: cacheSnap?.cacheCreation5m ?? 0,\n ephemeral_1h_input_tokens: cacheSnap?.cacheCreation1h ?? 0,\n },\n }),\n },\n modelUsage: {},\n totalCostUsd: costSnap?.cost ?? 0,\n durationMs: dur.durationMs,\n durationApiMs: 0,\n numTurns: turnSnap?.turns ?? 0,\n ...(ctxSnap?.contextTokensIn !== undefined && {\n contextTokensIn: ctxSnap.contextTokensIn,\n }),\n ...(ctxSnap?.contextTokensOut !== undefined && {\n contextTokensOut: ctxSnap.contextTokensOut,\n }),\n ...(compSnap && compSnap.compactions > 0\n ? {\n compactions: compSnap.compactions,\n compactionPreTokens: compSnap.preTokens,\n }\n : {}),\n };\n\n steps.push(step);\n }\n\n const totalTurns = turns?.totalTurns ?? 0;\n const totalCost = cost?.totalCost ?? 0;\n const totalCompactions = compactions?.totalCompactions ?? 0;\n const fromModelUsage =\n aggregateUsage.input_tokens +\n aggregateUsage.cache_read_input_tokens +\n aggregateUsage.cache_creation_input_tokens;\n const inputTokens =\n fromModelUsage > 0\n ? fromModelUsage\n : (tokens?.totalInput ?? 0) +\n (cache?.totalRead ?? 0) +\n (cache?.totalCreation ?? 0);\n const outputTokens =\n aggregateUsage.output_tokens > 0\n ? aggregateUsage.output_tokens\n : tokens?.totalOutput ?? 0;\n\n const benchmark: BenchmarkData = {\n timestamp: new Date().toISOString(),\n steps,\n totals: {\n totalCostUsd: totalCost,\n durationMs: totalDurationMs,\n inputTokens,\n outputTokens,\n numTurns: resultMessage?.num_turns ?? totalTurns,\n totalCompactions,\n totalCacheReadTokens: cache?.totalRead ?? 0,\n totalCacheCreation5mTokens: cache?.totalCreation5m ?? 0,\n totalCacheCreation1hTokens: cache?.totalCreation1h ?? 0,\n },\n };\n\n this.writeBenchmarkData(benchmark);\n return benchmark;\n }\n\n private writeBenchmarkData(data: BenchmarkData): void {\n try {\n fs.writeFileSync(this.outputPath, JSON.stringify(data, null, 2));\n logToFile(`Benchmark data written to ${this.outputPath}`);\n clack.log.info(\n `${chalk.blue('●')} ${chalk.cyan(\n AgentSignals.BENCHMARK,\n )} Results written to ${this.outputPath}`,\n );\n } catch (error) {\n logToFile('Failed to write benchmark data:', error);\n }\n }\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import clack from '../../../utils/clack';
2
+ import type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';
3
+ export declare class SummaryPlugin implements Middleware {
4
+ readonly name = "summary";
5
+ private spinner;
6
+ constructor(spinner: ReturnType<typeof clack.spinner>);
7
+ onPhaseTransition(fromPhase: string, toPhase: string, ctx: MiddlewareContext, _store: MiddlewareStore): void;
8
+ onFinalize(_resultMessage: any, totalDurationMs: number, ctx: MiddlewareContext, _store: MiddlewareStore): void;
9
+ }
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SummaryPlugin = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const clack_1 = __importDefault(require("../../../utils/clack"));
9
+ const agent_interface_1 = require("../../agent-interface");
10
+ function fmtDuration(ms) {
11
+ const s = Math.round(ms / 1000);
12
+ const m = Math.floor(s / 60);
13
+ return m > 0 ? `${m}m ${s % 60}s` : `${s}s`;
14
+ }
15
+ function fmtTok(n) {
16
+ if (n >= 1_000_000)
17
+ return `${(n / 1_000_000).toFixed(1)}M`;
18
+ if (n >= 1_000)
19
+ return `${(n / 1000).toFixed(1)}K`;
20
+ return n.toLocaleString();
21
+ }
22
+ function fmtCost(usd) {
23
+ if (usd > 0 && usd < 0.01)
24
+ return `$${usd.toFixed(4)}`;
25
+ return `$${usd.toFixed(2)}`;
26
+ }
27
+ function printPhase(s) {
28
+ const baseIn = Math.max(0, s.inputTokens - s.cacheRead - s.cacheCreation5m - s.cacheCreation1h);
29
+ return [
30
+ `${chalk_1.default.bold(s.phase)}: ${fmtDuration(s.durationMs)}, ${s.turns} turns, cost: ${fmtCost(s.cost)}`,
31
+ ` in: ${fmtTok(baseIn)}, out: ${fmtTok(s.outputTokens)}, cache_read: ${fmtTok(s.cacheRead)}, cache_5m: ${fmtTok(s.cacheCreation5m)}, cache_1h: ${fmtTok(s.cacheCreation1h)}`,
32
+ s.compactions > 0 ? ` ${s.compactions} compaction(s)` : null,
33
+ s.contextOut !== undefined ? ` ctx_out: ${fmtTok(s.contextOut)}` : null,
34
+ ]
35
+ .filter(Boolean)
36
+ .join('\n');
37
+ }
38
+ function getPhaseStats(i, ctx) {
39
+ const duration = ctx.get('duration');
40
+ const dur = duration?.phaseSnapshots[i];
41
+ if (!dur)
42
+ return null;
43
+ const tokens = ctx.get('tokens');
44
+ const turns = ctx.get('turns');
45
+ const cost = ctx.get('cost');
46
+ const compactions = ctx.get('compactions');
47
+ const contextSize = ctx.get('contextSize');
48
+ const cache = ctx.get('cache');
49
+ return {
50
+ phase: dur.phase,
51
+ durationMs: dur.durationMs,
52
+ turns: turns?.phaseSnapshots[i]?.turns ?? 0,
53
+ inputTokens: tokens?.phaseSnapshots[i]?.inputTokens ?? 0,
54
+ outputTokens: tokens?.phaseSnapshots[i]?.outputTokens ?? 0,
55
+ cacheRead: cache?.phaseSnapshots[i]?.cacheReadTokens ?? 0,
56
+ cacheCreation5m: cache?.phaseSnapshots[i]?.cacheCreation5m ?? 0,
57
+ cacheCreation1h: cache?.phaseSnapshots[i]?.cacheCreation1h ?? 0,
58
+ cost: cost?.phaseCosts[i]?.cost ?? 0,
59
+ compactions: compactions?.phaseSnapshots[i]?.compactions ?? 0,
60
+ contextOut: contextSize?.phaseSnapshots[i]?.contextTokensOut,
61
+ };
62
+ }
63
+ class SummaryPlugin {
64
+ name = 'summary';
65
+ spinner;
66
+ constructor(spinner) {
67
+ this.spinner = spinner;
68
+ }
69
+ onPhaseTransition(fromPhase, toPhase, ctx, _store) {
70
+ const duration = ctx.get('duration');
71
+ const idx = (duration?.phaseSnapshots.length ?? 1) - 1;
72
+ const stats = getPhaseStats(idx, ctx);
73
+ if (stats) {
74
+ this.spinner.stop(`${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} ${printPhase(stats)}`);
75
+ }
76
+ else {
77
+ this.spinner.stop(`${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} ${fromPhase}`);
78
+ }
79
+ clack_1.default.log.info(`${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} Starting phase: ${chalk_1.default.bold(toPhase)}`);
80
+ this.spinner.start(`Integrating PostHog (${toPhase})...`);
81
+ }
82
+ onFinalize(_resultMessage, totalDurationMs, ctx, _store) {
83
+ const duration = ctx.get('duration');
84
+ const cost = ctx.get('cost');
85
+ const tokens = ctx.get('tokens');
86
+ const cache = ctx.get('cache');
87
+ const phaseCount = duration?.phaseSnapshots.length ?? 0;
88
+ const totalCost = cost?.totalCost ?? 0;
89
+ clack_1.default.log.info('');
90
+ clack_1.default.log.info(`${chalk_1.default.green('◇')} ${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} ${phaseCount} phases in ${fmtDuration(totalDurationMs)}, cost: ${fmtCost(totalCost)}`);
91
+ clack_1.default.log.info(` total in: ${fmtTok(tokens?.totalInput ?? 0)}, out: ${fmtTok(tokens?.totalOutput ?? 0)}, cache_read: ${fmtTok(cache?.totalRead ?? 0)}, cache_5m: ${fmtTok(cache?.totalCreation5m ?? 0)}, cache_1h: ${fmtTok(cache?.totalCreation1h ?? 0)}`);
92
+ clack_1.default.log.info('');
93
+ clack_1.default.log.info(`${chalk_1.default.blue('●')} ${chalk_1.default.cyan(agent_interface_1.AgentSignals.BENCHMARK)} Summary by phase:`);
94
+ if (duration?.phaseSnapshots) {
95
+ for (let i = 0; i < duration.phaseSnapshots.length; i++) {
96
+ const stats = getPhaseStats(i, ctx);
97
+ if (stats) {
98
+ clack_1.default.log.info(printPhase(stats));
99
+ }
100
+ }
101
+ }
102
+ clack_1.default.log.info('');
103
+ }
104
+ }
105
+ exports.SummaryPlugin = SummaryPlugin;
106
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../../../src/lib/middleware/benchmarks/summary.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from 'chalk';\nimport clack from '../../../utils/clack';\nimport { AgentSignals } from '../../agent-interface';\nimport type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';\nimport type { TokenData } from './token-tracker';\nimport type { TurnData } from './turn-counter';\nimport type { CostData } from './cost-tracker';\nimport type { DurationData } from './duration-tracker';\nimport type { CompactionData } from './compaction-tracker';\nimport type { ContextSizeData } from './context-size-tracker';\nimport type { CacheData } from './cache-tracker';\n\nfunction fmtDuration(ms: number): string {\n const s = Math.round(ms / 1000);\n const m = Math.floor(s / 60);\n return m > 0 ? `${m}m ${s % 60}s` : `${s}s`;\n}\n\nfunction fmtTok(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1000).toFixed(1)}K`;\n return n.toLocaleString();\n}\n\nfunction fmtCost(usd: number): string {\n if (usd > 0 && usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n\ninterface PhaseStats {\n phase: string;\n durationMs: number;\n turns: number;\n inputTokens: number;\n outputTokens: number;\n cacheRead: number;\n cacheCreation5m: number;\n cacheCreation1h: number;\n cost: number;\n compactions: number;\n contextOut: number | undefined;\n}\n\nfunction printPhase(s: PhaseStats): string {\n const baseIn = Math.max(\n 0,\n s.inputTokens - s.cacheRead - s.cacheCreation5m - s.cacheCreation1h,\n );\n return [\n `${chalk.bold(s.phase)}: ${fmtDuration(s.durationMs)}, ${\n s.turns\n } turns, cost: ${fmtCost(s.cost)}`,\n ` in: ${fmtTok(baseIn)}, out: ${fmtTok(\n s.outputTokens,\n )}, cache_read: ${fmtTok(s.cacheRead)}, cache_5m: ${fmtTok(\n s.cacheCreation5m,\n )}, cache_1h: ${fmtTok(s.cacheCreation1h)}`,\n s.compactions > 0 ? ` ${s.compactions} compaction(s)` : null,\n s.contextOut !== undefined ? ` ctx_out: ${fmtTok(s.contextOut)}` : null,\n ]\n .filter(Boolean)\n .join('\\n');\n}\n\nfunction getPhaseStats(i: number, ctx: MiddlewareContext): PhaseStats | null {\n const duration = ctx.get<DurationData>('duration');\n const dur = duration?.phaseSnapshots[i];\n if (!dur) return null;\n\n const tokens = ctx.get<TokenData>('tokens');\n const turns = ctx.get<TurnData>('turns');\n const cost = ctx.get<CostData>('cost');\n const compactions = ctx.get<CompactionData>('compactions');\n const contextSize = ctx.get<ContextSizeData>('contextSize');\n const cache = ctx.get<CacheData>('cache');\n\n return {\n phase: dur.phase,\n durationMs: dur.durationMs,\n turns: turns?.phaseSnapshots[i]?.turns ?? 0,\n inputTokens: tokens?.phaseSnapshots[i]?.inputTokens ?? 0,\n outputTokens: tokens?.phaseSnapshots[i]?.outputTokens ?? 0,\n cacheRead: cache?.phaseSnapshots[i]?.cacheReadTokens ?? 0,\n cacheCreation5m: cache?.phaseSnapshots[i]?.cacheCreation5m ?? 0,\n cacheCreation1h: cache?.phaseSnapshots[i]?.cacheCreation1h ?? 0,\n cost: cost?.phaseCosts[i]?.cost ?? 0,\n compactions: compactions?.phaseSnapshots[i]?.compactions ?? 0,\n contextOut: contextSize?.phaseSnapshots[i]?.contextTokensOut,\n };\n}\n\nexport class SummaryPlugin implements Middleware {\n readonly name = 'summary';\n\n private spinner: ReturnType<typeof clack.spinner>;\n\n constructor(spinner: ReturnType<typeof clack.spinner>) {\n this.spinner = spinner;\n }\n\n onPhaseTransition(\n fromPhase: string,\n toPhase: string,\n ctx: MiddlewareContext,\n _store: MiddlewareStore,\n ): void {\n const duration = ctx.get<DurationData>('duration');\n const idx = (duration?.phaseSnapshots.length ?? 1) - 1;\n const stats = getPhaseStats(idx, ctx);\n\n if (stats) {\n this.spinner.stop(\n `${chalk.cyan(AgentSignals.BENCHMARK)} ${printPhase(stats)}`,\n );\n } else {\n this.spinner.stop(`${chalk.cyan(AgentSignals.BENCHMARK)} ${fromPhase}`);\n }\n\n clack.log.info(\n `${chalk.cyan(AgentSignals.BENCHMARK)} Starting phase: ${chalk.bold(\n toPhase,\n )}`,\n );\n this.spinner.start(`Integrating PostHog (${toPhase})...`);\n }\n\n onFinalize(\n _resultMessage: any,\n totalDurationMs: number,\n ctx: MiddlewareContext,\n _store: MiddlewareStore,\n ): void {\n const duration = ctx.get<DurationData>('duration');\n const cost = ctx.get<CostData>('cost');\n const tokens = ctx.get<TokenData>('tokens');\n const cache = ctx.get<CacheData>('cache');\n\n const phaseCount = duration?.phaseSnapshots.length ?? 0;\n const totalCost = cost?.totalCost ?? 0;\n\n clack.log.info('');\n clack.log.info(\n `${chalk.green('◇')} ${chalk.cyan(\n AgentSignals.BENCHMARK,\n )} ${phaseCount} phases in ${fmtDuration(\n totalDurationMs,\n )}, cost: ${fmtCost(totalCost)}`,\n );\n clack.log.info(\n ` total in: ${fmtTok(tokens?.totalInput ?? 0)}, out: ${fmtTok(\n tokens?.totalOutput ?? 0,\n )}, cache_read: ${fmtTok(cache?.totalRead ?? 0)}, cache_5m: ${fmtTok(\n cache?.totalCreation5m ?? 0,\n )}, cache_1h: ${fmtTok(cache?.totalCreation1h ?? 0)}`,\n );\n clack.log.info('');\n clack.log.info(\n `${chalk.blue('●')} ${chalk.cyan(\n AgentSignals.BENCHMARK,\n )} Summary by phase:`,\n );\n\n if (duration?.phaseSnapshots) {\n for (let i = 0; i < duration.phaseSnapshots.length; i++) {\n const stats = getPhaseStats(i, ctx);\n if (stats) {\n clack.log.info(printPhase(stats));\n }\n }\n }\n\n clack.log.info('');\n }\n}\n"]}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Token tracking plugin for input/output tokens.
3
+ *
4
+ * Accumulates per-turn token usage (input_tokens + cache_read_input_tokens
5
+ * + cache_creation_input_tokens = total input; output_tokens = output).
6
+ * Respects the dedup flag from TurnCounterPlugin. Cache breakdown (r/5m/1h)
7
+ * is tracked by CacheTrackerPlugin for reporting and pricing.
8
+ */
9
+ import type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';
10
+ export interface TokenData {
11
+ phaseInput: number;
12
+ phaseOutput: number;
13
+ totalInput: number;
14
+ totalOutput: number;
15
+ /** The raw usage object from the last non-duplicate assistant message */
16
+ lastUsage: any;
17
+ /** Per-phase token snapshots */
18
+ phaseSnapshots: Array<{
19
+ phase: string;
20
+ inputTokens: number;
21
+ outputTokens: number;
22
+ /** Number of turns in this phase that had usage (SDK may not report all) */
23
+ messagesWithUsage: number;
24
+ }>;
25
+ }
26
+ export declare class TokenTrackerPlugin implements Middleware {
27
+ readonly name = "tokens";
28
+ private phaseInput;
29
+ private phaseOutput;
30
+ private totalInput;
31
+ private totalOutput;
32
+ private lastUsage;
33
+ private phaseSnapshots;
34
+ private currentPhase;
35
+ private phaseMessagesWithUsage;
36
+ onMessage(message: any, ctx: MiddlewareContext, store: MiddlewareStore): void;
37
+ onPhaseTransition(fromPhase: string, toPhase: string, _ctx: MiddlewareContext, store: MiddlewareStore): void;
38
+ onFinalize(_resultMessage: any, _totalDurationMs: number, _ctx: MiddlewareContext, store: MiddlewareStore): void;
39
+ private getData;
40
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ /**
3
+ * Token tracking plugin for input/output tokens.
4
+ *
5
+ * Accumulates per-turn token usage (input_tokens + cache_read_input_tokens
6
+ * + cache_creation_input_tokens = total input; output_tokens = output).
7
+ * Respects the dedup flag from TurnCounterPlugin. Cache breakdown (r/5m/1h)
8
+ * is tracked by CacheTrackerPlugin for reporting and pricing.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.TokenTrackerPlugin = void 0;
12
+ class TokenTrackerPlugin {
13
+ name = 'tokens';
14
+ phaseInput = 0;
15
+ phaseOutput = 0;
16
+ totalInput = 0;
17
+ totalOutput = 0;
18
+ lastUsage = null;
19
+ phaseSnapshots = [];
20
+ currentPhase = 'setup';
21
+ phaseMessagesWithUsage = 0;
22
+ onMessage(message, ctx, store) {
23
+ if (message.type !== 'assistant')
24
+ return;
25
+ const turns = ctx.get('turns');
26
+ if (turns?.isDuplicate)
27
+ return;
28
+ const usage = message.message?.usage;
29
+ if (usage) {
30
+ const input = Number(usage.input_tokens ?? 0) +
31
+ Number(usage.cache_read_input_tokens ?? 0) +
32
+ Number(usage.cache_creation_input_tokens ?? 0);
33
+ const output = Number(usage.output_tokens ?? 0);
34
+ this.phaseInput += input;
35
+ this.phaseOutput += output;
36
+ this.totalInput += input;
37
+ this.totalOutput += output;
38
+ this.lastUsage = usage;
39
+ this.phaseMessagesWithUsage += 1;
40
+ }
41
+ store.set('tokens', this.getData());
42
+ }
43
+ onPhaseTransition(fromPhase, toPhase, _ctx, store) {
44
+ this.phaseSnapshots.push({
45
+ phase: fromPhase,
46
+ inputTokens: this.phaseInput,
47
+ outputTokens: this.phaseOutput,
48
+ messagesWithUsage: this.phaseMessagesWithUsage,
49
+ });
50
+ this.currentPhase = toPhase;
51
+ this.phaseInput = 0;
52
+ this.phaseOutput = 0;
53
+ this.phaseMessagesWithUsage = 0;
54
+ store.set('tokens', this.getData());
55
+ }
56
+ onFinalize(_resultMessage, _totalDurationMs, _ctx, store) {
57
+ this.phaseSnapshots.push({
58
+ phase: this.currentPhase,
59
+ inputTokens: this.phaseInput,
60
+ outputTokens: this.phaseOutput,
61
+ messagesWithUsage: this.phaseMessagesWithUsage,
62
+ });
63
+ store.set('tokens', this.getData());
64
+ }
65
+ getData() {
66
+ return {
67
+ phaseInput: this.phaseInput,
68
+ phaseOutput: this.phaseOutput,
69
+ totalInput: this.totalInput,
70
+ totalOutput: this.totalOutput,
71
+ lastUsage: this.lastUsage,
72
+ phaseSnapshots: [...this.phaseSnapshots],
73
+ };
74
+ }
75
+ }
76
+ exports.TokenTrackerPlugin = TokenTrackerPlugin;
77
+ //# sourceMappingURL=token-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../../../../src/lib/middleware/benchmarks/token-tracker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Token tracking plugin for input/output tokens.\n *\n * Accumulates per-turn token usage (input_tokens + cache_read_input_tokens\n * + cache_creation_input_tokens = total input; output_tokens = output).\n * Respects the dedup flag from TurnCounterPlugin. Cache breakdown (r/5m/1h)\n * is tracked by CacheTrackerPlugin for reporting and pricing.\n */\n\nimport type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';\nimport type { TurnData } from './turn-counter';\n\nexport interface TokenData {\n phaseInput: number;\n phaseOutput: number;\n totalInput: number;\n totalOutput: number;\n /** The raw usage object from the last non-duplicate assistant message */\n lastUsage: any;\n /** Per-phase token snapshots */\n phaseSnapshots: Array<{\n phase: string;\n inputTokens: number;\n outputTokens: number;\n /** Number of turns in this phase that had usage (SDK may not report all) */\n messagesWithUsage: number;\n }>;\n}\n\nexport class TokenTrackerPlugin implements Middleware {\n readonly name = 'tokens';\n\n private phaseInput = 0;\n private phaseOutput = 0;\n private totalInput = 0;\n private totalOutput = 0;\n private lastUsage: any = null;\n private phaseSnapshots: Array<{\n phase: string;\n inputTokens: number;\n outputTokens: number;\n messagesWithUsage: number;\n }> = [];\n private currentPhase = 'setup';\n private phaseMessagesWithUsage = 0;\n\n onMessage(\n message: any,\n ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n if (message.type !== 'assistant') return;\n\n const turns = ctx.get<TurnData>('turns');\n if (turns?.isDuplicate) return;\n\n const usage = message.message?.usage;\n if (usage) {\n const input =\n Number(usage.input_tokens ?? 0) +\n Number(usage.cache_read_input_tokens ?? 0) +\n Number(usage.cache_creation_input_tokens ?? 0);\n const output = Number(usage.output_tokens ?? 0);\n this.phaseInput += input;\n this.phaseOutput += output;\n this.totalInput += input;\n this.totalOutput += output;\n this.lastUsage = usage;\n this.phaseMessagesWithUsage += 1;\n }\n\n store.set('tokens', this.getData());\n }\n\n onPhaseTransition(\n fromPhase: string,\n toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: fromPhase,\n inputTokens: this.phaseInput,\n outputTokens: this.phaseOutput,\n messagesWithUsage: this.phaseMessagesWithUsage,\n });\n this.currentPhase = toPhase;\n this.phaseInput = 0;\n this.phaseOutput = 0;\n this.phaseMessagesWithUsage = 0;\n store.set('tokens', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: this.currentPhase,\n inputTokens: this.phaseInput,\n outputTokens: this.phaseOutput,\n messagesWithUsage: this.phaseMessagesWithUsage,\n });\n store.set('tokens', this.getData());\n }\n\n private getData(): TokenData {\n return {\n phaseInput: this.phaseInput,\n phaseOutput: this.phaseOutput,\n totalInput: this.totalInput,\n totalOutput: this.totalOutput,\n lastUsage: this.lastUsage,\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Turn counting plugin with message deduplication.
3
+ *
4
+ * The SDK emits multiple assistant events per turn (one per content block)
5
+ * with the same message ID. This plugin deduplicates and publishes turn
6
+ * counts + a duplicate flag for downstream plugins.
7
+ */
8
+ import type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';
9
+ export interface TurnData {
10
+ /** Whether the current message is a duplicate of the last processed turn */
11
+ isDuplicate: boolean;
12
+ /** Turns in the current phase */
13
+ phaseTurns: number;
14
+ /** Total turns across all phases */
15
+ totalTurns: number;
16
+ /** Per-phase turn snapshots: [{ phase, turns }] */
17
+ phaseSnapshots: Array<{
18
+ phase: string;
19
+ turns: number;
20
+ }>;
21
+ }
22
+ export declare class TurnCounterPlugin implements Middleware {
23
+ readonly name = "turns";
24
+ private lastMessageId;
25
+ private phaseTurns;
26
+ private totalTurns;
27
+ private isDuplicate;
28
+ private phaseSnapshots;
29
+ private currentPhase;
30
+ onMessage(message: any, _ctx: MiddlewareContext, store: MiddlewareStore): void;
31
+ onPhaseTransition(fromPhase: string, _toPhase: string, _ctx: MiddlewareContext, store: MiddlewareStore): void;
32
+ onFinalize(_resultMessage: any, _totalDurationMs: number, _ctx: MiddlewareContext, store: MiddlewareStore): void;
33
+ private getData;
34
+ }
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ /**
3
+ * Turn counting plugin with message deduplication.
4
+ *
5
+ * The SDK emits multiple assistant events per turn (one per content block)
6
+ * with the same message ID. This plugin deduplicates and publishes turn
7
+ * counts + a duplicate flag for downstream plugins.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.TurnCounterPlugin = void 0;
11
+ class TurnCounterPlugin {
12
+ name = 'turns';
13
+ lastMessageId = null;
14
+ phaseTurns = 0;
15
+ totalTurns = 0;
16
+ isDuplicate = false;
17
+ phaseSnapshots = [];
18
+ currentPhase = 'setup';
19
+ onMessage(message, _ctx, store) {
20
+ if (message.type !== 'assistant') {
21
+ this.isDuplicate = false;
22
+ store.set('turns', this.getData());
23
+ return;
24
+ }
25
+ const msgId = message.message?.id;
26
+ this.isDuplicate = msgId != null && msgId === this.lastMessageId;
27
+ if (msgId)
28
+ this.lastMessageId = msgId;
29
+ if (!this.isDuplicate) {
30
+ this.phaseTurns++;
31
+ this.totalTurns++;
32
+ }
33
+ store.set('turns', this.getData());
34
+ }
35
+ onPhaseTransition(fromPhase, _toPhase, _ctx, store) {
36
+ this.phaseSnapshots.push({ phase: fromPhase, turns: this.phaseTurns });
37
+ this.currentPhase = _toPhase;
38
+ this.phaseTurns = 0;
39
+ this.lastMessageId = null;
40
+ store.set('turns', this.getData());
41
+ }
42
+ onFinalize(_resultMessage, _totalDurationMs, _ctx, store) {
43
+ this.phaseSnapshots.push({
44
+ phase: this.currentPhase,
45
+ turns: this.phaseTurns,
46
+ });
47
+ store.set('turns', this.getData());
48
+ }
49
+ getData() {
50
+ return {
51
+ isDuplicate: this.isDuplicate,
52
+ phaseTurns: this.phaseTurns,
53
+ totalTurns: this.totalTurns,
54
+ phaseSnapshots: [...this.phaseSnapshots],
55
+ };
56
+ }
57
+ }
58
+ exports.TurnCounterPlugin = TurnCounterPlugin;
59
+ //# sourceMappingURL=turn-counter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-counter.js","sourceRoot":"","sources":["../../../../../src/lib/middleware/benchmarks/turn-counter.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAeH,MAAa,iBAAiB;IACnB,IAAI,GAAG,OAAO,CAAC;IAEhB,aAAa,GAAkB,IAAI,CAAC;IACpC,UAAU,GAAG,CAAC,CAAC;IACf,UAAU,GAAG,CAAC,CAAC;IACf,WAAW,GAAG,KAAK,CAAC;IACpB,cAAc,GAA4C,EAAE,CAAC;IAC7D,YAAY,GAAG,OAAO,CAAC;IAE/B,SAAS,CACP,OAAY,EACZ,IAAuB,EACvB,KAAsB;QAEtB,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAuB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC;QACjE,IAAI,KAAK;YAAE,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAEtC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,CAAC;QAED,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,iBAAiB,CACf,SAAiB,EACjB,QAAgB,EAChB,IAAuB,EACvB,KAAsB;QAEtB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QACvE,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,UAAU,CACR,cAAmB,EACnB,gBAAwB,EACxB,IAAuB,EACvB,KAAsB;QAEtB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YACvB,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,KAAK,EAAE,IAAI,CAAC,UAAU;SACvB,CAAC,CAAC;QACH,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACrC,CAAC;IAEO,OAAO;QACb,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,cAAc,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;SACzC,CAAC;IACJ,CAAC;CACF;AAnED,8CAmEC","sourcesContent":["/**\n * Turn counting plugin with message deduplication.\n *\n * The SDK emits multiple assistant events per turn (one per content block)\n * with the same message ID. This plugin deduplicates and publishes turn\n * counts + a duplicate flag for downstream plugins.\n */\n\nimport type { Middleware, MiddlewareContext, MiddlewareStore } from '../types';\n\nexport interface TurnData {\n /** Whether the current message is a duplicate of the last processed turn */\n isDuplicate: boolean;\n /** Turns in the current phase */\n phaseTurns: number;\n /** Total turns across all phases */\n totalTurns: number;\n /** Per-phase turn snapshots: [{ phase, turns }] */\n phaseSnapshots: Array<{ phase: string; turns: number }>;\n}\n\nexport class TurnCounterPlugin implements Middleware {\n readonly name = 'turns';\n\n private lastMessageId: string | null = null;\n private phaseTurns = 0;\n private totalTurns = 0;\n private isDuplicate = false;\n private phaseSnapshots: Array<{ phase: string; turns: number }> = [];\n private currentPhase = 'setup';\n\n onMessage(\n message: any,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n if (message.type !== 'assistant') {\n this.isDuplicate = false;\n store.set('turns', this.getData());\n return;\n }\n\n const msgId: string | undefined = message.message?.id;\n this.isDuplicate = msgId != null && msgId === this.lastMessageId;\n if (msgId) this.lastMessageId = msgId;\n\n if (!this.isDuplicate) {\n this.phaseTurns++;\n this.totalTurns++;\n }\n\n store.set('turns', this.getData());\n }\n\n onPhaseTransition(\n fromPhase: string,\n _toPhase: string,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({ phase: fromPhase, turns: this.phaseTurns });\n this.currentPhase = _toPhase;\n this.phaseTurns = 0;\n this.lastMessageId = null;\n store.set('turns', this.getData());\n }\n\n onFinalize(\n _resultMessage: any,\n _totalDurationMs: number,\n _ctx: MiddlewareContext,\n store: MiddlewareStore,\n ): void {\n this.phaseSnapshots.push({\n phase: this.currentPhase,\n turns: this.phaseTurns,\n });\n store.set('turns', this.getData());\n }\n\n private getData(): TurnData {\n return {\n isDuplicate: this.isDuplicate,\n phaseTurns: this.phaseTurns,\n totalTurns: this.totalTurns,\n phaseSnapshots: [...this.phaseSnapshots],\n };\n }\n}\n"]}