@iambarryking/ag 3.0.1 → 3.1.1

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,164 @@
1
+ import { createInterface } from 'node:readline';
2
+ import { loadConfig, saveConfig } from '../core/config.js';
3
+ // ── HTML stripping (native fallback when Jina is unavailable) ─────────────
4
+ function stripHtml(html) {
5
+ let text = html;
6
+ // Remove script, style, nav, header, footer, aside blocks
7
+ text = text.replace(/<(script|style|nav|header|footer|aside)\b[^>]*>[\s\S]*?<\/\1>/gi, '');
8
+ // Try to extract article or main content
9
+ const article = text.match(/<(article|main)\b[^>]*>([\s\S]*?)<\/\1>/i);
10
+ if (article)
11
+ text = article[2];
12
+ // Convert headings to markdown-style
13
+ text = text.replace(/<h([1-6])\b[^>]*>([\s\S]*?)<\/h\1>/gi, (_m, _l, content) => `\n## ${content.trim()}\n`);
14
+ // Convert links to text (url) format
15
+ text = text.replace(/<a\b[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, (_m, href, content) => {
16
+ const label = content.replace(/<[^>]+>/g, '').trim();
17
+ return href && !href.startsWith('#') ? `${label} (${href})` : label;
18
+ });
19
+ // Convert block elements to newlines
20
+ text = text.replace(/<\/?(p|div|li|tr|br)\b[^>]*\/?>/gi, '\n');
21
+ // Strip all remaining tags
22
+ text = text.replace(/<[^>]+>/g, '');
23
+ // Decode common HTML entities
24
+ text = text
25
+ .replace(/&amp;/g, '&')
26
+ .replace(/&lt;/g, '<')
27
+ .replace(/&gt;/g, '>')
28
+ .replace(/&quot;/g, '"')
29
+ .replace(/&#39;/g, "'")
30
+ .replace(/&nbsp;/g, ' ');
31
+ // Collapse whitespace
32
+ text = text.replace(/[ \t]+/g, ' ');
33
+ text = text.replace(/\n{3,}/g, '\n\n');
34
+ return text.trim();
35
+ }
36
+ // ── Action handlers ───────────────────────────────────────────────────────
37
+ async function doFetch(url, raw) {
38
+ try {
39
+ const parsed = new URL(url);
40
+ if (!['http:', 'https:'].includes(parsed.protocol)) {
41
+ return 'Error: URL must use http:// or https://';
42
+ }
43
+ }
44
+ catch {
45
+ return 'Error: Invalid URL.';
46
+ }
47
+ const fetchOpts = { signal: AbortSignal.timeout(15_000) };
48
+ // Try Jina Reader first (returns clean markdown, handles JS-rendered pages)
49
+ if (!raw) {
50
+ try {
51
+ const res = await fetch(`https://r.jina.ai/${url}`, {
52
+ ...fetchOpts,
53
+ headers: { 'Accept': 'text/markdown' }
54
+ });
55
+ if (res.ok) {
56
+ const text = await res.text();
57
+ if (text.trim())
58
+ return text;
59
+ }
60
+ }
61
+ catch {
62
+ // Fall through to native fetch
63
+ }
64
+ }
65
+ // Native fetch fallback
66
+ try {
67
+ const res = await fetch(url, fetchOpts);
68
+ if (!res.ok)
69
+ return `Fetch error: HTTP ${res.status}`;
70
+ const contentType = res.headers.get('content-type') || '';
71
+ if (contentType.includes('application/json')) {
72
+ const json = await res.json();
73
+ return JSON.stringify(json, null, 2);
74
+ }
75
+ const text = await res.text();
76
+ if (contentType.includes('text/html')) {
77
+ return stripHtml(text);
78
+ }
79
+ return text;
80
+ }
81
+ catch (error) {
82
+ return `Fetch failed: ${error.message}`;
83
+ }
84
+ }
85
+ async function ensureTavilyKey() {
86
+ const existing = process.env.TAVILY_API_KEY || loadConfig().tavilyApiKey;
87
+ if (existing)
88
+ return existing;
89
+ // Interactive prompt if TTY
90
+ if (process.stdin.isTTY) {
91
+ const C = await import('../core/colors.js').then(m => m.C);
92
+ console.error(`\n${C.bold}Web search requires a Tavily API key${C.reset}`);
93
+ console.error(`Sign up free (no credit card): ${C.cyan}https://app.tavily.com${C.reset}\n`);
94
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
95
+ const key = await new Promise(resolve => rl.question(`${C.yellow}Enter your Tavily API key:${C.reset} `, resolve));
96
+ rl.close();
97
+ const trimmed = key.trim();
98
+ if (!trimmed)
99
+ return null;
100
+ saveConfig({ tavilyApiKey: trimmed });
101
+ console.error(`${C.green}Key saved to config.${C.reset}\n`);
102
+ return trimmed;
103
+ }
104
+ return null;
105
+ }
106
+ async function doSearch(query) {
107
+ const key = await ensureTavilyKey();
108
+ if (!key) {
109
+ return 'Error: Tavily API key not configured. Sign up free at https://tavily.com (no credit card needed), then set TAVILY_API_KEY env var or run /config set tavilyApiKey <key>';
110
+ }
111
+ try {
112
+ const res = await fetch('https://api.tavily.com/search', {
113
+ method: 'POST',
114
+ headers: { 'Content-Type': 'application/json' },
115
+ signal: AbortSignal.timeout(15_000),
116
+ body: JSON.stringify({ api_key: key, query, max_results: 5 })
117
+ });
118
+ if (!res.ok)
119
+ return `Search error: HTTP ${res.status}`;
120
+ const data = await res.json();
121
+ if (!data.results?.length)
122
+ return 'No results found.';
123
+ return data.results.map((r, i) => `${i + 1}. ${r.title || '(untitled)'}\n ${r.url || ''}\n ${r.content || ''}`).join('\n\n');
124
+ }
125
+ catch (error) {
126
+ return `Search failed: ${error.message}`;
127
+ }
128
+ }
129
+ // ── Exported tool ─────────────────────────────────────────────────────────
130
+ export function webTool() {
131
+ return {
132
+ type: 'function',
133
+ function: {
134
+ name: 'web',
135
+ description: 'Web operations. Actions: fetch (retrieve readable content from a URL), search (search the web for current information via Tavily).',
136
+ parameters: {
137
+ type: 'object',
138
+ properties: {
139
+ action: { type: 'string', enum: ['fetch', 'search'], description: 'The web operation to perform.' },
140
+ url: { type: 'string', description: 'URL to fetch (for action=fetch).' },
141
+ query: { type: 'string', description: 'Search query (for action=search).' },
142
+ raw: { type: 'boolean', description: 'If true, use native fetch + HTML stripping instead of Jina Reader (for action=fetch). Default: false.' }
143
+ },
144
+ required: ['action']
145
+ }
146
+ },
147
+ execute: async ({ action, url, query, raw }) => {
148
+ switch (action) {
149
+ case 'fetch': {
150
+ if (!url)
151
+ return 'Error: url is required for action=fetch.';
152
+ return doFetch(url, raw);
153
+ }
154
+ case 'search': {
155
+ if (!query)
156
+ return 'Error: query is required for action=search.';
157
+ return doSearch(query);
158
+ }
159
+ default: return `Unknown action "${action}". Use: fetch, search.`;
160
+ }
161
+ }
162
+ };
163
+ }
164
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/tools/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE3D,6EAA6E;AAE7E,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,IAAI,GAAG,IAAI,CAAC;IAEhB,0DAA0D;IAC1D,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,iEAAiE,EAAE,EAAE,CAAC,CAAC;IAE3F,yCAAyC;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACvE,IAAI,OAAO;QAAE,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE/B,qCAAqC;IACrC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,sCAAsC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,QAAQ,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAE7G,qCAAqC;IACrC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,gDAAgD,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC1F,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACrD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,qCAAqC;IACrC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,mCAAmC,EAAE,IAAI,CAAC,CAAC;IAE/D,2BAA2B;IAC3B,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAEpC,8BAA8B;IAC9B,IAAI,GAAG,IAAI;SACR,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAE3B,sBAAsB;IACtB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACpC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAEvC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,6EAA6E;AAE7E,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,GAAa;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnD,OAAO,yCAAyC,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,MAAM,SAAS,GAAG,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IAE1D,4EAA4E;IAC5E,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,qBAAqB,GAAG,EAAE,EAAE;gBAClD,GAAG,SAAS;gBACZ,OAAO,EAAE,EAAE,QAAQ,EAAE,eAAe,EAAE;aACvC,CAAC,CAAC;YACH,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;gBACX,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,IAAI,EAAE;oBAAE,OAAO,IAAI,CAAC;YAC/B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,qBAAqB,GAAG,CAAC,MAAM,EAAE,CAAC;QAEtD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QAE1D,IAAI,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAE9B,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACtC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,iBAAiB,KAAK,CAAC,OAAO,EAAE,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,UAAU,EAAE,CAAC,YAAY,CAAC;IACzE,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,4BAA4B;IAC5B,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,uCAAuC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3E,OAAO,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,IAAI,yBAAyB,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC5F,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC7E,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,CAAS,OAAO,CAAC,EAAE,CAC9C,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,6BAA6B,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,CAAC,CACzE,CAAC;QACF,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,UAAU,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,uBAAuB,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC5D,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,KAAa;IACnC,MAAM,GAAG,GAAG,MAAM,eAAe,EAAE,CAAC;IACpC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,yKAAyK,CAAC;IACnL,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;YACnC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,sBAAsB,GAAG,CAAC,MAAM,EAAE,CAAC;QAEvD,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAE1B,CAAC;QAEF,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM;YAAE,OAAO,mBAAmB,CAAC;QAEtD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAC/B,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,YAAY,QAAQ,CAAC,CAAC,GAAG,IAAI,EAAE,QAAQ,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CACjF,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,6EAA6E;AAE7E,MAAM,UAAU,OAAO;IACrB,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,KAAK;YACX,WAAW,EAAE,oIAAoI;YACjJ,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE;oBACnG,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE;oBACxE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;oBAC3E,GAAG,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,uGAAuG,EAAE;iBAC/I;gBACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;aACrB;SACF;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAExC,EAAmB,EAAE;YACpB,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,IAAI,CAAC,GAAG;wBAAE,OAAO,0CAA0C,CAAC;oBAC5D,OAAO,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC3B,CAAC;gBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,IAAI,CAAC,KAAK;wBAAE,OAAO,6CAA6C,CAAC;oBACjE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACzB,CAAC;gBACD,OAAO,CAAC,CAAC,OAAO,mBAAmB,MAAM,wBAAwB,CAAC;YACpE,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iambarryking/ag",
3
- "version": "3.0.1",
3
+ "version": "3.1.1",
4
4
  "description": "Persistent AI coding agent with memory - any model via OpenRouter",
5
5
  "type": "module",
6
6
  "bin": {