@hasna/knowledge 0.2.10 → 0.2.11

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/README.md CHANGED
@@ -82,6 +82,10 @@ open-knowledge source resolve open-files://file/f_123/revision/rev_456 --scope p
82
82
 
83
83
  # Inspect local safety policy and approvals
84
84
  open-knowledge safety status --scope project --json
85
+
86
+ # Inspect AI SDK provider credentials and model aliases
87
+ open-knowledge providers status --scope project --json
88
+ open-knowledge providers models --scope project --json
85
89
  ```
86
90
 
87
91
  ## Commands
@@ -226,6 +230,19 @@ Inspect and operate the local safety model. Source reads are read-only by
226
230
  default, web search and S3 reads are opt-in, generated writes require approval
227
231
  by default, and known secret patterns are redacted before chunk storage.
228
232
 
233
+ ### providers
234
+ ```bash
235
+ open-knowledge providers status [--scope project] [--json]
236
+ open-knowledge providers models [--scope project] [--json]
237
+ open-knowledge providers check [provider|model-alias] [--scope project] [--json]
238
+ ```
239
+ Inspect AI SDK v6 provider readiness for OpenAI, Anthropic, and DeepSeek. The
240
+ provider layer resolves BYOK credentials from `OPENAI_API_KEY`,
241
+ `ANTHROPIC_API_KEY`, and `DEEPSEEK_API_KEY` by default, exposes model aliases
242
+ such as `default`, `fast`, `reasoning`, `sonnet`, and `deepseek`, and records
243
+ provider capability metadata for structured output, tool use, tool streaming,
244
+ reasoning, embeddings, and native web-search support.
245
+
229
246
  ### help
230
247
  ```bash
231
248
  open-knowledge help [command]
@@ -281,6 +298,11 @@ source ref. It does not copy raw files into the knowledge workspace; local file,
281
298
  S3, web, and open-files inputs are converted into redacted chunks with offsets,
282
299
  hashes, revision metadata, and FTS rows.
283
300
 
301
+ AI provider configuration is local/BYOK by default. `open-knowledge` declares
302
+ AI SDK v6 provider support through `ai`, `@ai-sdk/openai`,
303
+ `@ai-sdk/anthropic`, and `@ai-sdk/deepseek`, but does not call providers until a
304
+ future prompt/agent command explicitly requests a model.
305
+
284
306
  Generated knowledge artifacts can be stored locally under
285
307
  `.hasna/apps/knowledge/artifacts` or through the S3 artifact-store adapter.
286
308
 
