@theokit/sdk 2.0.1 → 2.1.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 (76) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/a2a/index.cjs +232 -171
  3. package/dist/a2a/index.cjs.map +1 -1
  4. package/dist/a2a/index.js +232 -171
  5. package/dist/a2a/index.js.map +1 -1
  6. package/dist/concurrency.cjs +86 -0
  7. package/dist/concurrency.cjs.map +1 -0
  8. package/dist/concurrency.d.cts +13 -0
  9. package/dist/concurrency.d.ts +13 -0
  10. package/dist/concurrency.js +83 -0
  11. package/dist/concurrency.js.map +1 -0
  12. package/dist/{cron-DFG9-W17.d.cts → cron-CSTqNZp9.d.cts} +1 -1
  13. package/dist/{cron-Bj8-Aq1O.d.ts → cron-Da6vF_2y.d.ts} +1 -1
  14. package/dist/cron.cjs +213 -169
  15. package/dist/cron.cjs.map +1 -1
  16. package/dist/cron.d.cts +1 -1
  17. package/dist/cron.d.ts +1 -1
  18. package/dist/cron.js +213 -169
  19. package/dist/cron.js.map +1 -1
  20. package/dist/{errors-DV9e0rcp.d.ts → errors--VP2qrGc.d.ts} +23 -1
  21. package/dist/{errors-ChqOmFH1.d.cts → errors-C9xkhNEF.d.cts} +23 -1
  22. package/dist/errors.cjs +17 -11
  23. package/dist/errors.cjs.map +1 -1
  24. package/dist/errors.d.cts +1 -1
  25. package/dist/errors.d.ts +22 -0
  26. package/dist/errors.js +17 -12
  27. package/dist/errors.js.map +1 -1
  28. package/dist/eval.cjs +213 -169
  29. package/dist/eval.cjs.map +1 -1
  30. package/dist/eval.js +213 -169
  31. package/dist/eval.js.map +1 -1
  32. package/dist/index.cjs +231 -171
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/index.d.cts +161 -119
  35. package/dist/index.d.ts +161 -119
  36. package/dist/index.js +231 -173
  37. package/dist/index.js.map +1 -1
  38. package/dist/internal/default-retriable.d.ts +1 -0
  39. package/dist/internal/persistence/index.cjs +75 -0
  40. package/dist/internal/persistence/index.cjs.map +1 -1
  41. package/dist/internal/persistence/index.d.cts +2 -0
  42. package/dist/internal/persistence/index.d.ts +2 -0
  43. package/dist/internal/persistence/index.js +74 -1
  44. package/dist/internal/persistence/index.js.map +1 -1
  45. package/dist/internal/persistence/sqlite-open.d.cts +47 -0
  46. package/dist/internal/persistence/sqlite-open.d.ts +47 -0
  47. package/dist/internal/providers/register-plugin-providers.d.ts +22 -0
  48. package/dist/internal/runtime/concurrency/map-with-concurrency.d.ts +28 -0
  49. package/dist/internal/runtime/retry/with-retry.d.ts +40 -0
  50. package/dist/internal/security/index.cjs +1 -0
  51. package/dist/internal/security/index.cjs.map +1 -1
  52. package/dist/internal/security/index.js +1 -0
  53. package/dist/internal/security/index.js.map +1 -1
  54. package/dist/path-safety.cjs +15 -0
  55. package/dist/path-safety.cjs.map +1 -1
  56. package/dist/path-safety.d.cts +1 -1
  57. package/dist/path-safety.d.ts +1 -1
  58. package/dist/path-safety.js +15 -1
  59. package/dist/path-safety.js.map +1 -1
  60. package/dist/retry.cjs +85 -0
  61. package/dist/retry.cjs.map +1 -0
  62. package/dist/retry.d.cts +9 -0
  63. package/dist/retry.d.ts +9 -0
  64. package/dist/retry.js +83 -0
  65. package/dist/retry.js.map +1 -0
  66. package/dist/server/errors-envelope.cjs +14 -12
  67. package/dist/server/errors-envelope.cjs.map +1 -1
  68. package/dist/server/errors-envelope.js +14 -12
  69. package/dist/server/errors-envelope.js.map +1 -1
  70. package/dist/subscription/index.cjs.map +1 -1
  71. package/dist/subscription/index.js.map +1 -1
  72. package/dist/task-store.cjs.map +1 -1
  73. package/dist/task-store.js.map +1 -1
  74. package/dist/workflow.cjs.map +1 -1
  75. package/dist/workflow.js.map +1 -1
  76. package/package.json +21 -1
