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.
@@ -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): ObservedSessionCollectionSource<ObservedAgentSessionV1>;
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
- message: {
209
- role: 'system',
210
- id: `${payload.id}:base-instructions`,
211
- sourceLabel: 'base instructions',
212
- content: [{ type: 'text', text }],
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
  }
@@ -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>;
@@ -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
- (0, modelInfo_1._setPricingOverrides)(cached.overrides);
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
- (0, modelInfo_1._setPricingOverrides)(overrides);
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
- (0, modelInfo_1._setPricingOverrides)(cached.overrides);
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 table.
119
- return { source: 'offline', entries: 0, fetchedAt: new Date(now).toISOString() };
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;
@@ -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) => {
@@ -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';
@@ -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.accountEntrySchema = 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.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 = 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 extractSessionEvents(message, depth + 1);
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
- const transcriptSourceSchema = zod_1.z.object({
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: transcriptSourceSchema,
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: transcriptSourceSchema,
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()),
@@ -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[];