@kodax-ai/kodax 0.7.41 → 0.7.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +119 -3
  2. package/README.md +214 -286
  3. package/README_CN.md +173 -277
  4. package/dist/chunks/chunk-7G5PSL6C.js +830 -0
  5. package/dist/chunks/{chunk-6OB4AJOM.js → chunk-IYSK7LUK.js} +1 -1
  6. package/dist/chunks/chunk-K75O2CAE.js +31 -0
  7. package/dist/chunks/chunk-UG4262JI.js +502 -0
  8. package/dist/chunks/chunk-VHKAJDQD.js +425 -0
  9. package/dist/chunks/chunk-YMRZBS4G.js +2 -0
  10. package/dist/chunks/{compaction-config-LT5PEXPT.js → compaction-config-3E57ABCT.js} +1 -1
  11. package/dist/chunks/{construction-bootstrap-HBCWJFHC.js → construction-bootstrap-JR63KI5N.js} +4 -4
  12. package/dist/chunks/dist-KWHUKXEL.js +2 -0
  13. package/dist/chunks/dist-XANXEVTU.js +2 -0
  14. package/dist/chunks/utils-HQ2QCKJA.js +2 -0
  15. package/dist/index.d.ts +15 -10
  16. package/dist/index.js +5 -5
  17. package/dist/kodax_cli.js +1084 -1054
  18. package/dist/sdk-agent.d.ts +853 -135
  19. package/dist/sdk-agent.js +1 -1
  20. package/dist/sdk-coding.d.ts +932 -981
  21. package/dist/sdk-coding.js +1 -1
  22. package/dist/sdk-llm.d.ts +8 -5
  23. package/dist/sdk-llm.js +1 -1
  24. package/dist/sdk-mcp.d.ts +17 -0
  25. package/dist/sdk-mcp.js +2 -0
  26. package/dist/sdk-repl.d.ts +343 -10
  27. package/dist/sdk-repl.js +2 -1
  28. package/dist/sdk-session.d.ts +176 -0
  29. package/dist/sdk-session.js +2 -0
  30. package/dist/sdk-skills.d.ts +72 -4
  31. package/dist/sdk-skills.js +1 -1
  32. package/dist/types-chunks/{cost-tracker.d-C4dMlQuV.d.ts → base.d-FUJahC0i.d.ts} +22 -112
  33. package/dist/types-chunks/{bash-prefix-extractor.d-B2iliwdi.d.ts → bash-prefix-extractor.d-DMrGImMl.d.ts} +266 -228
  34. package/dist/types-chunks/capability.d-3C62G8Eq.d.ts +39 -0
  35. package/dist/types-chunks/config.d-BfJUXxC0.d.ts +41 -0
  36. package/dist/types-chunks/cost-tracker.d-wRtyEW9d.d.ts +110 -0
  37. package/dist/types-chunks/{history-cleanup.d-q1vAvCss.d.ts → file-tracker.d-zaLZeNBK.d.ts} +532 -15
  38. package/dist/types-chunks/manager.d-87belpiS.d.ts +370 -0
  39. package/dist/types-chunks/{resolver.d-BwD6TKz7.d.ts → resolver.d-CA68_NeH.d.ts} +150 -5
  40. package/dist/types-chunks/storage.d-DPAEX7zS.d.ts +115 -0
  41. package/dist/types-chunks/{capability.d-BxNgd1-c.d.ts → types.d-B1uGoVTE.d.ts} +72 -40
  42. package/dist/types-chunks/{instance-discovery.d-DZhp77vb.d.ts → types.d-CKJtjo-6.d.ts} +168 -258
  43. package/dist/types-chunks/types.d-mM8vqvhT.d.ts +254 -0
  44. package/dist/types-chunks/{storage.d-Bv9T99Qu.d.ts → utils.d-DkLZD_wa.d.ts} +38 -112
  45. package/package.json +15 -6
  46. package/dist/chunks/chunk-5TFLMGER.js +0 -2
  47. package/dist/chunks/chunk-6QO6HWGU.js +0 -30
  48. package/dist/chunks/chunk-EQ5DGS2W.js +0 -14
  49. package/dist/chunks/chunk-HYWVRTFA.js +0 -1233
  50. package/dist/chunks/chunk-SX2IS5JP.js +0 -16
  51. package/dist/chunks/chunk-ZPJPNLBK.js +0 -462
  52. package/dist/chunks/dist-M57GIWR4.js +0 -2
  53. package/dist/chunks/dist-V3BS2NKB.js +0 -2
  54. package/dist/chunks/utils-FAFUQJ2A.js +0 -2