@@ -13660,7 +13660,7 @@ import { existsSync as existsSync7, readFileSync as readFileSync7, writeFileSync
13660
13660
  // package.json
13661
13661
  var package_default = {
13662
13662
  name: "@hasna/knowledge",
13663
- version: "0.2.10",
13663
+ version: "0.2.11",
13664
13664
  description: "Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",
13665
13665
  type: "module",
13666
13666
  bin: {
@@ -13677,7 +13677,7 @@ var package_default = {
13677
13677
  scripts: {
13678
13678
  test: "bun test",
13679
13679
  "test:cli": "bun test tests/cli.test.ts",
13680
- build: "bun build --target=bun --outfile=bin/open-knowledge.js --minify --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers src/cli.ts && bun build --target=bun --outfile=bin/open-knowledge-mcp.js --external @modelcontextprotocol/sdk --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers src/mcp.js",
13680
+ build: "bun build --target=bun --outfile=bin/open-knowledge.js --minify --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/cli.ts && bun build --target=bun --outfile=bin/open-knowledge-mcp.js --external @modelcontextprotocol/sdk --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/mcp.js",
13681
13681
  prepublishOnly: "bun run build",
13682
13682
  postinstall: "bun run build"
13683
13683
  },
@@ -13710,7 +13710,11 @@ var package_default = {
13710
13710
  dependencies: {
13711
13711
  "@aws-sdk/client-s3": "^3.1063.0",
13712
13712
  "@aws-sdk/credential-providers": "^3.1063.0",
13713
+ "@ai-sdk/anthropic": "^3.0.81",
13714
+ "@ai-sdk/deepseek": "^2.0.35",
13715
+ "@ai-sdk/openai": "^3.0.68",
13713
13716
  "@modelcontextprotocol/sdk": "^1.29.0",
13717
+ ai: "^6.0.197",
13714
13718
  zod: "^4.3.6"
13715
13719
  },
13716
13720
  devDependencies: {
@@ -13764,6 +13768,28 @@ function defaultKnowledgeConfig() {
13764
13768
  preferred_ref: "open-files",
13765
13769
  allowed_schemes: ["open-files", "s3", "file", "https", "http"]
13766
13770
  },
13771
+ providers: {
13772
+ default_model: "openai:gpt-5.2",
13773
+ aliases: {
13774
+ fast: "openai:gpt-5-mini",
13775
+ reasoning: "anthropic:claude-opus-4-6",
13776
+ sonnet: "anthropic:claude-sonnet-4-6",
13777
+ deepseek: "deepseek:deepseek-chat",
13778
+ "deepseek-reasoning": "deepseek:deepseek-reasoner"
13779
+ },
13780
+ openai: {
13781
+ api_key_env: "OPENAI_API_KEY",
13782
+ default_model: "gpt-5.2"
13783
+ },
13784
+ anthropic: {
13785
+ api_key_env: "ANTHROPIC_API_KEY",
13786
+ default_model: "claude-sonnet-4-6"
13787
+ },
13788
+ deepseek: {
13789
+ api_key_env: "DEEPSEEK_API_KEY",
13790
+ default_model: "deepseek-chat"
13791
+ }
13792
+ },
13767
13793
  safety: {
13768
13794
  network: {
13769
13795
  web_search_enabled: false,
@@ -15773,6 +15799,129 @@ async function ingestSourceRef(options) {
15773
15799
  };
15774
15800
  }
15775
15801
 
15802
+ // src/providers.ts
15803
+ var DEFAULT_PROVIDER_SETTINGS = {
15804
+ openai: {
15805
+ api_key_env: "OPENAI_API_KEY",
15806
+ default_model: "gpt-5.2"
15807
+ },
15808
+ anthropic: {
15809
+ api_key_env: "ANTHROPIC_API_KEY",
15810
+ default_model: "claude-sonnet-4-6"
15811
+ },
15812
+ deepseek: {
15813
+ api_key_env: "DEEPSEEK_API_KEY",
15814
+ default_model: "deepseek-chat"
15815
+ }
15816
+ };
15817
+ var PROVIDER_CAPABILITIES = {
15818
+ openai: {
15819
+ text_generation: true,
15820
+ structured_output: true,
15821
+ tool_usage: true,
15822
+ tool_streaming: true,
15823
+ image_input: true,
15824
+ native_web_search: true,
15825
+ reasoning: true,
15826
+ embeddings: true
15827
+ },
15828
+ anthropic: {
15829
+ text_generation: true,
15830
+ structured_output: true,
15831
+ tool_usage: true,
15832
+ tool_streaming: true,
15833
+ image_input: true,
15834
+ native_web_search: false,
15835
+ reasoning: true,
15836
+ embeddings: false
15837
+ },
15838
+ deepseek: {
15839
+ text_generation: true,
15840
+ structured_output: true,
15841
+ tool_usage: true,
15842
+ tool_streaming: true,
15843
+ image_input: false,
15844
+ native_web_search: false,
15845
+ reasoning: true,
15846
+ embeddings: false
15847
+ }
15848
+ };
15849
+ var BUILTIN_ALIASES = {
15850
+ default: "openai:gpt-5.2",
15851
+ fast: "openai:gpt-5-mini",
15852
+ reasoning: "anthropic:claude-opus-4-6",
15853
+ sonnet: "anthropic:claude-sonnet-4-6",
15854
+ deepseek: "deepseek:deepseek-chat",
15855
+ "deepseek-reasoning": "deepseek:deepseek-reasoner"
15856
+ };
15857
+ function providerConfig(config2) {
15858
+ return config2.providers ?? {};
15859
+ }
15860
+ function providerSettings(config2, provider) {
15861
+ const configured = providerConfig(config2)[provider] ?? {};
15862
+ return {
15863
+ ...DEFAULT_PROVIDER_SETTINGS[provider],
15864
+ ...configured
15865
+ };
15866
+ }
15867
+ function modelAliases(config2) {
15868
+ const configured = providerConfig(config2);
15869
+ return {
15870
+ ...BUILTIN_ALIASES,
15871
+ ...configured.default_model ? { default: configured.default_model } : {},
15872
+ ...configured.aliases ?? {}
15873
+ };
15874
+ }
15875
+ function parseModelRef(modelRef) {
15876
+ const [provider, ...rest] = modelRef.split(":");
15877
+ const model = rest.join(":");
15878
+ if (provider !== "openai" && provider !== "anthropic" && provider !== "deepseek") {
15879
+ throw new Error(`Unsupported AI provider: ${provider}`);
15880
+ }
15881
+ if (!model)
15882
+ throw new Error(`Invalid model ref: ${modelRef}. Expected provider:model.`);
15883
+ return { provider, model };
15884
+ }
15885
+ function resolveModelRef(aliasOrRef, config2) {
15886
+ const aliases = modelAliases(config2);
15887
+ return aliases[aliasOrRef] ?? aliasOrRef;
15888
+ }
15889
+ function listModelRegistry(config2) {
15890
+ const aliases = modelAliases(config2);
15891
+ return Object.entries(aliases).map(([alias, modelRef]) => {
15892
+ const parsed = parseModelRef(modelRef);
15893
+ return {
15894
+ alias,
15895
+ model_ref: modelRef,
15896
+ provider: parsed.provider,
15897
+ model: parsed.model,
15898
+ default: alias === "default",
15899
+ capabilities: PROVIDER_CAPABILITIES[parsed.provider]
15900
+ };
15901
+ });
15902
+ }
15903
+ function providerCredentialStatus(config2, env = process.env) {
15904
+ return Object.keys(DEFAULT_PROVIDER_SETTINGS).map((provider) => {
15905
+ const settings = providerSettings(config2, provider);
15906
+ const configured = Boolean(env[settings.api_key_env]);
15907
+ return {
15908
+ provider,
15909
+ api_key_env: settings.api_key_env,
15910
+ configured,
15911
+ source: configured ? "env" : "missing",
15912
+ base_url: settings.base_url ?? null,
15913
+ default_model: settings.default_model
15914
+ };
15915
+ });
15916
+ }
15917
+ function providerStatus(config2, env = process.env) {
15918
+ return {
15919
+ default_model: resolveModelRef("default", config2),
15920
+ providers: providerCredentialStatus(config2, env),
15921
+ models: listModelRegistry(config2)
15922
+ };
15923
+ }
15924
+
15776
15925
  // src/wiki-layout.ts
15777
15926
  function todayParts(now) {
15778
15927
  const year = String(now.getUTCFullYear());
@@ -15967,6 +16116,12 @@ class KnowledgeService {
15967
16116
  safetyPolicy: this.safetyPolicy()
15968
16117
  });
15969
16118
  }
16119
+ providerStatus(env = process.env) {
16120
+ return providerStatus(this.config(), env);
16121
+ }
16122
+ modelRegistry() {
16123
+ return listModelRegistry(this.config());
16124
+ }
15970
16125
  }
15971
16126
  function createKnowledgeService(options = {}) {
15972
16127
  return new KnowledgeService(options);
@@ -16058,6 +16213,18 @@ function buildServer() {
16058
16213
  return errorText(error48 instanceof Error ? error48.message : String(error48));
16059
16214
  }
16060
16215
  });
16216
+ registerTool(server, "ok_provider_status", "AI provider status", "Inspect configured AI SDK providers, model aliases, and BYOK credential availability", {
16217
+ scope: scopeField
16218
+ }, async ({ scope }) => {
16219
+ const service = createKnowledgeService({ scope });
16220
+ return jsonText({ ok: true, ...service.providerStatus() });
16221
+ });
16222
+ registerTool(server, "ok_provider_models", "AI provider models", "List AI SDK model aliases and capability metadata", {
16223
+ scope: scopeField
16224
+ }, async ({ scope }) => {
16225
+ const service = createKnowledgeService({ scope });
16226
+ return jsonText({ ok: true, models: service.modelRegistry() });
16227
+ });
16061
16228
  registerTool(server, "ok_add", "Add a knowledge item", "Add a new item to the knowledge store", {
16062
16229
  title: exports_external.string().describe("Item title"),
16063
16230
  content: exports_external.string().describe("Item content/body"),