sidekick-shared 0.24.0 → 0.24.2
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/README.md +42 -14
- package/dist/index.d.ts +4 -2
- package/dist/index.js +8 -2
- package/dist/modelContext.d.ts +50 -3
- package/dist/modelContext.js +133 -16
- package/dist/modelInfo.js +51 -6
- package/dist/node.d.ts +4 -2
- package/dist/node.js +6 -1
- package/dist/observedContextWindows.d.ts +54 -0
- package/dist/observedContextWindows.js +150 -0
- package/dist/observedSessionCollector.d.ts +5 -2
- package/dist/observedSessionCollector.js +1 -0
- package/dist/parsers/codexParser.js +11 -8
- package/dist/pricingCatalog.d.ts +12 -0
- package/dist/pricingCatalog.js +83 -22
- package/dist/providers/codex.js +13 -3
- package/dist/schemas/index.d.ts +2 -2
- package/dist/schemas/index.js +3 -2
- package/dist/schemas/sessionEvent.d.ts +20 -0
- package/dist/schemas/sessionEvent.js +25 -2
- package/dist/schemas/transcript.d.ts +2 -1
- package/dist/schemas/transcript.js +10 -4
- package/dist/transcript.d.ts +6 -0
- package/dist/transcript.js +15 -0
- package/dist/types/sessionEvent.d.ts +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Persisted record of context windows providers actually reported (Node-only).
|
|
4
|
+
*
|
|
5
|
+
* Some agents report the real context window for the running session — Codex
|
|
6
|
+
* emits `model_context_window` on every `token_count` event. That number is the
|
|
7
|
+
* *effective* window for the account and tier, which can sit well below the
|
|
8
|
+
* model's published maximum (e.g. 258,400 observed for `gpt-5.6-sol` against a
|
|
9
|
+
* catalog maximum of 1,050,000).
|
|
10
|
+
*
|
|
11
|
+
* A live session uses that value directly. This module keeps it across runs, so
|
|
12
|
+
* historical and static views don't fall back to a published maximum that would
|
|
13
|
+
* make the context gauge read far too empty.
|
|
14
|
+
*
|
|
15
|
+
* Precedence, most-trusted first: runtime → observed (here) → LiteLLM catalog →
|
|
16
|
+
* static table. See `modelContext.ts`.
|
|
17
|
+
*
|
|
18
|
+
* @module observedContextWindows
|
|
19
|
+
*/
|
|
20
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
21
|
+
if (k2 === undefined) k2 = k;
|
|
22
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
23
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
24
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
25
|
+
}
|
|
26
|
+
Object.defineProperty(o, k2, desc);
|
|
27
|
+
}) : (function(o, m, k, k2) {
|
|
28
|
+
if (k2 === undefined) k2 = k;
|
|
29
|
+
o[k2] = m[k];
|
|
30
|
+
}));
|
|
31
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
32
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
33
|
+
}) : function(o, v) {
|
|
34
|
+
o["default"] = v;
|
|
35
|
+
});
|
|
36
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
37
|
+
var ownKeys = function(o) {
|
|
38
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
39
|
+
var ar = [];
|
|
40
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
41
|
+
return ar;
|
|
42
|
+
};
|
|
43
|
+
return ownKeys(o);
|
|
44
|
+
};
|
|
45
|
+
return function (mod) {
|
|
46
|
+
if (mod && mod.__esModule) return mod;
|
|
47
|
+
var result = {};
|
|
48
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
49
|
+
__setModuleDefault(result, mod);
|
|
50
|
+
return result;
|
|
51
|
+
};
|
|
52
|
+
})();
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.getObservedContextWindowPath = getObservedContextWindowPath;
|
|
55
|
+
exports.loadObservedContextWindows = loadObservedContextWindows;
|
|
56
|
+
exports.recordObservedContextWindow = recordObservedContextWindow;
|
|
57
|
+
const node_fs_1 = require("node:fs");
|
|
58
|
+
const path = __importStar(require("node:path"));
|
|
59
|
+
const modelContext_1 = require("./modelContext");
|
|
60
|
+
const paths_1 = require("./paths");
|
|
61
|
+
const atomic_1 = require("./writers/atomic");
|
|
62
|
+
// ── Constants ──
|
|
63
|
+
const STORE_FILE_NAME = 'observed-context-windows.json';
|
|
64
|
+
const STORE_VERSION = 1;
|
|
65
|
+
/** Resolve the on-disk store path. */
|
|
66
|
+
function getObservedContextWindowPath(cacheDir) {
|
|
67
|
+
return path.join(cacheDir ?? (0, paths_1.getConfigDir)(), STORE_FILE_NAME);
|
|
68
|
+
}
|
|
69
|
+
function emptyStore() {
|
|
70
|
+
return { version: STORE_VERSION, models: {} };
|
|
71
|
+
}
|
|
72
|
+
/** Keep only well-formed entries; a hand-edited or partly-corrupt file shouldn't poison lookups. */
|
|
73
|
+
function toOverrideMap(store) {
|
|
74
|
+
const out = {};
|
|
75
|
+
for (const [modelId, entry] of Object.entries(store.models ?? {})) {
|
|
76
|
+
const window = entry?.contextWindow;
|
|
77
|
+
if (typeof window !== 'number' || !Number.isFinite(window) || window <= 0)
|
|
78
|
+
continue;
|
|
79
|
+
out[modelId] = window;
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
// ── Public API ──
|
|
84
|
+
/**
|
|
85
|
+
* Load persisted observations and apply them as context-window overrides.
|
|
86
|
+
*
|
|
87
|
+
* Always resolves — never throws. A missing, unreadable, or malformed store
|
|
88
|
+
* leaves the overrides empty and lookups fall through to catalog/static.
|
|
89
|
+
*/
|
|
90
|
+
async function loadObservedContextWindows(options = {}) {
|
|
91
|
+
const storePath = getObservedContextWindowPath(options.cacheDir);
|
|
92
|
+
try {
|
|
93
|
+
const raw = await node_fs_1.promises.readFile(storePath, 'utf8');
|
|
94
|
+
const parsed = JSON.parse(raw);
|
|
95
|
+
if (!parsed || typeof parsed !== 'object' || !parsed.models)
|
|
96
|
+
return {};
|
|
97
|
+
const overrides = toOverrideMap(parsed);
|
|
98
|
+
(0, modelContext_1._setObservedContextWindows)(overrides);
|
|
99
|
+
return overrides;
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
const code = err.code;
|
|
103
|
+
if (code !== 'ENOENT') {
|
|
104
|
+
options.logger?.(`observedContextWindows: failed to load ${storePath}: ${String(err)}`);
|
|
105
|
+
}
|
|
106
|
+
return {};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Record a provider-reported context window for a model.
|
|
111
|
+
*
|
|
112
|
+
* Applies in memory immediately, then persists — but only when the value
|
|
113
|
+
* actually changed. Codex reports a window on every `token_count` event, so an
|
|
114
|
+
* unconditional write would mean disk I/O many times per session for a value
|
|
115
|
+
* that almost never moves.
|
|
116
|
+
*
|
|
117
|
+
* Always resolves — never throws. Persistence failures are logged and dropped;
|
|
118
|
+
* the in-memory override still stands for this process.
|
|
119
|
+
*/
|
|
120
|
+
async function recordObservedContextWindow(modelId, contextWindow, options = {}) {
|
|
121
|
+
const normalizedId = modelId?.trim().toLowerCase();
|
|
122
|
+
if (!normalizedId)
|
|
123
|
+
return;
|
|
124
|
+
if (!Number.isFinite(contextWindow) || contextWindow <= 0)
|
|
125
|
+
return;
|
|
126
|
+
const current = (0, modelContext_1._getObservedContextWindows)();
|
|
127
|
+
if (current[normalizedId] === contextWindow)
|
|
128
|
+
return;
|
|
129
|
+
(0, modelContext_1._setObservedContextWindows)({ ...current, [normalizedId]: contextWindow });
|
|
130
|
+
const storePath = getObservedContextWindowPath(options.cacheDir);
|
|
131
|
+
try {
|
|
132
|
+
// Lock-guarded read-modify-write: the CLI and the extension host can both
|
|
133
|
+
// be observing sessions at once, and each should merge rather than clobber.
|
|
134
|
+
await (0, atomic_1.updateJsonStoreAtomic)(storePath, emptyStore, (latest) => {
|
|
135
|
+
const models = latest?.models ?? {};
|
|
136
|
+
if (models[normalizedId]?.contextWindow === contextWindow)
|
|
137
|
+
return latest;
|
|
138
|
+
return {
|
|
139
|
+
version: STORE_VERSION,
|
|
140
|
+
models: {
|
|
141
|
+
...models,
|
|
142
|
+
[normalizedId]: { contextWindow, observedAt: new Date().toISOString() },
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
options.logger?.(`observedContextWindows: failed to persist ${storePath}: ${String(err)}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ObservedAgentSessionV1 } from './types/observedSessionV1';
|
|
1
|
+
import type { ObservedAgentSessionV1, ProviderCapabilitiesV1 } from './types/observedSessionV1';
|
|
2
2
|
import type { SessionProviderBase } from './providers/types';
|
|
3
3
|
export interface ObservedSessionReference {
|
|
4
4
|
sessionId: string;
|
|
@@ -12,6 +12,9 @@ export interface ObservedSessionCollectionSource<T = unknown> {
|
|
|
12
12
|
read(reference: ObservedSessionReference): Promise<T> | T;
|
|
13
13
|
dispose?(): void;
|
|
14
14
|
}
|
|
15
|
+
export interface ProviderObservedSessionCollectionSource extends ObservedSessionCollectionSource<ObservedAgentSessionV1> {
|
|
16
|
+
capabilities: ProviderCapabilitiesV1;
|
|
17
|
+
}
|
|
15
18
|
export type ObservedSessionDiagnosticKind = 'provider-discovery-failed' | 'session-read-failed' | 'provider-recovered' | 'session-recovered';
|
|
16
19
|
/** Content-safe diagnostics: identifiers and retry metadata only. */
|
|
17
20
|
export interface ObservedSessionDiagnostic {
|
|
@@ -63,6 +66,6 @@ export declare class ObservedSessionCollector<T = unknown> {
|
|
|
63
66
|
* Adapt a provider using path-only discovery and independent adapter reads, so
|
|
64
67
|
* one malformed session cannot reject discovery of its healthy siblings.
|
|
65
68
|
*/
|
|
66
|
-
export declare function observedSessionSourceFromProvider(provider: SessionProviderBase, cwd: string):
|
|
69
|
+
export declare function observedSessionSourceFromProvider(provider: SessionProviderBase, cwd: string): ProviderObservedSessionCollectionSource;
|
|
67
70
|
/** Size/mtime fingerprint suitable for retry bypass; returns null for synthetic DB locators. */
|
|
68
71
|
export declare function fileFingerprint(sourcePath: string): string | null;
|
|
@@ -144,6 +144,7 @@ function observedSessionSourceFromProvider(provider, cwd) {
|
|
|
144
144
|
const adapter = (0, observedSessionV1_1.createProviderSessionAdapterV1)(provider);
|
|
145
145
|
return {
|
|
146
146
|
providerId: provider.id,
|
|
147
|
+
capabilities: adapter.capabilities,
|
|
147
148
|
discover() {
|
|
148
149
|
return provider.findAllSessions(cwd).map((sessionPath) => ({
|
|
149
150
|
sessionId: provider.getSessionId(sessionPath),
|
|
@@ -200,18 +200,21 @@ class CodexRolloutParser {
|
|
|
200
200
|
handleSessionMeta(timestamp, payload) {
|
|
201
201
|
this.sessionMeta = payload;
|
|
202
202
|
const text = payload.base_instructions?.text?.trim();
|
|
203
|
-
if (!text)
|
|
204
|
-
return [];
|
|
205
203
|
return [
|
|
206
204
|
{
|
|
207
205
|
type: 'system',
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
...(text
|
|
207
|
+
? {
|
|
208
|
+
message: {
|
|
209
|
+
role: 'system',
|
|
210
|
+
id: `${payload.id}:base-instructions`,
|
|
211
|
+
sourceLabel: 'base instructions',
|
|
212
|
+
content: [{ type: 'text', text }],
|
|
213
|
+
},
|
|
214
|
+
}
|
|
215
|
+
: {}),
|
|
214
216
|
timestamp,
|
|
217
|
+
cwd: payload.cwd || undefined,
|
|
215
218
|
},
|
|
216
219
|
];
|
|
217
220
|
}
|
package/dist/pricingCatalog.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export interface HydrateResult {
|
|
|
36
36
|
source: 'cache' | 'network' | 'offline';
|
|
37
37
|
/** Number of pricing entries applied to the override map. */
|
|
38
38
|
entries: number;
|
|
39
|
+
/** Number of context-window entries applied to the override map. */
|
|
40
|
+
contextWindowEntries: number;
|
|
39
41
|
/** ISO timestamp of the fetch that produced the cache. */
|
|
40
42
|
fetchedAt: string;
|
|
41
43
|
}
|
|
@@ -56,3 +58,13 @@ export declare function hydratePricingCatalog(options: HydrateOptions): Promise<
|
|
|
56
58
|
* Exported for tests; rarely called directly.
|
|
57
59
|
*/
|
|
58
60
|
export declare function normalizeLiteLlmCatalog(raw: unknown): Record<string, ModelPricing>;
|
|
61
|
+
/**
|
|
62
|
+
* Convert a LiteLLM catalog payload to a model → context-window override map.
|
|
63
|
+
*
|
|
64
|
+
* Kept separate from `normalizeLiteLlmCatalog` rather than folded into its
|
|
65
|
+
* return type: that function is public API on a published package, and pricing
|
|
66
|
+
* and context coverage differ (an entry can have one without the other).
|
|
67
|
+
*
|
|
68
|
+
* Exported for tests; rarely called directly.
|
|
69
|
+
*/
|
|
70
|
+
export declare function normalizeLiteLlmContextWindows(raw: unknown): Record<string, number>;
|
package/dist/pricingCatalog.js
CHANGED
|
@@ -54,8 +54,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
54
54
|
exports.LITELLM_CATALOG_URL = void 0;
|
|
55
55
|
exports.hydratePricingCatalog = hydratePricingCatalog;
|
|
56
56
|
exports.normalizeLiteLlmCatalog = normalizeLiteLlmCatalog;
|
|
57
|
+
exports.normalizeLiteLlmContextWindows = normalizeLiteLlmContextWindows;
|
|
57
58
|
const node_fs_1 = require("node:fs");
|
|
58
59
|
const path = __importStar(require("node:path"));
|
|
60
|
+
const modelContext_1 = require("./modelContext");
|
|
59
61
|
const modelInfo_1 = require("./modelInfo");
|
|
60
62
|
// ── Constants ──
|
|
61
63
|
exports.LITELLM_CATALOG_URL = 'https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json';
|
|
@@ -80,43 +82,51 @@ async function hydratePricingCatalog(options) {
|
|
|
80
82
|
// 1. Fresh cache?
|
|
81
83
|
const cached = await readCache(cachePath);
|
|
82
84
|
if (cached && now - Date.parse(cached.fetchedAt) < ttlMs) {
|
|
83
|
-
(
|
|
84
|
-
return {
|
|
85
|
-
source: 'cache',
|
|
86
|
-
entries: Object.keys(cached.overrides).length,
|
|
87
|
-
fetchedAt: cached.fetchedAt,
|
|
88
|
-
};
|
|
85
|
+
return applyCacheFile(cached, 'cache');
|
|
89
86
|
}
|
|
90
87
|
// 2. Try network.
|
|
91
88
|
if (fetchImpl) {
|
|
92
89
|
const fetched = await fetchCatalog(url, fetchImpl, timeoutMs, logger);
|
|
93
90
|
if (fetched) {
|
|
94
|
-
const overrides = normalizeLiteLlmCatalog(fetched);
|
|
95
91
|
const payload = {
|
|
96
92
|
fetchedAt: new Date(now).toISOString(),
|
|
97
93
|
url,
|
|
98
|
-
overrides,
|
|
94
|
+
overrides: normalizeLiteLlmCatalog(fetched),
|
|
95
|
+
contextWindows: normalizeLiteLlmContextWindows(fetched),
|
|
99
96
|
};
|
|
100
97
|
await writeCache(cachePath, payload, logger);
|
|
101
|
-
(
|
|
102
|
-
return {
|
|
103
|
-
source: 'network',
|
|
104
|
-
entries: Object.keys(overrides).length,
|
|
105
|
-
fetchedAt: payload.fetchedAt,
|
|
106
|
-
};
|
|
98
|
+
return applyCacheFile(payload, 'network');
|
|
107
99
|
}
|
|
108
100
|
}
|
|
109
101
|
// 3. Fall back to stale cache if present.
|
|
110
102
|
if (cached) {
|
|
111
|
-
(
|
|
112
|
-
return {
|
|
113
|
-
source: 'cache',
|
|
114
|
-
entries: Object.keys(cached.overrides).length,
|
|
115
|
-
fetchedAt: cached.fetchedAt,
|
|
116
|
-
};
|
|
103
|
+
return applyCacheFile(cached, 'cache');
|
|
117
104
|
}
|
|
118
|
-
// 4. Nothing we can do — stay on static
|
|
119
|
-
return {
|
|
105
|
+
// 4. Nothing we can do — stay on static tables.
|
|
106
|
+
return {
|
|
107
|
+
source: 'offline',
|
|
108
|
+
entries: 0,
|
|
109
|
+
contextWindowEntries: 0,
|
|
110
|
+
fetchedAt: new Date(now).toISOString(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Push a cache payload into both override maps and describe what was applied.
|
|
115
|
+
* `contextWindows` is absent on caches written before context hydration; those
|
|
116
|
+
* contribute no overrides rather than clearing whatever is already loaded.
|
|
117
|
+
*/
|
|
118
|
+
function applyCacheFile(cache, source) {
|
|
119
|
+
const contextWindows = cache.contextWindows ?? {};
|
|
120
|
+
(0, modelInfo_1._setPricingOverrides)(cache.overrides);
|
|
121
|
+
if (Object.keys(contextWindows).length > 0) {
|
|
122
|
+
(0, modelContext_1._setCatalogContextWindows)(contextWindows);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
source,
|
|
126
|
+
entries: Object.keys(cache.overrides).length,
|
|
127
|
+
contextWindowEntries: Object.keys(contextWindows).length,
|
|
128
|
+
fetchedAt: cache.fetchedAt,
|
|
129
|
+
};
|
|
120
130
|
}
|
|
121
131
|
/**
|
|
122
132
|
* Convert a LiteLLM catalog payload to our `ModelPricing` override map.
|
|
@@ -145,6 +155,57 @@ function normalizeLiteLlmCatalog(raw) {
|
|
|
145
155
|
}
|
|
146
156
|
return out;
|
|
147
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Convert a LiteLLM catalog payload to a model → context-window override map.
|
|
160
|
+
*
|
|
161
|
+
* Kept separate from `normalizeLiteLlmCatalog` rather than folded into its
|
|
162
|
+
* return type: that function is public API on a published package, and pricing
|
|
163
|
+
* and context coverage differ (an entry can have one without the other).
|
|
164
|
+
*
|
|
165
|
+
* Exported for tests; rarely called directly.
|
|
166
|
+
*/
|
|
167
|
+
function normalizeLiteLlmContextWindows(raw) {
|
|
168
|
+
const out = {};
|
|
169
|
+
if (!raw || typeof raw !== 'object')
|
|
170
|
+
return out;
|
|
171
|
+
// Bare-model aliases are gathered separately rather than written as we go. A
|
|
172
|
+
// `provider/model` entry describes that *provider's deployment* window, which
|
|
173
|
+
// is often a truncation of the model's own — the live catalog carries five
|
|
174
|
+
// different windows for `claude-sonnet-4`, from GitHub Copilot's 128K to
|
|
175
|
+
// Vertex's 1M. Taking whichever appeared first in the JSON is a coin flip, so
|
|
176
|
+
// an alias is only promoted when every provider mentioning it agrees.
|
|
177
|
+
const aliasWindows = new Map();
|
|
178
|
+
for (const [key, entry] of Object.entries(raw)) {
|
|
179
|
+
// LiteLLM ships a `sample_spec` header entry. Skip it.
|
|
180
|
+
if (key === 'sample_spec')
|
|
181
|
+
continue;
|
|
182
|
+
if (!entry || typeof entry !== 'object')
|
|
183
|
+
continue;
|
|
184
|
+
const window = entry.max_input_tokens;
|
|
185
|
+
if (typeof window !== 'number' || !Number.isFinite(window) || window <= 0)
|
|
186
|
+
continue;
|
|
187
|
+
out[key] = window;
|
|
188
|
+
const bare = stripProviderPrefix(key);
|
|
189
|
+
if (bare && bare !== key) {
|
|
190
|
+
const seen = aliasWindows.get(bare) ?? new Set();
|
|
191
|
+
seen.add(window);
|
|
192
|
+
aliasWindows.set(bare, seen);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const [bare, windows] of aliasWindows) {
|
|
196
|
+
// A top-level entry for the same ID is authoritative — never shadow it.
|
|
197
|
+
if (out[bare] !== undefined)
|
|
198
|
+
continue;
|
|
199
|
+
// Providers disagree, so none of their numbers can be attributed to the
|
|
200
|
+
// bare model. Record nothing and let a more trusted layer answer.
|
|
201
|
+
if (windows.size !== 1)
|
|
202
|
+
continue;
|
|
203
|
+
const [only] = windows;
|
|
204
|
+
if (typeof only === 'number')
|
|
205
|
+
out[bare] = only;
|
|
206
|
+
}
|
|
207
|
+
return out;
|
|
208
|
+
}
|
|
148
209
|
// ── Internals ──
|
|
149
210
|
function liteLlmEntryToPricing(entry) {
|
|
150
211
|
const input = entry.input_cost_per_token;
|
package/dist/providers/codex.js
CHANGED
|
@@ -53,6 +53,7 @@ const codexParser_1 = require("../parsers/codexParser");
|
|
|
53
53
|
const codexDatabase_1 = require("./codexDatabase");
|
|
54
54
|
const codexProfiles_1 = require("../codexProfiles");
|
|
55
55
|
const modelContext_1 = require("../modelContext");
|
|
56
|
+
const observedContextWindows_1 = require("../observedContextWindows");
|
|
56
57
|
const usageNormalization_1 = require("../usageNormalization");
|
|
57
58
|
// ---------------------------------------------------------------------------
|
|
58
59
|
// Helper functions
|
|
@@ -510,10 +511,12 @@ class CodexReader {
|
|
|
510
511
|
// Skip malformed JSON lines
|
|
511
512
|
}
|
|
512
513
|
}
|
|
513
|
-
// Propagate model_context_window from token_count events to the provider
|
|
514
|
+
// Propagate model_context_window from token_count events to the provider.
|
|
515
|
+
// The model comes along so the value can be persisted per model — the
|
|
516
|
+
// window Codex reports is tier-specific, not the published maximum.
|
|
514
517
|
const mcw = this.parser.getModelContextWindow();
|
|
515
518
|
if (mcw && this.onContextWindowLimit) {
|
|
516
|
-
this.onContextWindowLimit(mcw);
|
|
519
|
+
this.onContextWindowLimit(mcw, this.parser.getCurrentModel() ?? undefined);
|
|
517
520
|
}
|
|
518
521
|
// Propagate rate_limits from token_count events to the provider
|
|
519
522
|
const rateLimits = this.parser.getLastRateLimits();
|
|
@@ -791,8 +794,15 @@ class CodexProvider {
|
|
|
791
794
|
}
|
|
792
795
|
// --- Data reading ---
|
|
793
796
|
createReader(sessionPath) {
|
|
794
|
-
return new CodexReader(sessionPath, (limit) => {
|
|
797
|
+
return new CodexReader(sessionPath, (limit, modelId) => {
|
|
795
798
|
this.dynamicContextWindowLimit = limit;
|
|
799
|
+
if (modelId) {
|
|
800
|
+
// Fire-and-forget: persist so historical/static views keep this
|
|
801
|
+
// tier-specific window instead of falling back to the catalog maximum.
|
|
802
|
+
void (0, observedContextWindows_1.recordObservedContextWindow)(modelId, limit).catch(() => {
|
|
803
|
+
/* non-fatal; the in-memory limit above still applies */
|
|
804
|
+
});
|
|
805
|
+
}
|
|
796
806
|
}, (limits) => {
|
|
797
807
|
this.lastRateLimitsData = limits;
|
|
798
808
|
}, (usage) => {
|
package/dist/schemas/index.d.ts
CHANGED
|
@@ -16,8 +16,8 @@ export { normalizedUsageSchema, normalizedUsageCostSchema } from './usageNormali
|
|
|
16
16
|
export type { NormalizedUsage, NormalizedUsageCost } from '../usageNormalization';
|
|
17
17
|
export { tokenEstimateSchema } from './tokenEstimation';
|
|
18
18
|
export type { TokenEstimate } from '../tokenEstimation';
|
|
19
|
-
export { canonicalTranscriptBlockSchema, canonicalToolCallSchema, canonicalTranscriptMessageSchema, canonicalSessionTranscriptSchema, } from './transcript';
|
|
20
|
-
export type { CanonicalSessionTranscript, CanonicalTranscriptMessage, CanonicalToolCall, } from '../transcript';
|
|
19
|
+
export { transcriptSourceProvenanceSchema, canonicalTranscriptBlockSchema, canonicalToolCallSchema, canonicalTranscriptMessageSchema, canonicalSessionTranscriptSchema, } from './transcript';
|
|
20
|
+
export type { CanonicalSessionTranscript, CanonicalTranscriptMessage, CanonicalToolCall, TranscriptSourceProvenance, } from '../transcript';
|
|
21
21
|
export { observationProvenanceV1Schema, observedAgentSessionV1Schema, observedValueV1Schema, pendingUserRequestV1Schema, providerCapabilitiesV1Schema, providerSessionAdapterV1Schema, sessionEvidenceRefV1Schema, } from './observedSessionV1';
|
|
22
22
|
export type { ObservationProvenanceV1, ObservedAgentSessionV1, ObservedValueV1, PendingUserRequestV1, ProviderCapabilitiesV1, ProviderSessionAdapterV1, SessionEvidenceRefV1, } from '../types/observedSessionV1';
|
|
23
23
|
export { quotaWindowSchema, quotaStateSchema, quotaFailureKindSchema, quotaProviderIdSchema, quotaSourceSchema, codexResetCreditSchema, codexResetCreditsSnapshotSchema, peakHoursStateSchema, quotaFailureDescriptorSchema, runtimeQuotaProviderSchema, providerQuotaStateSchema, claudeProviderQuotaStateSchema, codexProviderQuotaStateSchema, zaiProviderQuotaStateSchema, providerQuotaMapSchema, } from './quota';
|
package/dist/schemas/index.js
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* subpath is self-sufficient for boundary-validation modules.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.
|
|
16
|
-
exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = void 0;
|
|
15
|
+
exports.accountLoginStatusSchema = exports.beginAccountLoginResultSchema = exports.accountManagerResultSchema = exports.accountProviderIdSchema = exports.activeAccountStatusSchema = exports.activeProviderAccountStatusSchema = exports.quotaHistoryDailyBucketSchema = exports.quotaHistorySampleSchema = exports.quotaHistoryRuntimeProviderSchema = exports.providerQuotaMapSchema = exports.zaiProviderQuotaStateSchema = exports.codexProviderQuotaStateSchema = exports.claudeProviderQuotaStateSchema = exports.providerQuotaStateSchema = exports.runtimeQuotaProviderSchema = exports.quotaFailureDescriptorSchema = exports.peakHoursStateSchema = exports.codexResetCreditsSnapshotSchema = exports.codexResetCreditSchema = exports.quotaSourceSchema = exports.quotaProviderIdSchema = exports.quotaFailureKindSchema = exports.quotaStateSchema = exports.quotaWindowSchema = exports.sessionEvidenceRefV1Schema = exports.providerSessionAdapterV1Schema = exports.providerCapabilitiesV1Schema = exports.pendingUserRequestV1Schema = exports.observedValueV1Schema = exports.observedAgentSessionV1Schema = exports.observationProvenanceV1Schema = exports.canonicalSessionTranscriptSchema = exports.canonicalTranscriptMessageSchema = exports.canonicalToolCallSchema = exports.canonicalTranscriptBlockSchema = exports.transcriptSourceProvenanceSchema = exports.tokenEstimateSchema = exports.normalizedUsageCostSchema = exports.normalizedUsageSchema = exports.toolResultSessionEventSchema = exports.toolUseSessionEventSchema = exports.systemSessionEventSchema = exports.summarySessionEventSchema = exports.assistantSessionEventSchema = exports.userSessionEventSchema = exports.extractSessionEvents = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = void 0;
|
|
16
|
+
exports.assistantTurnToolRefSchema = exports.assistantTurnToolGroupStepSchema = exports.assistantTurnTimelineItemSchema = exports.assistantTurnSubagentStatusSchema = exports.assistantTurnSubagentSchema = exports.assistantTurnReasoningTimelineItemSchema = exports.assistantTurnProjectionSchema = exports.assistantTurnProcessStepSchema = exports.assistantTurnProcessSchema = exports.assistantTurnNarrationStepSchema = exports.assistantTurnEventTypeSchema = exports.assistantTurnEventSchema = exports.listAllAccountsResultSchema = exports.savedAccountProfileSchema = exports.accountEntrySchema = void 0;
|
|
17
17
|
var sessionEvent_1 = require("./sessionEvent");
|
|
18
18
|
Object.defineProperty(exports, "messageUsageSchema", { enumerable: true, get: function () { return sessionEvent_1.messageUsageSchema; } });
|
|
19
19
|
Object.defineProperty(exports, "sessionMessageSchema", { enumerable: true, get: function () { return sessionEvent_1.sessionMessageSchema; } });
|
|
@@ -32,6 +32,7 @@ Object.defineProperty(exports, "normalizedUsageCostSchema", { enumerable: true,
|
|
|
32
32
|
var tokenEstimation_1 = require("./tokenEstimation");
|
|
33
33
|
Object.defineProperty(exports, "tokenEstimateSchema", { enumerable: true, get: function () { return tokenEstimation_1.tokenEstimateSchema; } });
|
|
34
34
|
var transcript_1 = require("./transcript");
|
|
35
|
+
Object.defineProperty(exports, "transcriptSourceProvenanceSchema", { enumerable: true, get: function () { return transcript_1.transcriptSourceProvenanceSchema; } });
|
|
35
36
|
Object.defineProperty(exports, "canonicalTranscriptBlockSchema", { enumerable: true, get: function () { return transcript_1.canonicalTranscriptBlockSchema; } });
|
|
36
37
|
Object.defineProperty(exports, "canonicalToolCallSchema", { enumerable: true, get: function () { return transcript_1.canonicalToolCallSchema; } });
|
|
37
38
|
Object.defineProperty(exports, "canonicalTranscriptMessageSchema", { enumerable: true, get: function () { return transcript_1.canonicalTranscriptMessageSchema; } });
|
|
@@ -61,7 +61,11 @@ export declare const permissionModeSchema: z.ZodEnum<{
|
|
|
61
61
|
}>;
|
|
62
62
|
export declare const userSessionEventSchema: z.ZodObject<{
|
|
63
63
|
timestamp: z.ZodString;
|
|
64
|
+
entrypoint: z.ZodOptional<z.ZodString>;
|
|
65
|
+
isMeta: z.ZodOptional<z.ZodBoolean>;
|
|
64
66
|
isSidechain: z.ZodOptional<z.ZodBoolean>;
|
|
67
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
68
|
+
gitBranch: z.ZodOptional<z.ZodString>;
|
|
65
69
|
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
66
70
|
default: "default";
|
|
67
71
|
acceptEdits: "acceptEdits";
|
|
@@ -136,7 +140,11 @@ export declare const userSessionEventSchema: z.ZodObject<{
|
|
|
136
140
|
}, z.core.$strip>;
|
|
137
141
|
export declare const assistantSessionEventSchema: z.ZodObject<{
|
|
138
142
|
timestamp: z.ZodString;
|
|
143
|
+
entrypoint: z.ZodOptional<z.ZodString>;
|
|
144
|
+
isMeta: z.ZodOptional<z.ZodBoolean>;
|
|
139
145
|
isSidechain: z.ZodOptional<z.ZodBoolean>;
|
|
146
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
147
|
+
gitBranch: z.ZodOptional<z.ZodString>;
|
|
140
148
|
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
141
149
|
default: "default";
|
|
142
150
|
acceptEdits: "acceptEdits";
|
|
@@ -212,7 +220,11 @@ export declare const assistantSessionEventSchema: z.ZodObject<{
|
|
|
212
220
|
export declare const summarySessionEventSchema: z.ZodType<SummarySessionEvent>;
|
|
213
221
|
export declare const systemSessionEventSchema: z.ZodObject<{
|
|
214
222
|
timestamp: z.ZodString;
|
|
223
|
+
entrypoint: z.ZodOptional<z.ZodString>;
|
|
224
|
+
isMeta: z.ZodOptional<z.ZodBoolean>;
|
|
215
225
|
isSidechain: z.ZodOptional<z.ZodBoolean>;
|
|
226
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
227
|
+
gitBranch: z.ZodOptional<z.ZodString>;
|
|
216
228
|
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
217
229
|
default: "default";
|
|
218
230
|
acceptEdits: "acceptEdits";
|
|
@@ -291,7 +303,11 @@ export declare const toolUseSessionEventSchema: z.ZodObject<{
|
|
|
291
303
|
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
292
304
|
}, z.core.$strip>;
|
|
293
305
|
timestamp: z.ZodString;
|
|
306
|
+
entrypoint: z.ZodOptional<z.ZodString>;
|
|
307
|
+
isMeta: z.ZodOptional<z.ZodBoolean>;
|
|
294
308
|
isSidechain: z.ZodOptional<z.ZodBoolean>;
|
|
309
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
310
|
+
gitBranch: z.ZodOptional<z.ZodString>;
|
|
295
311
|
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
296
312
|
default: "default";
|
|
297
313
|
acceptEdits: "acceptEdits";
|
|
@@ -371,7 +387,11 @@ export declare const toolResultSessionEventSchema: z.ZodObject<{
|
|
|
371
387
|
is_error: z.ZodOptional<z.ZodBoolean>;
|
|
372
388
|
}, z.core.$strip>;
|
|
373
389
|
timestamp: z.ZodString;
|
|
390
|
+
entrypoint: z.ZodOptional<z.ZodString>;
|
|
391
|
+
isMeta: z.ZodOptional<z.ZodBoolean>;
|
|
374
392
|
isSidechain: z.ZodOptional<z.ZodBoolean>;
|
|
393
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
394
|
+
gitBranch: z.ZodOptional<z.ZodString>;
|
|
375
395
|
permissionMode: z.ZodOptional<z.ZodEnum<{
|
|
376
396
|
default: "default";
|
|
377
397
|
acceptEdits: "acceptEdits";
|
|
@@ -41,7 +41,11 @@ exports.permissionModeSchema = zod_1.z.enum([
|
|
|
41
41
|
// ── SessionEvent ──
|
|
42
42
|
const eventBaseShape = {
|
|
43
43
|
timestamp: zod_1.z.string(),
|
|
44
|
+
entrypoint: zod_1.z.string().optional(),
|
|
45
|
+
isMeta: zod_1.z.boolean().optional(),
|
|
44
46
|
isSidechain: zod_1.z.boolean().optional(),
|
|
47
|
+
cwd: zod_1.z.string().optional(),
|
|
48
|
+
gitBranch: zod_1.z.string().optional(),
|
|
45
49
|
permissionMode: exports.permissionModeSchema.optional(),
|
|
46
50
|
rateLimits: zod_1.z
|
|
47
51
|
.object({
|
|
@@ -169,19 +173,38 @@ const MAX_PROGRESS_DEPTH = 8;
|
|
|
169
173
|
* Returns zero events for unrecognized input — never throws.
|
|
170
174
|
*/
|
|
171
175
|
function extractSessionEvents(raw, depth = 0) {
|
|
176
|
+
return extractSessionEventsWithProvenance(raw, depth, {});
|
|
177
|
+
}
|
|
178
|
+
function extractSessionEventsWithProvenance(raw, depth, inherited) {
|
|
172
179
|
const direct = exports.sessionEventSchema.safeParse(raw);
|
|
173
180
|
if (direct.success)
|
|
174
|
-
return [direct.data];
|
|
181
|
+
return [{ ...inherited, ...direct.data }];
|
|
175
182
|
if (depth >= MAX_PROGRESS_DEPTH)
|
|
176
183
|
return [];
|
|
177
184
|
if (typeof raw === 'object' && raw !== null && raw.type === 'progress') {
|
|
185
|
+
const provenance = { ...inherited, ...progressProvenance(raw) };
|
|
178
186
|
const data = raw.data;
|
|
179
187
|
if (typeof data === 'object' && data !== null) {
|
|
180
188
|
const message = data.message;
|
|
181
189
|
if (typeof message === 'object' && message !== null) {
|
|
182
|
-
return
|
|
190
|
+
return extractSessionEventsWithProvenance(message, depth + 1, provenance);
|
|
183
191
|
}
|
|
184
192
|
}
|
|
185
193
|
}
|
|
186
194
|
return [];
|
|
187
195
|
}
|
|
196
|
+
function progressProvenance(raw) {
|
|
197
|
+
const value = raw;
|
|
198
|
+
const provenance = {};
|
|
199
|
+
if (typeof value.entrypoint === 'string')
|
|
200
|
+
provenance.entrypoint = value.entrypoint;
|
|
201
|
+
if (typeof value.isMeta === 'boolean')
|
|
202
|
+
provenance.isMeta = value.isMeta;
|
|
203
|
+
if (typeof value.isSidechain === 'boolean')
|
|
204
|
+
provenance.isSidechain = value.isSidechain;
|
|
205
|
+
if (typeof value.cwd === 'string')
|
|
206
|
+
provenance.cwd = value.cwd;
|
|
207
|
+
if (typeof value.gitBranch === 'string')
|
|
208
|
+
provenance.gitBranch = value.gitBranch;
|
|
209
|
+
return provenance;
|
|
210
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import type { CanonicalSessionTranscript, CanonicalTranscriptMessage, CanonicalToolCall } from '../transcript';
|
|
2
|
+
import type { CanonicalSessionTranscript, CanonicalTranscriptMessage, CanonicalToolCall, TranscriptSourceProvenance } from '../transcript';
|
|
3
|
+
export declare const transcriptSourceProvenanceSchema: z.ZodType<TranscriptSourceProvenance>;
|
|
3
4
|
export declare const canonicalTranscriptBlockSchema: z.ZodObject<{
|
|
4
5
|
type: z.ZodEnum<{
|
|
5
6
|
unknown: "unknown";
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.canonicalSessionTranscriptSchema = exports.canonicalTranscriptMessageSchema = exports.canonicalToolCallSchema = exports.canonicalTranscriptBlockSchema = void 0;
|
|
3
|
+
exports.canonicalSessionTranscriptSchema = exports.canonicalTranscriptMessageSchema = exports.canonicalToolCallSchema = exports.canonicalTranscriptBlockSchema = exports.transcriptSourceProvenanceSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const usageNormalization_1 = require("./usageNormalization");
|
|
6
|
-
|
|
6
|
+
exports.transcriptSourceProvenanceSchema = zod_1.z.object({
|
|
7
7
|
provider: zod_1.z.string().optional(),
|
|
8
8
|
sessionId: zod_1.z.string().optional(),
|
|
9
9
|
sourcePath: zod_1.z.string().optional(),
|
|
10
10
|
source: zod_1.z.string().optional(),
|
|
11
|
+
entrypoint: zod_1.z.string().optional(),
|
|
12
|
+
isMeta: zod_1.z.boolean().optional(),
|
|
13
|
+
isSidechain: zod_1.z.boolean().optional(),
|
|
14
|
+
originalRole: zod_1.z.string().optional(),
|
|
11
15
|
eventIndex: zod_1.z.number().int().nonnegative(),
|
|
12
16
|
eventType: zod_1.z.enum(['user', 'assistant', 'tool_use', 'tool_result', 'summary', 'system']),
|
|
13
17
|
eventId: zod_1.z.string().optional(),
|
|
@@ -32,7 +36,7 @@ exports.canonicalToolCallSchema = zod_1.z.object({
|
|
|
32
36
|
output: zod_1.z.unknown().optional(),
|
|
33
37
|
isError: zod_1.z.boolean().optional(),
|
|
34
38
|
command: zod_1.z.string().optional(),
|
|
35
|
-
source:
|
|
39
|
+
source: exports.transcriptSourceProvenanceSchema,
|
|
36
40
|
});
|
|
37
41
|
exports.canonicalTranscriptMessageSchema = zod_1.z.object({
|
|
38
42
|
id: zod_1.z.string().optional(),
|
|
@@ -46,12 +50,14 @@ exports.canonicalTranscriptMessageSchema = zod_1.z.object({
|
|
|
46
50
|
cost: usageNormalization_1.normalizedUsageCostSchema.optional(),
|
|
47
51
|
tools: zod_1.z.array(exports.canonicalToolCallSchema),
|
|
48
52
|
commands: zod_1.z.array(zod_1.z.string()),
|
|
49
|
-
source:
|
|
53
|
+
source: exports.transcriptSourceProvenanceSchema,
|
|
50
54
|
});
|
|
51
55
|
exports.canonicalSessionTranscriptSchema = zod_1.z.object({
|
|
52
56
|
provider: zod_1.z.string().optional(),
|
|
53
57
|
sessionId: zod_1.z.string().optional(),
|
|
54
58
|
sourcePath: zod_1.z.string().optional(),
|
|
59
|
+
cwd: zod_1.z.string().optional(),
|
|
60
|
+
gitBranch: zod_1.z.string().optional(),
|
|
55
61
|
startedAt: zod_1.z.string().optional(),
|
|
56
62
|
endedAt: zod_1.z.string().optional(),
|
|
57
63
|
models: zod_1.z.array(zod_1.z.string()),
|
package/dist/transcript.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ export interface TranscriptSourceProvenance {
|
|
|
7
7
|
sessionId?: string;
|
|
8
8
|
sourcePath?: string;
|
|
9
9
|
source?: string;
|
|
10
|
+
entrypoint?: string;
|
|
11
|
+
isMeta?: boolean;
|
|
12
|
+
isSidechain?: boolean;
|
|
13
|
+
originalRole?: string;
|
|
10
14
|
eventIndex: number;
|
|
11
15
|
eventType: SessionEvent['type'];
|
|
12
16
|
eventId?: string;
|
|
@@ -61,6 +65,8 @@ export interface CanonicalSessionTranscript {
|
|
|
61
65
|
provider?: ProviderId | string;
|
|
62
66
|
sessionId?: string;
|
|
63
67
|
sourcePath?: string;
|
|
68
|
+
cwd?: string;
|
|
69
|
+
gitBranch?: string;
|
|
64
70
|
startedAt?: string;
|
|
65
71
|
endedAt?: string;
|
|
66
72
|
models: string[];
|