@@ -0,0 +1,176 @@
1
+ import { S as SessionData, F as FileSessionStorage } from './types-chunks/storage.d-DPAEX7zS.js';
2
+ import './types-chunks/types.d-mM8vqvhT.js';
3
+ import './types-chunks/types.d-B1uGoVTE.js';
4
+
5
+ /**
6
+ * FEATURE_173 Part B (v0.7.42) — Session Management Public SDK.
7
+ *
8
+ * Thin facades over FileSessionStorage + discoverInstances. All methods
9
+ * NEVER throw — missing sessions return null, blocked operations return
10
+ * an error envelope, missing directories return empty arrays / no-op
11
+ * watchers.
12
+ *
13
+ * The `@kodax-ai/kodax/session` SDK subpath re-exports this module.
14
+ */
15
+
16
+ interface SessionSummary {
17
+ readonly id: string;
18
+ readonly title: string;
19
+ readonly msgCount: number;
20
+ readonly createdAt?: string;
21
+ readonly runtimeInfo?: {
22
+ workspaceRoot?: string;
23
+ gitRoot?: string;
24
+ };
25
+ }
26
+ interface ListSessionsOptions {
27
+ /**
28
+ * Alias for gitRoot; backwards-compat with KodaX Space terminology.
29
+ * When provided, list() is scoped to sessions from this project root.
30
+ */
31
+ readonly projectRoot?: string;
32
+ /**
33
+ * Which session scopes to include.
34
+ * - 'user' (default): only user-initiated sessions.
35
+ * - 'managed-task-worker': only managed-task worker sessions.
36
+ * - 'all': no scope filter.
37
+ */
38
+ readonly scope?: 'user' | 'managed-task-worker' | 'all';
39
+ /**
40
+ * Whether to include archived sessions (filename starts with `archived-`).
41
+ * Default false — no archived sessions exist today; reserved for future use.
42
+ */
43
+ readonly includeArchived?: boolean;
44
+ /** Maximum number of sessions to return. Default 50. */
45
+ readonly limit?: number;
46
+ /**
47
+ * ISO date string — return only sessions whose createdAt is before this
48
+ * timestamp. Applied after list + scope filtering.
49
+ */
50
+ readonly before?: string;
51
+ }
52
+ type WatchSessionsCallback = (event: {
53
+ kind: 'change' | 'add' | 'remove';
54
+ sessionId: string;
55
+ }) => void;
56
+ interface SessionManager {
57
+ listSessions: typeof listSessions;
58
+ loadSession: typeof loadSession;
59
+ forkSession: typeof forkSession;
60
+ rewindSession: typeof rewindSession;
61
+ setActiveEntry: typeof setActiveEntry;
62
+ deleteSession: typeof deleteSession;
63
+ listRunningSessions: typeof listRunningSessions;
64
+ watchSessions: typeof watchSessions;
65
+ /**
66
+ * v0.7.43 — the raw write-side storage instance. SDK embedders pass
67
+ * this into `runKodaX({ session: { id, scope, storage } })` so the
68
+ * SA / AMA loops write per-turn JSONL snapshots to disk. Without an
69
+ * injected storage, `saveSessionSnapshot` is a silent no-op and the
70
+ * sessions directory stays empty regardless of `session.id`.
71
+ *
72
+ * See {@link FileSessionStorage} for the concrete implementation and
73
+ * `docs/SDK_EMBEDDER_GUIDE.md` §6 for the end-to-end recipe.
74
+ */
75
+ storage: FileSessionStorage;
76
+ }
77
+ /**
78
+ * List sessions, optionally filtered by scope, limit, and date.
79
+ * NEVER throws. Returns [] when the sessions directory is empty or missing.
80
+ */
81
+ declare function listSessions(opts?: ListSessionsOptions): Promise<SessionSummary[]>;
82
+ /**
83
+ * Load full session data by ID.
84
+ * Returns null for a missing session. NEVER throws.
85
+ */
86
+ declare function loadSession(id: string): Promise<SessionData | null>;
87
+ /**
88
+ * Fork a session at an optional selector.
89
+ * Returns null for a missing session. NEVER throws.
90
+ */
91
+ declare function forkSession(id: string, opts?: {
92
+ selector?: string;
93
+ sessionId?: string;
94
+ title?: string;
95
+ }): Promise<{
96
+ sessionId: string;
97
+ data: SessionData;
98
+ } | null>;
99
+ /**
100
+ * Rewind a session to a previous user entry.
101
+ * Returns null for a missing session. NEVER throws.
102
+ */
103
+ declare function rewindSession(id: string, opts?: {
104
+ selector?: string;
105
+ }): Promise<SessionData | null>;
106
+ /**
107
+ * Set the active lineage entry by selector.
108
+ * Returns null for a missing session. NEVER throws.
109
+ */
110
+ declare function setActiveEntry(id: string, selector: string): Promise<SessionData | null>;
111
+ interface RunningSessionInfo {
112
+ readonly pid: number;
113
+ readonly startedAt: number;
114
+ readonly cwd: string;
115
+ /**
116
+ * v0.7.43 — populated from `PersistedSessionState.sessionId`, published
117
+ * by the REPL after `createInteractiveContext`. Remains `undefined` for
118
+ * a brief window during a peer's bootstrap (before the first sessionId
119
+ * is generated) and for peers running pre-v0.7.43 binaries; consumers
120
+ * MUST handle `undefined`.
121
+ */
122
+ readonly sessionId: string | undefined;
123
+ }
124
+ /**
125
+ * Returns live KodaX sibling instances (excluding this process).
126
+ * Uses discoverInstances() from @kodax-ai/agent (FEATURE_125 Team Mode).
127
+ * NEVER throws. Returns [] when no instances directory exists.
128
+ */
129
+ declare function listRunningSessions(): Promise<RunningSessionInfo[]>;
130
+ type DeleteSessionResult = {
131
+ ok: true;
132
+ } | {
133
+ error: {
134
+ code: 'session_running';
135
+ runningProcess: {
136
+ pid: number;
137
+ startedAt: number;
138
+ };
139
+ };
140
+ };
141
+ /**
142
+ * Delete a session by ID.
143
+ * Returns { ok: true } on success (including when the session doesn't exist).
144
+ * Returns an error envelope when the session is currently running.
145
+ * NEVER throws.
146
+ */
147
+ declare function deleteSession(id: string): Promise<DeleteSessionResult>;
148
+ /**
149
+ * Watch the sessions directory for changes.
150
+ * Returns { close() } that stops the watcher / poll interval.
151
+ *
152
+ * Platform branches:
153
+ * - POSIX: fs.watch() with 100ms debounce.
154
+ * - Windows: readdir poll every 1000ms, diffed against a snapshot.
155
+ *
156
+ * NEVER throws — if the directory doesn't exist the watcher is a no-op
157
+ * until the directory is created.
158
+ */
159
+ declare function watchSessions(cb: WatchSessionsCallback): {
160
+ close: () => void;
161
+ };
162
+ /**
163
+ * Factory that returns an object with all session management methods bound.
164
+ *
165
+ * v0.7.43 (FEATURE_173 Part B follow-up) — the `sessionsDir` override is
166
+ * now honored. When provided, all read/write/watch operations go through
167
+ * that directory instead of the module-load-frozen `KODAX_SESSIONS_DIR`.
168
+ * `listRunningSessions` still consults the agent-config-home instances
169
+ * directory (sibling-process awareness is not scoped per sessions dir).
170
+ */
171
+ declare function createSessionManager(opts?: {
172
+ sessionsDir?: string;
173
+ }): SessionManager;
174
+
175
+ export { createSessionManager, deleteSession, forkSession, listRunningSessions, listSessions, loadSession, rewindSession, setActiveEntry, watchSessions };
176
+ export type { DeleteSessionResult, ListSessionsOptions, RunningSessionInfo, SessionManager, SessionSummary, WatchSessionsCallback };
@@ -0,0 +1,2 @@
1
+ // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
+ import{bc as s,cc as e,dc as n,ec as i,fc as o,gc as t,hc as S,ic as a,jc as r}from"./chunks/chunk-UG4262JI.js";import"./chunks/chunk-YMRZBS4G.js";import"./chunks/chunk-IYSK7LUK.js";import"./chunks/chunk-EVIDQWMF.js";import"./chunks/chunk-7G5PSL6C.js";import"./chunks/chunk-K75O2CAE.js";import"./chunks/chunk-VHKAJDQD.js";import"./chunks/chunk-V4WSBIXB.js";export{r as createSessionManager,S as deleteSession,n as forkSession,t as listRunningSessions,s as listSessions,e as loadSession,i as rewindSession,o as setActiveEntry,a as watchSessions};
@@ -116,12 +116,68 @@ interface ISkillRegistry {
116
116
  /** Number of discovered skills */
117
117
  readonly size: number;
118
118
  }
