@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/CHANGELOG.md +12 -0
- package/dist/cron.cjs +107 -8
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +110 -11
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +107 -8
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +110 -11
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +108 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +109 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.15.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- fix(providers): M47 adversarial-review fixes on the dynamic-loader trust gate — (F1) `Agent.resume` now runs provider-plugin discovery (a fresh process resuming a persisted agent whose model targets a plugin provider no longer fails resolution); (F2) `Theokit.models.list({provider})` local path runs discovery too (sync surfaces stay builtins-only, documented); (F3) the discovery idempotence flag moved to `globalThis` (`Symbol.for`) matching the registry's M44 B1 pattern — no duplicate discovery per bundle entry; (F4/F7) the NOT-trusted WARN now says "then restart the process" and documents the comma-separated env format; (F5) non-string entries in a valid trust-file array WARN instead of being silently discarded.
|
|
8
|
+
|
|
9
|
+
## 4.15.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- fix(providers): wire `discoverProviderPlugins()` into `Agent.create` — the dynamic provider-plugin loader (and its M47 trust gate) was exported but never invoked on any production path, making the whole discovery surface dead code at runtime. Discovery now runs upfront on agent initialization (idempotent, fail-tolerant), honoring the `resolveProviderChain` contract.
|
|
14
|
+
|
|
3
15
|
## 4.15.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/cron.cjs
CHANGED
|
@@ -8940,14 +8940,14 @@ var PluginsManager = class {
|
|
|
8940
8940
|
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: MD-first + JSON fallback + both-present detection per plugin folder — branch table is clearer inlined.
|
|
8941
8941
|
async refresh() {
|
|
8942
8942
|
this.plugins = [];
|
|
8943
|
-
const
|
|
8944
|
-
const entries = await readWorkspaceDir(
|
|
8943
|
+
const pluginsRoot2 = path.join(this.cwd, ".theokit", "plugins");
|
|
8944
|
+
const entries = await readWorkspaceDir(pluginsRoot2, "plugins_read_error", "plugins directory");
|
|
8945
8945
|
for (const entry of entries) {
|
|
8946
8946
|
if (!entry.isDirectory()) continue;
|
|
8947
8947
|
const folderName = entry.name;
|
|
8948
|
-
const mdPath = path.join(
|
|
8949
|
-
const jsonPath = path.join(
|
|
8950
|
-
const metadata = fs.existsSync(mdPath) ? await loadPluginManifestFromMarkdown(
|
|
8948
|
+
const mdPath = path.join(pluginsRoot2, folderName, "PLUGIN.md");
|
|
8949
|
+
const jsonPath = path.join(pluginsRoot2, folderName, "plugin.json");
|
|
8950
|
+
const metadata = fs.existsSync(mdPath) ? await loadPluginManifestFromMarkdown(pluginsRoot2, folderName) : await loadPluginManifestFromJson(jsonPath, folderName);
|
|
8951
8951
|
if (fs.existsSync(mdPath) && fs.existsSync(jsonPath)) {
|
|
8952
8952
|
warnOnce(
|
|
8953
8953
|
`plugin-${folderName}-both`,
|
|
@@ -9026,8 +9026,8 @@ async function loadPluginManifestFromJson(manifestPath, folderName) {
|
|
|
9026
9026
|
if (typeof record.entry === "string") metadata.entry = record.entry;
|
|
9027
9027
|
return metadata;
|
|
9028
9028
|
}
|
|
9029
|
-
async function loadPluginManifestFromMarkdown(
|
|
9030
|
-
const mdPath = path.join(
|
|
9029
|
+
async function loadPluginManifestFromMarkdown(pluginsRoot2, folderName) {
|
|
9030
|
+
const mdPath = path.join(pluginsRoot2, folderName, "PLUGIN.md");
|
|
9031
9031
|
let raw;
|
|
9032
9032
|
try {
|
|
9033
9033
|
raw = await promises.readFile(mdPath, "utf8");
|
|
@@ -9037,7 +9037,7 @@ async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
|
|
|
9037
9037
|
cause
|
|
9038
9038
|
});
|
|
9039
9039
|
}
|
|
9040
|
-
const fakeDir = path.join(
|
|
9040
|
+
const fakeDir = path.join(pluginsRoot2, folderName);
|
|
9041
9041
|
const entities = await loadMarkdownEntities({
|
|
9042
9042
|
dir: fakeDir,
|
|
9043
9043
|
schema: PluginFrontmatterSchema,
|
|
@@ -12036,6 +12036,103 @@ function registerBuiltins() {
|
|
|
12036
12036
|
registerProvider(CEREBRAS);
|
|
12037
12037
|
registerCatalogProviders();
|
|
12038
12038
|
}
|
|
12039
|
+
function globalSingleton3(key, create) {
|
|
12040
|
+
const g = globalThis;
|
|
12041
|
+
const sym = Symbol.for(key);
|
|
12042
|
+
if (g[sym] === void 0) g[sym] = create();
|
|
12043
|
+
return g[sym];
|
|
12044
|
+
}
|
|
12045
|
+
var discoveryState = globalSingleton3("theokit-sdk.providers.discovered", () => ({
|
|
12046
|
+
done: false
|
|
12047
|
+
}));
|
|
12048
|
+
function pluginsRoot() {
|
|
12049
|
+
return path.join(os.homedir(), ".theokit", "plugins", "model-providers");
|
|
12050
|
+
}
|
|
12051
|
+
function trustFilePath() {
|
|
12052
|
+
return path.join(os.homedir(), ".theokit", "plugins", "trusted-providers.json");
|
|
12053
|
+
}
|
|
12054
|
+
function loadTrustedNames() {
|
|
12055
|
+
const trusted = /* @__PURE__ */ new Set();
|
|
12056
|
+
const path = trustFilePath();
|
|
12057
|
+
if (fs.existsSync(path)) {
|
|
12058
|
+
try {
|
|
12059
|
+
const parsed = JSON.parse(fs.readFileSync(path, "utf-8"));
|
|
12060
|
+
if (Array.isArray(parsed)) {
|
|
12061
|
+
let discarded = 0;
|
|
12062
|
+
for (const name of parsed) {
|
|
12063
|
+
if (typeof name === "string" && name.length > 0) trusted.add(name);
|
|
12064
|
+
else discarded += 1;
|
|
12065
|
+
}
|
|
12066
|
+
if (discarded > 0) {
|
|
12067
|
+
process.stderr.write(
|
|
12068
|
+
`[theokit-sdk] WARN: ${path} contains ${discarded} non-string entr${discarded === 1 ? "y" : "ies"} \u2014 discarded (entries must be plugin-name strings)
|
|
12069
|
+
`
|
|
12070
|
+
);
|
|
12071
|
+
}
|
|
12072
|
+
} else {
|
|
12073
|
+
process.stderr.write(
|
|
12074
|
+
`[theokit-sdk] WARN: ${path} is not a JSON array \u2014 trusting NO provider plugins (fail-closed)
|
|
12075
|
+
`
|
|
12076
|
+
);
|
|
12077
|
+
}
|
|
12078
|
+
} catch {
|
|
12079
|
+
process.stderr.write(
|
|
12080
|
+
`[theokit-sdk] WARN: ${path} is not valid JSON \u2014 trusting NO provider plugins (fail-closed)
|
|
12081
|
+
`
|
|
12082
|
+
);
|
|
12083
|
+
}
|
|
12084
|
+
}
|
|
12085
|
+
for (const name of (process.env.THEOKIT_TRUSTED_PROVIDERS ?? "").split(",")) {
|
|
12086
|
+
const trimmed = name.trim();
|
|
12087
|
+
if (trimmed.length > 0) trusted.add(trimmed);
|
|
12088
|
+
}
|
|
12089
|
+
return trusted;
|
|
12090
|
+
}
|
|
12091
|
+
async function discoverProviderPlugins() {
|
|
12092
|
+
if (discoveryState.done) return;
|
|
12093
|
+
discoveryState.done = true;
|
|
12094
|
+
const root = pluginsRoot();
|
|
12095
|
+
if (!fs.existsSync(root)) return;
|
|
12096
|
+
let entries;
|
|
12097
|
+
try {
|
|
12098
|
+
entries = await promises.readdir(root);
|
|
12099
|
+
} catch {
|
|
12100
|
+
return;
|
|
12101
|
+
}
|
|
12102
|
+
const trusted = loadTrustedNames();
|
|
12103
|
+
for (const entry of entries) {
|
|
12104
|
+
if (!trusted.has(entry)) {
|
|
12105
|
+
process.stderr.write(
|
|
12106
|
+
`[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.
|
|
12107
|
+
`
|
|
12108
|
+
);
|
|
12109
|
+
continue;
|
|
12110
|
+
}
|
|
12111
|
+
await loadOne(path.join(root, entry), entry);
|
|
12112
|
+
}
|
|
12113
|
+
}
|
|
12114
|
+
async function loadOne(dir, entryName) {
|
|
12115
|
+
for (const ext of ["index.mjs", "index.js"]) {
|
|
12116
|
+
const indexPath = path.join(dir, ext);
|
|
12117
|
+
if (!fs.existsSync(indexPath)) continue;
|
|
12118
|
+
try {
|
|
12119
|
+
const mod = await import(url.pathToFileURL(indexPath).href);
|
|
12120
|
+
const plugin = mod.default ?? mod[entryName] ?? mod;
|
|
12121
|
+
if (plugin !== null && typeof plugin === "object" && plugin.kind === "model-provider") {
|
|
12122
|
+
const profile = plugin.profile;
|
|
12123
|
+
if (profile !== void 0 && typeof profile === "object") {
|
|
12124
|
+
registerProvider(profile);
|
|
12125
|
+
}
|
|
12126
|
+
}
|
|
12127
|
+
return;
|
|
12128
|
+
} catch (err) {
|
|
12129
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12130
|
+
process.stderr.write(`[theokit-sdk] failed to load provider plugin "${entryName}": ${msg}
|
|
12131
|
+
`);
|
|
12132
|
+
return;
|
|
12133
|
+
}
|
|
12134
|
+
}
|
|
12135
|
+
}
|
|
12039
12136
|
|
|
12040
12137
|
// src/internal/llm/anthropic.ts
|
|
12041
12138
|
init_errors();
|
|
@@ -18584,6 +18681,7 @@ function resolveAgentPersistenceCwd(options) {
|
|
|
18584
18681
|
return process.cwd();
|
|
18585
18682
|
}
|
|
18586
18683
|
async function rehydrateExistingAgent(agentId, existing, options) {
|
|
18684
|
+
await discoverProviderPlugins();
|
|
18587
18685
|
await validateRehydratedAgent(agentId, existing);
|
|
18588
18686
|
const mergedLocal = options.local !== void 0 && existing.options.local !== void 0 ? { ...existing.options.local, ...options.local } : options.local ?? existing.options.local;
|
|
18589
18687
|
const mergedOptions = {
|
|
@@ -18713,6 +18811,7 @@ var Agent = class _Agent {
|
|
|
18713
18811
|
pluginCount: enabledPluginNames(options.plugins).length
|
|
18714
18812
|
});
|
|
18715
18813
|
try {
|
|
18814
|
+
await discoverProviderPlugins();
|
|
18716
18815
|
const agent = await runCreateUnderSpan(options, span);
|
|
18717
18816
|
return agent;
|
|
18718
18817
|
} catch (err) {
|