@aid-framework/cli 0.1.59 → 0.1.60

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/dist/trace.js ADDED
@@ -0,0 +1,212 @@
1
+ /**
2
+ * Reading the local trace sink back into numbers.
3
+ *
4
+ * The format is the one `runtimes/{python,typescript}/src/.../local_trace` writes: one
5
+ * JSON object per line, one line per span. This module is the third consumer of that
6
+ * contract and the only one written in TypeScript that does not live in the runtime, so
7
+ * it repeats the field names in one place rather than importing a runtime that drags a
8
+ * provider SDK into the CLI.
9
+ *
10
+ * Two rules keep the report honest:
11
+ *
12
+ * - A span that cannot be parsed is **counted and skipped**, never guessed at. A crash
13
+ * truncated the last line of a file is normal; a line that is not a span at all is not,
14
+ * and the caller reports the count either way.
15
+ * - A span with tokens but no `aid.cost.usd` is **unpriced**, not free. Summing it as
16
+ * zero would make a missing cost look like a cheap run, which is the same failure the
17
+ * IR's cost gate refuses.
18
+ */
19
+ /** The attribute keys the report reads, from the runtime's own conventions table. */
20
+ const ATTRIBUTES = {
21
+ alias: 'aid.model.alias',
22
+ costUsd: 'aid.cost.usd',
23
+ inputTokens: 'gen_ai.usage.input_tokens',
24
+ outputTokens: 'gen_ai.usage.output_tokens',
25
+ responseModel: 'gen_ai.response.model',
26
+ requestModel: 'gen_ai.request.model',
27
+ };
28
+ const UNKNOWN_MODEL = '(unknown)';
29
+ /** The model a span is attributed to: the pinned alias, else the model the provider served. */
30
+ function modelOf(span) {
31
+ const attributes = span.attributes ?? {};
32
+ for (const key of [ATTRIBUTES.alias, ATTRIBUTES.responseModel, ATTRIBUTES.requestModel]) {
33
+ const value = attributes[key];
34
+ if (typeof value === 'string' && value !== '')
35
+ return value;
36
+ }
37
+ return UNKNOWN_MODEL;
38
+ }
39
+ /** A non-negative finite number, accepting the string form an attribute may carry. */
40
+ function numeric(value) {
41
+ if (typeof value === 'number')
42
+ return Number.isFinite(value) && value >= 0 ? value : undefined;
43
+ if (typeof value === 'string' && value.trim() !== '') {
44
+ const parsed = Number(value);
45
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;
46
+ }
47
+ return undefined;
48
+ }
49
+ function isSpan(value) {
50
+ if (typeof value !== 'object' || value === null)
51
+ return false;
52
+ const candidate = value;
53
+ return (typeof candidate.trace_id === 'string' &&
54
+ typeof candidate.span_id === 'string' &&
55
+ typeof candidate.name === 'string' &&
56
+ typeof candidate.started_at === 'string');
57
+ }
58
+ /**
59
+ * Parse one JSONL file. A blank line is not a failure -- the sink never writes one, but
60
+ * a file being appended to while it is read can end in a partial line, and that is the
61
+ * one case a reader has to tolerate.
62
+ */
63
+ export function parseTraceLines(text) {
64
+ const spans = [];
65
+ let skipped = 0;
66
+ for (const line of text.split(/\r?\n/)) {
67
+ if (line.trim() === '')
68
+ continue;
69
+ try {
70
+ const parsed = JSON.parse(line);
71
+ if (isSpan(parsed))
72
+ spans.push(parsed);
73
+ else
74
+ skipped += 1;
75
+ }
76
+ catch {
77
+ skipped += 1;
78
+ }
79
+ }
80
+ return { spans, skipped };
81
+ }
82
+ /**
83
+ * Normalise `--since` to the ISO instant the sink writes, or `undefined` when the value
84
+ * is not a date. A plain `YYYY-MM-DD` is UTC midnight; anything else must be ISO 8601
85
+ * with an explicit offset, because a bare local time would mean a different instant on
86
+ * every machine reading the same repository.
87
+ */
88
+ export function parseSince(value) {
89
+ const trimmed = value.trim();
90
+ const day = /^(\d{4})-(\d{2})-(\d{2})$/;
91
+ if (day.test(trimmed)) {
92
+ const date = new Date(`${trimmed}T00:00:00.000Z`);
93
+ // A round trip rejects 2026-02-31, which `Date` would otherwise roll into March.
94
+ if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== trimmed) {
95
+ return undefined;
96
+ }
97
+ return date.toISOString();
98
+ }
99
+ if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:\d{2})$/.test(trimmed)) {
100
+ return undefined;
101
+ }
102
+ const date = new Date(trimmed);
103
+ return Number.isNaN(date.getTime()) ? undefined : date.toISOString();
104
+ }
105
+ /** Nearest-rank percentile: the smallest value at or above the given fraction. */
106
+ function percentile(sorted, fraction) {
107
+ if (sorted.length === 0)
108
+ return 0;
109
+ const rank = Math.ceil(fraction * sorted.length);
110
+ const index = Math.min(Math.max(rank - 1, 0), sorted.length - 1);
111
+ return sorted[index] ?? 0;
112
+ }
113
+ /**
114
+ * Aggregate spans into one report.
115
+ *
116
+ * `since` filters on `started_at` by string comparison, which is exact because both
117
+ * sides are the UTC ISO form the sink writes.
118
+ */
119
+ export function summariseSpans(spans, options = {}) {
120
+ const counted = options.since === undefined
121
+ ? spans
122
+ : spans.filter((span) => span.started_at >= options.since);
123
+ const traceIds = new Set();
124
+ const byModel = new Map();
125
+ const durations = [];
126
+ let errors = 0;
127
+ let inputTokens = 0;
128
+ let outputTokens = 0;
129
+ let costUsd = 0;
130
+ let unpricedSpans = 0;
131
+ for (const span of counted) {
132
+ traceIds.add(span.trace_id);
133
+ if (span.status?.code === 'ERROR')
134
+ errors += 1;
135
+ const attributes = span.attributes ?? {};
136
+ const cost = numeric(attributes[ATTRIBUTES.costUsd]);
137
+ const input = numeric(attributes[ATTRIBUTES.inputTokens]);
138
+ const output = numeric(attributes[ATTRIBUTES.outputTokens]);
139
+ const hasUsage = input !== undefined || output !== undefined;
140
+ if (cost !== undefined)
141
+ costUsd += cost;
142
+ if (input !== undefined)
143
+ inputTokens += input;
144
+ if (output !== undefined)
145
+ outputTokens += output;
146
+ if (hasUsage && cost === undefined)
147
+ unpricedSpans += 1;
148
+ if (hasUsage) {
149
+ const duration = span.duration_ms;
150
+ if (typeof duration === 'number' && Number.isFinite(duration) && duration >= 0) {
151
+ durations.push(duration);
152
+ }
153
+ }
154
+ if (!hasUsage && cost === undefined)
155
+ continue;
156
+ const model = modelOf(span);
157
+ const existing = byModel.get(model);
158
+ const addition = {
159
+ input: input ?? 0,
160
+ output: output ?? 0,
161
+ cost: cost ?? 0,
162
+ unpriced: hasUsage && cost === undefined ? 1 : 0,
163
+ };
164
+ if (existing === undefined) {
165
+ byModel.set(model, {
166
+ model,
167
+ calls: 1,
168
+ inputTokens: addition.input,
169
+ outputTokens: addition.output,
170
+ costUsd: addition.cost,
171
+ unpricedCalls: addition.unpriced,
172
+ });
173
+ }
174
+ else {
175
+ byModel.set(model, {
176
+ model,
177
+ calls: existing.calls + 1,
178
+ inputTokens: existing.inputTokens + addition.input,
179
+ outputTokens: existing.outputTokens + addition.output,
180
+ costUsd: existing.costUsd + addition.cost,
181
+ unpricedCalls: existing.unpricedCalls + addition.unpriced,
182
+ });
183
+ }
184
+ }
185
+ // Priciest first, then busiest, then by name, so two runs over the same spans print
186
+ // the same order without depending on the order the files happened to be read in.
187
+ const models = [...byModel.values()].sort((left, right) => right.costUsd - left.costUsd ||
188
+ right.calls - left.calls ||
189
+ (left.model < right.model ? -1 : left.model > right.model ? 1 : 0));
190
+ durations.sort((left, right) => left - right);
191
+ const summary = {
192
+ spans: counted.length,
193
+ traces: traceIds.size,
194
+ errors,
195
+ inputTokens,
196
+ outputTokens,
197
+ costUsd,
198
+ unpricedSpans,
199
+ models,
200
+ ...(durations.length === 0
201
+ ? {}
202
+ : {
203
+ latency: {
204
+ p50: Math.round(percentile(durations, 0.5)),
205
+ p95: Math.round(percentile(durations, 0.95)),
206
+ samples: durations.length,
207
+ },
208
+ }),
209
+ };
210
+ return summary;
211
+ }
212
+ //# sourceMappingURL=trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aid-framework/cli",
3
- "version": "0.1.59",
3
+ "version": "0.1.60",
4
4
  "description": "The `aid` command: scaffold a project, validate its spec, generate its code, and run its eval gate.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -33,11 +33,11 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@aid-framework/generator-py-fastapi": "0.1.59",
37
- "@aid-framework/generator-sdk": "0.1.59",
38
- "@aid-framework/generator-ts-vercel": "0.1.59",
39
- "@aid-framework/ir": "0.1.59",
40
- "@aid-framework/spec": "0.1.59"
36
+ "@aid-framework/generator-py-fastapi": "0.1.60",
37
+ "@aid-framework/generator-sdk": "0.1.60",
38
+ "@aid-framework/generator-ts-vercel": "0.1.60",
39
+ "@aid-framework/ir": "0.1.60",
40
+ "@aid-framework/spec": "0.1.60"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "^26.6.5"