actoviq-agent-sdk 0.4.0 → 0.4.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/README-zh.md +15 -2
- package/README.md +20 -7
- package/dist/src/cli/actoviq-react.js +178 -3
- package/dist/src/cli/actoviq-react.js.map +1 -1
- package/dist/src/cli/actoviq-tui.js +2 -2
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +17 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/router/modelRouter.d.ts +46 -0
- package/dist/src/router/modelRouter.d.ts.map +1 -0
- package/dist/src/router/modelRouter.js +227 -0
- package/dist/src/router/modelRouter.js.map +1 -0
- package/dist/src/runtime/actoviqSkills.d.ts +6 -0
- package/dist/src/runtime/actoviqSkills.d.ts.map +1 -1
- package/dist/src/runtime/actoviqSkills.js +69 -1
- package/dist/src/runtime/actoviqSkills.js.map +1 -1
- package/dist/src/runtime/agentClient.d.ts +16 -0
- package/dist/src/runtime/agentClient.d.ts.map +1 -1
- package/dist/src/runtime/agentClient.js +89 -9
- package/dist/src/runtime/agentClient.js.map +1 -1
- package/dist/src/runtime/conversationEngine.d.ts +2 -0
- package/dist/src/runtime/conversationEngine.d.ts.map +1 -1
- package/dist/src/runtime/conversationEngine.js +6 -5
- package/dist/src/runtime/conversationEngine.js.map +1 -1
- package/dist/src/storage/sessionStore.d.ts.map +1 -1
- package/dist/src/storage/sessionStore.js +25 -6
- package/dist/src/storage/sessionStore.js.map +1 -1
- package/dist/src/team/agentPool.d.ts +26 -0
- package/dist/src/team/agentPool.d.ts.map +1 -0
- package/dist/src/team/agentPool.js +97 -0
- package/dist/src/team/agentPool.js.map +1 -0
- package/dist/src/team/modelTeam.d.ts +56 -0
- package/dist/src/team/modelTeam.d.ts.map +1 -0
- package/dist/src/team/modelTeam.js +542 -0
- package/dist/src/team/modelTeam.js.map +1 -0
- package/dist/src/team/pricing.d.ts +15 -0
- package/dist/src/team/pricing.d.ts.map +1 -0
- package/dist/src/team/pricing.js +80 -0
- package/dist/src/team/pricing.js.map +1 -0
- package/dist/src/team/teamDefinitions.d.ts +28 -0
- package/dist/src/team/teamDefinitions.d.ts.map +1 -0
- package/dist/src/team/teamDefinitions.js +151 -0
- package/dist/src/team/teamDefinitions.js.map +1 -0
- package/dist/src/tools/actoviqCoreTools.d.ts.map +1 -1
- package/dist/src/tools/actoviqCoreTools.js +6 -1
- package/dist/src/tools/actoviqCoreTools.js.map +1 -1
- package/dist/src/tools/enterWorktree.d.ts +11 -0
- package/dist/src/tools/enterWorktree.d.ts.map +1 -0
- package/dist/src/tools/enterWorktree.js +79 -0
- package/dist/src/tools/enterWorktree.js.map +1 -0
- package/dist/src/tools/exitWorktree.d.ts +4 -0
- package/dist/src/tools/exitWorktree.d.ts.map +1 -0
- package/dist/src/tools/exitWorktree.js +48 -0
- package/dist/src/tools/exitWorktree.js.map +1 -0
- package/dist/src/tools/tavilySearch.d.ts +12 -0
- package/dist/src/tools/tavilySearch.d.ts.map +1 -0
- package/dist/src/tools/tavilySearch.js +139 -0
- package/dist/src/tools/tavilySearch.js.map +1 -0
- package/dist/src/tui/actoviqTui.d.ts +10 -0
- package/dist/src/tui/actoviqTui.d.ts.map +1 -1
- package/dist/src/tui/actoviqTui.js +606 -35
- package/dist/src/tui/actoviqTui.js.map +1 -1
- package/dist/src/tui/editor.d.ts +2 -0
- package/dist/src/tui/editor.d.ts.map +1 -1
- package/dist/src/tui/editor.js +5 -0
- package/dist/src/tui/editor.js.map +1 -1
- package/dist/src/types.d.ts +323 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/workflow/workflowPersistence.d.ts +34 -0
- package/dist/src/workflow/workflowPersistence.d.ts.map +1 -0
- package/dist/src/workflow/workflowPersistence.js +144 -0
- package/dist/src/workflow/workflowPersistence.js.map +1 -0
- package/dist/src/workflow/workflowScriptRuntime.d.ts +22 -0
- package/dist/src/workflow/workflowScriptRuntime.d.ts.map +1 -0
- package/dist/src/workflow/workflowScriptRuntime.js +655 -0
- package/dist/src/workflow/workflowScriptRuntime.js.map +1 -0
- package/dist/src/worktree/worktreeHooks.d.ts +38 -0
- package/dist/src/worktree/worktreeHooks.d.ts.map +1 -0
- package/dist/src/worktree/worktreeHooks.js +82 -0
- package/dist/src/worktree/worktreeHooks.js.map +1 -0
- package/dist/src/worktree/worktreeInclude.d.ts +11 -0
- package/dist/src/worktree/worktreeInclude.d.ts.map +1 -0
- package/dist/src/worktree/worktreeInclude.js +65 -0
- package/dist/src/worktree/worktreeInclude.js.map +1 -0
- package/dist/src/worktree/worktreeService.d.ts +43 -0
- package/dist/src/worktree/worktreeService.d.ts.map +1 -0
- package/dist/src/worktree/worktreeService.js +356 -0
- package/dist/src/worktree/worktreeService.js.map +1 -0
- package/package.json +2 -24
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/** $ per 1M tokens */
|
|
4
|
+
const BUILT_IN_PRICING = {
|
|
5
|
+
// ── Anthropic ──────────────────────────────────────────────────
|
|
6
|
+
'claude-opus-4-8': { input: 15.0, output: 75.0 },
|
|
7
|
+
'claude-opus-4-7': { input: 15.0, output: 75.0 },
|
|
8
|
+
'claude-opus-4-6': { input: 15.0, output: 75.0 },
|
|
9
|
+
'claude-sonnet-4-6': { input: 3.0, output: 15.0 },
|
|
10
|
+
'claude-sonnet-4-5': { input: 3.0, output: 15.0 },
|
|
11
|
+
'claude-haiku-4-5': { input: 0.8, output: 4.0 },
|
|
12
|
+
'claude-fable-5': { input: 3.0, output: 15.0 },
|
|
13
|
+
// ── OpenAI ─────────────────────────────────────────────────────
|
|
14
|
+
'gpt-5.5': { input: 2.5, output: 10.0 },
|
|
15
|
+
'gpt-5': { input: 2.5, output: 10.0 },
|
|
16
|
+
'gpt-4.1': { input: 2.0, output: 8.0 },
|
|
17
|
+
'gpt-4o': { input: 2.5, output: 10.0 },
|
|
18
|
+
'gpt-4o-mini': { input: 0.15, output: 0.6 },
|
|
19
|
+
'o4-mini': { input: 1.1, output: 4.4 },
|
|
20
|
+
'o3': { input: 10.0, output: 40.0 },
|
|
21
|
+
// ── DeepSeek ───────────────────────────────────────────────────
|
|
22
|
+
'deepseek-v4-pro': { input: 0.55, output: 2.19 },
|
|
23
|
+
'deepseek-v3': { input: 0.27, output: 1.1 },
|
|
24
|
+
'deepseek-r1': { input: 0.55, output: 2.19 },
|
|
25
|
+
// ── Google ─────────────────────────────────────────────────────
|
|
26
|
+
'gemini-3-flash': { input: 0.1, output: 0.4 },
|
|
27
|
+
'gemini-3-pro': { input: 1.25, output: 10.0 },
|
|
28
|
+
'gemini-2.5-pro': { input: 1.25, output: 10.0 },
|
|
29
|
+
'gemini-2.5-flash': { input: 0.15, output: 0.6 },
|
|
30
|
+
// ── MiniMax ─────────────────────────────────────────────────────
|
|
31
|
+
'MiniMax-M3': { input: 0.5, output: 2.0 },
|
|
32
|
+
'MiniMax-M2': { input: 0.3, output: 1.2 },
|
|
33
|
+
// ── Kimi / Moonshot ────────────────────────────────────────────
|
|
34
|
+
'kimi-k2.6': { input: 0.6, output: 2.4 },
|
|
35
|
+
'kimi-k2': { input: 0.6, output: 2.4 },
|
|
36
|
+
};
|
|
37
|
+
function resolvePricingPath(homeDir) {
|
|
38
|
+
return path.join(homeDir ?? process.env.ACTOVIQ_HOME ?? path.join(process.env.HOME ?? process.env.USERPROFILE ?? '.', '.actoviq'), 'pricing.json');
|
|
39
|
+
}
|
|
40
|
+
let _userPricing = null;
|
|
41
|
+
let _userPricingLoaded = false;
|
|
42
|
+
function loadUserPricing(homeDir) {
|
|
43
|
+
if (_userPricingLoaded)
|
|
44
|
+
return _userPricing ?? {};
|
|
45
|
+
_userPricingLoaded = true;
|
|
46
|
+
try {
|
|
47
|
+
const p = resolvePricingPath(homeDir);
|
|
48
|
+
if (fs.existsSync(p)) {
|
|
49
|
+
_userPricing = JSON.parse(fs.readFileSync(p, 'utf-8'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Missing or malformed — ignore
|
|
54
|
+
}
|
|
55
|
+
return _userPricing ?? {};
|
|
56
|
+
}
|
|
57
|
+
/** Get pricing for a model. Returns null if unavailable. */
|
|
58
|
+
export function getModelPricing(model, homeDir) {
|
|
59
|
+
const user = loadUserPricing(homeDir);
|
|
60
|
+
if (user[model])
|
|
61
|
+
return user[model];
|
|
62
|
+
return BUILT_IN_PRICING[model] ?? null;
|
|
63
|
+
}
|
|
64
|
+
/** Compute cost from token counts. Returns null if pricing unavailable. */
|
|
65
|
+
export function estimateCost(model, inputTokens, outputTokens, homeDir) {
|
|
66
|
+
const pricing = getModelPricing(model, homeDir);
|
|
67
|
+
if (!pricing)
|
|
68
|
+
return null;
|
|
69
|
+
return (inputTokens / 1_000_000) * pricing.input + (outputTokens / 1_000_000) * pricing.output;
|
|
70
|
+
}
|
|
71
|
+
/** Check if all models in a list have pricing data. */
|
|
72
|
+
export function hasFullPricing(models, homeDir) {
|
|
73
|
+
return models.every((m) => getModelPricing(m, homeDir) !== null);
|
|
74
|
+
}
|
|
75
|
+
/** Clear cached user pricing (for testing). */
|
|
76
|
+
export function clearPricingCache() {
|
|
77
|
+
_userPricing = null;
|
|
78
|
+
_userPricingLoaded = false;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../../src/team/pricing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { TeamDefinition } from '../types.js';
|
|
2
|
+
export interface LoadedTeamDefinition {
|
|
3
|
+
name: string;
|
|
4
|
+
definition: TeamDefinition;
|
|
5
|
+
source: 'project' | 'personal';
|
|
6
|
+
filePath: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Load a team definition by name from disk.
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadTeamDefinition(name: string, projectDir?: string, homeDir?: string): LoadedTeamDefinition | null;
|
|
12
|
+
/**
|
|
13
|
+
* Save a team definition to disk.
|
|
14
|
+
*/
|
|
15
|
+
export declare function saveTeamDefinition(definition: TeamDefinition, options?: {
|
|
16
|
+
projectDir?: string;
|
|
17
|
+
homeDir?: string;
|
|
18
|
+
overwrite?: boolean;
|
|
19
|
+
}): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* List all team definitions from all search paths.
|
|
22
|
+
*/
|
|
23
|
+
export declare function listTeamDefinitions(projectDir?: string, homeDir?: string): LoadedTeamDefinition[];
|
|
24
|
+
/**
|
|
25
|
+
* Delete a team definition from disk.
|
|
26
|
+
*/
|
|
27
|
+
export declare function deleteTeamDefinition(name: string, projectDir?: string, homeDir?: string): Promise<boolean>;
|
|
28
|
+
//# sourceMappingURL=teamDefinitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teamDefinitions.d.ts","sourceRoot":"","sources":["../../../src/team/teamDefinitions.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,cAAc,CAAC;IAC3B,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;CAClB;AAsCD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,oBAAoB,GAAG,IAAI,CAuB7B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,cAAc,EAC1B,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3E,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,oBAAoB,EAAE,CAqCxB;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team definitions from disk — load/save team configurations.
|
|
3
|
+
*
|
|
4
|
+
* Search path:
|
|
5
|
+
* 1. .actoviq/teams/<name>.json (project)
|
|
6
|
+
* 2. ~/.actoviq/teams/<name>.json (personal)
|
|
7
|
+
*
|
|
8
|
+
* apiKey values starting with $ are resolved from environment variables at load time.
|
|
9
|
+
*/
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { mkdir } from 'node:fs/promises';
|
|
13
|
+
function resolveTeamDirs(projectDir, homeDir) {
|
|
14
|
+
const dirs = [];
|
|
15
|
+
const home = homeDir ?? process.env.ACTOVIQ_HOME ?? path.join(process.env.HOME ?? process.env.USERPROFILE ?? '.', '.actoviq');
|
|
16
|
+
if (projectDir) {
|
|
17
|
+
dirs.push(path.join(projectDir, '.actoviq', 'teams'));
|
|
18
|
+
}
|
|
19
|
+
dirs.push(path.join(home, 'teams'));
|
|
20
|
+
return dirs;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve $ENV_VAR references in team definition values.
|
|
24
|
+
*/
|
|
25
|
+
function resolveEnvVars(def) {
|
|
26
|
+
const resolve = (val) => {
|
|
27
|
+
if (!val)
|
|
28
|
+
return val;
|
|
29
|
+
if (val.startsWith('$')) {
|
|
30
|
+
return process.env[val.slice(1)] ?? val;
|
|
31
|
+
}
|
|
32
|
+
return val;
|
|
33
|
+
};
|
|
34
|
+
const resolvedMembers = def.members?.map((m) => ({
|
|
35
|
+
...m,
|
|
36
|
+
apiKey: resolve(m.apiKey),
|
|
37
|
+
}));
|
|
38
|
+
return {
|
|
39
|
+
...def,
|
|
40
|
+
members: resolvedMembers ?? def.members,
|
|
41
|
+
primary: def.primary ? { ...def.primary, apiKey: resolve(def.primary.apiKey) } : undefined,
|
|
42
|
+
reviewer: def.reviewer ? { ...def.reviewer, apiKey: resolve(def.reviewer.apiKey) } : undefined,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load a team definition by name from disk.
|
|
47
|
+
*/
|
|
48
|
+
export function loadTeamDefinition(name, projectDir, homeDir) {
|
|
49
|
+
const dirs = resolveTeamDirs(projectDir, homeDir);
|
|
50
|
+
for (let i = 0; i < dirs.length; i++) {
|
|
51
|
+
const dir = dirs[i];
|
|
52
|
+
const filePath = path.join(dir, `${name}.json`);
|
|
53
|
+
if (fs.existsSync(filePath)) {
|
|
54
|
+
try {
|
|
55
|
+
const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
56
|
+
const definition = resolveEnvVars(raw);
|
|
57
|
+
return {
|
|
58
|
+
name,
|
|
59
|
+
definition,
|
|
60
|
+
source: i === 0 && projectDir ? 'project' : 'personal',
|
|
61
|
+
filePath,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
throw new Error(`Failed to load team definition "${name}" from ${filePath}: ${err.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Save a team definition to disk.
|
|
73
|
+
*/
|
|
74
|
+
export async function saveTeamDefinition(definition, options = {}) {
|
|
75
|
+
const dirs = resolveTeamDirs(options.projectDir, options.homeDir);
|
|
76
|
+
const targetDir = dirs[0];
|
|
77
|
+
await mkdir(targetDir, { recursive: true });
|
|
78
|
+
const filePath = path.join(targetDir, `${definition.name}.json`);
|
|
79
|
+
if (fs.existsSync(filePath) && !options.overwrite) {
|
|
80
|
+
throw new Error(`Team "${definition.name}" already exists at ${filePath}. Use overwrite: true to replace.`);
|
|
81
|
+
}
|
|
82
|
+
// Strip env var values before saving (save the $VAR reference, not the resolved value)
|
|
83
|
+
const stripEnvVars = (def) => {
|
|
84
|
+
const restore = (val) => val?.startsWith?.('$') ? val : val;
|
|
85
|
+
return {
|
|
86
|
+
...def,
|
|
87
|
+
members: def.members?.map((m) => ({ ...m, apiKey: m.apiKey?.startsWith?.('$') ? m.apiKey : undefined })),
|
|
88
|
+
primary: def.primary ? { ...def.primary, apiKey: undefined } : undefined,
|
|
89
|
+
reviewer: def.reviewer ? { ...def.reviewer, apiKey: undefined } : undefined,
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
fs.writeFileSync(filePath, JSON.stringify(stripEnvVars(definition), null, 2), 'utf-8');
|
|
93
|
+
return filePath;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* List all team definitions from all search paths.
|
|
97
|
+
*/
|
|
98
|
+
export function listTeamDefinitions(projectDir, homeDir) {
|
|
99
|
+
const dirs = resolveTeamDirs(projectDir, homeDir);
|
|
100
|
+
const seen = new Set();
|
|
101
|
+
const teams = [];
|
|
102
|
+
for (let i = 0; i < dirs.length; i++) {
|
|
103
|
+
const dir = dirs[i];
|
|
104
|
+
if (!fs.existsSync(dir))
|
|
105
|
+
continue;
|
|
106
|
+
try {
|
|
107
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
108
|
+
for (const entry of entries) {
|
|
109
|
+
if (!entry.isFile() || !entry.name.endsWith('.json'))
|
|
110
|
+
continue;
|
|
111
|
+
const name = entry.name.slice(0, -5);
|
|
112
|
+
if (seen.has(name))
|
|
113
|
+
continue;
|
|
114
|
+
seen.add(name);
|
|
115
|
+
const filePath = path.join(dir, entry.name);
|
|
116
|
+
try {
|
|
117
|
+
const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
118
|
+
const definition = resolveEnvVars(raw);
|
|
119
|
+
teams.push({
|
|
120
|
+
name,
|
|
121
|
+
definition,
|
|
122
|
+
source: i === 0 && projectDir ? 'project' : 'personal',
|
|
123
|
+
filePath,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Skip invalid definitions
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Skip inaccessible directories
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return teams;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Delete a team definition from disk.
|
|
139
|
+
*/
|
|
140
|
+
export async function deleteTeamDefinition(name, projectDir, homeDir) {
|
|
141
|
+
const dirs = resolveTeamDirs(projectDir, homeDir);
|
|
142
|
+
for (const dir of dirs) {
|
|
143
|
+
const filePath = path.join(dir, `${name}.json`);
|
|
144
|
+
if (fs.existsSync(filePath)) {
|
|
145
|
+
fs.unlinkSync(filePath);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=teamDefinitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teamDefinitions.js","sourceRoot":"","sources":["../../../src/team/teamDefinitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actoviqCoreTools.d.ts","sourceRoot":"","sources":["../../../src/tools/actoviqCoreTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"actoviqCoreTools.d.ts","sourceRoot":"","sources":["../../../src/tools/actoviqCoreTools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAA0B,KAAK,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAW7F,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACtE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,mBAAmB,EAAE,CAmBvB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createActoviqFileTools } from './actoviqFileTools.js';
|
|
2
2
|
import { createActoviqWebTools } from './actoviqWebTools.js';
|
|
3
|
+
import { createTavilySearchTool } from './tavilySearch.js';
|
|
3
4
|
import { createBashTool } from './bash/BashTool.js';
|
|
4
5
|
import { createTodoWriteTool } from './todo/TodoWriteTool.js';
|
|
5
6
|
import { createAskUserQuestionTool } from './askUserQuestion/AskUserQuestionTool.js';
|
|
@@ -17,8 +18,12 @@ export function createActoviqCoreTools(options = {}) {
|
|
|
17
18
|
tools.push(createTodoWriteTool());
|
|
18
19
|
if (options.askUserQuestion !== false)
|
|
19
20
|
tools.push(createAskUserQuestionTool());
|
|
20
|
-
if (options.webTools !== false)
|
|
21
|
+
if (options.webTools !== false) {
|
|
21
22
|
tools.push(...createActoviqWebTools());
|
|
23
|
+
// Tavily: enabled when TAVILY_API_KEY is set (no Python dependency)
|
|
24
|
+
if (process.env.TAVILY_API_KEY)
|
|
25
|
+
tools.push(createTavilySearchTool());
|
|
26
|
+
}
|
|
22
27
|
if (options.taskTools === true)
|
|
23
28
|
tools.push(...createActoviqTaskTools());
|
|
24
29
|
if (options.notebookEdit !== false)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actoviqCoreTools.js","sourceRoot":"","sources":["../../../src/tools/actoviqCoreTools.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,sBAAsB,EAAgC,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAa/D,MAAM,UAAU,sBAAsB,CACpC,UAAmC,EAAE;IAErC,MAAM,KAAK,GAA0B;QACnC,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAChD,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,eAAe,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC;IAC/E,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK;
|
|
1
|
+
{"version":3,"file":"actoviqCoreTools.js","sourceRoot":"","sources":["../../../src/tools/actoviqCoreTools.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,sBAAsB,EAAgC,MAAM,uBAAuB,CAAC;AAC7F,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAa/D,MAAM,UAAU,sBAAsB,CACpC,UAAmC,EAAE;IAErC,MAAM,KAAK,GAA0B;QACnC,GAAG,sBAAsB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAChD,CAAC;IAEF,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IACzD,IAAI,OAAO,CAAC,SAAS,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,eAAe,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC,CAAC;IAC/E,IAAI,OAAO,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,GAAG,qBAAqB,EAAE,CAAC,CAAC;QACvC,oEAAoE;QACpE,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;YAAE,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,sBAAsB,EAAE,CAAC,CAAC;IACxE,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACzE,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACrE,IAAI,OAAO,CAAC,SAAS,KAAK,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,GAAG,sBAAsB,EAAE,CAAC,CAAC;IAExE,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { WorktreeService } from '../worktree/worktreeService.js';
|
|
2
|
+
export declare const ENTER_WORKTREE_TOOL_NAME = "EnterWorktree";
|
|
3
|
+
export declare function createEnterWorktreeTool(getWorktreeService: () => WorktreeService | undefined): import("../types.js").AgentToolDefinition<{
|
|
4
|
+
path?: string | undefined;
|
|
5
|
+
name?: string | undefined;
|
|
6
|
+
branch?: string | undefined;
|
|
7
|
+
ref?: string | undefined;
|
|
8
|
+
detach?: boolean | undefined;
|
|
9
|
+
pr?: string | undefined;
|
|
10
|
+
}, string>;
|
|
11
|
+
//# sourceMappingURL=enterWorktree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enterWorktree.d.ts","sourceRoot":"","sources":["../../../src/tools/enterWorktree.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAaxD,wBAAgB,uBAAuB,CAAC,kBAAkB,EAAE,MAAM,eAAe,GAAG,SAAS;;;;;;;WAwE5F"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EnterWorktree tool — creates an isolated git worktree and switches
|
|
3
|
+
* the agent's working directory into it.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { tool } from '../runtime/tools.js';
|
|
7
|
+
export const ENTER_WORKTREE_TOOL_NAME = 'EnterWorktree';
|
|
8
|
+
const enterWorktreeSchema = z.strictObject({
|
|
9
|
+
path: z.string().optional().describe('Path to an existing worktree to enter'),
|
|
10
|
+
name: z.string().optional().describe('Name for the new worktree (generates branch worktree-<name>)'),
|
|
11
|
+
branch: z.string().optional().describe('Explicit branch name (overrides auto-generated)'),
|
|
12
|
+
ref: z.string().optional().describe('Git ref to checkout (default: HEAD or origin/HEAD per baseRef)'),
|
|
13
|
+
detach: z.boolean().optional().describe('Create detached HEAD worktree'),
|
|
14
|
+
pr: z.string().optional().describe('PR number (e.g. "1234") or full GitHub PR URL'),
|
|
15
|
+
});
|
|
16
|
+
export function createEnterWorktreeTool(getWorktreeService) {
|
|
17
|
+
return tool({
|
|
18
|
+
name: ENTER_WORKTREE_TOOL_NAME,
|
|
19
|
+
description: 'Creates an isolated git worktree and switches the agent\'s working directory into it. ' +
|
|
20
|
+
'Pass a path to switch into an existing worktree. ' +
|
|
21
|
+
'From within a worktree, only the path form is available and the target must be under .actoviq/worktrees/.',
|
|
22
|
+
inputSchema: enterWorktreeSchema,
|
|
23
|
+
isConcurrencySafe: () => false,
|
|
24
|
+
prompt: async () => {
|
|
25
|
+
return [
|
|
26
|
+
'## EnterWorktree Tool',
|
|
27
|
+
'Creates an isolated git worktree for parallel work. Use when:',
|
|
28
|
+
'- Working on multiple features/bugs simultaneously',
|
|
29
|
+
'- Testing changes in isolation without affecting the main checkout',
|
|
30
|
+
'- Reviewing PRs in a clean workspace',
|
|
31
|
+
'',
|
|
32
|
+
'Parameters:',
|
|
33
|
+
'- `name`: Human-readable name (auto-generates branch worktree-<name>)',
|
|
34
|
+
'- `branch`: Explicit branch name (overrides auto-generated)',
|
|
35
|
+
'- `ref`: Git ref to base the worktree on',
|
|
36
|
+
'- `detach`: Create a detached HEAD worktree',
|
|
37
|
+
'- `pr`: PR number or URL to check out',
|
|
38
|
+
'- `path`: Enter an existing worktree by path',
|
|
39
|
+
'',
|
|
40
|
+
'After entering, all file operations use the worktree directory. Use ExitWorktree to return.',
|
|
41
|
+
].join('\n');
|
|
42
|
+
},
|
|
43
|
+
}, async (input, context) => {
|
|
44
|
+
const service = getWorktreeService();
|
|
45
|
+
if (!service) {
|
|
46
|
+
return 'Worktree service is not available. Ensure the project is a git repository.';
|
|
47
|
+
}
|
|
48
|
+
// Enter existing worktree
|
|
49
|
+
if (input.path) {
|
|
50
|
+
const entry = await service.enterWorktree(input.path, input.branch);
|
|
51
|
+
return `Entered existing worktree at ${entry.workDir} (branch: ${entry.worktreeBranch ?? 'detached'}).\n\n` +
|
|
52
|
+
`Working directory is now: ${entry.workDir}\n` +
|
|
53
|
+
`Use ExitWorktree to return to the original directory.`;
|
|
54
|
+
}
|
|
55
|
+
// Create new worktree
|
|
56
|
+
if (service.isInWorktree) {
|
|
57
|
+
return 'Cannot create a new worktree from within a worktree. Use the path form to switch to another existing worktree, or ExitWorktree first.';
|
|
58
|
+
}
|
|
59
|
+
const entry = await service.createAndEnterWorktree({
|
|
60
|
+
name: input.name,
|
|
61
|
+
branch: input.branch,
|
|
62
|
+
ref: input.ref,
|
|
63
|
+
detach: input.detach,
|
|
64
|
+
pr: input.pr,
|
|
65
|
+
});
|
|
66
|
+
const parts = [
|
|
67
|
+
`Created worktree at ${entry.workDir}`,
|
|
68
|
+
`Branch: ${entry.worktreeBranch ?? 'detached HEAD'}`,
|
|
69
|
+
`Working directory is now: ${entry.workDir}`,
|
|
70
|
+
'',
|
|
71
|
+
'Use ExitWorktree to return to the original directory.',
|
|
72
|
+
];
|
|
73
|
+
if (input.pr) {
|
|
74
|
+
parts.unshift(`Checked out PR #${input.pr.replace(/^#/, '')}`);
|
|
75
|
+
}
|
|
76
|
+
return parts.join('\n');
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=enterWorktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enterWorktree.js","sourceRoot":"","sources":["../../../src/tools/enterWorktree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorktreeService } from '../worktree/worktreeService.js';
|
|
2
|
+
export declare const EXIT_WORKTREE_TOOL_NAME = "ExitWorktree";
|
|
3
|
+
export declare function createExitWorktreeTool(getWorktreeService: () => WorktreeService | undefined): import("../types.js").AgentToolDefinition<Record<string, never>, string>;
|
|
4
|
+
//# sourceMappingURL=exitWorktree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exitWorktree.d.ts","sourceRoot":"","sources":["../../../src/tools/exitWorktree.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEtE,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAItD,wBAAgB,sBAAsB,CAAC,kBAAkB,EAAE,MAAM,eAAe,GAAG,SAAS,4EAuD3F"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExitWorktree tool — exits the current worktree and returns to
|
|
3
|
+
* the original working directory.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { tool } from '../runtime/tools.js';
|
|
7
|
+
export const EXIT_WORKTREE_TOOL_NAME = 'ExitWorktree';
|
|
8
|
+
const exitWorktreeSchema = z.strictObject({});
|
|
9
|
+
export function createExitWorktreeTool(getWorktreeService) {
|
|
10
|
+
return tool({
|
|
11
|
+
name: EXIT_WORKTREE_TOOL_NAME,
|
|
12
|
+
description: 'Exits the current worktree and returns to the original working directory. ' +
|
|
13
|
+
'Not available to subagents already running in worktree isolation.',
|
|
14
|
+
inputSchema: exitWorktreeSchema,
|
|
15
|
+
isConcurrencySafe: () => false,
|
|
16
|
+
prompt: async () => {
|
|
17
|
+
return [
|
|
18
|
+
'## ExitWorktree Tool',
|
|
19
|
+
'Exits the current worktree and returns to the original working directory.',
|
|
20
|
+
'The worktree is NOT automatically cleaned up — if it has changes, you will',
|
|
21
|
+
'be prompted to keep or discard them.',
|
|
22
|
+
].join('\n');
|
|
23
|
+
},
|
|
24
|
+
}, async (_input) => {
|
|
25
|
+
const service = getWorktreeService();
|
|
26
|
+
if (!service) {
|
|
27
|
+
return 'Worktree service is not available.';
|
|
28
|
+
}
|
|
29
|
+
if (!service.isInWorktree) {
|
|
30
|
+
return 'Not currently in a worktree. Nothing to exit.';
|
|
31
|
+
}
|
|
32
|
+
const prevWorkDir = service.currentWorkDir;
|
|
33
|
+
const popped = service.exitWorktree();
|
|
34
|
+
if (!popped) {
|
|
35
|
+
return 'Not currently in a worktree. Nothing to exit.';
|
|
36
|
+
}
|
|
37
|
+
const dirty = await service.isWorktreeDirty(prevWorkDir);
|
|
38
|
+
const parts = [
|
|
39
|
+
`Exited worktree at ${prevWorkDir}.`,
|
|
40
|
+
`Working directory restored to: ${service.currentWorkDir}`,
|
|
41
|
+
];
|
|
42
|
+
if (dirty) {
|
|
43
|
+
parts.push('', `⚠ The worktree at ${prevWorkDir} has uncommitted changes.`, `Branch: ${popped.worktreeBranch ?? 'detached'}`, 'The worktree directory and branch have been preserved. Clean up manually when ready:', ` git -C "${service.repoRootPath}" worktree remove --force "${prevWorkDir}"`);
|
|
44
|
+
}
|
|
45
|
+
return parts.join('\n');
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=exitWorktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exitWorktree.js","sourceRoot":"","sources":["../../../src/tools/exitWorktree.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAG3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,cAAc,CAAC;AAEtD,MAAM,kBAAkB,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;AAE9C,MAAM,UAAU,sBAAsB,CAAC,kBAAqD;IAC1F,OAAO,IAAI,CACT;QACE,IAAI,EAAE,uBAAuB;QAC7B,WAAW,EACT,4EAA4E;YAC5E,mEAAmE;QACrE,WAAW,EAAE,kBAAkB;QAC/B,iBAAiB,EAAE,GAAG,EAAE,CAAC,KAAK;QAC9B,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,OAAO;gBACL,sBAAsB;gBACtB,2EAA2E;gBAC3E,4EAA4E;gBAC5E,sCAAsC;aACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;KACF,EACD,KAAK,EAAE,MAA6B,EAAE,EAAE;QACtC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,oCAAoC,CAAC;QAC9C,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC1B,OAAO,+CAA+C,CAAC;QACzD,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;QAEtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,+CAA+C,CAAC;QACzD,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC;QAEzD,MAAM,KAAK,GAAa;YACtB,sBAAsB,WAAW,GAAG;YACpC,kCAAkC,OAAO,CAAC,cAAc,EAAE;SAC3D,CAAC;QAEF,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,IAAI,CACR,EAAE,EACF,qBAAqB,WAAW,2BAA2B,EAC3D,WAAW,MAAM,CAAC,cAAc,IAAI,UAAU,EAAE,EAChD,sFAAsF,EACtF,aAAa,OAAO,CAAC,YAAY,8BAA8B,WAAW,GAAG,CAC9E,CAAC;QACJ,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const TAVILY_SEARCH_TOOL_NAME = "TavilySearch";
|
|
2
|
+
export declare function createTavilySearchTool(): import("../types.js").AgentToolDefinition<{
|
|
3
|
+
query: string;
|
|
4
|
+
depth: "basic" | "advanced";
|
|
5
|
+
topic: "general" | "news";
|
|
6
|
+
max_results: number;
|
|
7
|
+
include_answer: boolean;
|
|
8
|
+
include_raw_content: boolean;
|
|
9
|
+
include_domains?: string[] | undefined;
|
|
10
|
+
exclude_domains?: string[] | undefined;
|
|
11
|
+
}, string>;
|
|
12
|
+
//# sourceMappingURL=tavilySearch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tavilySearch.d.ts","sourceRoot":"","sources":["../../../src/tools/tavilySearch.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,uBAAuB,iBAAiB,CAAC;AAwEtD,wBAAgB,sBAAsB;;;;;;;;;WAuFrC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily Search Tool — AI-optimized web search via Tavily REST API.
|
|
3
|
+
* No Python dependency. Uses fetch() directly.
|
|
4
|
+
*
|
|
5
|
+
* Requires: TAVILY_API_KEY env var (get key at https://tavily.com)
|
|
6
|
+
*/
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { tool } from '../runtime/tools.js';
|
|
9
|
+
export const TAVILY_SEARCH_TOOL_NAME = 'TavilySearch';
|
|
10
|
+
const tavilySearchSchema = z.strictObject({
|
|
11
|
+
query: z.string().min(2).describe('The search query'),
|
|
12
|
+
depth: z.enum(['basic', 'advanced']).optional().default('basic')
|
|
13
|
+
.describe('Search depth: basic (fast, 1-2s) or advanced (comprehensive, 5-10s)'),
|
|
14
|
+
topic: z.enum(['general', 'news']).optional().default('general')
|
|
15
|
+
.describe('general for broad web, news for current events (last 7 days)'),
|
|
16
|
+
max_results: z.number().int().min(1).max(20).optional().default(5)
|
|
17
|
+
.describe('Number of results (1-20)'),
|
|
18
|
+
include_answer: z.boolean().optional().default(true)
|
|
19
|
+
.describe('Include AI-generated answer summary'),
|
|
20
|
+
include_raw_content: z.boolean().optional().default(false)
|
|
21
|
+
.describe('Include raw HTML content of sources'),
|
|
22
|
+
include_domains: z.array(z.string()).optional()
|
|
23
|
+
.describe('Only include results from these domains'),
|
|
24
|
+
exclude_domains: z.array(z.string()).optional()
|
|
25
|
+
.describe('Exclude results from these domains'),
|
|
26
|
+
});
|
|
27
|
+
function formatResults(data, input) {
|
|
28
|
+
const lines = [];
|
|
29
|
+
lines.push(`Query: "${data.query}"`);
|
|
30
|
+
if (data.response_time)
|
|
31
|
+
lines.push(`Response time: ${data.response_time.toFixed(2)}s`);
|
|
32
|
+
if (data.answer) {
|
|
33
|
+
lines.push('');
|
|
34
|
+
lines.push('## AI Answer');
|
|
35
|
+
lines.push(data.answer);
|
|
36
|
+
}
|
|
37
|
+
if (data.results.length > 0) {
|
|
38
|
+
lines.push('');
|
|
39
|
+
lines.push(`## Results (${data.results.length})`);
|
|
40
|
+
for (let i = 0; i < data.results.length; i++) {
|
|
41
|
+
const r = data.results[i];
|
|
42
|
+
lines.push(`\n${i + 1}. **${r.title}**`);
|
|
43
|
+
lines.push(` URL: ${r.url}`);
|
|
44
|
+
lines.push(` Score: ${r.score.toFixed(2)}`);
|
|
45
|
+
lines.push(` ${r.content.slice(0, 300)}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (data.images && data.images.length > 0) {
|
|
49
|
+
lines.push(`\n## Images (${data.images.length})`);
|
|
50
|
+
for (const img of data.images.slice(0, 5)) {
|
|
51
|
+
lines.push(` ${img}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return lines.join('\n');
|
|
55
|
+
}
|
|
56
|
+
export function createTavilySearchTool() {
|
|
57
|
+
return tool({
|
|
58
|
+
name: TAVILY_SEARCH_TOOL_NAME,
|
|
59
|
+
description: 'AI-optimized web search via Tavily. Returns clean structured results with ' +
|
|
60
|
+
'optional AI-generated answer summary. Supports domain filtering, news search, ' +
|
|
61
|
+
'and raw content extraction. Use for research, fact-checking, current events.',
|
|
62
|
+
inputSchema: tavilySearchSchema,
|
|
63
|
+
isReadOnly: () => true,
|
|
64
|
+
prompt: async () => [
|
|
65
|
+
'## TavilySearch Tool',
|
|
66
|
+
'AI-optimized web search. Key capabilities:',
|
|
67
|
+
'- AI-generated answer summaries from search results',
|
|
68
|
+
'- Clean structured results (title, URL, content, relevance score)',
|
|
69
|
+
'- `depth: "basic"` for quick facts, `"advanced"` for comprehensive research',
|
|
70
|
+
'- `topic: "news"` for current events (last 7 days)',
|
|
71
|
+
'- Domain filtering with `include_domains` / `exclude_domains`',
|
|
72
|
+
'- Set `include_raw_content: true` for full HTML of sources',
|
|
73
|
+
'',
|
|
74
|
+
'Best practices:',
|
|
75
|
+
'- Start with basic depth for most queries',
|
|
76
|
+
'- Use advanced only for complex research topics',
|
|
77
|
+
'- Limit max_results to what you actually need',
|
|
78
|
+
'- Always cite sources in your response',
|
|
79
|
+
].join('\n'),
|
|
80
|
+
}, async (input, _context, onProgress) => {
|
|
81
|
+
// Resolve API key: env var > ~/.tavily/config.json
|
|
82
|
+
let apiKey = process.env.TAVILY_API_KEY;
|
|
83
|
+
if (!apiKey) {
|
|
84
|
+
try {
|
|
85
|
+
const fs = await import('node:fs');
|
|
86
|
+
const path = await import('node:path');
|
|
87
|
+
const os = await import('node:os');
|
|
88
|
+
const configPath = path.join(os.homedir(), '.tavily', 'config.json');
|
|
89
|
+
if (fs.existsSync(configPath)) {
|
|
90
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
91
|
+
apiKey = config.api_key;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch { /* ignore */ }
|
|
95
|
+
}
|
|
96
|
+
if (!apiKey) {
|
|
97
|
+
return 'Error: Tavily API key not found. Set TAVILY_API_KEY env var or create ~/.tavily/config.json with {"api_key": "tvly-..."}. Get a free key at https://tavily.com';
|
|
98
|
+
}
|
|
99
|
+
onProgress?.({
|
|
100
|
+
toolUseID: '',
|
|
101
|
+
data: { type: 'searching', message: `Tavily search: "${input.query}" (${input.depth}/${input.topic})` },
|
|
102
|
+
});
|
|
103
|
+
const body = {
|
|
104
|
+
api_key: apiKey,
|
|
105
|
+
query: input.query,
|
|
106
|
+
search_depth: input.depth,
|
|
107
|
+
topic: input.topic,
|
|
108
|
+
max_results: input.max_results,
|
|
109
|
+
include_answer: input.include_answer,
|
|
110
|
+
include_raw_content: input.include_raw_content,
|
|
111
|
+
};
|
|
112
|
+
if (input.include_domains)
|
|
113
|
+
body.include_domains = input.include_domains;
|
|
114
|
+
if (input.exclude_domains)
|
|
115
|
+
body.exclude_domains = input.exclude_domains;
|
|
116
|
+
try {
|
|
117
|
+
const response = await fetch('https://api.tavily.com/search', {
|
|
118
|
+
method: 'POST',
|
|
119
|
+
headers: { 'Content-Type': 'application/json' },
|
|
120
|
+
body: JSON.stringify(body),
|
|
121
|
+
signal: AbortSignal.timeout(30000),
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok) {
|
|
124
|
+
const errText = await response.text().catch(() => '');
|
|
125
|
+
return `Tavily search failed: HTTP ${response.status} ${response.statusText}. ${errText.slice(0, 200)}`;
|
|
126
|
+
}
|
|
127
|
+
const data = (await response.json());
|
|
128
|
+
return formatResults(data, input);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
132
|
+
if (message.includes('abort') || message.includes('timeout')) {
|
|
133
|
+
return `Tavily search timed out after 30s. Try a simpler query or use basic depth.`;
|
|
134
|
+
}
|
|
135
|
+
return `Tavily search failed: ${message}`;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=tavilySearch.js.map
|