Skip to content

Commit 1b52b32

Browse files
authored
adding fetch tool (#1474)
* adding fetch tool * basic fetch working
1 parent b915de5 commit 1b52b32

File tree

17 files changed

+225
-39
lines changed

17 files changed

+225
-39
lines changed

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"echomodel",
6666
"emojify",
6767
"Entra",
68+
"evalprompt",
6869
"Evals",
6970
"execa",
7071
"extname",
@@ -92,6 +93,7 @@
9293
"htmlescape",
9394
"huggingface",
9495
"icontains",
96+
"importprompt",
9597
"jaegertracing",
9698
"Jamba",
9799
"JSONLLM",
@@ -163,12 +165,14 @@
163165
"previ",
164166
"PRICINGS",
165167
"priompt",
168+
"promptcontext",
166169
"promptdom",
167170
"promptfoo",
168171
"promptfooconfig",
169172
"promptjson",
170173
"promptrunner",
171174
"prompty",
175+
"proxify",
172176
"pyodide",
173177
"quoteify",
174178
"qwen",
@@ -210,6 +214,7 @@
210214
"tvly",
211215
"typecheck",
212216
"unfence",
217+
"unmarkdown",
213218
"unthink",
214219
"unwrappers",
215220
"urllib",

docs/genaisrc/tsconfig.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
"erasableSyntaxOnly": true
1818
},
1919
"include": [
20-
"*.mjs",
21-
"*.mts",
22-
"src/*.mts",
20+
"**/*.mjs",
21+
"**/*.mts",
2322
"./genaiscript.d.ts"
2423
]
2524
}

docs/src/components/BuiltinTools.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { LinkCard } from '@astrojs/starlight/components';
66

77
### Builtin tools
88

9+
<LinkCard title="fetch" description="Fetch data from a URL from allowed domains." href="/genaiscript/reference/scripts/system#systemfetch" />
910
<LinkCard title="fs_ask_file" description="Runs a LLM query over the content of a file. Use this tool to extract information from a file." href="/genaiscript/reference/scripts/system#systemfs_ask_file" />
1011
<LinkCard title="fs_data_query" description="Query data in a file using GROQ syntax" href="/genaiscript/reference/scripts/system#systemfs_data_query" />
1112
<LinkCard title="fs_diff_files" description="Computes a diff between two different files. Use git diff instead to compare versions of a file." href="/genaiscript/reference/scripts/system#systemfs_diff_files" />