119
+ /**
120
+ * v0.7.42 — SDK-embedder hook for `!`cmd`` dynamic context resolution.
121
+ *
122
+ * Receives the literal command string and the working directory the resolver
123
+ * would have used. Must return the command's text output (which the resolver
124
+ * splices into the skill markdown in place of the `!`cmd`` token), or throw
125
+ * to deny.
126
+ *
127
+ * **Trust boundary**: when the KodaX SDK is embedded inside a host app
128
+ * (e.g. KodaX Space, IDE extensions), the host typically mediates shell
129
+ * execution through a permission broker so the end user can approve / deny
130
+ * each command. Without this hook, `VariableResolver` directly `execSync`s
131
+ * commands using its own built-in whitelist — bypassing the host's broker
132
+ * and producing OS side-effects the user never saw.
133
+ *
134
+ * Embedders should route here to:
135
+ * - prompt the user via their own UI,
136
+ * - log execution to their audit trail,
137
+ * - apply policy (e.g. block network commands),
138
+ * - or refuse outright (throw).
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * const context: SkillContext = {
143
+ * workingDirectory: '/repo',
144
+ * executeDynamicContext: async (cmd, cwd) => {
145
+ * const approved = await brokerAskUser({ kind: 'skill-cmd', command: cmd, cwd });
146
+ * if (!approved) throw new Error('user denied');
147
+ * return await brokerExecute(cmd, cwd);
148
+ * },
149
+ * };
150
+ * ```
151
+ */
152
+ type SkillDynamicContextExecutor = (command: string, cwd: string) => Promise<string>;
119
153
  interface SkillContext {
120
154
  workingDirectory: string;
121
155
  projectRoot?: string;
122
- sessionId: string;
156
+ /**
157
+ * Optional. Used to substitute `${CLAUDE_SESSION_ID}` / `${KODAX_SESSION_ID}`
158
+ * template variables in skill markdown. Tool-invocation callers (e.g. the
159
+ * `skill` tool) may not have a session bound — in that case the resolver
160
+ * falls back to an empty replacement so the substitution doesn't leak the
161
+ * literal `${...}` to the LLM.
162
+ */
163
+ sessionId?: string;
123
164
  environment?: Record<string, string>;
124
165
  messages?: unknown[];
166
+ /**
167
+ * v0.7.42 — SDK-embedder hook for `!`cmd`` dynamic-context resolution.
168
+ * See {@link SkillDynamicContextExecutor} for the trust-boundary rationale.
169
+ * When present, completely replaces the built-in `execSync`-based path
170
+ * (whitelist + 5s timeout). When absent, the legacy whitelist path runs.
171
+ */
172
+ executeDynamicContext?: SkillDynamicContextExecutor;
173
+ /**
174
+ * v0.7.42 — hard-disable `!`cmd`` resolution.
175
+ * When `true`, encountering a `!`cmd`` token throws
176
+ * `[Dynamic context disabled by host]` regardless of any hook. Useful for
177
+ * embedders that want a single-flag kill switch without writing a hook.
178
+ * `executeDynamicContext` is ignored when this is `true`.
179
+ */
180
+ disableDynamicContext?: boolean;
125
181
  }
