@brunobracaioli/aibrain 0.2.0-beta.1 → 0.3.0-beta.13

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.
@@ -0,0 +1,131 @@
1
+ {
2
+ "version": 3,
3
+ "native": "0.163.0",
4
+ "consumed_pagination": {
5
+ "method": "thread/turns/list",
6
+ "request_schema": "v2/ThreadTurnsListParams.json",
7
+ "response_schema": "v2/ThreadTurnsListResponse.json",
8
+ "request_schema_sha256": "29717980579b77eb4c7cbd1118dd238fcb3e010f3ef5236d74bd4e4f6e02c005",
9
+ "response_schema_sha256": "b8425849527d5eec7abdae313afed8c78b0f8536a86ea13e0b565299792b354d",
10
+ "graph_sha256": "522a82295aadb10860029e5929d2d327ef77aa6a29bf6d5ea3e3de311ba60817",
11
+ "ordering": "asc",
12
+ "items_view": "full"
13
+ },
14
+ "roots": {
15
+ "v2/ThreadTurnsListParams.json": {
16
+ "methods": null,
17
+ "sha256": "29717980579b77eb4c7cbd1118dd238fcb3e010f3ef5236d74bd4e4f6e02c005"
18
+ },
19
+ "v2/ThreadTurnsListResponse.json": {
20
+ "methods": null,
21
+ "sha256": "b8425849527d5eec7abdae313afed8c78b0f8536a86ea13e0b565299792b354d"
22
+ },
23
+ "ClientRequest.json": {
24
+ "methods": [
25
+ "initialize",
26
+ "thread/start",
27
+ "thread/resume",
28
+ "thread/fork",
29
+ "thread/delete",
30
+ "thread/unsubscribe",
31
+ "thread/compact/start",
32
+ "thread/list",
33
+ "thread/read",
34
+ "thread/turns/list",
35
+ "thread/items/list",
36
+ "thread/inject_items",
37
+ "turn/start",
38
+ "mcpServer/tool/call",
39
+ "config/read",
40
+ "account/read"
41
+ ],
42
+ "sha256": "edc4fca01569666515db57c583f9d0d2d68387d42178856bd431cf34696b1904"
43
+ },
44
+ "ClientNotification.json": {
45
+ "methods": ["initialized"],
46
+ "sha256": "c6c3ba53650b9dd3aadea19e732ff67b566b162fce7abac361de0d03c91e6624"
47
+ },
48
+ "ServerRequest.json": {
49
+ "methods": [
50
+ "item/commandExecution/requestApproval",
51
+ "item/fileChange/requestApproval",
52
+ "item/tool/requestUserInput",
53
+ "mcpServer/elicitation/request",
54
+ "item/permissions/requestApproval",
55
+ "item/tool/call",
56
+ "account/chatgptAuthTokens/refresh",
57
+ "attestation/generate",
58
+ "currentTime/read",
59
+ "applyPatchApproval",
60
+ "execCommandApproval"
61
+ ],
62
+ "sha256": "f6dbc427473ebb6ffd634cb22a45f3330c48ea9719e2c54fb3f9b0c39f76ef22"
63
+ },
64
+ "ServerNotification.json": {
65
+ "methods": [
66
+ "error",
67
+ "thread/started",
68
+ "thread/status/changed",
69
+ "thread/deleted",
70
+ "thread/closed",
71
+ "thread/tokenUsage/updated",
72
+ "turn/started",
73
+ "turn/completed",
74
+ "item/started",
75
+ "item/completed",
76
+ "item/agentMessage/delta",
77
+ "item/mcpToolCall/progress",
78
+ "thread/compacted",
79
+ "warning"
80
+ ],
81
+ "sha256": "fbb6aa0b4baf418cd9334d642a60e4d070d67aff3dae7ac1792a37c4af79d95f"
82
+ },
83
+ "JSONRPCResponse.json": {
84
+ "methods": null,
85
+ "sha256": "7260ccd0d4c3aeebf068cbbd7e9cb8db122343a981f00c46c3658253a6e9bed5"
86
+ },
87
+ "JSONRPCNotification.json": {
88
+ "methods": null,
89
+ "sha256": "5573b596fa9025a65fc85af984e6f55189a8ab86d3e156efa301ca0eb586f089"
90
+ },
91
+ "v1/InitializeResponse.json": {
92
+ "methods": null,
93
+ "sha256": "3949f87454760303004691e3b22712ffcf3455bf430e132a5e6db510be888306"
94
+ },
95
+ "v2/ConfigReadResponse.json": {
96
+ "methods": null,
97
+ "sha256": "9fc9bdea31211e362cc7d5d66d0c0213c1dafc0b902e3a981866a88328476ea6"
98
+ },
99
+ "v2/McpServerToolCallResponse.json": {
100
+ "methods": null,
101
+ "sha256": "6f67616ad852f8cb2fc34803bfb8a0811817238a9ff74742368d904fb1f67b94"
102
+ },
103
+ "v2/ThreadCompactStartResponse.json": {
104
+ "methods": null,
105
+ "sha256": "30597c637d705b8086eced83a667814d8676d820164e93f55be5e644a085f07a"
106
+ },
107
+ "v2/ThreadForkResponse.json": {
108
+ "methods": null,
109
+ "sha256": "fbaee7dea57bfba20ede06458e1815725c6b9069a63011537cba6eca5cf9a724"
110
+ },
111
+ "v2/ThreadInjectItemsResponse.json": {
112
+ "methods": null,
113
+ "sha256": "30597c637d705b8086eced83a667814d8676d820164e93f55be5e644a085f07a"
114
+ },
115
+ "v2/ThreadReadResponse.json": {
116
+ "methods": null,
117
+ "sha256": "d92dbeb557402c3591713b14a55a09a331fa5e4338fe92f472a9ae0ff7c6fd0a"
118
+ },
119
+ "v2/ThreadResumeResponse.json": {
120
+ "methods": null,
121
+ "sha256": "3361e3179d0a2ac69377fad7358a37f01ae6e3b594d0d0eaedb87f0fa5bac169"
122
+ },
123
+ "v2/ThreadStartResponse.json": {
124
+ "methods": null,
125
+ "sha256": "fbaee7dea57bfba20ede06458e1815725c6b9069a63011537cba6eca5cf9a724"
126
+ }
127
+ },
128
+ "requiredClientFlags": ["app-server", "--listen", "stdio://"],
129
+ "requiredTerminalFlags": ["--remote", "unix://"],
130
+ "generatedFrom": "codex app-server generate-json-schema --experimental"
131
+ }
@@ -0,0 +1,257 @@
1
+ /**
2
+ * Browser safe v1 wire contract for content-free context telemetry.
3
+ *
4
+ * Keep this module free of Node, database and provider imports. Adapters use
5
+ * the same validator as the server boundary so an event rejected locally can
6
+ * never contain a larger or richer shape than the server accepts.
7
+ */
8
+ export const CONTEXT_TELEMETRY_SCHEMA_VERSION = 1;
9
+ export const CONTEXT_TELEMETRY_MAX_BYTES = 8 * 1024;
10
+ export const CONTEXT_TELEMETRY_RETENTION_DAYS = 30;
11
+ export const CONTEXT_TELEMETRY_FRESHNESS_SECONDS = 180;
12
+ export const CONTEXT_TELEMETRY_PHASES = [
13
+ 'connected',
14
+ 'usage',
15
+ 'disconnected',
16
+ 'plan_prepared',
17
+ 'selection_completed',
18
+ 'notes_written',
19
+ 'native_completed',
20
+ 'recovery_attached',
21
+ 'applied',
22
+ 'fallback',
23
+ 'failed',
24
+ 'uncertain',
25
+ ];
26
+ const PHASES = new Set(CONTEXT_TELEMETRY_PHASES);
27
+ const REASONS = new Set([
28
+ 'provider_unavailable',
29
+ 'insufficient_reduction',
30
+ 'protected_context',
31
+ 'stale_context',
32
+ 'rate_limited',
33
+ 'native_error',
34
+ 'recovery_pending',
35
+ 'recovery_uncertain',
36
+ 'unsupported',
37
+ 'unknown',
38
+ ]);
39
+ const UNITS = new Set(['tokens', 'estimated_tokens', 'characters']);
40
+ const CLIENTS = new Set(['claude-code', 'codex-cli']);
41
+ const OPERATION_PHASES = new Set([
42
+ 'plan_prepared',
43
+ 'selection_completed',
44
+ 'notes_written',
45
+ 'native_completed',
46
+ 'recovery_attached',
47
+ 'applied',
48
+ 'fallback',
49
+ 'failed',
50
+ 'uncertain',
51
+ ]);
52
+ const CLAUDE_PHASES = new Set([
53
+ 'connected',
54
+ 'usage',
55
+ 'disconnected',
56
+ 'plan_prepared',
57
+ 'notes_written',
58
+ 'native_completed',
59
+ 'recovery_attached',
60
+ 'applied',
61
+ 'fallback',
62
+ 'failed',
63
+ 'uncertain',
64
+ ]);
65
+ const CODEX_PHASES = new Set([
66
+ 'connected',
67
+ 'usage',
68
+ 'disconnected',
69
+ 'selection_completed',
70
+ 'notes_written',
71
+ 'native_completed',
72
+ 'recovery_attached',
73
+ 'failed',
74
+ 'fallback',
75
+ 'uncertain',
76
+ ]);
77
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
78
+ const SESSION_KEY = /^[0-9a-f]{64}$/;
79
+ const UTC_TIMESTAMP = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,9})?Z$/;
80
+ const SEMVER = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
81
+ const MAX_SEQUENCE = 2_147_483_647;
82
+ const MAX_COUNT = 1_000_000;
83
+ const COUNT_KEYS = ['eligible', 'protected', 'kept', 'reduced', 'dropped', 'selected'];
84
+ export class ContextTelemetryValidationError extends Error {
85
+ constructor(message) {
86
+ super(message);
87
+ this.name = 'ContextTelemetryValidationError';
88
+ }
89
+ }
90
+ function fail(message) {
91
+ throw new ContextTelemetryValidationError(message);
92
+ }
93
+ function isRecord(value) {
94
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
95
+ }
96
+ function closed(value, allowed) {
97
+ const accepted = new Set(allowed);
98
+ for (const key of Object.keys(value))
99
+ if (!accepted.has(key))
100
+ fail('unknown telemetry field');
101
+ }
102
+ function stringField(value, max, pattern) {
103
+ if (typeof value !== 'string' || value.length === 0 || value.length > max)
104
+ fail('invalid telemetry string');
105
+ if (pattern !== undefined && !pattern.test(value))
106
+ fail('invalid telemetry string');
107
+ return value;
108
+ }
109
+ function safeInteger(value, min, max) {
110
+ if (!Number.isSafeInteger(value) || value < min || value > max)
111
+ fail('invalid telemetry integer');
112
+ return value;
113
+ }
114
+ function measurement(value) {
115
+ if (!isRecord(value))
116
+ fail('invalid telemetry measurement');
117
+ closed(value, ['unit', 'used', 'capacity']);
118
+ if (typeof value.unit !== 'string' || !UNITS.has(value.unit))
119
+ fail('invalid measurement unit');
120
+ const used = safeInteger(value.used, 0, Number.MAX_SAFE_INTEGER);
121
+ let capacity;
122
+ if (value.capacity !== undefined) {
123
+ capacity = safeInteger(value.capacity, 1, Number.MAX_SAFE_INTEGER);
124
+ }
125
+ return {
126
+ unit: value.unit,
127
+ used,
128
+ ...(capacity === undefined ? {} : { capacity }),
129
+ };
130
+ }
131
+ function counts(value) {
132
+ if (!isRecord(value))
133
+ fail('invalid telemetry counts');
134
+ closed(value, COUNT_KEYS);
135
+ const result = {};
136
+ for (const key of COUNT_KEYS) {
137
+ if (value[key] !== undefined)
138
+ result[key] = safeInteger(value[key], 0, MAX_COUNT);
139
+ }
140
+ return result;
141
+ }
142
+ function bytes(value) {
143
+ try {
144
+ return new TextEncoder().encode(JSON.stringify(value)).byteLength;
145
+ }
146
+ catch {
147
+ return Number.POSITIVE_INFINITY;
148
+ }
149
+ }
150
+ /** Validate and return the closed v1 report without adding fields. */
151
+ export function parseContextTelemetryReport(value, now = new Date()) {
152
+ if (bytes(value) > CONTEXT_TELEMETRY_MAX_BYTES)
153
+ fail('telemetry report is too large');
154
+ if (!isRecord(value))
155
+ fail('telemetry report must be an object');
156
+ closed(value, [
157
+ 'schema_version',
158
+ 'event_id',
159
+ 'session_key',
160
+ 'instance_id',
161
+ 'sequence',
162
+ 'observed_at',
163
+ 'client',
164
+ 'client_version',
165
+ 'phase',
166
+ 'operation_id',
167
+ 'trigger_percent',
168
+ 'measurement',
169
+ 'before',
170
+ 'after',
171
+ 'counts',
172
+ 'reason',
173
+ ]);
174
+ if (value.schema_version !== 1)
175
+ fail('unsupported telemetry schema');
176
+ const eventId = stringField(value.event_id, 36, UUID);
177
+ const sessionKey = stringField(value.session_key, 64, SESSION_KEY);
178
+ const instanceId = stringField(value.instance_id, 36, UUID);
179
+ const sequence = safeInteger(value.sequence, 1, MAX_SEQUENCE);
180
+ const observedAt = stringField(value.observed_at, 30, UTC_TIMESTAMP);
181
+ const observedMillis = Date.parse(observedAt);
182
+ if (!Number.isFinite(observedMillis))
183
+ fail('invalid telemetry timestamp');
184
+ const nowMillis = now.getTime();
185
+ if (observedMillis > nowMillis + 5 * 60_000 || observedMillis < nowMillis - 24 * 60 * 60_000)
186
+ fail('telemetry timestamp outside accepted window');
187
+ if (typeof value.client !== 'string' || !CLIENTS.has(value.client))
188
+ fail('invalid telemetry client');
189
+ const client = value.client;
190
+ const clientVersion = stringField(value.client_version, 40, SEMVER);
191
+ if (typeof value.phase !== 'string' || !PHASES.has(value.phase))
192
+ fail('invalid telemetry phase');
193
+ const phase = value.phase;
194
+ if (!(client === 'claude-code' ? CLAUDE_PHASES : CODEX_PHASES).has(phase))
195
+ fail('phase is incompatible with client');
196
+ const operationId = value.operation_id === undefined ? undefined : stringField(value.operation_id, 36, UUID);
197
+ if (OPERATION_PHASES.has(phase) !== (operationId !== undefined))
198
+ fail('operation id is required for this phase');
199
+ const triggerPercent = value.trigger_percent === undefined ? undefined : value.trigger_percent;
200
+ if (triggerPercent !== undefined &&
201
+ (typeof triggerPercent !== 'number' ||
202
+ !Number.isFinite(triggerPercent) ||
203
+ triggerPercent < 1 ||
204
+ triggerPercent > 95))
205
+ fail('invalid telemetry trigger');
206
+ const reportMeasurement = value.measurement === undefined ? undefined : measurement(value.measurement);
207
+ const before = value.before === undefined ? undefined : measurement(value.before);
208
+ const after = value.after === undefined ? undefined : measurement(value.after);
209
+ const reportCounts = value.counts === undefined ? undefined : counts(value.counts);
210
+ const reason = value.reason === undefined ? undefined : value.reason;
211
+ if (phase === 'usage' && reportMeasurement === undefined)
212
+ fail('usage requires measurement');
213
+ if ((phase === 'connected' || phase === 'disconnected') &&
214
+ (reportMeasurement !== undefined || before !== undefined || after !== undefined))
215
+ fail('session phase cannot carry measurements');
216
+ if (!OPERATION_PHASES.has(phase) &&
217
+ (before !== undefined ||
218
+ after !== undefined ||
219
+ reportCounts !== undefined ||
220
+ reason !== undefined))
221
+ fail('session phase cannot carry operation results');
222
+ if (before !== undefined &&
223
+ after !== undefined &&
224
+ (before.unit !== after.unit || before.capacity !== after.capacity))
225
+ fail('before and after measurements must match');
226
+ if (phase === 'applied' && after === undefined)
227
+ fail('applied requires an actual measurement');
228
+ if (reason !== undefined && (typeof reason !== 'string' || !REASONS.has(reason)))
229
+ fail('invalid telemetry reason');
230
+ return {
231
+ schema_version: 1,
232
+ event_id: eventId,
233
+ session_key: sessionKey,
234
+ instance_id: instanceId,
235
+ sequence,
236
+ observed_at: observedAt,
237
+ client,
238
+ client_version: clientVersion,
239
+ phase,
240
+ ...(operationId === undefined ? {} : { operation_id: operationId }),
241
+ ...(triggerPercent === undefined ? {} : { trigger_percent: triggerPercent }),
242
+ ...(reportMeasurement === undefined ? {} : { measurement: reportMeasurement }),
243
+ ...(before === undefined ? {} : { before }),
244
+ ...(after === undefined ? {} : { after }),
245
+ ...(reportCounts === undefined ? {} : { counts: reportCounts }),
246
+ ...(reason === undefined ? {} : { reason: reason }),
247
+ };
248
+ }
249
+ export function isContextTelemetryReport(value, now) {
250
+ try {
251
+ parseContextTelemetryReport(value, now);
252
+ return true;
253
+ }
254
+ catch {
255
+ return false;
256
+ }
257
+ }