ex-brain 0.2.2 → 0.2.4

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
@@ -2,6 +2,10 @@
2
2
 
3
3
  CLI personal knowledge base built on [seekdb](https://docs.seekdb.ai/), featuring page management, hybrid search, timelines, tags, import/export, and MCP Server.
4
4
 
5
+ ## Demo
6
+
7
+ <video controls="true" width="800" height="438"><source src="https://obcommunityprod.oss-cn-shanghai.aliyuncs.com/prod/blog/2026-04/6aaf141a-75e6-4557-a37d-58036f52fb35.mp4" type="video/mp4"></video>
8
+
5
9
  ## Core Features
6
10
 
7
11
  - **Knowledge Graph Visualization** - Interactive graph showing entity relationships
@@ -10,7 +14,7 @@ CLI personal knowledge base built on [seekdb](https://docs.seekdb.ai/), featurin
10
14
  - **Hybrid Search** - Full-text search + vector semantic queries
11
15
  - **Entity Linking** - Auto-detect entities and create linked pages
12
16
 
13
- <img src="https://mdn.alipayobjects.com/huamei_ytl0i7/afts/img/A*TqdfTZ-yCPwAAAAAgBAAAAgAejCYAQ/original" width="800">
17
+ <img src="https://mdn.alipayobjects.com/huamei_ytl0i7/afts/img/A*jyPOT4CzwL0AAAAAgBAAAAgAejCYAQ/original" width="800">
14
18
 
15
19
  ## Data Collection
16
20
 
@@ -142,4 +146,4 @@ Configure LLM in `~/.ebrain/settings.json`:
142
146
  bun install
143
147
  bun run src/cli.ts --help
144
148
  bun test
145
- ```
149
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ex-brain",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "CLI personal knowledge base powered by seekdb",
5
5
  "module": "src/cli.ts",
6
6
  "type": "module",
@@ -24,6 +24,7 @@
24
24
  "typescript": "^5"
25
25
  },
26
26
  "dependencies": {
27
+ "@ax-llm/ax": "^19.0.43",
27
28
  "@modelcontextprotocol/sdk": "^1.29.0",
28
29
  "@seekdb/js-bindings": "^1.2.0",
29
30
  "@seekdb/openai": "1.2.0",
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Ax Adapter — bridges ex-brain settings to @ax-llm/ax AI instances.
3
+ *
4
+ * Provides a single factory to create Ax AI clients from ex-brain's
5
+ * ResolvedLLM configuration, supporting any OpenAI-compatible endpoint.
6
+ *
7
+ * Fix: Injects enable_thinking: false for DashScope/qwen compatibility.
8
+ * qwen3.5-plus has thinking mode enabled by default, which doesn't support
9
+ * the tool_choice format Ax uses for complex object outputs.
10
+ */
11
+
12
+ import { ai, AxAIOpenAI, type AxAIServiceOptions } from "@ax-llm/ax";
13
+ import type { ResolvedLLM } from "../settings";
14
+
15
+ // ---------------------------------------------------------------------------
16
+ // Custom fetch wrapper: inject enable_thinking: false
17
+ // ---------------------------------------------------------------------------
18
+
19
+ function createThinkingDisabledFetch(originalFetch: typeof fetch): typeof fetch {
20
+ return async function (input: RequestInfo | URL, init?: RequestInit) {
21
+ if (init?.body && typeof init.body === "string") {
22
+ try {
23
+ const body = JSON.parse(init.body);
24
+ // Disable thinking mode for DashScope/qwen compatibility
25
+ // qwen3.5-plus thinking mode doesn't support tool_choice with object format
26
+ body.enable_thinking = false;
27
+ init.body = JSON.stringify(body);
28
+ } catch {
29
+ // Not JSON, leave as-is
30
+ }
31
+ }
32
+ return originalFetch(input, init);
33
+ };
34
+ }
35
+
36
+ // ---------------------------------------------------------------------------
37
+ // Public API
38
+ // ---------------------------------------------------------------------------
39
+
40
+ /**
41
+ * Create an Ax AI instance from ex-brain LLM settings.
42
+ * Returns null if no API key is configured.
43
+ */
44
+ export function createAxAI(llm: ResolvedLLM): AxAIOpenAI<string> | null {
45
+ const apiKey = resolveApiKey(llm);
46
+ if (!apiKey) return null;
47
+
48
+ // Wrap fetch to inject enable_thinking: false for DashScope compatibility
49
+ const wrappedFetch = createThinkingDisabledFetch(fetch);
50
+
51
+ const options: AxAIServiceOptions = {
52
+ fetch: wrappedFetch,
53
+ };
54
+
55
+ // ex-brain uses OpenAI-compatible endpoints (DashScope, etc.)
56
+ // AxAIOpenAI supports custom apiURL for any compatible endpoint.
57
+ return ai({
58
+ name: "openai",
59
+ apiKey,
60
+ ...(llm.baseURL ? { apiURL: llm.baseURL } : {}),
61
+ ...(llm.model ? { config: { model: llm.model } } : {}),
62
+ options,
63
+ });
64
+ }
65
+
66
+ /**
67
+ * Resolve API key from LLM config (direct key or env var).
68
+ */
69
+ export function resolveApiKey(llm: ResolvedLLM): string {
70
+ if (llm.apiKey) return llm.apiKey;
71
+ if (llm.apiKeyEnv) return process.env[llm.apiKeyEnv] ?? "";
72
+ return "";
73
+ }
74
+
75
+ /**
76
+ * Check if LLM is properly configured with an API key.
77
+ */
78
+ export function isConfigured(llm: ResolvedLLM): boolean {
79
+ return !!resolveApiKey(llm);
80
+ }