toolpack-cli 1.0.1 → 1.1.0-SNAPSHOT
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,14 @@
|
|
|
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
4
|
import { XAIAdapter } from '../custom-providers/XAIAdapter.js';
|
|
5
5
|
import { skillToolsProject } from '../custom-tools/skill-tools/index.js';
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as os from 'os';
|
|
8
8
|
import * as path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
9
12
|
const ToolpackContext = createContext(undefined);
|
|
10
13
|
export function ToolpackProvider({ children }) {
|
|
11
14
|
const [toolpack, setToolpack] = useState(null);
|
|
@@ -21,6 +24,7 @@ export function ToolpackProvider({ children }) {
|
|
|
21
24
|
const [toolsUnsupportedWarning, setToolsUnsupportedWarning] = useState(null);
|
|
22
25
|
const [configSource, setConfigSource] = useState('default');
|
|
23
26
|
const [activeConfigPath, setActiveConfigPath] = useState(null);
|
|
27
|
+
const [knowledgeProgress, setKnowledgeProgress] = useState(null);
|
|
24
28
|
useEffect(() => {
|
|
25
29
|
async function init() {
|
|
26
30
|
// Get config status
|
|
@@ -41,6 +45,28 @@ export function ToolpackProvider({ children }) {
|
|
|
41
45
|
systemPrompt: 'You are a helpful assistant. Provide clear and concise responses.',
|
|
42
46
|
blockAllTools: true,
|
|
43
47
|
});
|
|
48
|
+
const knowledgeBasePath = ensureGlobalKnowledgeAssets();
|
|
49
|
+
const kb = await Knowledge.create({
|
|
50
|
+
provider: new MemoryProvider(),
|
|
51
|
+
sources: [
|
|
52
|
+
new MarkdownSource(path.join(knowledgeBasePath, '**/*.md'), { namespace: 'docs' }),
|
|
53
|
+
new JSONSource(path.join(knowledgeBasePath, 'toolpack-cli.json'), {
|
|
54
|
+
chunkBy: 'item',
|
|
55
|
+
contentFields: ['title', 'description'],
|
|
56
|
+
metadataFields: ['id', 'category'],
|
|
57
|
+
namespace: 'json',
|
|
58
|
+
}),
|
|
59
|
+
new SQLiteTextSource(path.join(knowledgeBasePath, 'toolpack-guides.db'), {
|
|
60
|
+
table: 'guides',
|
|
61
|
+
contentColumns: ['title', 'body'],
|
|
62
|
+
metadataColumns: ['category'],
|
|
63
|
+
namespace: 'guides',
|
|
64
|
+
}),
|
|
65
|
+
],
|
|
66
|
+
onEmbeddingProgress: event => {
|
|
67
|
+
setKnowledgeProgress(event);
|
|
68
|
+
},
|
|
69
|
+
});
|
|
44
70
|
const instance = await Toolpack.init({
|
|
45
71
|
defaultMode: 'agent',
|
|
46
72
|
configPath: tempConfigPath, // Use our merged temp config
|
|
@@ -55,6 +81,7 @@ export function ToolpackProvider({ children }) {
|
|
|
55
81
|
customModes: [simpleChat],
|
|
56
82
|
customProviders: [new XAIAdapter()],
|
|
57
83
|
customTools: [skillToolsProject],
|
|
84
|
+
knowledge: kb,
|
|
58
85
|
modeOverrides: {
|
|
59
86
|
agent: {
|
|
60
87
|
// Override the agent mode system prompt to include skill search and read
|
|
@@ -210,6 +237,7 @@ export function ToolpackProvider({ children }) {
|
|
|
210
237
|
setToolsUnsupportedWarning,
|
|
211
238
|
configSource,
|
|
212
239
|
activeConfigPath,
|
|
240
|
+
knowledgeProgress,
|
|
213
241
|
}, children: children }));
|
|
214
242
|
}
|
|
215
243
|
export function useToolpack() {
|
|
@@ -219,3 +247,27 @@ export function useToolpack() {
|
|
|
219
247
|
}
|
|
220
248
|
return context;
|
|
221
249
|
}
|
|
250
|
+
function ensureGlobalKnowledgeAssets() {
|
|
251
|
+
const sourceDir = path.join(__dirname, '..', '..', 'knowledge');
|
|
252
|
+
const globalDir = path.join(os.homedir(), '.toolpack');
|
|
253
|
+
const targetDir = path.join(globalDir, 'knowledge');
|
|
254
|
+
fs.mkdirSync(globalDir, { recursive: true });
|
|
255
|
+
copyDirectoryRecursive(sourceDir, targetDir);
|
|
256
|
+
return targetDir;
|
|
257
|
+
}
|
|
258
|
+
function copyDirectoryRecursive(source, destination) {
|
|
259
|
+
if (!fs.existsSync(source)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const stats = fs.statSync(source);
|
|
263
|
+
if (stats.isDirectory()) {
|
|
264
|
+
fs.mkdirSync(destination, { recursive: true });
|
|
265
|
+
for (const entry of fs.readdirSync(source)) {
|
|
266
|
+
const srcPath = path.join(source, entry);
|
|
267
|
+
const destPath = path.join(destination, entry);
|
|
268
|
+
copyDirectoryRecursive(srcPath, destPath);
|
|
269
|
+
}
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
fs.copyFileSync(source, destination);
|
|
273
|
+
}
|
|
@@ -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",
|
|
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": {
|