@combycode/llm-sdk 1.0.0-rc.0

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 (228) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +103 -0
  4. package/dist/agent/approval-types.d.ts +49 -0
  5. package/dist/agent/context-registry/layers.d.ts +39 -0
  6. package/dist/agent/context-registry/registry-internal.d.ts +14 -0
  7. package/dist/agent/context-registry/registry.d.ts +104 -0
  8. package/dist/agent/context-registry/types.d.ts +110 -0
  9. package/dist/agent/guardrail-types.d.ts +58 -0
  10. package/dist/agent/history-types.d.ts +40 -0
  11. package/dist/agent/history.d.ts +111 -0
  12. package/dist/agent/loop-config.d.ts +67 -0
  13. package/dist/agent/loop-internals.d.ts +46 -0
  14. package/dist/agent/loop-step-state.d.ts +20 -0
  15. package/dist/agent/loop.d.ts +133 -0
  16. package/dist/agent/tool-key.d.ts +3 -0
  17. package/dist/agent/types.d.ts +138 -0
  18. package/dist/bus/agent-bus.d.ts +99 -0
  19. package/dist/bus/async-context.browser.d.ts +13 -0
  20. package/dist/bus/async-context.d.ts +11 -0
  21. package/dist/bus/async-context.types.d.ts +14 -0
  22. package/dist/bus/hook-bus.d.ts +43 -0
  23. package/dist/bus/hook-map.d.ts +592 -0
  24. package/dist/helpers/agent.d.ts +32 -0
  25. package/dist/helpers/batch.d.ts +74 -0
  26. package/dist/helpers/calibration-store.d.ts +27 -0
  27. package/dist/helpers/calibration-types.d.ts +64 -0
  28. package/dist/helpers/chain.d.ts +30 -0
  29. package/dist/helpers/client-pool.d.ts +15 -0
  30. package/dist/helpers/client-resolver.d.ts +62 -0
  31. package/dist/helpers/collection.d.ts +19 -0
  32. package/dist/helpers/consolidate.d.ts +66 -0
  33. package/dist/helpers/content.d.ts +25 -0
  34. package/dist/helpers/conversation-export.d.ts +14 -0
  35. package/dist/helpers/conversation-zip.d.ts +28 -0
  36. package/dist/helpers/count-tokens.d.ts +26 -0
  37. package/dist/helpers/define-tool.d.ts +66 -0
  38. package/dist/helpers/delegate.d.ts +6 -0
  39. package/dist/helpers/embed.d.ts +24 -0
  40. package/dist/helpers/engine.d.ts +121 -0
  41. package/dist/helpers/estimate-types.d.ts +67 -0
  42. package/dist/helpers/estimate.d.ts +45 -0
  43. package/dist/helpers/estimator.d.ts +48 -0
  44. package/dist/helpers/handoff-types.d.ts +18 -0
  45. package/dist/helpers/handoff.d.ts +14 -0
  46. package/dist/helpers/llm.d.ts +24 -0
  47. package/dist/helpers/mcp.d.ts +82 -0
  48. package/dist/helpers/media.d.ts +58 -0
  49. package/dist/helpers/models.d.ts +36 -0
  50. package/dist/helpers/moderate-types.d.ts +73 -0
  51. package/dist/helpers/moderate.d.ts +13 -0
  52. package/dist/helpers/moderation-guardrail.d.ts +29 -0
  53. package/dist/helpers/observer.d.ts +36 -0
  54. package/dist/helpers/one-shot.d.ts +86 -0
  55. package/dist/helpers/parallel.d.ts +16 -0
  56. package/dist/helpers/realtime.d.ts +25 -0
  57. package/dist/helpers/route.d.ts +29 -0
  58. package/dist/helpers/select-model.d.ts +41 -0
  59. package/dist/helpers/server.d.ts +32 -0
  60. package/dist/helpers/transcribe.d.ts +36 -0
  61. package/dist/index.browser.js +38047 -0
  62. package/dist/index.d.ts +275 -0
  63. package/dist/index.js +37974 -0
  64. package/dist/llm/audio/voices.d.ts +7 -0
  65. package/dist/llm/client-config.d.ts +37 -0
  66. package/dist/llm/client-internal.d.ts +28 -0
  67. package/dist/llm/client.d.ts +68 -0
  68. package/dist/llm/providers/_shared/constants.d.ts +5 -0
  69. package/dist/llm/providers/_shared/response-utils.d.ts +8 -0
  70. package/dist/llm/providers/anthropic/batch.d.ts +19 -0
  71. package/dist/llm/providers/anthropic/constants.d.ts +13 -0
  72. package/dist/llm/providers/anthropic/files.d.ts +23 -0
  73. package/dist/llm/providers/anthropic/messages.d.ts +30 -0
  74. package/dist/llm/providers/google/batch.d.ts +20 -0
  75. package/dist/llm/providers/google/constants.d.ts +6 -0
  76. package/dist/llm/providers/google/embeddings.d.ts +15 -0
  77. package/dist/llm/providers/google/files.d.ts +22 -0
  78. package/dist/llm/providers/google/generate.d.ts +27 -0
  79. package/dist/llm/providers/google/interactions.d.ts +30 -0
  80. package/dist/llm/providers/google/media.d.ts +27 -0
  81. package/dist/llm/providers/google/realtime.d.ts +27 -0
  82. package/dist/llm/providers/openai/batch.d.ts +19 -0
  83. package/dist/llm/providers/openai/completions.d.ts +25 -0
  84. package/dist/llm/providers/openai/embeddings.d.ts +16 -0
  85. package/dist/llm/providers/openai/files.d.ts +23 -0
  86. package/dist/llm/providers/openai/media.d.ts +28 -0
  87. package/dist/llm/providers/openai/moderations.d.ts +19 -0
  88. package/dist/llm/providers/openai/realtime.d.ts +24 -0
  89. package/dist/llm/providers/openai/responses.d.ts +29 -0
  90. package/dist/llm/providers/openai/tiers.d.ts +13 -0
  91. package/dist/llm/providers/openai/transcription.d.ts +20 -0
  92. package/dist/llm/providers/openrouter/completions.d.ts +15 -0
  93. package/dist/llm/providers/openrouter/embeddings.d.ts +7 -0
  94. package/dist/llm/providers/openrouter/media.d.ts +25 -0
  95. package/dist/llm/providers/openrouter/responses.d.ts +17 -0
  96. package/dist/llm/providers/xai/batch.d.ts +19 -0
  97. package/dist/llm/providers/xai/completions.d.ts +24 -0
  98. package/dist/llm/providers/xai/files.d.ts +23 -0
  99. package/dist/llm/providers/xai/media.d.ts +27 -0
  100. package/dist/llm/providers/xai/responses.d.ts +20 -0
  101. package/dist/llm/realtime/session.d.ts +34 -0
  102. package/dist/llm/realtime/types.d.ts +66 -0
  103. package/dist/llm/server-state.d.ts +32 -0
  104. package/dist/llm/types/audio.d.ts +18 -0
  105. package/dist/llm/types/messages.d.ts +125 -0
  106. package/dist/llm/types/options.d.ts +51 -0
  107. package/dist/llm/types/provider.d.ts +39 -0
  108. package/dist/llm/types/request.d.ts +51 -0
  109. package/dist/llm/types/response.d.ts +36 -0
  110. package/dist/llm/types/schema-utils.d.ts +8 -0
  111. package/dist/llm/types/stream.d.ts +42 -0
  112. package/dist/llm/types/tiers.d.ts +11 -0
  113. package/dist/llm/types/tools.d.ts +20 -0
  114. package/dist/network/engine.d.ts +87 -0
  115. package/dist/network/errors.d.ts +14 -0
  116. package/dist/network/queue-state-config.d.ts +41 -0
  117. package/dist/network/queue-state.d.ts +45 -0
  118. package/dist/network/rate-limiter.d.ts +49 -0
  119. package/dist/network/realtime-connection.d.ts +40 -0
  120. package/dist/network/request-queue.d.ts +40 -0
  121. package/dist/network/semaphore.d.ts +12 -0
  122. package/dist/network/sse.d.ts +3 -0
  123. package/dist/network/types.d.ts +127 -0
  124. package/dist/plugins/batch/batcher.d.ts +45 -0
  125. package/dist/plugins/batch/strategy.d.ts +20 -0
  126. package/dist/plugins/batch/types.d.ts +54 -0
  127. package/dist/plugins/cache/cache.d.ts +50 -0
  128. package/dist/plugins/cache/file-store.d.ts +15 -0
  129. package/dist/plugins/cache/memory-store.d.ts +10 -0
  130. package/dist/plugins/cache/types.d.ts +28 -0
  131. package/dist/plugins/configuration/configuration.d.ts +71 -0
  132. package/dist/plugins/context-guard/facts.d.ts +14 -0
  133. package/dist/plugins/context-guard/guard.d.ts +27 -0
  134. package/dist/plugins/context-guard/strategies/layered.d.ts +24 -0
  135. package/dist/plugins/context-guard/strategies/truncate.d.ts +19 -0
  136. package/dist/plugins/context-guard/tools.d.ts +50 -0
  137. package/dist/plugins/context-guard/types.d.ts +110 -0
  138. package/dist/plugins/context-measurer/calibration/store.d.ts +19 -0
  139. package/dist/plugins/context-measurer/counter/count-api.d.ts +41 -0
  140. package/dist/plugins/context-measurer/counter/heuristic.d.ts +25 -0
  141. package/dist/plugins/context-measurer/counter/hybrid.d.ts +33 -0
  142. package/dist/plugins/context-measurer/counter/tiktoken.d.ts +13 -0
  143. package/dist/plugins/context-measurer/measurer.d.ts +49 -0
  144. package/dist/plugins/context-measurer/types.d.ts +40 -0
  145. package/dist/plugins/cost-collector/collector.d.ts +42 -0
  146. package/dist/plugins/cost-collector/cost-collector-internal.d.ts +58 -0
  147. package/dist/plugins/cost-collector/cost-collector-types.d.ts +42 -0
  148. package/dist/plugins/embeddings/types.d.ts +23 -0
  149. package/dist/plugins/files/attachment.d.ts +79 -0
  150. package/dist/plugins/files/provider-adapter.d.ts +37 -0
  151. package/dist/plugins/files/registry.d.ts +48 -0
  152. package/dist/plugins/files/strategy.d.ts +38 -0
  153. package/dist/plugins/internal-tools/backends/local.d.ts +12 -0
  154. package/dist/plugins/internal-tools/builtin/builtin.d.ts +21 -0
  155. package/dist/plugins/internal-tools/builtin/clarify.d.ts +12 -0
  156. package/dist/plugins/internal-tools/builtin/classify.d.ts +12 -0
  157. package/dist/plugins/internal-tools/builtin/score.d.ts +13 -0
  158. package/dist/plugins/internal-tools/builtin/structure.d.ts +11 -0
  159. package/dist/plugins/internal-tools/builtin/summarize.d.ts +19 -0
  160. package/dist/plugins/internal-tools/id.d.ts +12 -0
  161. package/dist/plugins/internal-tools/registry.d.ts +24 -0
  162. package/dist/plugins/internal-tools/runner/define.d.ts +7 -0
  163. package/dist/plugins/internal-tools/runner/json-enforcement.d.ts +3 -0
  164. package/dist/plugins/internal-tools/runner/runner.d.ts +47 -0
  165. package/dist/plugins/internal-tools/runner/template.d.ts +10 -0
  166. package/dist/plugins/internal-tools/runner/types.d.ts +57 -0
  167. package/dist/plugins/internal-tools/runner/variants.d.ts +34 -0
  168. package/dist/plugins/internal-tools/types.d.ts +80 -0
  169. package/dist/plugins/logger/console-sink.d.ts +26 -0
  170. package/dist/plugins/logger/logger.d.ts +38 -0
  171. package/dist/plugins/logger/types.d.ts +25 -0
  172. package/dist/plugins/mcp/base-transport.d.ts +58 -0
  173. package/dist/plugins/mcp/client.d.ts +92 -0
  174. package/dist/plugins/mcp/jsonrpc.d.ts +20 -0
  175. package/dist/plugins/mcp/oauth.d.ts +122 -0
  176. package/dist/plugins/mcp/sampling.d.ts +17 -0
  177. package/dist/plugins/mcp/tools.d.ts +20 -0
  178. package/dist/plugins/mcp/transport-http.d.ts +50 -0
  179. package/dist/plugins/mcp/transport-stdio.d.ts +23 -0
  180. package/dist/plugins/mcp/transport-ws.d.ts +32 -0
  181. package/dist/plugins/mcp/transport.d.ts +29 -0
  182. package/dist/plugins/mcp/types.d.ts +202 -0
  183. package/dist/plugins/mcp/url-guard.d.ts +70 -0
  184. package/dist/plugins/mcp/win-spawn.d.ts +20 -0
  185. package/dist/plugins/media/file-store.d.ts +24 -0
  186. package/dist/plugins/media/memory-store.d.ts +17 -0
  187. package/dist/plugins/media/output.d.ts +44 -0
  188. package/dist/plugins/media/source-image.d.ts +36 -0
  189. package/dist/plugins/media/types.d.ts +146 -0
  190. package/dist/plugins/model-catalog/catalog.d.ts +152 -0
  191. package/dist/plugins/permissions/glob.d.ts +6 -0
  192. package/dist/plugins/permissions/matchers.d.ts +7 -0
  193. package/dist/plugins/permissions/policy.d.ts +10 -0
  194. package/dist/plugins/permissions/types.d.ts +22 -0
  195. package/dist/plugins/persistence/file.d.ts +25 -0
  196. package/dist/plugins/persistence/memory.d.ts +23 -0
  197. package/dist/plugins/persistence/types.d.ts +21 -0
  198. package/dist/plugins/retrieval/chunker.d.ts +28 -0
  199. package/dist/plugins/retrieval/hosted-google.d.ts +60 -0
  200. package/dist/plugins/retrieval/hosted-openai.d.ts +45 -0
  201. package/dist/plugins/retrieval/hosted-xai.d.ts +57 -0
  202. package/dist/plugins/retrieval/index.d.ts +70 -0
  203. package/dist/plugins/retrieval/local.d.ts +50 -0
  204. package/dist/plugins/retrieval/types.d.ts +161 -0
  205. package/dist/plugins/retrieval/vector-store.d.ts +70 -0
  206. package/dist/plugins/scheduler/scheduler.d.ts +31 -0
  207. package/dist/plugins/telemetry/telemetry.d.ts +118 -0
  208. package/dist/plugins/tool-catalog/catalog.d.ts +31 -0
  209. package/dist/plugins/tool-catalog/errors.d.ts +22 -0
  210. package/dist/plugins/tool-catalog/types.d.ts +44 -0
  211. package/dist/runtime/runtime.d.ts +20 -0
  212. package/dist/server/auth.d.ts +25 -0
  213. package/dist/server/dispatch.d.ts +35 -0
  214. package/dist/server/loaders.d.ts +26 -0
  215. package/dist/server/oai-adapter.d.ts +30 -0
  216. package/dist/server/oai-types.d.ts +114 -0
  217. package/dist/server/response-store.d.ts +59 -0
  218. package/dist/server/router.d.ts +59 -0
  219. package/dist/server/server.d.ts +61 -0
  220. package/dist/types/request-context.d.ts +46 -0
  221. package/dist/util/async.d.ts +3 -0
  222. package/dist/util/base64.d.ts +8 -0
  223. package/dist/util/duration.d.ts +12 -0
  224. package/dist/util/http.d.ts +9 -0
  225. package/dist/util/image-mime.d.ts +8 -0
  226. package/dist/util/json-schema.d.ts +7 -0
  227. package/dist/util/wav.d.ts +20 -0
  228. package/package.json +95 -0