package/dist/a2a/index.js CHANGED
@@ -129,6 +129,24 @@ var init_agent_builder = __esm({
129
129
  }
130
130
  });
131
131
 
132
+ // src/internal/default-retriable.ts
133
+ function defaultRetriableForCode(code) {
134
+ switch (code) {
135
+ case "rate_limit":
136
+ case "timeout":
137
+ case "server_error":
138
+ case "network":
139
+ case "provider_unreachable":
140
+ return true;
141
+ default:
142
+ return false;
143
+ }
144
+ }
145
+ var init_default_retriable = __esm({
146
+ "src/internal/default-retriable.ts"() {
147
+ }
148
+ });
149
+
132
150
  // src/internal/security/redact.ts
133
151
  function readEnvOnce() {
134
152
  const raw = process.env.THEOKIT_REDACT_SECRETS;
@@ -279,7 +297,8 @@ __export(errors_exports, {
279
297
  UnsupportedBudgetOperationError: () => UnsupportedBudgetOperationError,
280
298
  UnsupportedRunOperationError: () => UnsupportedRunOperationError,
281
299
  UnsupportedTaskOperationError: () => UnsupportedTaskOperationError,
282
- coerceToKnownAgentRunErrorCode: () => coerceToKnownAgentRunErrorCode
300
+ coerceToKnownAgentRunErrorCode: () => coerceToKnownAgentRunErrorCode,
301
+ isTransientError: () => isTransientError
283
302
  });
284
303
  function coerceToKnownAgentRunErrorCode(code) {
285
304
  if (code !== void 0 && KNOWN_AGENT_RUN_ERROR_CODES.has(code)) {
@@ -311,21 +330,13 @@ function safeStringify(value) {
311
330
  return String(value);
312
331
  }
313
332
  }
314
- function defaultRetriableForCode(code) {
315
- switch (code) {
316
- case "rate_limit":
317
- case "timeout":
318
- case "server_error":
319
- case "network":
320
- case "provider_unreachable":
321
- return true;
322
- default:
323
- return false;
324
- }
333
+ function isTransientError(err) {
334
+ return err instanceof TheokitAgentError && err.isRetryable === true;
325
335
  }
326
336
  var KNOWN_AGENT_RUN_ERROR_CODES, TheokitAgentError, AuthenticationError, RateLimitError, ConfigurationError, IntegrationNotConnectedError, NetworkError, UnknownAgentError, AgentRunError, UnsupportedRunOperationError, CredentialPoolExhaustedError, MemoryAdapterError, InvalidTaskIdError, TaskNotFoundError, UnsupportedTaskOperationError, BudgetExceededError, AgentDisposedError, UnsupportedBudgetOperationError;
327
337
  var init_errors = __esm({
328
338
  "src/errors.ts"() {
339
+ init_default_retriable();
329
340
  init_redact();
330
341
  KNOWN_AGENT_RUN_ERROR_CODES = /* @__PURE__ */ new Set([
331
342
  "rate_limit",
@@ -1024,6 +1035,19 @@ function sanitizeIdentifier(input, options) {
1024
1035
  }
1025
1036
  return input.toLowerCase();
1026
1037
  }
1038
+ function safeFilenameForId(id, options) {
1039
+ if (id.length === 0) {
1040
+ throw new ConfigurationError("Filename id must be a non-empty string", {
1041
+ code: "invalid_filename_id"
1042
+ });
1043
+ }
1044
+ const maxLen = options?.maxLen;
1045
+ const lower = id.toLowerCase();
1046
+ if (lower.length <= maxLen && IDENTIFIER_PATTERN.test(lower)) {
1047
+ return lower;
1048
+ }
1049
+ return `h-${createHash("sha256").update(id).digest("hex").slice(0, 16)}`;
1050
+ }
1027
1051
  var PathTraversalError, IDENTIFIER_PATTERN;
1028
1052
  var init_path_guard = __esm({
1029
1053
  "src/internal/security/path-guard.ts"() {
@@ -4240,10 +4264,7 @@ function sessionsDir(cwd) {
4240
4264
  return join(memoryDir(cwd), "sessions");
4241
4265
  }
4242
4266
  function sessionSummaryPath(cwd, runId) {
4243
- return join(sessionsDir(cwd), `${sanitizeRunId(runId)}.md`);
4244
- }
4245
- function sanitizeRunId(runId) {
4246
- return runId.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 128);
4267
+ return join(sessionsDir(cwd), `${safeFilenameForId(runId, { maxLen: 128 })}.md`);
4247
4268
  }
4248
4269
  function truncate(text) {
4249
4270
  if (text.length <= MAX_TURN_CHARS) return text;
@@ -4279,6 +4300,7 @@ var MAX_TURN_CHARS;
4279
4300
  var init_session_summary_writer = __esm({
4280
4301
  "src/internal/memory/storage/session-summary-writer.ts"() {
4281
4302
  init_atomic_write();
4303
+ init_path_guard();
4282
4304
  init_types();
4283
4305
  init_markdown_store();
4284
4306
  MAX_TURN_CHARS = 2e3;
@@ -7109,6 +7131,75 @@ var init_async_local_storage = __esm({
7109
7131
  }
7110
7132
  });
7111
7133
 
7134
+ // src/internal/runtime/concurrency/async-semaphore.ts
7135
+ function createSemaphore(permits) {
7136
+ if (!Number.isInteger(permits) || permits < 1) {
7137
+ throw new ConfigurationError(
7138
+ `async-semaphore: permits must be a positive integer, got ${permits}`,
7139
+ { code: "invalid_concurrency" }
7140
+ );
7141
+ }
7142
+ let active = 0;
7143
+ const queue = [];
7144
+ function tryGrant() {
7145
+ if (active < permits && queue.length > 0) {
7146
+ const resolve3 = queue.shift();
7147
+ if (resolve3 !== void 0) {
7148
+ active += 1;
7149
+ resolve3();
7150
+ }
7151
+ }
7152
+ }
7153
+ return {
7154
+ inFlight: () => active,
7155
+ pending: () => queue.length + active,
7156
+ async acquire() {
7157
+ await new Promise((resolve3) => {
7158
+ queue.push(resolve3);
7159
+ tryGrant();
7160
+ });
7161
+ let released = false;
7162
+ return () => {
7163
+ if (released) return;
7164
+ released = true;
7165
+ active -= 1;
7166
+ tryGrant();
7167
+ };
7168
+ }
7169
+ };
7170
+ }
7171
+ var init_async_semaphore = __esm({
7172
+ "src/internal/runtime/concurrency/async-semaphore.ts"() {
7173
+ init_errors();
7174
+ }
7175
+ });
7176
+
7177
+ // src/internal/runtime/concurrency/map-with-concurrency.ts
7178
+ async function mapWithConcurrency(items, concurrency, fn, options) {
7179
+ const semaphore = createSemaphore(concurrency);
7180
+ const signal = NEVER_ABORT;
7181
+ return Promise.all(
7182
+ items.map(async (item, index) => {
7183
+ const release = await semaphore.acquire();
7184
+ try {
7185
+ if (signal.aborted) {
7186
+ throw signal.reason instanceof Error ? signal.reason : new Error("mapWithConcurrency: aborted");
7187
+ }
7188
+ return await fn(item, index, signal);
7189
+ } finally {
7190
+ release();
7191
+ }
7192
+ })
7193
+ );
7194
+ }
7195
+ var NEVER_ABORT;
7196
+ var init_map_with_concurrency = __esm({
7197
+ "src/internal/runtime/concurrency/map-with-concurrency.ts"() {
7198
+ init_async_semaphore();
7199
+ NEVER_ABORT = new AbortController().signal;
7200
+ }
7201
+ });
7202
+
7112
7203
  // src/internal/tool-dispatch/repair-middleware.ts
7113
7204
  function repairToolCall(raw, registry) {
7114
7205
  const repairs = [];
@@ -7298,38 +7389,12 @@ var init_tool_executors = __esm({
7298
7389
  // src/internal/agent-loop/tool-dispatch.ts
7299
7390
  async function dispatchTools(inputs, tools, toolCalls, events) {
7300
7391
  const maxConcurrent = inputs.maxConcurrentTools ?? 4;
7301
- return boundedParallel(
7302
- maxConcurrent,
7392
+ return mapWithConcurrency(
7303
7393
  toolCalls,
7394
+ maxConcurrent,
7304
7395
  (call) => dispatchSingleCall(inputs, tools, call, events)
7305
7396
  );
7306
7397
  }
7307
- async function boundedParallel(max, items, fn) {
7308
- let running = 0;
7309
- const queue = [];
7310
- async function acquire() {
7311
- if (running < max) {
7312
- running++;
7313
- return;
7314
- }
7315
- await new Promise((resolve3) => queue.push(resolve3));
7316
- running++;
7317
- }
7318
- function release() {
7319
- running--;
7320
- if (queue.length > 0) queue.shift()();
7321
- }
7322
- return Promise.all(
7323
- items.map(async (item) => {
7324
- await acquire();
7325
- try {
7326
- return await fn(item);
7327
- } finally {
7328
- release();
7329
- }
7330
- })
7331
- );
7332
- }
7333
7398
  async function dispatchSingleCall(inputs, tools, call, events) {
7334
7399
  const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
7335
7400
  const callId = generateCallId();
@@ -7553,6 +7618,7 @@ var init_tool_dispatch = __esm({
7553
7618
  "src/internal/agent-loop/tool-dispatch.ts"() {
7554
7619
  init_ids();
7555
7620
  init_async_local_storage();
7621
+ init_map_with_concurrency();
7556
7622
  init_repair_middleware();
7557
7623
  init_tool_executors();
7558
7624
  }
@@ -10824,6 +10890,21 @@ var init_client = __esm({
10824
10890
  }
10825
10891
  });
10826
10892
 
10893
+ // src/internal/providers/register-plugin-providers.ts
10894
+ function registerPluginProviderProfiles(entries) {
10895
+ let registered4 = 0;
10896
+ for (const entry of entries) {
10897
+ registerProvider(entry.profile);
10898
+ registered4 += 1;
10899
+ }
10900
+ return registered4;
10901
+ }
10902
+ var init_register_plugin_providers = __esm({
10903
+ "src/internal/providers/register-plugin-providers.ts"() {
10904
+ init_registry();
10905
+ }
10906
+ });
10907
+
10827
10908
  // src/internal/tool-registry/personality-filter.ts
10828
10909
  function applyPersonalityFilter(exposedTools, whitelist, opts) {
10829
10910
  if (whitelist === void 0) return exposedTools;
@@ -10904,12 +10985,26 @@ function createRealLocalRun(options) {
10904
10985
  registerRun(handle);
10905
10986
  return handle;
10906
10987
  }
10907
- function buildLoopInputs(options, runId, userText) {
10988
+ function resolveRunProvider(options) {
10908
10989
  registerBuiltins();
10990
+ const profiles = options.pluginManager?.aggregated.providerProfiles ?? [];
10991
+ const registered4 = registerPluginProviderProfiles(profiles);
10992
+ if (registered4 > 0 && !pluginProvidersAnnounced) {
10993
+ pluginProvidersAnnounced = true;
10994
+ const names = profiles.map((e) => e.profile.name).join(", ");
10995
+ process.stderr.write(
10996
+ `[theokit-sdk] registered ${registered4} plugin provider profile(s): ${names}
10997
+ `
10998
+ );
10999
+ }
10909
11000
  const parsedModel = parseModelId(options.model?.id);
10910
11001
  const inferredProvider = parsedModel.provider !== void 0 && getProviderProfile(parsedModel.provider) !== void 0 ? parsedModel.provider : void 0;
10911
11002
  const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? inferredProvider ?? detectPrimaryProvider();
10912
11003
  const effectiveModelId = inferredProvider !== void 0 ? parsedModel.name : options.model?.id ?? "claude-sonnet-4-6";
11004
+ return { primary, effectiveModelId };
11005
+ }
11006
+ function buildLoopInputs(options, runId, userText) {
11007
+ const { primary, effectiveModelId } = resolveRunProvider(options);
10913
11008
  const fallback = options.agentOptions.providers?.fallback;
10914
11009
  const apiKeys = options.agentOptions.providers?.apiKeys;
10915
11010
  const credentialPoolStrategy = options.agentOptions.providers?.credentialPoolStrategy;
@@ -11003,7 +11098,7 @@ function buildMcpMap(options) {
11003
11098
  }
11004
11099
  return map;
11005
11100
  }
11006
- var RealLocalRun;
11101
+ var pluginProvidersAnnounced, RealLocalRun;
11007
11102
  var init_real_local_run = __esm({
11008
11103
  "src/internal/runtime/local-agent/real-local-run.ts"() {
11009
11104
  init_loop();
@@ -11012,10 +11107,12 @@ var init_real_local_run = __esm({
11012
11107
  init_router();
11013
11108
  init_client();
11014
11109
  init_providers();
11110
+ init_register_plugin_providers();
11015
11111
  init_tracer();
11016
11112
  init_personality_filter();
11017
11113
  init_fixture_run_base();
11018
11114
  init_run_registry();
11115
+ pluginProvidersAnnounced = false;
11019
11116
  RealLocalRun = class extends FixtureRunBase {
11020
11117
  buildInputs;
11021
11118
  constructor(options, buildInputs) {
@@ -11567,7 +11664,7 @@ async function embedTexts(input) {
11567
11664
  pending
11568
11665
  });
11569
11666
  }
11570
- await runBatches(input, pending, results);
11667
+ await embedInBoundedBatches(input, pending, results);
11571
11668
  return results.map((v) => v ?? new Array(dimension).fill(0));
11572
11669
  }
11573
11670
  function classifyEntry(args) {
@@ -11585,45 +11682,34 @@ function classifyEntry(args) {
11585
11682
  args.stats.cacheMisses += 1;
11586
11683
  args.pending.push({ index: args.index, text: args.text, key });
11587
11684
  }
11588
- async function runBatches(input, pending, results) {
11685
+ async function embedInBoundedBatches(input, pending, results) {
11589
11686
  const batches = [];
11590
11687
  for (let offset = 0; offset < pending.length; offset += MAX_BATCH) {
11591
11688
  batches.push(pending.slice(offset, offset + MAX_BATCH));
11592
11689
  }
11593
- let running = 0;
11594
- const queue = [];
11595
- await Promise.all(batches.map((batch) => processBatch(input, batch, results, acquire, release)));
11596
- async function acquire() {
11597
- if (running >= MAX_CONCURRENT_BATCHES) await new Promise((r) => queue.push(r));
11598
- running++;
11599
- }
11600
- function release() {
11601
- running--;
11602
- if (queue.length > 0) queue.shift()();
11603
- }
11690
+ await mapWithConcurrency(
11691
+ batches,
11692
+ MAX_CONCURRENT_BATCHES,
11693
+ (batch) => processBatch(input, batch, results)
11694
+ );
11604
11695
  }
11605
- async function processBatch(input, batch, results, acquire, release) {
11606
- await acquire();
11607
- try {
11608
- const vectors = await embedBatch({
11609
- apiKey: input.apiKey,
11610
- baseUrl: input.baseUrl,
11611
- embeddingsPath: input.embeddingsPath,
11612
- model: input.model,
11613
- inputs: batch.map((b) => b.text),
11614
- fetchImpl: input.fetchImpl,
11615
- stats: input.stats,
11616
- providerId: input.providerId
11617
- });
11618
- for (let j = 0; j < batch.length; j++) {
11619
- const slot = batch[j];
11620
- const vector = vectors[j];
11621
- if (slot === void 0 || vector === void 0) continue;
11622
- results[slot.index] = vector;
11623
- input.cache.set(slot.key, vector);
11624
- }
11625
- } finally {
11626
- release();
11696
+ async function processBatch(input, batch, results) {
11697
+ const vectors = await embedBatch({
11698
+ apiKey: input.apiKey,
11699
+ baseUrl: input.baseUrl,
11700
+ embeddingsPath: input.embeddingsPath,
11701
+ model: input.model,
11702
+ inputs: batch.map((b) => b.text),
11703
+ fetchImpl: input.fetchImpl,
11704
+ stats: input.stats,
11705
+ providerId: input.providerId
11706
+ });
11707
+ for (let j = 0; j < batch.length; j++) {
11708
+ const slot = batch[j];
11709
+ const vector = vectors[j];
11710
+ if (slot === void 0 || vector === void 0) continue;
11711
+ results[slot.index] = vector;
11712
+ input.cache.set(slot.key, vector);
11627
11713
  }
11628
11714
  }
11629
11715
  async function embedBatch(opts) {
@@ -11697,6 +11783,7 @@ var init_openai_compatible2 = __esm({
11697
11783
  "src/internal/memory/adapters/openai-compatible.ts"() {
11698
11784
  init_errors();
11699
11785
  init_openai_compatible();
11786
+ init_map_with_concurrency();
11700
11787
  init_embedding_cache();
11701
11788
  MAX_BATCH = 100;
11702
11789
  MAX_RETRIES = 2;
@@ -12181,6 +12268,61 @@ var init_sqlite_wal = __esm({
12181
12268
  warnedLabels = /* @__PURE__ */ new Set();
12182
12269
  }
12183
12270
  });
12271
+ async function openSqliteResilient(options) {
12272
+ await mkdir(dirname(options.filePath), { recursive: true });
12273
+ try {
12274
+ return await openConcrete(options);
12275
+ } catch (cause) {
12276
+ if (options.recoverCorrupt !== false && isCorruptionError(cause)) {
12277
+ await renameAside(options.filePath, options.label ?? "sqlite");
12278
+ return await openConcrete(options);
12279
+ }
12280
+ throw cause;
12281
+ }
12282
+ }
12283
+ async function openConcrete(options) {
12284
+ const db = await loadDriver(options.filePath);
12285
+ applyWalWithFallback(db, options.label ?? "sqlite");
12286
+ await options.onOpen?.(db);
12287
+ return db;
12288
+ }
12289
+ async function loadDriver(filePath) {
12290
+ try {
12291
+ const mod = await import('better-sqlite3');
12292
+ const Ctor = mod.default ?? mod;
12293
+ if (typeof Ctor !== "function") {
12294
+ throw new Error(`better-sqlite3 export is not a constructor (got ${typeof Ctor})`);
12295
+ }
12296
+ return new Ctor(filePath);
12297
+ } catch (cause) {
12298
+ const message = cause instanceof Error ? cause.message : String(cause);
12299
+ throw new ConfigurationError(
12300
+ `Failed to load SQLite driver. Install \`better-sqlite3\` or run on Node 22.5+ for built-in \`node:sqlite\`. Cause: ${message}`,
12301
+ { code: "sqlite_driver_unavailable", cause }
12302
+ );
12303
+ }
12304
+ }
12305
+ function isCorruptionError(cause) {
12306
+ if (!(cause instanceof Error)) return false;
12307
+ const msg = cause.message.toLowerCase();
12308
+ return msg.includes("malformed") || msg.includes("not a database") || msg.includes("encrypted") || msg.includes("disk image is malformed");
12309
+ }
12310
+ async function renameAside(filePath, label) {
12311
+ const asidePath = `${filePath}.corrupt-${Date.now()}`;
12312
+ await rename(filePath, asidePath).catch(() => void 0);
12313
+ await rename(`${filePath}-wal`, `${asidePath}-wal`).catch(() => void 0);
12314
+ await rename(`${filePath}-shm`, `${asidePath}-shm`).catch(() => void 0);
12315
+ process.stderr.write(
12316
+ `[theokit-sdk] ${label} database corrupt; renamed aside to ${asidePath} and rebuilt schema
12317
+ `
12318
+ );
12319
+ }
12320
+ var init_sqlite_open = __esm({
12321
+ "src/internal/persistence/sqlite-open.ts"() {
12322
+ init_errors();
12323
+ init_sqlite_wal();
12324
+ }
12325
+ });
12184
12326
 
12185
12327
  // src/internal/memory/index-schema.ts
12186
12328
  var SCHEMA_STATEMENTS, PRAGMA_STATEMENTS;
@@ -12228,60 +12370,22 @@ var init_index_schema = __esm({
12228
12370
  }
12229
12371
  });
12230
12372
  async function openMemoryDb(opts) {
12231
- await mkdir(dirname(opts.filePath), { recursive: true });
12232
- try {
12233
- return await openConcrete(opts.filePath);
12234
- } catch (cause) {
12235
- if (opts.recoverCorrupt !== false && isCorruptionError(cause)) {
12236
- await renameAside(opts.filePath);
12237
- return await openConcrete(opts.filePath);
12373
+ return openSqliteResilient({
12374
+ filePath: opts.filePath,
12375
+ label: "memory-index",
12376
+ recoverCorrupt: opts.recoverCorrupt,
12377
+ onOpen: (db) => {
12378
+ for (const pragma of PRAGMA_STATEMENTS) db.exec(pragma);
12379
+ for (const stmt of SCHEMA_STATEMENTS) db.exec(stmt);
12238
12380
  }
12239
- throw cause;
12240
- }
12241
- }
12242
- async function openConcrete(filePath) {
12243
- const db = await loadDriver(filePath);
12244
- applyWalWithFallback(db, "memory-index");
12245
- for (const pragma of PRAGMA_STATEMENTS) db.exec(pragma);
12246
- for (const stmt of SCHEMA_STATEMENTS) db.exec(stmt);
12247
- return db;
12248
- }
12249
- async function loadDriver(filePath) {
12250
- try {
12251
- const mod = await import('better-sqlite3');
12252
- const Ctor = mod.default ?? mod;
12253
- const db = new Ctor(filePath);
12254
- return db;
12255
- } catch (cause) {
12256
- const message = cause instanceof Error ? cause.message : String(cause);
12257
- throw new ConfigurationError(
12258
- `Failed to load SQLite driver. Install \`better-sqlite3\` or run on Node 22.5+ for built-in \`node:sqlite\`. Cause: ${message}`,
12259
- { code: "sqlite_driver_unavailable", cause }
12260
- );
12261
- }
12262
- }
12263
- function isCorruptionError(cause) {
12264
- if (!(cause instanceof Error)) return false;
12265
- const msg = cause.message.toLowerCase();
12266
- return msg.includes("malformed") || msg.includes("not a database") || msg.includes("encrypted") || msg.includes("disk image is malformed");
12267
- }
12268
- async function renameAside(filePath) {
12269
- const asidePath = `${filePath}.corrupt-${Date.now()}`;
12270
- await rename(filePath, asidePath).catch(() => void 0);
12271
- await rename(`${filePath}-wal`, `${asidePath}-wal`).catch(() => void 0);
12272
- await rename(`${filePath}-shm`, `${asidePath}-shm`).catch(() => void 0);
12273
- process.stderr.write(
12274
- `[theokit-sdk] memory index corrupt; renamed aside to ${asidePath} and rebuilt schema
12275
- `
12276
- );
12381
+ });
12277
12382
  }
12278
12383
  function defaultIndexPath(cwd) {
12279
12384
  return join(cwd, ".theokit", "memory", ".index", "memory.sqlite");
12280
12385
  }
12281
12386
  var init_index_db = __esm({
12282
12387
  "src/internal/memory/index-db.ts"() {
12283
- init_errors();
12284
- init_sqlite_wal();
12388
+ init_sqlite_open();
12285
12389
  init_index_schema();
12286
12390
  }
12287
12391
  });
@@ -14344,49 +14448,6 @@ var init_task = __esm({
14344
14448
  }
14345
14449
  });
14346
14450
 
14347
- // src/internal/runtime/concurrency/async-semaphore.ts
14348
- function createSemaphore(permits) {
14349
- if (!Number.isInteger(permits) || permits < 1) {
14350
- throw new ConfigurationError(
14351
- `async-semaphore: permits must be a positive integer, got ${permits}`,
14352
- { code: "invalid_concurrency" }
14353
- );
14354
- }
14355
- let active = 0;
14356
- const queue = [];
14357
- function tryGrant() {
14358
- if (active < permits && queue.length > 0) {
14359
- const resolve3 = queue.shift();
14360
- if (resolve3 !== void 0) {
14361
- active += 1;
14362
- resolve3();
14363
- }
14364
- }
14365
- }
14366
- return {
14367
- inFlight: () => active,
14368
- pending: () => queue.length + active,
14369
- async acquire() {
14370
- await new Promise((resolve3) => {
14371
- queue.push(resolve3);
14372
- tryGrant();
14373
- });
14374
- let released = false;
14375
- return () => {
14376
- if (released) return;
14377
- released = true;
14378
- active -= 1;
14379
- tryGrant();
14380
- };
14381
- }
14382
- };
14383
- }
14384
- var init_async_semaphore = __esm({
14385
- "src/internal/runtime/concurrency/async-semaphore.ts"() {
14386
- init_errors();
14387
- }
14388
- });
14389
-
14390
14451
  // src/internal/task/ring-buffer.ts
14391
14452
  var RingBuffer;
14392
14453
  var init_ring_buffer = __esm({