toolpack-cli 1.0.1 → 1.1.0-SNAPSHOT.202603211
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.
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function KnowledgeLoader(): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { useToolpack } from '../context/ToolpackContext.js';
|
|
4
|
+
import { useTheme } from '../theme/ThemeContext.js';
|
|
5
|
+
const BAR_WIDTH = 30;
|
|
6
|
+
export function KnowledgeLoader() {
|
|
7
|
+
const { knowledgeProgress } = useToolpack();
|
|
8
|
+
const { theme } = useTheme();
|
|
9
|
+
if (!knowledgeProgress || knowledgeProgress.phase === 'complete') {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
const percentage = Math.min(knowledgeProgress.percentage ?? 0, 99);
|
|
13
|
+
const filled = Math.round((percentage / 100) * BAR_WIDTH);
|
|
14
|
+
const label = knowledgeProgress.phase === 'start'
|
|
15
|
+
? 'Scanning knowledge sources...'
|
|
16
|
+
: `Embedding content (${percentage}%)`;
|
|
17
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: theme.colors.border, paddingX: 2, paddingY: 1, marginBottom: 1, children: [_jsx(Text, { color: theme.colors.primary, children: "Knowledge base initializing\u2026" }), _jsx(Text, { color: theme.colors.text, children: label }), _jsxs(Text, { color: theme.colors.textSecondary, children: ["[", '#'.repeat(Math.max(0, filled)), ' '.repeat(Math.max(0, BAR_WIDTH - filled)), "] ", percentage, "%"] }), knowledgeProgress.currentSource && (_jsxs(Text, { color: theme.colors.textSecondary, children: ["Source: ", knowledgeProgress.currentSource] }))] }));
|
|
18
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import { Toolpack, ModeConfig, ToolLogEvent, WorkflowProgress } from 'toolpack-sdk';
|
|
2
|
+
import { Toolpack, ModeConfig, ToolLogEvent, WorkflowProgress, EmbeddingProgressEvent } from 'toolpack-sdk';
|
|
3
3
|
/**
|
|
4
4
|
* Clean React Context wrapper for the Toolpack SDK.
|
|
5
5
|
* Manages SDK-related state only: modes, models, and the toolpack instance.
|
|
@@ -47,6 +47,7 @@ interface ToolpackContextType {
|
|
|
47
47
|
setToolsUnsupportedWarning: (msg: string) => void;
|
|
48
48
|
configSource: 'local' | 'global' | 'base' | 'default';
|
|
49
49
|
activeConfigPath: string | null;
|
|
50
|
+
knowledgeProgress: EmbeddingProgressEvent | null;
|
|
50
51
|
}
|
|
51
52
|
export declare function ToolpackProvider({ children }: {
|
|
52
53
|
children: ReactNode;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useContext, useEffect, useState, useCallback, } from 'react';
|
|
3
|
-
import { Toolpack, createMode, loadRuntimeConfig, getRuntimeConfigStatus, } from 'toolpack-sdk';
|
|
3
|
+
import { Toolpack, createMode, loadRuntimeConfig, getRuntimeConfigStatus, Knowledge, MemoryProvider, MarkdownSource, JSONSource, SQLiteTextSource, } from 'toolpack-sdk';
|
|
4
|
+
import Database from 'better-sqlite3';
|
|
4
5
|
import { XAIAdapter } from '../custom-providers/XAIAdapter.js';
|
|
5
6
|
import { skillToolsProject } from '../custom-tools/skill-tools/index.js';
|
|
6
7
|
import * as fs from 'fs';
|
|
7
8
|
import * as os from 'os';
|
|
8
9
|
import * as path from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
9
13
|
const ToolpackContext = createContext(undefined);
|
|
10
14
|
export function ToolpackProvider({ children }) {
|
|
11
15
|
const [toolpack, setToolpack] = useState(null);
|
|
@@ -21,6 +25,7 @@ export function ToolpackProvider({ children }) {
|
|
|
21
25
|
const [toolsUnsupportedWarning, setToolsUnsupportedWarning] = useState(null);
|
|
22
26
|
const [configSource, setConfigSource] = useState('default');
|
|
23
27
|
const [activeConfigPath, setActiveConfigPath] = useState(null);
|
|
28
|
+
const [knowledgeProgress, setKnowledgeProgress] = useState(null);
|
|
24
29
|
useEffect(() => {
|
|
25
30
|
async function init() {
|
|
26
31
|
// Get config status
|
|
@@ -41,6 +46,28 @@ export function ToolpackProvider({ children }) {
|
|
|
41
46
|
systemPrompt: 'You are a helpful assistant. Provide clear and concise responses.',
|
|
42
47
|
blockAllTools: true,
|
|
43
48
|
});
|
|
49
|
+
const knowledgeBasePath = ensureGlobalKnowledgeAssets();
|
|
50
|
+
const kb = await Knowledge.create({
|
|
51
|
+
provider: new MemoryProvider(),
|
|
52
|
+
sources: [
|
|
53
|
+
new MarkdownSource(path.join(knowledgeBasePath, '**/*.md'), { namespace: 'docs' }),
|
|
54
|
+
new JSONSource(path.join(knowledgeBasePath, 'toolpack-cli.json'), {
|
|
55
|
+
chunkBy: 'item',
|
|
56
|
+
contentFields: ['title', 'description'],
|
|
57
|
+
metadataFields: ['id', 'category'],
|
|
58
|
+
namespace: 'json',
|
|
59
|
+
}),
|
|
60
|
+
new SQLiteTextSource(path.join(knowledgeBasePath, 'toolpack-guides.db'), {
|
|
61
|
+
table: 'guides',
|
|
62
|
+
contentColumns: ['title', 'body'],
|
|
63
|
+
metadataColumns: ['category'],
|
|
64
|
+
namespace: 'guides',
|
|
65
|
+
}),
|
|
66
|
+
],
|
|
67
|
+
onEmbeddingProgress: event => {
|
|
68
|
+
setKnowledgeProgress(event);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
44
71
|
const instance = await Toolpack.init({
|
|
45
72
|
defaultMode: 'agent',
|
|
46
73
|
configPath: tempConfigPath, // Use our merged temp config
|
|
@@ -55,6 +82,7 @@ export function ToolpackProvider({ children }) {
|
|
|
55
82
|
customModes: [simpleChat],
|
|
56
83
|
customProviders: [new XAIAdapter()],
|
|
57
84
|
customTools: [skillToolsProject],
|
|
85
|
+
knowledge: kb,
|
|
58
86
|
modeOverrides: {
|
|
59
87
|
agent: {
|
|
60
88
|
// Override the agent mode system prompt to include skill search and read
|
|
@@ -210,6 +238,7 @@ export function ToolpackProvider({ children }) {
|
|
|
210
238
|
setToolsUnsupportedWarning,
|
|
211
239
|
configSource,
|
|
212
240
|
activeConfigPath,
|
|
241
|
+
knowledgeProgress,
|
|
213
242
|
}, children: children }));
|
|
214
243
|
}
|
|
215
244
|
export function useToolpack() {
|
|
@@ -219,3 +248,85 @@ export function useToolpack() {
|
|
|
219
248
|
}
|
|
220
249
|
return context;
|
|
221
250
|
}
|
|
251
|
+
function ensureGlobalKnowledgeAssets() {
|
|
252
|
+
const bundledDir = path.join(__dirname, '..', '..', 'knowledge');
|
|
253
|
+
const globalDir = path.join(os.homedir(), '.toolpack');
|
|
254
|
+
const targetDir = path.join(globalDir, 'knowledge');
|
|
255
|
+
fs.mkdirSync(globalDir, { recursive: true });
|
|
256
|
+
if (fs.existsSync(bundledDir)) {
|
|
257
|
+
copyDirectoryRecursive(bundledDir, targetDir);
|
|
258
|
+
}
|
|
259
|
+
seedKnowledgeSamples(targetDir);
|
|
260
|
+
return targetDir;
|
|
261
|
+
}
|
|
262
|
+
function copyDirectoryRecursive(source, destination) {
|
|
263
|
+
if (!fs.existsSync(source)) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const stats = fs.statSync(source);
|
|
267
|
+
if (stats.isDirectory()) {
|
|
268
|
+
fs.mkdirSync(destination, { recursive: true });
|
|
269
|
+
for (const entry of fs.readdirSync(source)) {
|
|
270
|
+
const srcPath = path.join(source, entry);
|
|
271
|
+
const destPath = path.join(destination, entry);
|
|
272
|
+
copyDirectoryRecursive(srcPath, destPath);
|
|
273
|
+
}
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
fs.mkdirSync(path.dirname(destination), { recursive: true });
|
|
277
|
+
fs.copyFileSync(source, destination);
|
|
278
|
+
}
|
|
279
|
+
function seedKnowledgeSamples(targetDir) {
|
|
280
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
281
|
+
const markdownPath = path.join(targetDir, 'toolpack-overview.md');
|
|
282
|
+
const jsonPath = path.join(targetDir, 'toolpack-cli.json');
|
|
283
|
+
const sqlitePath = path.join(targetDir, 'toolpack-guides.db');
|
|
284
|
+
if (!fs.existsSync(markdownPath)) {
|
|
285
|
+
fs.writeFileSync(markdownPath, `# Toolpack SDK Overview\n\nThe Toolpack SDK provides a provider-agnostic agent runtime with built-in tooling, workflow automation, and knowledge retrieval.\n\n## Highlights\n- Unified API across OpenAI, Anthropic, Gemini, and local providers\n- Configurable agent modes (agent, chat, simpleChat, custom modes)\n- Knowledge module for RAG with Markdown/JSON/SQLite sources\n- Workflow engine with hooks for pre/post tool execution\n\n## CLI Integration\nThe sample CLI demonstrates multi-mode chat, provider switching, history, telemetry, and automatic knowledge bootstrapping.\n`);
|
|
286
|
+
}
|
|
287
|
+
if (!fs.existsSync(jsonPath)) {
|
|
288
|
+
fs.writeFileSync(jsonPath, JSON.stringify([
|
|
289
|
+
{
|
|
290
|
+
id: 'cli_modes',
|
|
291
|
+
title: 'Toolpack CLI Modes',
|
|
292
|
+
description: 'The CLI ships with agent, chat, and simpleChat modes plus an example custom mode.',
|
|
293
|
+
capabilities: ['mode switching', 'history', 'provider selection'],
|
|
294
|
+
category: 'cli',
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'sdk_features',
|
|
298
|
+
title: 'Toolpack SDK Features',
|
|
299
|
+
description: 'Unified provider API, workflow engine, tool telemetry, and knowledge integration.',
|
|
300
|
+
category: 'sdk',
|
|
301
|
+
},
|
|
302
|
+
], null, 2));
|
|
303
|
+
}
|
|
304
|
+
if (!fs.existsSync(sqlitePath)) {
|
|
305
|
+
fs.mkdirSync(path.dirname(sqlitePath), { recursive: true });
|
|
306
|
+
const db = new Database(sqlitePath);
|
|
307
|
+
try {
|
|
308
|
+
db.exec(`CREATE TABLE IF NOT EXISTS guides (
|
|
309
|
+
id TEXT PRIMARY KEY,
|
|
310
|
+
title TEXT,
|
|
311
|
+
body TEXT,
|
|
312
|
+
category TEXT
|
|
313
|
+
);`);
|
|
314
|
+
const insert = db.prepare('INSERT OR REPLACE INTO guides (id, title, body, category) VALUES (@id, @title, @body, @category)');
|
|
315
|
+
insert.run({
|
|
316
|
+
id: 'sdk_init',
|
|
317
|
+
title: 'Initializing Toolpack SDK',
|
|
318
|
+
body: 'Use Toolpack.init with provider configs, tools flag, knowledge instance, and custom modes to bootstrap your agent runtime.',
|
|
319
|
+
category: 'sdk',
|
|
320
|
+
});
|
|
321
|
+
insert.run({
|
|
322
|
+
id: 'cli_setup',
|
|
323
|
+
title: 'Toolpack CLI Setup',
|
|
324
|
+
body: 'Install dependencies, configure toolpack.config.json, and start via `toolpack` to enter the Ink interface.',
|
|
325
|
+
category: 'cli',
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
finally {
|
|
329
|
+
db.close();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
@@ -10,10 +10,12 @@ import { HomeInput } from '../components/HomeInput.js';
|
|
|
10
10
|
import { ModeSelect } from '../components/common/ModeSelect.js';
|
|
11
11
|
import { ModelSelect } from '../components/common/ModelSelect.js';
|
|
12
12
|
import { HistorySelect } from '../components/common/HistorySelect.js';
|
|
13
|
+
import { KnowledgeLoader } from '../components/KnowledgeLoader.js';
|
|
13
14
|
export function HomeScreen() {
|
|
14
15
|
const { theme } = useTheme();
|
|
15
16
|
const { stdout } = useStdout();
|
|
16
|
-
const { setMode, setModel, models } = useToolpack();
|
|
17
|
+
const { setMode, setModel, models, knowledgeProgress } = useToolpack();
|
|
18
|
+
const knowledgeReady = !knowledgeProgress || knowledgeProgress.phase === 'complete';
|
|
17
19
|
const { loadConversation, setScreen } = useConversation();
|
|
18
20
|
// 0 = TextInput, 1 = Mode, 2 = Model, 3 = History
|
|
19
21
|
const [focusedIndex, setFocusedIndex] = useState(0);
|
|
@@ -37,7 +39,7 @@ export function HomeScreen() {
|
|
|
37
39
|
setScreen('settings');
|
|
38
40
|
}
|
|
39
41
|
});
|
|
40
|
-
return (_jsxs(Box, { width: stdout.columns, height: stdout.rows - 1, flexDirection: "column", position: "relative", children: [_jsxs(Box, { width: "100%", alignItems: "center", flexDirection: "column", paddingTop: 6, flexShrink: 0, children: [_jsx(Logo, {}), _jsx(AppInfo, {})] }), _jsx(Box, { flexGrow: 1, width: "100%", justifyContent: "center", alignItems: "center", flexDirection: "column", children: _jsx(Box, { width: "80%", children: _jsx(HomeInput, { focusedIndex: focusedIndex, showModeSelect: showModeSelect, setShowModeSelect: setShowModeSelect, showModelSelect: showModelSelect, setShowModelSelect: setShowModelSelect, showHistorySelect: showHistorySelect, setShowHistorySelect: setShowHistorySelect }) }) }), _jsx(Box, { width: "100%", flexDirection: "column", alignItems: "center", paddingBottom: 1, flexShrink: 0, children: _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.colors.textSecondary, children: [_jsx(Text, { color: "#eab308", bold: true, children: "\u2022 Note" }), ' ', "If you are using local models, make sure to have them downloaded and available."] }) }) }), showModeSelect && (_jsx(ModeSelect, { onSelect: val => {
|
|
42
|
+
return (_jsxs(Box, { width: stdout.columns, height: stdout.rows - 1, flexDirection: "column", position: "relative", children: [_jsxs(Box, { width: "100%", alignItems: "center", flexDirection: "column", paddingTop: 6, flexShrink: 0, children: [_jsx(Logo, {}), _jsx(AppInfo, {}), knowledgeProgress && knowledgeProgress.phase !== 'complete' && (_jsx(Box, { width: "100%", marginTop: 1, alignItems: "center", justifyContent: "center", children: _jsx(KnowledgeLoader, {}) }))] }), _jsx(Box, { flexGrow: 1, width: "100%", justifyContent: "center", alignItems: "center", flexDirection: "column", children: knowledgeReady ? (_jsx(Box, { width: "80%", children: _jsx(HomeInput, { focusedIndex: focusedIndex, showModeSelect: showModeSelect, setShowModeSelect: setShowModeSelect, showModelSelect: showModelSelect, setShowModelSelect: setShowModelSelect, showHistorySelect: showHistorySelect, setShowHistorySelect: setShowHistorySelect }) })) : (_jsx(Text, { color: theme.colors.textSecondary, children: "Preparing knowledge workspace\u2026" })) }), _jsx(Box, { width: "100%", flexDirection: "column", alignItems: "center", paddingBottom: 1, flexShrink: 0, children: _jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: theme.colors.textSecondary, children: [_jsx(Text, { color: "#eab308", bold: true, children: "\u2022 Note" }), ' ', "If you are using local models, make sure to have them downloaded and available."] }) }) }), showModeSelect && (_jsx(ModeSelect, { onSelect: val => {
|
|
41
43
|
setMode(val);
|
|
42
44
|
setShowModeSelect(false);
|
|
43
45
|
setFocusedIndex(0); // Return focus to input
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolpack-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.1.0-SNAPSHOT.202603211",
|
|
4
4
|
"description": "Rich interactive command-line interface directly powering the Toolpack SDK",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"preferGlobal": true,
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"node-pty": "^1.1.0",
|
|
57
57
|
"open": "^11.0.0",
|
|
58
58
|
"react": "^18.2.0",
|
|
59
|
-
"toolpack-sdk": "
|
|
59
|
+
"toolpack-sdk": "1.1.0-SNAPSHOT",
|
|
60
60
|
"uuid": "^13.0.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|