docs/src/content/docs/reference/scripts/system.mdx

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ system({ ...,
6060
parameters: {
6161
model: {
6262
type: "string",
63-
description: "LLM model to use",
64-
default: "gpt-35-turbo",
63+
description: "LLM model to use"
6564
},
6665
},
6766
})
@@ -1184,6 +1183,92 @@ export default function (ctx: ChatGenerationContext) {
11841183
`````
11851184
11861185
1186+
### `system.fetch`
1187+
1188+
A tool that can fetch data from a URL
1189+
1190+
1191+
1192+
- tool `fetch`: Fetch data from a URL from allowed domains.
1193+
1194+
`````js wrap title="system.fetch"
1195+
system({
1196+
title: "A tool that can fetch data from a URL",
1197+
parameters: {
1198+
domains: {
1199+
type: "array",
1200+
items: {
1201+
type: "string",
1202+
description: "A list of allowed domains to fetch data from.",
1203+
},
1204+
},
1205+
},
1206+
})
1207+
1208+
export default function (ctx: ChatGenerationContext) {
1209+
const { defTool, env } = ctx
1210+
1211+
const dbg = host.logger(`system:fetch`)
1212+
const domains = env.vars["system.fetch.domains"] || []
1213+
dbg(`allowed domains: %o`, domains)
1214+
1215+
defTool(
1216+
"fetch",
1217+
"Fetch data from a URL from allowed domains.",
1218+
{
1219+
url: {
1220+
type: "string",
1221+
description: "The URL to fetch data from.",
1222+
required: true,
1223+
},
1224+
convert: {
1225+
type: "string",
1226+
description: "Converts HTML to Markdown or plain text.",
1227+
required: false,
1228+
enum: ["markdown", "text"],
1229+
},
1230+
skipToContent: {
1231+
type: "string",
1232+
description: "Skip to a specific string in the content.",
1233+
required: false,
1234+
},
1235+
},
1236+
async ({ context, ...args }) => {
1237+
const { url, convert, skipToContent } = args as {
1238+
url: string
1239+
convert: FetchTextOptions["convert"]
1240+
skipToContent: string
1241+
}
1242+
const method = "GET"
1243+
const uri = new URL(url)
1244+
const domain = uri.hostname
1245+
if (!domains.includes(domain))
1246+
return `error: domain ${domain} is not allowed.`
1247+
1248+
dbg(`${method} ${url}`)
1249+
const res = await host.fetchText(url, { convert })
1250+
dbg(`response: %d`, res.status)
1251+
if (!res.ok) return `error: ${res.status}`
1252+
if (!res.text) return res.file ?? res.status
1253+
1254+
let result = res.text
1255+
if (skipToContent) {
1256+
const index = result.indexOf(skipToContent)
1257+
if (index === -1)
1258+
return `error: skipTo '${skipToContent}' not found.`
1259+
result = result.slice(index + skipToContent.length)
1260+
}
1261+
return result
1262+
},
1263+
{
1264+
detectPromptInjection: "available",
1265+
}
1266+
)
1267+
}
1268+
1269+
`````
1270+
1271+
11871272
### `system.files`
11881273
11891274
File generation

eval/extrism/genaisrc/tsconfig.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
"erasableSyntaxOnly": true
1818
},
1919
"include": [
20-
"*.mjs",
21-
"*.mts",
22-
"src/*.mts",
20+
"**/*.mjs",
21+
"**/*.mts",
2322
"./genaiscript.d.ts"
2423
]
2524
}

genaisrc/tsconfig.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
"erasableSyntaxOnly": true
1818
},
1919
"include": [
20-
"*.mjs",
21-
"*.mts",
22-
"src/*.mts",
20+
"**/*.mjs",
21+
"**/*.mts",
2322
"./genaiscript.d.ts"
2423
]
2524
}

packages/auto/tsconfig.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
"erasableSyntaxOnly": true
1818
},
1919
"include": [
20-
"*.mjs",
21-
"*.mts",
22-
"src/*.mts",
20+
"**/*.mjs",
21+
"**/*.mts",
2322
"./genaiscript.d.ts"
2423
]
2524
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
system({
2+
title: "A tool that can fetch data from a URL",
3+
parameters: {
4+
domains: {
5+
type: "array",
6+
items: {
7+
type: "string",
8+
description: "A list of allowed domains to fetch data from.",
9+
},
10+
},
11+
},
12+
})
13+
14+
export default function (ctx: ChatGenerationContext) {
15+
const { defTool, env } = ctx
16+
17+
const dbg = host.logger(`system:fetch`)
18+
const domains = env.vars["system.fetch.domains"] || []
19+
dbg(`allowed domains: %o`, domains)
20+
21+
defTool(
22+
"fetch",
23+
"Fetch data from a URL from allowed domains.",
24+
{
25+
url: {
26+
type: "string",
27+
description: "The URL to fetch data from.",
28+
required: true,
29+
},
30+
convert: {
31+
type: "string",
32+
description: "Converts HTML to Markdown or plain text.",
33+
required: false,
34+
enum: ["markdown", "text"],
35+
},
36+
skipToContent: {
37+
type: "string",
38+
description: "Skip to a specific string in the content.",
39+
required: false,
40+
},
41+
},
42+
async ({ context, ...args }) => {
43+
const { url, convert, skipToContent } = args as {
44+
url: string
45+
convert: FetchTextOptions["convert"]
46+
skipToContent: string
47+
}
48+
const method = "GET"
49+
const uri = new URL(url)
50+
const domain = uri.hostname
51+
if (!domains.includes(domain))
52+
return `error: domain ${domain} is not allowed.`
53+
54+
dbg(`${method} ${url}`)
55+
const res = await host.fetchText(url, { convert })
56+
dbg(`response: %d`, res.status)
57+
if (!res.ok) return `error: ${res.status}`
58+
if (!res.text) return res.file ?? res.status
59+
60+
let result = res.text
61+
if (skipToContent) {
62+
const index = result.indexOf(skipToContent)
63+
if (index === -1)
64+
return `error: skipTo '${skipToContent}' not found.`
65+
result = result.slice(index + skipToContent.length)
66+
}
67+
return result
68+
},
69+
{
70+
detectPromptInjection: "available",
71+
}
72+
)
73+
}

packages/core/bundleprompts.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,7 @@ system({ ...,
218218
parameters: {
219219
model: {
220220
type: "string",
221-
description: "LLM model to use",
222-
default: "gpt-35-turbo",
221+
description: "LLM model to use"
223222
},
224223
},
225224
})

packages/core/src/chatrenderterminal.ts

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ const dbg = genaiscriptDebug("chat:render")
3030

3131
function renderTrimmed(s: string, rows: number, width: number) {
3232
const lines = s.split(/\n/g).filter((l) => !!l)
33-
const head = Math.min(rows >> 1, lines.length - 1)
34-
const tail = rows - head
35-
const trimmed = lines.slice(0, head)
36-
if (tail) {
37-
const hidden = lines.length - head - tail
38-
if (hidden === 1) trimmed.push(lines.at(-tail - 1))
39-
else if (hidden > 0) trimmed.push(`... (${hidden} lines)`)
40-
trimmed.push(...lines.slice(-tail))
33+
let trimmed = lines.slice(0)
34+
if (lines.length > rows) {
35+
const head = Math.min(rows >> 1, lines.length - 1)
36+
const tail = rows - head
37+
trimmed = lines.slice(0, head)
38+
if (tail) {
39+
const hidden = lines.length - head - tail
40+
if (hidden === 1) trimmed.push(lines.at(-tail - 1))
41+
else if (hidden > 0) trimmed.push(`... (${hidden} lines)`)
42+
trimmed.push(...lines.slice(-tail))
43+
}
4144
}
4245
const res = trimmed.map((l) =>
4346
wrapColor(CONSOLE_COLOR_DEBUG, "│" + ellipse(l, width) + "\n")

0 commit comments

Comments
 (0)