@@ -0,0 +1,54 @@
1
+ /** Batch types — strategy, provider adapter contract, pending job shape.
2
+ *
3
+ * All BatchProviderAdapter HTTP calls flow through an injected EngineFetch
4
+ * (NetworkEngine queue) — adapters do not hold their own fetch fn. The
5
+ * Batcher class threads `engine.fetch` into adapter methods on every call,
6
+ * so rate-limit, retry, and observability hooks apply uniformly. */
7
+ import type { EngineFetch } from '../../network/types';
8
+ export interface BatchStrategy {
9
+ collectionWindowMs: number;
10
+ minBatchSize: number;
11
+ maxBatchSize: number;
12
+ shouldBatch(ctx: {
13
+ provider: string;
14
+ markedRequestorsCount: number;
15
+ pendingCount: number;
16
+ }): boolean;
17
+ estimateFirstPoll(batchSize: number): number;
18
+ pollIntervalMs: number;
19
+ }
20
+ export interface BatchProviderAdapter {
21
+ readonly name: string;
22
+ submit(requests: BatchRequest[], fetch: EngineFetch): Promise<string>;
23
+ getStatus(batchId: string, fetch: EngineFetch): Promise<BatchStatus>;
24
+ getResults(batchId: string, fetch: EngineFetch): Promise<BatchResult[]>;
25
+ cancel(batchId: string, fetch: EngineFetch): Promise<void>;
26
+ }
27
+ export interface BatchRequest {
28
+ customId: string;
29
+ body: Record<string, unknown>;
30
+ }
31
+ export interface BatchStatus {
32
+ id: string;
33
+ status: 'pending' | 'processing' | 'completed' | 'failed' | 'expired' | 'cancelled';
34
+ total: number;
35
+ completed: number;
36
+ failed: number;
37
+ pending: number;
38
+ }
39
+ export interface BatchResult {
40
+ customId: string;
41
+ success: boolean;
42
+ response: unknown | null;
43
+ error: string | null;
44
+ }
45
+ export interface PendingBatchJob {
46
+ batchId: string;
47
+ provider: string;
48
+ createdAt: number;
49
+ requests: Array<{
50
+ customId: string;
51
+ conversationId: string;
52
+ clientId: string;
53
+ }>;
54
+ }
@@ -0,0 +1,50 @@
1
+ /** Cache — semantic-keyed response cache.
2
+ *
3
+ * Lives at the network layer. Caller (LLMClient via RequestContext, or any
4
+ * application) supplies:
5
+ * - `cacheName`: namespace ("default", "user-${userId}", "shared", ...)
6
+ * - `cacheKey`: content key (typically a content hash computed by LLMClient)
7
+ *
8
+ * Storage key composition: `cache:{cacheName}:{cacheKey}`.
9
+ *
10
+ * The cache is content-agnostic. It does not compute keys itself — that's
11
+ * semantic. The cache itself does not subscribe to a hook bus; NetworkEngine
12
+ * owns the bus wiring and emits the relevant cache events.
13
+ *
14
+ * TTL: per-entry, with default at construction. Expired entries are
15
+ * detected on `get()` and dropped lazily. */
16
+ import type { CacheStore } from './types';
17
+ export interface CachePluginConfig {
18
+ store: CacheStore;
19
+ /** Default TTL in ms applied to entries when caller does not specify one.
20
+ * Use Number.POSITIVE_INFINITY for "never expire". */
21
+ ttlMs?: number;
22
+ /** Namespace fallback when caller passes `set(undefined, ...)`. Default: 'default'. */
23
+ defaultName?: string;
24
+ }
25
+ export interface InvalidateScope {
26
+ /** Keep only entries whose cacheName matches this exact namespace. */
27
+ cacheName?: string;
28
+ /** Sub-pattern within a name. Currently a string prefix on cacheKey. */
29
+ keyPrefix?: string;
30
+ }
31
+ export declare class Cache {
32
+ private readonly store;
33
+ private readonly defaultTtl;
34
+ private readonly defaultName;
35
+ constructor(config: CachePluginConfig);
36
+ /** Look up a cached response by (cacheName, cacheKey). Null if missing or expired. */
37
+ get<T = unknown>(cacheName: string | undefined, cacheKey: string): Promise<T | null>;
38
+ /** Store a response under (cacheName, cacheKey). Overwrites any existing entry. */
39
+ set<T = unknown>(cacheName: string | undefined, cacheKey: string, body: T, options?: {
40
+ ttlMs?: number;
41
+ }): Promise<void>;
42
+ /** Remove a single entry. */
43
+ delete(cacheName: string | undefined, cacheKey: string): Promise<void>;
44
+ /** Drop entries matching scope. Empty scope clears everything cache-managed.
45
+ * Returns the number of entries removed. */
46
+ invalidate(scope?: InvalidateScope): Promise<number>;
47
+ /** Drop all entries (cache-managed and otherwise) from the store.
48
+ * Compare with `invalidate({})` which only removes cache-prefixed entries. */
49
+ clear(): Promise<void>;
50
+ }
@@ -0,0 +1,15 @@
1
+ /** FileCacheStore — persists CacheEntries as JSON files via FilePersistence.
2
+ * Survives process restart. */
3
+ import type { CacheEntry, CacheStore } from './types';
4
+ export interface FileCacheStoreConfig {
5
+ dir: string;
6
+ }
7
+ export declare class FileCacheStore implements CacheStore {
8
+ private readonly store;
9
+ constructor(config: FileCacheStoreConfig);
10
+ get<T = unknown>(storageKey: string): Promise<CacheEntry<T> | null>;
11
+ set<T = unknown>(storageKey: string, entry: CacheEntry<T>): Promise<void>;
12
+ delete(storageKey: string): Promise<void>;
13
+ keys(prefix?: string): Promise<string[]>;
14
+ clear(): Promise<void>;
15
+ }
@@ -0,0 +1,10 @@
1
+ /** MemoryCacheStore — in-process Map-backed CacheStore. Lost on restart. */
2
+ import type { CacheEntry, CacheStore } from './types';
3
+ export declare class MemoryCacheStore implements CacheStore {
4
+ private map;
5
+ get<T = unknown>(storageKey: string): Promise<CacheEntry<T> | null>;
6
+ set<T = unknown>(storageKey: string, entry: CacheEntry<T>): Promise<void>;
7
+ delete(storageKey: string): Promise<void>;
8
+ keys(prefix?: string): Promise<string[]>;
9
+ clear(): Promise<void>;
10
+ }
@@ -0,0 +1,28 @@
1
+ /** Cache types — store interface + entry shape.
2
+ *
3
+ * The Cache plugin stores arbitrary response bodies under (cacheName, cacheKey)
4
+ * pairs. The semantic layer decides what makes "the same request" by computing
5
+ * the `cacheKey`; the cache itself is content-agnostic. */
6
+ export interface CacheEntry<T = unknown> {
7
+ /** Stored payload — typically a provider's raw response body. */
8
+ body: T;
9
+ /** ms-epoch when written. */
10
+ storedAt: number;
11
+ /** TTL in ms. Stores prune lazily on get. */
12
+ ttlMs: number;
13
+ /** Cache namespace this entry belongs to. Used by `invalidate(cacheName)`. */
14
+ cacheName: string;
15
+ }
16
+ /** Storage backend. Implementations: MemoryCacheStore, FileCacheStore. */
17
+ export interface CacheStore {
18
+ /** Get an entry by full storage key. Null if missing or expired. */
19
+ get<T = unknown>(storageKey: string): Promise<CacheEntry<T> | null>;
20
+ /** Write an entry. */
21
+ set<T = unknown>(storageKey: string, entry: CacheEntry<T>): Promise<void>;
22
+ /** Drop a specific entry. */
23
+ delete(storageKey: string): Promise<void>;
24
+ /** List all keys, optionally filtered by prefix. */
25
+ keys(prefix?: string): Promise<string[]>;
26
+ /** Drop everything. */
27
+ clear(): Promise<void>;
28
+ }
@@ -0,0 +1,71 @@
1
+ /** ConfigurationPlugin — open-shape settings registry keyed by `configName`.
2
+ *
3
+ * Stores arbitrary configuration bundles. Consumers (rate limiter, retry,
4
+ * cache TTL, custom plugins) read their own typed slice off each entry by
5
+ * convention. The registry itself is opaque about content.
6
+ *
7
+ * Lookup order at consumer time (e.g. NetworkEngine creating a queue):
8
+ * 1. Lookup by `configName`.
9
+ * 2. Fallback to a parent name via `extend()` chain (handled internally).
10
+ * 3. If nothing registered: consumer applies its own hard-coded defaults.
11
+ *
12
+ * Snapshot semantics: when a queue is created, it captures its slice from
13
+ * the current config. Subsequent `set()` calls do NOT affect existing queues.
14
+ * Live updates are deferred (see report 016 §open-questions).
15
+ *
16
+ * Persistence: optional. When a `Persistence` is supplied, `load()` and
17
+ * `save()` round-trip the registry through it under the key `__configurations`.
18
+ * The registry does not auto-save; callers do.
19
+ */
20
+ import type { Persistence } from '../persistence/types';
21
+ /** Per-name settings bundle. Values are opaque. */
22
+ export type ConfigurationEntry = Record<string, unknown>;
23
+ /** What `serialize()` emits / `deserialize()` accepts. */
24
+ export interface SerializedConfigurations {
25
+ version: 1;
26
+ entries: Record<string, ConfigurationEntry>;
27
+ /** Parent chain: child name → parent name. */
28
+ parents: Record<string, string>;
29
+ }
30
+ export interface ConfigurationPluginConfig {
31
+ /** Optional storage. When given, `load()` / `save()` use it. */
32
+ persistence?: Persistence;
33
+ /** Storage key under which the registry is persisted. Defaults to `__configurations`. */
34
+ storageKey?: string;
35
+ /** Initial entries seeded at construction. */
36
+ initial?: Record<string, ConfigurationEntry>;
37
+ }
38
+ export declare class ConfigurationPlugin {
39
+ private readonly entries;
40
+ private readonly parents;
41
+ private readonly persistence?;
42
+ private readonly storageKey;
43
+ constructor(config?: ConfigurationPluginConfig);
44
+ /** Register or replace settings for a name. Throws if `name` is empty.
45
+ * Defensive deep clone: caller's nested objects can be mutated freely
46
+ * after `set()` without affecting the stored copy. */
47
+ set(name: string, settings: ConfigurationEntry): void;
48
+ /** Look up resolved settings for a name. Walks the parent chain (child overrides
49
+ * parent). Returns null if the name (and any ancestor) is unknown. */
50
+ get(name: string): ConfigurationEntry | null;
51
+ /** Create a derived configuration that inherits from `baseName`.
52
+ * The derived entry stores ONLY the overrides; `get(newName)` merges
53
+ * them with the base. */
54
+ extend(baseName: string, newName: string, overrides: ConfigurationEntry): void;
55
+ /** Whether a name is registered (directly or via parent chain). */
56
+ has(name: string): boolean;
57
+ /** Remove a name. If others extend from it, they remain but `get()` on them
58
+ * returns null when their full chain becomes broken. */
59
+ delete(name: string): void;
60
+ /** All registered names. */
61
+ names(): string[];
62
+ /** Snapshot the registry. */
63
+ serialize(): SerializedConfigurations;
64
+ /** Replace the registry from a snapshot. */
65
+ deserialize(data: SerializedConfigurations): void;
66
+ /** Load from configured persistence. No-op if no persistence attached.
67
+ * Returns true if data was loaded; false if storage was empty. */
68
+ load(): Promise<boolean>;
69
+ /** Save to configured persistence. Throws if no persistence attached. */
70
+ save(): Promise<void>;
71
+ }
@@ -0,0 +1,14 @@
1
+ /** ExtractedFact — universal fact shape used by ContextGuard's strategies.
2
+ * Producers (fact-extract tools, memory tools, custom extractors) emit facts
3
+ * in this shape; consumers (renderFactsLayer, snapshots) read them. */
4
+ export declare const FACT_CATEGORIES: readonly ["name", "date", "time", "path", "url", "email", "phone", "address", "amount", "number", "identifier", "other"];
5
+ export type FactCategory = (typeof FACT_CATEGORIES)[number];
6
+ export interface ExtractedFact {
7
+ /** Short descriptive label. Lowercase, snake_or_dotted notation. */
8
+ key: string;
9
+ /** Fact value — verbatim from source for verifiability. */
10
+ value: string;
11
+ category: FactCategory;
12
+ /** Optional surrounding context for ambiguous values. */
13
+ span?: string;
14
+ }
@@ -0,0 +1,27 @@
1
+ /** ContextGuard — stateless engine that routes onContextMeasure events to
2
+ * per-conversation strategies. */
3
+ import type { ContextGuardConfig } from './types';
4
+ export declare class ContextGuard {
5
+ private readonly hooks;
6
+ private readonly measurer;
7
+ private readonly contextTools;
8
+ private readonly strategies;
9
+ private readonly defaultStrategy;
10
+ private readonly onUnknownStrategy;
11
+ private readonly maxRetries;
12
+ private readonly criticalFloor;
13
+ private readonly triggerCache;
14
+ private readonly warnedUnknownStrategies;
15
+ private unsubscribe;
16
+ constructor(config: ContextGuardConfig);
17
+ destroy(): void;
18
+ private wire;
19
+ private handleMeasure;
20
+ private resolveStrategy;
21
+ private resolveStrategyName;
22
+ private getSortedTriggers;
23
+ private readState;
24
+ private writeState;
25
+ private readStrategyState;
26
+ private writeStrategyState;
27
+ }
@@ -0,0 +1,24 @@
1
+ /** LayeredStrategy — three-zone compaction policy.
2
+ *
3
+ * Zones: recent (verbatim) / middle (per-segment summary) / old (fact-only).
4
+ * Escalation by trigger level: healthy/pressure/urgent/critical. */
5
+ import type { ContextStrategy, ReactContext, StrategyDecision, TriggerLevel } from '../types';
6
+ export interface LayeredStrategyConfig {
7
+ recentCount?: number;
8
+ middleSummaryChars?: number;
9
+ oldSummaryChars?: number;
10
+ jumpEscalateDelta?: number;
11
+ declineCeiling?: number;
12
+ triggers?: TriggerLevel[];
13
+ }
14
+ export declare class LayeredStrategy implements ContextStrategy {
15
+ readonly triggers: TriggerLevel[];
16
+ private readonly cfg;
17
+ constructor(config?: LayeredStrategyConfig);
18
+ react(ctx: ReactContext): Promise<StrategyDecision>;
19
+ private compactOldLayer;
20
+ private compactOldAndMiddle;
21
+ private compactAll;
22
+ private compactAggressive;
23
+ private applyJumpEscalation;
24
+ }
@@ -0,0 +1,19 @@
1
+ /** TruncateStrategy — cheapest possible compaction.
2
+ *
3
+ * Drops the oldest messages when usage crosses a threshold. NO LLM calls,
4
+ * NO fact extraction, NO summarization. Use for prototypes, smoke tests,
5
+ * and conversations where losing old context is acceptable. */
6
+ import type { ContextStrategy, ReactContext, StrategyDecision, TriggerLevel } from '../types';
7
+ export interface TruncateStrategyConfig {
8
+ keepRecent?: number;
9
+ triggers?: TriggerLevel[];
10
+ declineCeiling?: number;
11
+ }
12
+ export declare class TruncateStrategy implements ContextStrategy {
13
+ readonly name: "truncate";
14
+ readonly triggers: TriggerLevel[];
15
+ private readonly keepRecent;
16
+ private readonly declineCeiling;
17
+ constructor(config?: TruncateStrategyConfig);
18
+ react(ctx: ReactContext): Promise<StrategyDecision>;
19
+ }
@@ -0,0 +1,50 @@
1
+ /** StrategyToolsImpl — plumbing the guard provides to each strategy.
2
+ * Wraps history mutation, token measurement, summarize/fact-extract calls,
3
+ * and fact injection so policy code stays short. */
4
+ import type { Message } from '../../llm/types/messages';
5
+ import type { TokenCounter } from '../../agent/types';
6
+ import type { ConversationHistory } from '../../agent/history';
7
+ import type { HistoryEntry } from '../../agent/history-types';
8
+ import type { ContextRegistry } from '../../agent/context-registry/registry';
9
+ import type { ExtractedFact } from './facts';
10
+ import type { ContextTools, FactInjectionSite, StrategyTools } from './types';
11
+ export interface StrategyToolsDeps {
12
+ history: ConversationHistory;
13
+ /** Active messages array — mutated in place when replaceRange/dropOldest
14
+ * fire so the current request reflects the compaction. */
15
+ activeMessages: Message[];
16
+ counter: TokenCounter;
17
+ contextTools: ContextTools;
18
+ provider: string;
19
+ model: string;
20
+ }
21
+ export declare class StrategyToolsImpl implements StrategyTools {
22
+ private readonly deps;
23
+ constructor(deps: StrategyToolsDeps);
24
+ get historyLength(): number;
25
+ segment(opts?: {
26
+ recentCount?: number;
27
+ timeWindow?: number;
28
+ }): {
29
+ recent: HistoryEntry[];
30
+ middle: HistoryEntry[];
31
+ old: HistoryEntry[];
32
+ };
33
+ measure(items: readonly HistoryEntry[] | Message[]): number;
34
+ extractFacts(entries: readonly HistoryEntry[], categories?: string[]): Promise<ExtractedFact[]>;
35
+ summarize(entries: readonly HistoryEntry[], maxLength: number, focus?: string): Promise<string>;
36
+ replaceRange(from: number, to: number, replacement: Message): void;
37
+ dropOldest(n: number): void;
38
+ injectFacts(facts: ExtractedFact[], site: FactInjectionSite): void;
39
+ private concatContent;
40
+ private contentToPlainText;
41
+ private prependText;
42
+ }
43
+ export declare function renderFactsBlock(facts: ExtractedFact[], opts?: {
44
+ bareBlock?: boolean;
45
+ }): string;
46
+ export declare function renderFactsLayer(facts: ExtractedFact[]): string;
47
+ export declare function readFactsLayer(registry: ContextRegistry): ExtractedFact[] | null;
48
+ export declare function parseFactsBlock(system: string): ExtractedFact[];
49
+ export declare function writeFactsBlock(system: string, facts: ExtractedFact[]): string;
50
+ export declare function renderPriorFactsForExtraction(facts: ExtractedFact[]): string;
@@ -0,0 +1,110 @@
1
+ /** ContextGuard types — strategy interface, decisions, trigger ladder. */
2
+ import type { Message } from '../../llm/types/messages';
3
+ import type { HookBus } from '../../bus/hook-bus';
4
+ import type { HistoryEntry } from '../../agent/history-types';
5
+ import type { ContextMeasurer } from '../context-measurer/measurer';
6
+ import type { ExtractedFact } from './facts';
7
+ /** One step of the trigger ladder. */
8
+ export interface TriggerLevel {
9
+ level: string;
10
+ at: number;
11
+ }
12
+ /** Pluggable adapter for the LLM-driven helpers a strategy may need.
13
+ * Default impl is a no-op (TruncateStrategy works without it). Layered
14
+ * strategy benefits from real summarize/extractFacts (e.g. backed by an
15
+ * agent or a built-in tool registry). */
16
+ export interface ContextTools {
17
+ summarize(content: string, maxLength: number, focus?: string): Promise<string>;
18
+ extractFacts(content: string, categories?: string[]): Promise<ExtractedFact[]>;
19
+ }
20
+ /** Default no-op tools — returns empty summary and no facts. Sufficient for
21
+ * TruncateStrategy and tests. */
22
+ export declare class NoopContextTools implements ContextTools {
23
+ summarize(): Promise<string>;
24
+ extractFacts(): Promise<ExtractedFact[]>;
25
+ }
26
+ /** Adapter that delegates ContextTools to an InternalToolRunner.
27
+ * - summarize → runs `orxa:summarize@1.0.0` and returns its `summary` field.
28
+ * - extractFacts → runs `orxa:fact-extract@1.0.0` when present in the
29
+ * registry, else returns []. (fact-extract ships in extensions/, not core.)
30
+ */
31
+ export declare class RunnerContextTools implements ContextTools {
32
+ private readonly deps;
33
+ constructor(deps: {
34
+ runner: {
35
+ run<T>(toolId: string, input: unknown): Promise<T>;
36
+ registry: {
37
+ get(toolId: string): Promise<unknown>;
38
+ };
39
+ };
40
+ summarizeId?: string;
41
+ factExtractId?: string;
42
+ });
43
+ summarize(content: string, maxLength: number, focus?: string): Promise<string>;
44
+ extractFacts(content: string, categories?: string[]): Promise<ExtractedFact[]>;
45
+ }
46
+ export interface ReactContext {
47
+ level: string;
48
+ percentage: number;
49
+ current: number;
50
+ window: number | null;
51
+ delta: number;
52
+ provider: string;
53
+ model: string;
54
+ attempt: number;
55
+ tools: StrategyTools;
56
+ state: Record<string, unknown>;
57
+ }
58
+ export type StrategyDecision = {
59
+ action: 'none';
60
+ } | {
61
+ action: 'compacted';
62
+ note?: string;
63
+ } | {
64
+ action: 'warn';
65
+ message: string;
66
+ } | {
67
+ action: 'decline';
68
+ reason: string;
69
+ };
70
+ export interface ContextStrategy {
71
+ readonly triggers: TriggerLevel[];
72
+ react(ctx: ReactContext): StrategyDecision | Promise<StrategyDecision>;
73
+ }
74
+ export type FactInjectionSite = 'system-append' | 'first-user-prefix';
75
+ export interface StrategyTools {
76
+ segment(opts?: {
77
+ recentCount?: number;
78
+ timeWindow?: number;
79
+ }): {
80
+ recent: HistoryEntry[];
81
+ middle: HistoryEntry[];
82
+ old: HistoryEntry[];
83
+ };
84
+ measure(items: readonly HistoryEntry[] | Message[]): number;
85
+ extractFacts(entries: readonly HistoryEntry[], categories?: string[]): Promise<ExtractedFact[]>;
86
+ summarize(entries: readonly HistoryEntry[], maxLength: number, focus?: string): Promise<string>;
87
+ replaceRange(from: number, to: number, replacement: Message): void;
88
+ dropOldest(n: number): void;
89
+ injectFacts(facts: ExtractedFact[], site: FactInjectionSite): void;
90
+ readonly historyLength: number;
91
+ }
92
+ export type UnknownStrategyPolicy = 'skip' | 'fallback-default' | 'throw';
93
+ export interface ContextGuardConfig {
94
+ hooks: HookBus;
95
+ measurer: ContextMeasurer;
96
+ /** Pluggable summarize / fact-extract backend. Defaults to a no-op
97
+ * (sufficient for TruncateStrategy; LayeredStrategy needs a real one). */
98
+ contextTools?: ContextTools;
99
+ strategies: Record<string, ContextStrategy>;
100
+ defaultStrategy: string;
101
+ onUnknownStrategy?: UnknownStrategyPolicy;
102
+ maxCompactRetries?: number;
103
+ criticalFloor?: number;
104
+ }
105
+ export interface GuardConversationState {
106
+ v: 1;
107
+ lastLevelIdx: number;
108
+ lastCurrent: number;
109
+ strategyState?: Record<string, Record<string, unknown>>;
110
+ }
@@ -0,0 +1,19 @@
1
+ /** PersistenceCalibrationStore — EMA-backed persistence of token rates. */
2
+ import type { ContentClass } from '../../../agent/types';
3
+ import type { Persistence } from '../../persistence/types';
4
+ import type { CalibrationStore, CalibrationEntry, CalibrationConfig } from '../types';
5
+ export declare class PersistenceCalibrationStore implements CalibrationStore {
6
+ private readonly persistence;
7
+ private config;
8
+ constructor(persistence: Persistence, config?: Partial<CalibrationConfig>);
9
+ get(provider: string, model: string, contentClass?: ContentClass): Promise<CalibrationEntry | null>;
10
+ update(input: Omit<CalibrationEntry, 'lastUpdated' | 'confidence'>): Promise<CalibrationEntry>;
11
+ list(opts?: {
12
+ provider?: string;
13
+ model?: string;
14
+ }): Promise<CalibrationEntry[]>;
15
+ reset(opts?: {
16
+ provider?: string;
17
+ model?: string;
18
+ }): Promise<void>;
19
+ }
@@ -0,0 +1,41 @@
1
+ /** Count API adapter — exact token counting via provider endpoints. */
2
+ import type { Message } from '../../../llm/types/messages';
3
+ import type { TokenCountContext, TokenCounter, LearnInput } from '../../../agent/types';
4
+ import type { FetchFn } from '../../../network/types';
5
+ import type { ModelCatalog } from '../../model-catalog/catalog';
6
+ /** Anthropic count endpoint: POST /v1/messages/count_tokens */
7
+ export declare class AnthropicCountApi {
8
+ private readonly apiKey;
9
+ private readonly fetchFn;
10
+ private readonly baseURL;
11
+ constructor(apiKey: string, fetchFn?: FetchFn, baseURL?: string);
12
+ countMessages(model: string, messages: Array<{
13
+ role: string;
14
+ content: unknown;
15
+ }>, system?: string): Promise<number>;
16
+ countText(model: string, text: string): Promise<number>;
17
+ }
18
+ /** Google count endpoint: POST /v1beta/models/{model}:countTokens */
19
+ export declare class GoogleCountApi {
20
+ private readonly apiKey;
21
+ private readonly fetchFn;
22
+ private readonly baseURL;
23
+ constructor(apiKey: string, fetchFn?: FetchFn, baseURL?: string);
24
+ countText(model: string, text: string): Promise<number>;
25
+ }
26
+ /** TokenCounter backed by Anthropic/Google count APIs. Falls back to heuristic
27
+ * for fast estimates and unknown providers. */
28
+ export declare class CountApiCounter implements TokenCounter {
29
+ private readonly providers;
30
+ private heuristic;
31
+ constructor(catalog: ModelCatalog | null, providers?: {
32
+ anthropic?: AnthropicCountApi;
33
+ google?: GoogleCountApi;
34
+ });
35
+ estimate(text: string, ctx?: TokenCountContext): number;
36
+ estimateMessage(msg: Message, ctx?: TokenCountContext): number;
37
+ measure(text: string, ctx?: TokenCountContext): Promise<number>;
38
+ measureMessage(msg: Message, ctx?: TokenCountContext): Promise<number>;
39
+ learn(input: LearnInput): void;
40
+ private apiFor;
41
+ }
@@ -0,0 +1,25 @@
1
+ /** Heuristic token counter — chars-per-token with optional calibration. */
2
+ import type { Message } from '../../../llm/types/messages';
3
+ import type { TokenCountContext, TokenCounter, LearnInput } from '../../../agent/types';
4
+ import type { ModelCatalog } from '../../model-catalog/catalog';
5
+ import type { CalibrationStore } from '../types';
6
+ /** Count chars across a message's content parts. */
7
+ export declare function messageChars(msg: Message): number;
8
+ export declare class HeuristicCounter implements TokenCounter {
9
+ private readonly catalog;
10
+ private readonly calibrationStore;
11
+ private readonly cache;
12
+ constructor(catalog: ModelCatalog | null, calibrationStore?: CalibrationStore | null);
13
+ estimate(text: string, ctx?: TokenCountContext): number;
14
+ estimateMessage(msg: Message, ctx?: TokenCountContext): number;
15
+ measure(text: string, ctx?: TokenCountContext): Promise<number>;
16
+ measureMessage(msg: Message, ctx?: TokenCountContext): Promise<number>;
17
+ learn(input: LearnInput): void;
18
+ /** Pre-warm the sync cache from the calibration store. */
19
+ warmCache(): Promise<void>;
20
+ private rateSync;
21
+ private rate;
22
+ private catalogDefault;
23
+ private cacheKey;
24
+ private cacheKeyFor;
25
+ }
@@ -0,0 +1,33 @@
1
+ /** HybridTokenCounter — selects strategy per model based on catalog config. */
2
+ import type { Message } from '../../../llm/types/messages';
3
+ import type { TokenCountContext, TokenCounter, LearnInput } from '../../../agent/types';
4
+ import type { ModelCatalog } from '../../model-catalog/catalog';
5
+ import type { CalibrationStore } from '../types';
6
+ export interface HybridCounterConfig {
7
+ catalog?: ModelCatalog;
8
+ calibrationStore?: CalibrationStore;
9
+ countApiKeys?: {
10
+ anthropic?: string;
11
+ google?: string;
12
+ };
13
+ }
14
+ /**
15
+ * HybridTokenCounter routes based on catalog's tokenizer.strategy:
16
+ * 'tiktoken' → TiktokenCounter (exact for OpenAI)
17
+ * 'count_api' → CountApiCounter (exact via provider endpoint for Anthropic/Google)
18
+ * 'heuristic' → HeuristicCounter (calibration-aware fallback)
19
+ */
20
+ export declare class HybridTokenCounter implements TokenCounter {
21
+ private heuristic;
22
+ private tiktoken;
23
+ private countApi;
24
+ private readonly _config;
25
+ constructor(config: HybridCounterConfig);
26
+ warmCache(): Promise<void>;
27
+ estimate(text: string, ctx?: TokenCountContext): number;
28
+ estimateMessage(msg: Message, ctx?: TokenCountContext): number;
29
+ measure(text: string, ctx?: TokenCountContext): Promise<number>;
30
+ measureMessage(msg: Message, ctx?: TokenCountContext): Promise<number>;
31
+ learn(input: LearnInput): void;
32
+ private strategyFor;
33
+ }
@@ -0,0 +1,13 @@
1
+ /** Tiktoken adapter — exact tokenization for OpenAI models. */
2
+ import type { Message } from '../../../llm/types/messages';
3
+ import type { TokenCountContext, TokenCounter, LearnInput } from '../../../agent/types';
4
+ export declare class TiktokenCounter implements TokenCounter {
5
+ private encodings;
6
+ estimate(text: string, ctx?: TokenCountContext): number;
7
+ estimateMessage(msg: Message, ctx?: TokenCountContext): number;
8
+ measure(text: string, ctx?: TokenCountContext): Promise<number>;
9
+ measureMessage(msg: Message, ctx?: TokenCountContext): Promise<number>;
10
+ learn(_input: LearnInput): void;
11
+ private encodingFor;
12
+ private getEncoder;
13
+ }