126
182
  interface SkillResult {
127
183
  success: boolean;
@@ -273,11 +329,23 @@ declare class VariableResolver implements IVariableResolver {
273
329
  */
274
330
  private resolveEnvVars;
275
331
  /**
276
- * Replace !`command` with command output (dynamic context)
332
+ * Replace !`command` with command output (dynamic context).
333
+ *
334
+ * Three-tier dispatch (v0.7.42):
335
+ * 1. `context.disableDynamicContext === true` → throw immediately,
336
+ * surfaced to the LLM as `[Error: …]`. Host-level kill switch.
337
+ * 2. `context.executeDynamicContext` provided → route there. Embedder
338
+ * mediates shell execution (broker, audit, deny).
339
+ * 3. else → legacy built-in path (`isSafeDynamicContextCommand`
340
+ * whitelist + `execSync` with 5s timeout).
341
+ *
342
+ * The resolver inlines an `[Error: …]` placeholder for any thrown
343
+ * exception so a single bad token doesn't poison the whole skill load.
277
344
  */
278
345
  private resolveDynamicContext;
279
346
  /**
280
- * Execute a dynamic context command
347
+ * Execute a dynamic context command via the appropriate dispatch tier.
348
+ * See `resolveDynamicContext` JSDoc for the 3-tier ordering rationale.
281
349
  */
282
350
  private executeDynamicCommand;
283
351
  }
@@ -489,4 +557,4 @@ declare function expandSkillForLLM(skill: Skill, args: string, context: SkillCon
489
557
  declare function formatSkillActivationMessage(skillName: string, args: string): string;
490
558
 
491
559
  export { SkillExecutor, SkillRegistry, VariableResolver, clearPluginSkillPaths, createExecutor, createResolver, discoverSkills, discoverSkillsWithMonorepo, executeSkill, expandSkillForLLM, formatSkillActivationMessage, getDefaultSkillPaths, getNestedSkillPaths, getSkillPathsFlat, getSkillRegistry, initializeSkillRegistry, listPluginSkillPaths, loadFullSkill, loadSkillFileContent, loadSkillMetadata, parseArguments, parseSkillMarkdown, registerPluginSkillPath, resetSkillRegistry, resolveSkillContent, unregisterPluginSkillPath };
492
- export type { DiscoveryResult, ExecutionMode, ExecutionOptions, ISkillRegistry, IVariableResolver, Skill, SkillArtifact, SkillContext, SkillExpansionResult, SkillFile, SkillFrontmatter, SkillHook, SkillHooks, SkillMetadata, SkillPathsConfig, SkillResult, SkillSource };
560
+ export type { DiscoveryResult, ExecutionMode, ExecutionOptions, ISkillRegistry, IVariableResolver, Skill, SkillArtifact, SkillContext, SkillDynamicContextExecutor, SkillExpansionResult, SkillFile, SkillFrontmatter, SkillHook, SkillHooks, SkillMetadata, SkillPathsConfig, SkillResult, SkillSource };
@@ -1,2 +1,2 @@
1
1
  // @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
2
- import{A as w,B as y,C as z,a as o,b as r,c as e,d as f,e as m,f as p,j as t,k as x,l as a,m as b,n as c,o as d,p as g,q as h,r as i,s as j,t as k,u as l,v as n,w as q,x as s,y as u,z as v}from"./chunks/chunk-EQ5DGS2W.js";import"./chunks/chunk-V4WSBIXB.js";export{u as SkillExecutor,l as SkillRegistry,i as VariableResolver,f as clearPluginSkillPaths,v as createExecutor,j as createResolver,c as discoverSkills,g as discoverSkillsWithMonorepo,w as executeSkill,y as expandSkillForLLM,z as formatSkillActivationMessage,m as getDefaultSkillPaths,d as getNestedSkillPaths,p as getSkillPathsFlat,n as getSkillRegistry,q as initializeSkillRegistry,e as listPluginSkillPaths,a as loadFullSkill,b as loadSkillFileContent,x as loadSkillMetadata,h as parseArguments,t as parseSkillMarkdown,o as registerPluginSkillPath,s as resetSkillRegistry,k as resolveSkillContent,r as unregisterPluginSkillPath};
2
+ import{Ab as o,Eb as k,Fb as r,Gb as S,Hb as s,Ib as n,Jb as g,Kb as u,Lb as c,Mb as x,Nb as d,Ob as P,Pb as R,Qb as h,Rb as p,Sb as v,Tb as y,Ub as M,Vb as f,Wb as m,Xb as E,vb as l,wb as e,xb as i,yb as t,zb as a}from"./chunks/chunk-VHKAJDQD.js";import"./chunks/chunk-V4WSBIXB.js";export{y as SkillExecutor,R as SkillRegistry,x as VariableResolver,t as clearPluginSkillPaths,M as createExecutor,d as createResolver,n as discoverSkills,u as discoverSkillsWithMonorepo,f as executeSkill,m as expandSkillForLLM,E as formatSkillActivationMessage,a as getDefaultSkillPaths,g as getNestedSkillPaths,o as getSkillPathsFlat,h as getSkillRegistry,p as initializeSkillRegistry,i as listPluginSkillPaths,S as loadFullSkill,s as loadSkillFileContent,r as loadSkillMetadata,c as parseArguments,k as parseSkillMarkdown,l as registerPluginSkillPath,v as resetSkillRegistry,P as resolveSkillContent,e as unregisterPluginSkillPath};
@@ -1,4 +1,4 @@
1
- import { t as KodaXProviderConfig, o as KodaXMessage, _ as KodaXToolDefinition, I as KodaXReasoningRequest, B as KodaXProviderStreamOptions, N as KodaXStreamResult, p as KodaXModelDescriptor, s as KodaXProviderCapabilityProfile, F as KodaXReasoningCapability, H as KodaXReasoningOverride } from './capability.d-BxNgd1-c.js';
1
+ import { r as KodaXProviderConfig, m as KodaXMessage, X as KodaXToolDefinition, F as KodaXReasoningRequest, z as KodaXProviderStreamOptions, J as KodaXStreamResult, n as KodaXModelDescriptor, q as KodaXProviderCapabilityProfile, C as KodaXReasoningCapability, E as KodaXReasoningOverride } from './types.d-B1uGoVTE.js';
2
2
 
3
3
  /**
4
4
  * Retry-After header parsing — FEATURE_130 (v0.7.36).
@@ -145,8 +145,26 @@ declare abstract class KodaXBaseProvider {
145
145
  * Returns undefined when no cap is configured. Consumed by the
146
146
  * resilience layer to abort a doomed stream before the server-side
147
147
  * kill window fires; routed through `non_streaming_fallback`.
148
+ *
149
+ * Cascade (highest to lowest):
150
+ * 1. Active model descriptor's `streamMaxDurationMs`
151
+ * 2. Provider config default
152
+ * 3. undefined (watchdog disabled)
148
153
  */
149
- getStreamMaxDurationMs(): number | undefined;
154
+ getStreamMaxDurationMs(model?: string): number | undefined;
155
+ /**
156
+ * Resolves whether OpenAI-compat `reasoning_content` should echo back
157
+ * on replayed assistant messages for the given model. Same cascade as
158
+ * `getStreamMaxDurationMs`. Defaults to false when neither layer sets it.
159
+ */
160
+ getEffectiveReplayReasoningContent(model?: string): boolean;
161
+ /**
162
+ * Resolves whether Anthropic-style thinking signatures must verify
163
+ * strictly (Anthropic proper only). Same cascade as
164
+ * `getStreamMaxDurationMs`. Defaults to false (lenient) when neither
165
+ * layer sets it — matches third-party Anthropic-compat behavior.
166
+ */
167
+ getEffectiveStrictThinkingSignature(model?: string): boolean;
150
168
  abstract stream(messages: KodaXMessage[], tools: KodaXToolDefinition[], system: string, reasoning?: boolean | KodaXReasoningRequest, streamOptions?: KodaXProviderStreamOptions, signal?: AbortSignal): Promise<KodaXStreamResult>;
151
169
  supportsNonStreamingFallback(): boolean;
152
170
  complete(_messages: KodaXMessage[], _tools: KodaXToolDefinition[], _system: string, _reasoning?: boolean | KodaXReasoningRequest, _streamOptions?: KodaXProviderStreamOptions, _signal?: AbortSignal): Promise<KodaXStreamResult>;
@@ -230,113 +248,5 @@ declare abstract class KodaXBaseProvider {
230
248
  protected withRateLimit<T>(fn: () => Promise<T>, signal?: AbortSignal, retries?: number, onRateLimit?: (attempt: number, maxRetries: number, delayMs: number) => void, onRetryAfter?: KodaXOnRetryAfterCallback): Promise<T>;
231
249
  }
232
250
 
233
- /**
234
- * KodaX Cost Rates - Multi-Provider pricing table
235
- *
236
- * 成本费率表 - 所有 Provider 的计费标准
237
- * 支持 11 个内置 Provider 的成本追踪,用户可以覆盖默认费率
238
- */
239
- interface CostRate {
240
- readonly inputPer1M: number;
241
- readonly outputPer1M: number;
242
- readonly cachePer1M?: number;
243
- }
244
- declare const DEFAULT_COST_RATES: Readonly<Record<string, Readonly<Record<string, CostRate>>>>;
245
- declare function getCostRate(provider: string, model: string, userOverrides?: Readonly<Record<string, Readonly<Record<string, CostRate>>>>): CostRate | undefined;
246
- declare function calculateCost(rate: CostRate, inputTokens: number, outputTokens: number, cacheTokens?: number): number;
247
-
248
- /**
249
- * KodaX Cost Tracker - Immutable session cost tracking
250
- *
251
- * 成本追踪器 - 不可变的会话成本追踪
252
- * 使用 Immutable 模式,每次操作都返回新对象而不修改原有对象
253
- */
254
-
255
- interface TokenUsageRecord {
256
- readonly timestamp: number;
257
- readonly provider: string;
258
- readonly model: string;
259
- readonly inputTokens: number;
260
- readonly outputTokens: number;
261
- readonly cacheReadTokens: number;
262
- readonly cacheWriteTokens: number;
263
- readonly cost: number;
264
- readonly role?: string;
265
- }
266
- interface ProviderCostSummary {
267
- readonly cost: number;
268
- readonly calls: number;
269
- readonly inputTokens: number;
270
- readonly outputTokens: number;
271
- }
272
- /**
273
- * FEATURE_130 (v0.7.36) — per-retry record. Captures the wait the
274
- * provider asked us to take so `/cost` can report "X retries, Ys total
275
- * wait" alongside the token cost. Lives in the same tracker as token
276
- * records to keep one source of truth for the session.
277
- */
278
- interface RetryRecord {
279
- readonly timestamp: number;
280
- readonly provider: string;
281
- readonly waitMs: number;
282
- readonly reason: 'rate-limit' | 'overloaded';
283
- readonly source: 'retry-after-seconds' | 'retry-after-date' | 'retry-after-ms' | 'exponential-backoff';
284
- }
285
- interface SessionCostSummary {
286
- readonly totalCost: number;
287
- readonly totalInputTokens: number;
288
- readonly totalOutputTokens: number;
289
- readonly totalCacheTokens: number;
290
- /** FEATURE_116 (v0.7.37): cumulative cache-read input tokens across the
291
- * session. Splits `totalCacheTokens` into the read half so the hit rate
292
- * (`cacheHitRate = totalCacheReadTokens / totalCacheTokens`) is
293
- * derivable for `/cost` reporting. */
294
- readonly totalCacheReadTokens: number;
295
- /** FEATURE_116 (v0.7.37): cumulative cache-write (creation) input tokens. */
296
- readonly totalCacheWriteTokens: number;
297
- /** FEATURE_116 (v0.7.37): cache-read share of all cache tokens this
298
- * session, in [0, 1]. Computed as `totalCacheReadTokens /
299
- * (totalCacheReadTokens + totalCacheWriteTokens)`. Returns 0 when no
300
- * cache activity has been recorded — a session with zero cache
301
- * activity is not "0% hit rate", just untracked. */
302
- readonly cacheHitRate: number;
303
- readonly callCount: number;
304
- /** FEATURE_130: total retries triggered across the session. */
305
- readonly retryCount: number;
306
- /** FEATURE_130: cumulative milliseconds spent in retry-after sleeps. */
307
- readonly retryWaitMs: number;
308
- readonly byProvider: Readonly<Record<string, ProviderCostSummary>>;
309
- readonly byRole: Readonly<Record<string, ProviderCostSummary>>;
310
- }
311
- interface CostTracker {
312
- readonly records: readonly TokenUsageRecord[];
313
- /** FEATURE_130 (v0.7.36): retry-wait records, append-only and immutable. */
314
- readonly retries: readonly RetryRecord[];
315
- }
316
- declare function createCostTracker(): CostTracker;
317
- /**
318
- * FEATURE_130 (v0.7.36): record a retry-after wait. The InkREPL spinner
319
- * (or any other consumer of `KodaXEvents.onRetryAfter`) calls this so
320
- * `/cost` can surface accurate session-wide retry telemetry.
321
- */
322
- declare function recordRetry(tracker: CostTracker, entry: {
323
- readonly provider: string;
324
- readonly waitMs: number;
325
- readonly reason: 'rate-limit' | 'overloaded';
326
- readonly source: 'retry-after-seconds' | 'retry-after-date' | 'retry-after-ms' | 'exponential-backoff';
327
- }): CostTracker;
328
- declare function recordUsage(tracker: CostTracker, entry: {
329
- readonly provider: string;
330
- readonly model: string;
331
- readonly inputTokens: number;
332
- readonly outputTokens: number;
333
- readonly cacheReadTokens?: number;
334
- readonly cacheWriteTokens?: number;
335
- readonly role?: string;
336
- }, userCostOverrides?: Readonly<Record<string, Readonly<Record<string, CostRate>>>>): CostTracker;
337
- declare function getSummary(tracker: CostTracker): SessionCostSummary;
338
- declare function formatCost(usd: number): string;
339
- declare function formatCostReport(summary: SessionCostSummary): string;
340
-
341
- export { DEFAULT_COST_RATES as D, KodaXBaseProvider as K, calculateCost as g, createCostTracker as h, extractHeadersFromError as i, formatCost as j, formatCostReport as k, getCostRate as l, getSummary as m, recordUsage as n, parseRetryAfter as p, recordRetry as r };
342
- export type { CostRate as C, ParseRetryAfterOptions as P, RetryAfterResult as R, SessionCostSummary as S, TokenUsageRecord as T, CostTracker as a, KodaXOnRetryAfterCallback as b, KodaXRetryAfterEvent as c, ProviderCostSummary as d, RetryAfterSource as e, RetryRecord as f };
251
+ export { KodaXBaseProvider as K, extractHeadersFromError as e, parseRetryAfter as p };
252
+ export type { ParseRetryAfterOptions as P, RetryAfterResult as R, KodaXOnRetryAfterCallback as a, KodaXRetryAfterEvent as b, RetryAfterSource as c };