@theokit/sdk 4.15.0 → 4.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import { existsSync, rmSync, mkdirSync, renameSync, readFileSync, realpathSync,
7
7
  import { AsyncLocalStorage } from 'async_hooks';
8
8
  import { homedir } from 'os';
9
9
  import { spawn } from 'child_process';
10
- import { fileURLToPath } from 'url';
10
+ import { fileURLToPath, pathToFileURL } from 'url';
11
11
  import { Cron as Cron$1 } from 'croner';
12
12
 
13
13
  var __defProp = Object.defineProperty;
@@ -11519,14 +11519,14 @@ var PluginsManager = class {
11519
11519
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: MD-first + JSON fallback + both-present detection per plugin folder — branch table is clearer inlined.
11520
11520
  async refresh() {
11521
11521
  this.plugins = [];
11522
- const pluginsRoot = join(this.cwd, ".theokit", "plugins");
11523
- const entries = await readWorkspaceDir(pluginsRoot, "plugins_read_error", "plugins directory");
11522
+ const pluginsRoot2 = join(this.cwd, ".theokit", "plugins");
11523
+ const entries = await readWorkspaceDir(pluginsRoot2, "plugins_read_error", "plugins directory");
11524
11524
  for (const entry of entries) {
11525
11525
  if (!entry.isDirectory()) continue;
11526
11526
  const folderName = entry.name;
11527
- const mdPath = join(pluginsRoot, folderName, "PLUGIN.md");
11528
- const jsonPath = join(pluginsRoot, folderName, "plugin.json");
11529
- const metadata = existsSync(mdPath) ? await loadPluginManifestFromMarkdown(pluginsRoot, folderName) : await loadPluginManifestFromJson(jsonPath, folderName);
11527
+ const mdPath = join(pluginsRoot2, folderName, "PLUGIN.md");
11528
+ const jsonPath = join(pluginsRoot2, folderName, "plugin.json");
11529
+ const metadata = existsSync(mdPath) ? await loadPluginManifestFromMarkdown(pluginsRoot2, folderName) : await loadPluginManifestFromJson(jsonPath, folderName);
11530
11530
  if (existsSync(mdPath) && existsSync(jsonPath)) {
11531
11531
  warnOnce(
11532
11532
  `plugin-${folderName}-both`,
@@ -11605,8 +11605,8 @@ async function loadPluginManifestFromJson(manifestPath, folderName) {
11605
11605
  if (typeof record.entry === "string") metadata.entry = record.entry;
11606
11606
  return metadata;
11607
11607
  }
11608
- async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
11609
- const mdPath = join(pluginsRoot, folderName, "PLUGIN.md");
11608
+ async function loadPluginManifestFromMarkdown(pluginsRoot2, folderName) {
11609
+ const mdPath = join(pluginsRoot2, folderName, "PLUGIN.md");
11610
11610
  let raw;
11611
11611
  try {
11612
11612
  raw = await readFile(mdPath, "utf8");
@@ -11616,7 +11616,7 @@ async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
11616
11616
  cause
11617
11617
  });
11618
11618
  }
11619
- const fakeDir = join(pluginsRoot, folderName);
11619
+ const fakeDir = join(pluginsRoot2, folderName);
11620
11620
  const entities = await loadMarkdownEntities({
11621
11621
  dir: fakeDir,
11622
11622
  schema: PluginFrontmatterSchema,
@@ -14632,6 +14632,103 @@ function registerBuiltins() {
14632
14632
  registerProvider(CEREBRAS);
14633
14633
  registerCatalogProviders();
14634
14634
  }
14635
+ function globalSingleton3(key2, create) {
14636
+ const g = globalThis;
14637
+ const sym = Symbol.for(key2);
14638
+ if (g[sym] === void 0) g[sym] = create();
14639
+ return g[sym];
14640
+ }
14641
+ var discoveryState = globalSingleton3("theokit-sdk.providers.discovered", () => ({
14642
+ done: false
14643
+ }));
14644
+ function pluginsRoot() {
14645
+ return join(homedir(), ".theokit", "plugins", "model-providers");
14646
+ }
14647
+ function trustFilePath() {
14648
+ return join(homedir(), ".theokit", "plugins", "trusted-providers.json");
14649
+ }
14650
+ function loadTrustedNames() {
14651
+ const trusted = /* @__PURE__ */ new Set();
14652
+ const path = trustFilePath();
14653
+ if (existsSync(path)) {
14654
+ try {
14655
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
14656
+ if (Array.isArray(parsed)) {
14657
+ let discarded = 0;
14658
+ for (const name of parsed) {
14659
+ if (typeof name === "string" && name.length > 0) trusted.add(name);
14660
+ else discarded += 1;
14661
+ }
14662
+ if (discarded > 0) {
14663
+ process.stderr.write(
14664
+ `[theokit-sdk] WARN: ${path} contains ${discarded} non-string entr${discarded === 1 ? "y" : "ies"} \u2014 discarded (entries must be plugin-name strings)
14665
+ `
14666
+ );
14667
+ }
14668
+ } else {
14669
+ process.stderr.write(
14670
+ `[theokit-sdk] WARN: ${path} is not a JSON array \u2014 trusting NO provider plugins (fail-closed)
14671
+ `
14672
+ );
14673
+ }
14674
+ } catch {
14675
+ process.stderr.write(
14676
+ `[theokit-sdk] WARN: ${path} is not valid JSON \u2014 trusting NO provider plugins (fail-closed)
14677
+ `
14678
+ );
14679
+ }
14680
+ }
14681
+ for (const name of (process.env.THEOKIT_TRUSTED_PROVIDERS ?? "").split(",")) {
14682
+ const trimmed = name.trim();
14683
+ if (trimmed.length > 0) trusted.add(trimmed);
14684
+ }
14685
+ return trusted;
14686
+ }
14687
+ async function discoverProviderPlugins() {
14688
+ if (discoveryState.done) return;
14689
+ discoveryState.done = true;
14690
+ const root = pluginsRoot();
14691
+ if (!existsSync(root)) return;
14692
+ let entries;
14693
+ try {
14694
+ entries = await readdir(root);
14695
+ } catch {
14696
+ return;
14697
+ }
14698
+ const trusted = loadTrustedNames();
14699
+ for (const entry of entries) {
14700
+ if (!trusted.has(entry)) {
14701
+ process.stderr.write(
14702
+ `[theokit-sdk] WARN: provider plugin "${entry}" is present but NOT trusted \u2014 skipped. To trust it, add "${entry}" to ${trustFilePath()} (JSON array of names) or THEOKIT_TRUSTED_PROVIDERS (comma-separated), then restart the process.
14703
+ `
14704
+ );
14705
+ continue;
14706
+ }
14707
+ await loadOne(join(root, entry), entry);
14708
+ }
14709
+ }
14710
+ async function loadOne(dir, entryName) {
14711
+ for (const ext of ["index.mjs", "index.js"]) {
14712
+ const indexPath = join(dir, ext);
14713
+ if (!existsSync(indexPath)) continue;
14714
+ try {
14715
+ const mod = await import(pathToFileURL(indexPath).href);
14716
+ const plugin = mod.default ?? mod[entryName] ?? mod;
14717
+ if (plugin !== null && typeof plugin === "object" && plugin.kind === "model-provider") {
14718
+ const profile = plugin.profile;
14719
+ if (profile !== void 0 && typeof profile === "object") {
14720
+ registerProvider(profile);
14721
+ }
14722
+ }
14723
+ return;
14724
+ } catch (err) {
14725
+ const msg = err instanceof Error ? err.message : String(err);
14726
+ process.stderr.write(`[theokit-sdk] failed to load provider plugin "${entryName}": ${msg}
14727
+ `);
14728
+ return;
14729
+ }
14730
+ }
14731
+ }
14635
14732
 
14636
14733
  // src/internal/llm/anthropic.ts
14637
14734
  init_errors();
@@ -20234,6 +20331,7 @@ function resolveAgentPersistenceCwd(options) {
20234
20331
  return process.cwd();
20235
20332
  }
20236
20333
  async function rehydrateExistingAgent(agentId, existing, options) {
20334
+ await discoverProviderPlugins();
20237
20335
  await validateRehydratedAgent(agentId, existing);
20238
20336
  const mergedLocal = options.local !== void 0 && existing.options.local !== void 0 ? { ...existing.options.local, ...options.local } : options.local ?? existing.options.local;
20239
20337
  const mergedOptions = {
@@ -20363,6 +20461,7 @@ var Agent = class _Agent {
20363
20461
  pluginCount: enabledPluginNames(options.plugins).length
20364
20462
  });
20365
20463
  try {
20464
+ await discoverProviderPlugins();
20366
20465
  const agent = await runCreateUnderSpan(options, span);
20367
20466
  return agent;
20368
20467
  } catch (err) {
@@ -23311,6 +23410,7 @@ var Theokit = class {
23311
23410
  };
23312
23411
  async function maybeListLocalModels(providerName) {
23313
23412
  registerBuiltins();
23413
+ await discoverProviderPlugins();
23314
23414
  const profile = getProviderProfile(providerName);
23315
23415
  if (profile === void 0) return void 0;
23316
23416
  if (profile.authType !== "none") return void 0;