diff --git a/docs/genaisrc/genaiscript.d.ts b/docs/genaisrc/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/docs/genaisrc/genaiscript.d.ts +++ b/docs/genaisrc/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/docs/src/content/docs/reference/scripts/cache.mdx b/docs/src/content/docs/reference/scripts/cache.mdx index 5e7cdf8bd6..c9de83b0d1 100644 --- a/docs/src/content/docs/reference/scripts/cache.mdx +++ b/docs/src/content/docs/reference/scripts/cache.mdx @@ -67,4 +67,18 @@ npx genaiscript run .... --cache-name summary - cache - summary.jsonl - \ No newline at end of file + + +## Programmatic cache + +You can instantiate a custom cache object to manage the cache programmatically. + +```js +const cache = await workspace.cache("summary") +// write entries +await cache.set("file.txt", "...") +// read entries +const content = await cache.get("file.txt") +// list entries +const entries = await cache.values() +``` \ No newline at end of file diff --git a/genaisrc/genaiscript.d.ts b/genaisrc/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/genaisrc/genaiscript.d.ts +++ b/genaisrc/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/core/src/filesystem.ts b/packages/core/src/filesystem.ts index e6760e14c2..f4e7f20f25 100644 --- a/packages/core/src/filesystem.ts +++ b/packages/core/src/filesystem.ts @@ -1,3 +1,4 @@ +import { JSONLineCache } from "./cache" import { DOT_ENV_REGEX } from "./constants" import { NotSupportedError, errorMessage } from "./error" import { resolveFileContent } from "./file" @@ -67,6 +68,16 @@ export function createFileSystem(): Omit { const res = XMLParse(file.content) return res }, + cache: async (name: string) => { + if (!name) throw new NotSupportedError("missing cache name") + const res = JSONLineCache.byName(name) + return >{ + get: async (key: any) => res.get(key), + set: async (key: any, val: any) => res.set(key, val), + values: async () => + res.entries().then((es) => es.map((e) => e.val)), + } + }, } ;(fs as any).readFile = readText return Object.freeze(fs) diff --git a/packages/core/src/genaisrc/genaiscript.d.ts b/packages/core/src/genaisrc/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/core/src/genaisrc/genaiscript.d.ts +++ b/packages/core/src/genaisrc/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/core/src/promptcontext.ts b/packages/core/src/promptcontext.ts index a886688ce9..ab6acee5e8 100644 --- a/packages/core/src/promptcontext.ts +++ b/packages/core/src/promptcontext.ts @@ -17,7 +17,6 @@ import { YAMLParse, YAMLStringify } from "./yaml" import { createParsers } from "./parsers" import { readText } from "./fs" import { - PromptImage, PromptNode, appendChild, createFileMergeNode, @@ -105,6 +104,7 @@ export async function createPromptContext( readJSON: (f) => runtimeHost.workspace.readJSON(f), readXML: (f) => runtimeHost.workspace.readXML(f), writeText: (f, c) => runtimeHost.workspace.writeText(f, c), + cache: (n) => runtimeHost.workspace.cache(n), findFiles: async (pattern, options) => { const res = await runtimeHost.workspace.findFiles(pattern, options) trace.files(res, { diff --git a/packages/core/src/types/prompt_template.d.ts b/packages/core/src/types/prompt_template.d.ts index 496c757ffb..70300854f0 100644 --- a/packages/core/src/types/prompt_template.d.ts +++ b/packages/core/src/types/prompt_template.d.ts @@ -475,6 +475,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -524,6 +543,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1641,6 +1669,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/genaisrc/cache.genai.mts b/packages/sample/genaisrc/cache.genai.mts new file mode 100644 index 0000000000..a4dad263f0 --- /dev/null +++ b/packages/sample/genaisrc/cache.genai.mts @@ -0,0 +1,17 @@ +script({ + model: "openai:gpt-3.5-turbo", + tests: {}, +}) + +const cache = await workspace.cache("test-cache") +const key = Math.random() +const value = Math.random() + +await cache.set(key, value) +const result = await cache.get(key) +if (result !== value) throw new Error(`unexpected value: ${result}`) + +const values = await cache.values() +if (!values.includes(value)) throw new Error(`unexpected values: ${values}`) + +console.log(`cache test passed`) diff --git a/packages/sample/genaisrc/genaiscript.d.ts b/packages/sample/genaisrc/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/genaisrc/genaiscript.d.ts +++ b/packages/sample/genaisrc/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/genaisrc/node/genaiscript.d.ts b/packages/sample/genaisrc/node/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/genaisrc/node/genaiscript.d.ts +++ b/packages/sample/genaisrc/node/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/genaisrc/python/genaiscript.d.ts b/packages/sample/genaisrc/python/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/genaisrc/python/genaiscript.d.ts +++ b/packages/sample/genaisrc/python/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/genaisrc/style/genaiscript.d.ts b/packages/sample/genaisrc/style/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/genaisrc/style/genaiscript.d.ts +++ b/packages/sample/genaisrc/style/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/src/aici/genaiscript.d.ts b/packages/sample/src/aici/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/src/aici/genaiscript.d.ts +++ b/packages/sample/src/aici/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/src/errors/genaiscript.d.ts b/packages/sample/src/errors/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/src/errors/genaiscript.d.ts +++ b/packages/sample/src/errors/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/src/makecode/genaiscript.d.ts b/packages/sample/src/makecode/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/src/makecode/genaiscript.d.ts +++ b/packages/sample/src/makecode/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/src/tla/genaiscript.d.ts b/packages/sample/src/tla/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/src/tla/genaiscript.d.ts +++ b/packages/sample/src/tla/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/packages/sample/src/vision/genaiscript.d.ts b/packages/sample/src/vision/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/packages/sample/src/vision/genaiscript.d.ts +++ b/packages/sample/src/vision/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML diff --git a/slides/genaisrc/genaiscript.d.ts b/slides/genaisrc/genaiscript.d.ts index 21c6d21a0e..2868d9057b 100644 --- a/slides/genaisrc/genaiscript.d.ts +++ b/slides/genaisrc/genaiscript.d.ts @@ -500,6 +500,25 @@ interface ToolCallContent { type ToolCallOutput = string | ToolCallContent | ShellOutput | WorkspaceFile +interface WorkspaceFileCache { + /** + * Gets the value associated with the key, or undefined if there is none. + * @param key + */ + get(key: K): Promise + /** + * Sets the value associated with the key. + * @param key + * @param value + */ + set(key: K, value: V): Promise + + /** + * List the values in the cache. + */ + values(): Promise +} + interface WorkspaceFileSystem { /** * Searches for files using the glob pattern and returns a list of files. @@ -549,6 +568,15 @@ interface WorkspaceFileSystem { * @param content */ writeText(path: string, content: string): Promise + + /** + * Opens a key-value cache for the given cache name. + * The cache is persisted accross runs of the script. Entries are dropped when the cache grows too large. + * @param cacheName + */ + cache( + cacheName: string + ): Promise> } interface ToolCallContext { @@ -1666,6 +1694,9 @@ interface PromptContext extends ChatGenerationContext { path: Path parsers: Parsers retrieval: Retrieval + /** + * @deprecated Use `workspace` instead + */ fs: WorkspaceFileSystem workspace: WorkspaceFileSystem YAML: YAML