diff --git a/docs/genaisrc/genaiscript.d.ts b/docs/genaisrc/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/docs/genaisrc/genaiscript.d.ts +++ b/docs/genaisrc/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/docs/src/components/BuiltinAgents.mdx b/docs/src/components/BuiltinAgents.mdx new file mode 100644 index 0000000000..d27df7e75d --- /dev/null +++ b/docs/src/components/BuiltinAgents.mdx @@ -0,0 +1,13 @@ +--- +title: Builtin Agents +description: List of agents in system prompts +--- +import { LinkCard } from '@astrojs/starlight/components'; + +### Builtin Agents + + + + + + diff --git a/docs/src/components/BuiltinTools.mdx b/docs/src/components/BuiltinTools.mdx index 3e45d136ce..b6a730b7eb 100644 --- a/docs/src/components/BuiltinTools.mdx +++ b/docs/src/components/BuiltinTools.mdx @@ -6,24 +6,19 @@ import { LinkCard } from '@astrojs/starlight/components'; ### Builtin tools - - - - - - - + + - - - - + + + + diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index 75ad333bb1..91dd3fcfd1 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -21,6 +21,7 @@ import { Card, CardGrid } from "@astrojs/starlight/components" import { FileTree } from "@astrojs/starlight/components" import AudioPlayer from "../../components/AudioPlayer.astro" import DirectoryLinks from "../../components/DirectoryLinks.astro" +import { Content as BuiltinAgents } from "../../components/BuiltinAgents.mdx" import vscodeSrc from "../../../public/images/visual-studio-code.png" @@ -116,6 +117,43 @@ or with a [command line](/genaiscript/getting-started/installation). + + +Register JavaScript functions as [LLM tools](/genaiscript/reference/scripts/tools/) + +```js wrap +defTool("weather", "live weahter", + { city: "Paris" }, // schema + async ({ city }) => // callback + { ... "sunny" } +) +``` + +or use built-in [@agentic tools](/genaiscript/guides/agentic-tools/) + +```js wrap +import { WeatherClient } from "@agentic/weather" +defTool(new WeatherClient()) +``` + + + + + +Combine [tools](/genaiscript/reference/scripts/tools) and [inline prompts](/genaiscript/reference/scripts/inline-prompts/) +into an [agent](/genaiscript/reference/scripts/agents). + +```js wrap +defAgent( + "git", + "Agent that answer git questions for the current repo", + "You are a helpful expert in using git.", + { tools: ["git"] } +) +``` + + + Scripts are [files](/genaiscript/reference/scripts/)! They can be versioned, shared, forked, ... @@ -259,27 +297,6 @@ script({ ..., model: "ollama:phi3" }) - - -Register JavaScript functions as [LLM tools](/genaiscript/reference/scripts/tools/) - -```js wrap -defTool("weather", "live weahter", - { city: "Paris" }, // schema - async ({ city }) => // callback - { ... "sunny" } -) -``` - -or use built-in [@agentic tools](/genaiscript/guides/agentic-tools/) - -```js wrap -import { WeatherClient } from "@agentic/weather" -defTool(new WeatherClient()) -``` - - - Let the LLM run code in a sandboxed execution environment. @@ -379,16 +396,23 @@ script({ ..., tests: { ## Case Studies + Tales from the real world using GenAIScript. ## Samples + Fully fledged scripts ready to use. ## Guides + A cookbook full of recipes to make you a genius scripter. + +## Agents + + diff --git a/docs/src/content/docs/reference/scripts/agents.mdx b/docs/src/content/docs/reference/scripts/agents.mdx new file mode 100644 index 0000000000..287ff040c6 --- /dev/null +++ b/docs/src/content/docs/reference/scripts/agents.mdx @@ -0,0 +1,37 @@ +--- +title: Agents (LLM Tools) +description: An Agent is a tool that queries LLM, equipped with other tools, to accomplish tasks. +sidebar: + order: 7.1 +--- + +import { Content as BuiltinAgents } from "../../../../components/BuiltinAgents.mdx" + +GenAIScript defines an **agent** as a [tool](/genaiscript/reference/scripts/tools) that +runs an [inline prompt](/genaiscript/reference/scripts/inline-prompts) to accomplish a task. The agent LLM is typically augmented with +additional tools. + +## Agent flow engine + +**GenAIScript does _not_ implement any agentic workflow or decision.** +It relies entierly on [tools](/genaiscript/reference/scripts/tools) support builtin to the LLMs. + +## defAgent + +The `defAgent` function is used to define an agent that can be called by the LLM. It takes a JSON schema to define the input and expects a string output. The LLM decides to call this agent on its own! + +```ts +defAgent( + "git", // agent id becomes 'agent_git' + "Handles any git operation", // description + "You are a helpful expert in using git.", + { + tools: ["git"], + } +) +``` + +- the agent id will become the tool id `agent_` +- the description of the agent will automatically be augmented with information about the available tools + + diff --git a/docs/src/content/docs/reference/scripts/system.mdx b/docs/src/content/docs/reference/scripts/system.mdx index 9fbb1af67d..1c48e73c85 100644 --- a/docs/src/content/docs/reference/scripts/system.mdx +++ b/docs/src/content/docs/reference/scripts/system.mdx @@ -102,7 +102,7 @@ Agent that can find, search or read files to accomplish tasks -- tool `agent_fs`: Agent that can query files to accomplish tasks + `````js wrap title="system.agent_fs" system({ @@ -111,47 +111,19 @@ system({ const model = env.vars.agentFsModel -defTool( - "agent_fs", - "Agent that can query files to accomplish tasks", +defAgent( + "fs", + "Queries files to accomplish tasks", + "Your are a helpfull LLM agent that can query the file system to accomplish tasks.", { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent fs: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - - _.$`Your are a helpfull LLM agent that can query the file system to accomplish tasks. - - Analyze and answer QUERY. - - - Assume that your answer will be analyzed by an LLM, not a human. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.fs_find_files", - "system.fs_read_file", - "system.fs_diff_files", - "system.retrieval_fuzz_search", - "system.md_frontmatter", - ], - label: "agent file system", - } - ) - return res + model, + tools: [ + "fs_find_files", + "fs_read_file", + "fs_diff_files", + "retrieval_fuzz_search", + "md_frontmatter", + ], } ) @@ -164,7 +136,7 @@ Agent that can query Git to accomplish tasks. -- tool `agent_git`: Agent that can query a repository using Git to accomplish tasks. Provide all the context information available to execute git queries. + `````js wrap title="system.agent_git" system({ @@ -173,44 +145,11 @@ system({ const model = env.vars.agentGitModel -defTool( - "agent_git", +defAgent( + "git", "Agent that can query a repository using Git to accomplish tasks. Provide all the context information available to execute git queries.", - { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent git: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - - _.$`Your are a helpfull LLM agent that can use git tools to query a repository. - - Analyze and answer QUERY. - - - Assume that your answer will be analyzed by an LLM, not a human. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.git", - ], - label: "agent git", - } - ) - return res - } + `Your are a helpfull LLM agent that can use the git tools to query the current repository. The current repository is the same as github repository.`, + { model, system: ["system.github_info"], tools: ["git"] } ) ````` @@ -222,7 +161,7 @@ Agent that can query GitHub to accomplish tasks. -- tool `agent_github`: Agent that can query GitHub to accomplish tasks + `````js wrap title="system.agent_github" system({ @@ -231,50 +170,22 @@ system({ const model = env.vars.agentGithubModel -defTool( - "agent_github", +defAgent( + "github", "Agent that can query GitHub to accomplish tasks", + `Your are a helpfull LLM agent that can query GitHub to accomplish tasks. + Prefer diffing job logs rather downloading entire logs which can be very large.`, { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent github: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - - _.$`Your are a helpfull LLM agent that can query GitHub to accomplish tasks. - - Analyze and answer QUERY. - - ## Constraints - - - Assume that your answer will be analyzed by an LLM, not a human. - - Prefer diffing job logs rather downloading entire logs which can be very large. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.github_actions", - "system.github_files", - "system.github_issues", - "system.github_pulls", - ], - label: "agent github", - } - ) - return res + model, + system: [ + "system.tools", + "system.explanations", + "system.github_info", + "system.github_actions", + "system.github_files", + "system.github_issues", + "system.github_pulls", + ], } ) @@ -287,7 +198,7 @@ Agent that can run code interpreters for Python, Math. -- tool `agent_interpreter`: Run code interpreters for Python, Math. Use this agent to ground computation questions. + `````js wrap title="system.agent_interpreter" system({ @@ -295,45 +206,22 @@ system({ }) const model = env.vars.agentInterpreterModel -defTool( - "agent_interpreter", +defAgent( + "interpreter", "Run code interpreters for Python, Math. Use this agent to ground computation questions.", + `You are an agent that can run code interpreters for Python, Math. + - Prefer math_eval for math expressions as it is much more efficient. + - To use file data in python, prefer copying data files using python_code_interpreter_copy_files rather than inline data in code. + `, { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent interpreter: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - _.$`You are an agent that can run code interpreters for Python, Math. - - Analyze and answer QUERY. Use the best tool to ground computation questions. - - - Assume that your answer will be analyzed by an AI, not a human. - - Prefer math_eval for math expressions as it is much more efficient. - - To use file data in python, prefer copying data files using python_code_interpreter_copy_files rather than inline data in code. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.math", - "system.python_code_interpreter", - ], - label: "agent interpreter", - } - ) - return res + model, + system: [ + "system", + "system.tools", + "system.explanations", + "system.math", + "system.python_code_interpreter", + ], } ) @@ -346,7 +234,7 @@ Agent that can asks questions to the user. -- tool `agent_user_input`: Ask user for input to confirm, select or answer a question. + `````js wrap title="system.agent_user_input" system({ @@ -354,38 +242,14 @@ system({ }) const model = env.vars.agentInterpreterModel -defTool( - "agent_user_input", +defAgent( + "user_input", "Ask user for input to confirm, select or answer a question.", + `You are an agent that can ask questions to the user and receive answers. Use the tools to interact with the user. + - the message should be very clear. Add context from the conversation as needed.`, { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent user input: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - _.$`You are an agent that can ask questions to the user and receive answers. Use the tools to interact with the user. - - Analyze and answer QUERY. - - - the message should be very clear. Add context from the conversation as needed. - - Assume that your answer will be analyzed by an AI, not a human. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: ["system", "system.tools", "system.user_input"], - label: "agent user input", - } - ) - return res + model, + system: ["system", "system.tools", "system.user_input"], } ) @@ -862,8 +726,8 @@ Tools to query a git repository. - tool `git_branch_current`: Gets the current branch using git. - tool `git_branch_list`: List all branches using git. -- tool `git_diff`: Computes file diffs using git. If the diff is too large, it returns the list of modified/added files. -- tool `git_log`: Generates a log of commits using git. +- tool `git_diff`: Computes file diffs using the git diff command. If the diff is too large, it returns the list of modified/added files. +- tool `git_list_commits`: Generates a history of commits using the git log command. - tool `git_status`: Generates a status of the repository using git. - tool `git_last_tag`: Gets the last tag using git. @@ -888,7 +752,7 @@ defTool("git_branch_list", "List all branches using git.", {}, async () => { defTool( "git_diff", - "Computes file diffs using git. If the diff is too large, it returns the list of modified/added files.", + "Computes file diffs using the git diff command. If the diff is too large, it returns the list of modified/added files.", { type: "object", properties: { @@ -938,8 +802,8 @@ defTool( ) defTool( - "git_log", - "Generates a log of commits using git.", + "git_list_commits", + "Generates a history of commits using the git log command.", { type: "object", properties: { @@ -996,22 +860,23 @@ defTool("git_last_tag", "Gets the last tag using git.", {}, async () => { github workflows -Queries results from workflows in GitHub actions. +Queries results from workflows in GitHub actions. Prefer using dffs to compare logs. -- tool `github_actions_workflows_list`: List all workflows as a list of 'id: name' pair. -- tool `github_actions_jobs_list`: List all jobs for a run. -- tool `github_actions_job_logs_get`: Download workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs. -- tool `github_actions_job_logs_diff`: Diffs two workflow job logsr. +- tool `github_actions_workflows_list`: List all github workflows. +- tool `github_actions_jobs_list`: List all jobs for a github workflow run. +- tool `github_actions_job_logs_get`: Download github workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs. +- tool `github_actions_job_logs_diff`: Diffs two github workflow job logs. `````js wrap title="system.github_actions" system({ title: "github workflows", - description: "Queries results from workflows in GitHub actions.", + description: + "Queries results from workflows in GitHub actions. Prefer using dffs to compare logs.", }) defTool( "github_actions_workflows_list", - "List all workflows as a list of 'id: name' pair.", + "List all github workflows.", {}, async (args) => { const { context } = args @@ -1027,9 +892,9 @@ defTool( defTool( "github_actions_runs_list", `List all runs for a workflow or the entire repository. - Use 'git_actions_list_workflows' to list workflows. - Omit 'workflow_id' to list all runs. - head_sha is the commit hash.`, + - Use 'git_actions_list_workflows' to list workflows. + - Omit 'workflow_id' to list all runs. + - head_sha is the commit hash.`, { type: "object", properties: { @@ -1077,7 +942,7 @@ defTool( defTool( "github_actions_jobs_list", - "List all jobs for a run.", + "List all jobs for a github workflow run.", { type: "object", properties: { @@ -1102,7 +967,7 @@ defTool( defTool( "github_actions_job_logs_get", - "Download workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs.", + "Download github workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs.", { type: "object", properties: { @@ -1127,7 +992,7 @@ defTool( defTool( "github_actions_job_logs_diff", - "Diffs two workflow job logsr.", + "Diffs two github workflow job logs.", { type: "object", properties: { @@ -1236,11 +1101,9 @@ system({ const info = await github.info() if (info?.owner) { - const { auth, ...rest } = info - $`## GitHub information: - -${YAML.stringify(rest)} -` + const { auth, owner, repo, baseUrl } = info + $`- current github repository: ${owner}/${repo}` + if (baseUrl) $`- current github base url: ${baseUrl}` } ````` diff --git a/docs/src/content/docs/reference/scripts/tools.mdx b/docs/src/content/docs/reference/scripts/tools.mdx index 5574eb164b..345fe14f20 100644 --- a/docs/src/content/docs/reference/scripts/tools.mdx +++ b/docs/src/content/docs/reference/scripts/tools.mdx @@ -1,5 +1,5 @@ --- -title: Tools (Functions) +title: Tools description: Learn how to define and use tools within GenAIScript to enhance answer assembly with custom logic and CLI tools. keywords: functions,tools, custom logic, CLI integration, scripting, automation sidebar: diff --git a/genaisrc/genaiscript.d.ts b/genaisrc/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/genaisrc/genaiscript.d.ts +++ b/genaisrc/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/auto/genaiscript.d.ts b/packages/auto/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/auto/genaiscript.d.ts +++ b/packages/auto/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/cli/src/nodehost.ts b/packages/cli/src/nodehost.ts index a367f9783a..bd9f613b7f 100644 --- a/packages/cli/src/nodehost.ts +++ b/packages/cli/src/nodehost.ts @@ -53,6 +53,7 @@ import { shellConfirm, shellInput, shellSelect } from "./input" import { shellQuote } from "../../core/src/shell" import { uniq } from "es-toolkit" import { PLimitPromiseQueue } from "../../core/src/concurrency" +import { Project } from "../../core/src/ast" class NodeServerManager implements ServerManager { async start(): Promise { @@ -103,6 +104,7 @@ class ModelManager implements ModelService { export class NodeHost implements RuntimeHost { readonly dotEnvPath: string + project: Project userState: any = {} models: ModelService readonly path = createNodePath() diff --git a/packages/core/bundleprompts.js b/packages/core/bundleprompts.js index 37370aea16..2629b19365 100644 --- a/packages/core/bundleprompts.js +++ b/packages/core/bundleprompts.js @@ -6,6 +6,7 @@ async function main() { const fp = "./src/default_prompts.ts" const fmp = "../../docs/src/content/docs/reference/scripts/system.mdx" const fnp = "../../docs/src/components/BuiltinTools.mdx" + const fap = "../../docs/src/components/BuiltinAgents.mdx" console.debug(`bundling ${dir}/*.genai.js into default_prompts.ts`) const promptMap = {} const prompts = readdirSync(dir) @@ -83,9 +84,14 @@ async function main() { const v = promptMap[k] const tools = [] v.replace( - /defTool\s*\(\s*"([^"]+)"\s*,\s*"([^"]+)"/gm, - (m, name, description) => { - tools.push({ id: k, name, description }) + /def(Agent|Tool)\s*\(\s*"([^"]+)"\s*,\s*"([^"]+)"/gm, + (m, kind, name, description) => { + tools.push({ + id: k, + kind: kind.toLowerCase(), + name, + description, + }) return "" } ) @@ -234,8 +240,34 @@ import { LinkCard } from '@astrojs/starlight/components'; ### Builtin tools -${functions.map(({ id, name, description }) => ``).join("\n")} +${functions + .filter(({ kind }) => kind === "tool") + .map( + ({ id, name, description }) => + `` + ) + .join("\n")} +`, + "utf-8" + ) + writeFileSync( + fap, + `--- +title: Builtin Agents +description: List of agents in system prompts +--- +import { LinkCard } from '@astrojs/starlight/components'; + +### Builtin Agents + +${functions + .filter(({ kind }) => kind === "agent") + .map( + ({ id, name, description }) => + `` + ) + .join("\n")} `, "utf-8" ) diff --git a/packages/core/src/chat.ts b/packages/core/src/chat.ts index 7ca113fa47..2173130726 100644 --- a/packages/core/src/chat.ts +++ b/packages/core/src/chat.ts @@ -11,6 +11,7 @@ import { import { assert, logError, logVerbose, logWarn } from "./util" import { extractFenced, findFirstDataFence, unfence } from "./fence" import { + JSONSchemaToFunctionParameters, toStrictJSONSchema, validateFencesWithSchema, validateJSONWithSchema, @@ -180,7 +181,9 @@ async function runToolCalls( const tool = tools.find((f) => f.spec.name === toolName) if (!tool) { logVerbose(JSON.stringify(tu, null, 2)) - throw new Error(`tool ${toolName} not found`) + throw new Error( + `multi tool ${toolName} not found in ${tools.map((t) => t.spec.name).join(", ")}` + ) } return { tool, args: tu.parameters } }) @@ -188,7 +191,9 @@ async function runToolCalls( const tool = tools.find((f) => f.spec.name === call.name) if (!tool) { logVerbose(JSON.stringify(call, null, 2)) - throw new Error(`tool ${call.name} not found`) + throw new Error( + `tool ${call.name} not found in ${tools.map((t) => t.spec.name).join(", ")}` + ) } todos = [{ tool, args: callArgs }] } @@ -597,7 +602,34 @@ export async function executeChatSession( })) : undefined trace.startDetails(`🧠 llm chat`) - if (tools?.length) trace.detailsFenced(`🛠️ tools`, tools, "yaml") + if (toolDefinitions?.length) + trace.details( + `🛠️ tools`, + dedent`\`\`\`ts + ${toolDefinitions + .map( + (t) => dedent`/** + * ${t.spec.description}${ + t.spec.parameters?.type === "object" + ? Object.entries( + t.spec.parameters.properties || {} + ) + .filter(([, ps]) => ps.description) + .map( + ([pn, ps]) => + `\n * @param ${pn} ${ps.description}` + ) + .join("") + : "" + } + */ + function ${t.spec.name}(${JSONSchemaToFunctionParameters(t.spec.parameters)}) + ` + ) + .join("\n")} + \`\`\` + ` + ) try { let genVars: Record while (true) { diff --git a/packages/core/src/expander.ts b/packages/core/src/expander.ts index 267aa7b27e..fa1c27a4a6 100644 --- a/packages/core/src/expander.ts +++ b/packages/core/src/expander.ts @@ -242,18 +242,18 @@ export async function expandTemplate( if (status !== "success" || text === "") // cancelled - return Object.freeze({ + return { status, statusText, messages, - }) + } if (cancellationToken?.isCancellationRequested) - return Object.freeze({ + return { status: "cancelled", statusText: "user cancelled", messages, - }) + } const systemMessage: ChatCompletionSystemMessageParam = { role: "system", @@ -366,7 +366,7 @@ ${schemaTs} trace.endDetails() - return Object.freeze({ + return { messages, images, schemas, @@ -385,5 +385,5 @@ ${schemaTs} outputProcessors, chatParticipants, fileOutputs, - }) + } } diff --git a/packages/core/src/genaisrc/genaiscript.d.ts b/packages/core/src/genaisrc/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/core/src/genaisrc/genaiscript.d.ts +++ b/packages/core/src/genaisrc/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/core/src/genaisrc/system.agent_fs.genai.mjs b/packages/core/src/genaisrc/system.agent_fs.genai.mjs index 0833f1e49d..1f3b521864 100644 --- a/packages/core/src/genaisrc/system.agent_fs.genai.mjs +++ b/packages/core/src/genaisrc/system.agent_fs.genai.mjs @@ -4,46 +4,18 @@ system({ const model = env.vars.agentFsModel -defTool( - "agent_fs", - "Agent that can query files to accomplish tasks", +defAgent( + "fs", + "Queries files to accomplish tasks", + "Your are a helpfull LLM agent that can query the file system to accomplish tasks.", { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent fs: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - - _.$`Your are a helpfull LLM agent that can query the file system to accomplish tasks. - - Analyze and answer QUERY. - - - Assume that your answer will be analyzed by an LLM, not a human. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.fs_find_files", - "system.fs_read_file", - "system.fs_diff_files", - "system.retrieval_fuzz_search", - "system.md_frontmatter", - ], - label: "agent file system", - } - ) - return res + model, + tools: [ + "fs_find_files", + "fs_read_file", + "fs_diff_files", + "retrieval_fuzz_search", + "md_frontmatter", + ], } ) diff --git a/packages/core/src/genaisrc/system.agent_git.genai.mjs b/packages/core/src/genaisrc/system.agent_git.genai.mjs index 099d403612..88e0823c65 100644 --- a/packages/core/src/genaisrc/system.agent_git.genai.mjs +++ b/packages/core/src/genaisrc/system.agent_git.genai.mjs @@ -4,42 +4,9 @@ system({ const model = env.vars.agentGitModel -defTool( - "agent_git", +defAgent( + "git", "Agent that can query a repository using Git to accomplish tasks. Provide all the context information available to execute git queries.", - { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent git: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - - _.$`Your are a helpfull LLM agent that can use git tools to query a repository. - - Analyze and answer QUERY. - - - Assume that your answer will be analyzed by an LLM, not a human. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.git", - ], - label: "agent git", - } - ) - return res - } + `Your are a helpfull LLM agent that can use the git tools to query the current repository. The current repository is the same as github repository.`, + { model, system: ["system.github_info"], tools: ["git"] } ) diff --git a/packages/core/src/genaisrc/system.agent_github.genai.mjs b/packages/core/src/genaisrc/system.agent_github.genai.mjs index e3e0900341..7977b630ce 100644 --- a/packages/core/src/genaisrc/system.agent_github.genai.mjs +++ b/packages/core/src/genaisrc/system.agent_github.genai.mjs @@ -4,49 +4,21 @@ system({ const model = env.vars.agentGithubModel -defTool( - "agent_github", +defAgent( + "github", "Agent that can query GitHub to accomplish tasks", + `Your are a helpfull LLM agent that can query GitHub to accomplish tasks. + Prefer diffing job logs rather downloading entire logs which can be very large.`, { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent github: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - - _.$`Your are a helpfull LLM agent that can query GitHub to accomplish tasks. - - Analyze and answer QUERY. - - ## Constraints - - - Assume that your answer will be analyzed by an LLM, not a human. - - Prefer diffing job logs rather downloading entire logs which can be very large. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.github_actions", - "system.github_files", - "system.github_issues", - "system.github_pulls", - ], - label: "agent github", - } - ) - return res + model, + system: [ + "system.tools", + "system.explanations", + "system.github_info", + "system.github_actions", + "system.github_files", + "system.github_issues", + "system.github_pulls", + ], } ) diff --git a/packages/core/src/genaisrc/system.agent_interpreter.genai.mjs b/packages/core/src/genaisrc/system.agent_interpreter.genai.mjs index d8e240a7e6..b01ebab5eb 100644 --- a/packages/core/src/genaisrc/system.agent_interpreter.genai.mjs +++ b/packages/core/src/genaisrc/system.agent_interpreter.genai.mjs @@ -3,44 +3,21 @@ system({ }) const model = env.vars.agentInterpreterModel -defTool( - "agent_interpreter", +defAgent( + "interpreter", "Run code interpreters for Python, Math. Use this agent to ground computation questions.", + `You are an agent that can run code interpreters for Python, Math. + - Prefer math_eval for math expressions as it is much more efficient. + - To use file data in python, prefer copying data files using python_code_interpreter_copy_files rather than inline data in code. + `, { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent interpreter: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - _.$`You are an agent that can run code interpreters for Python, Math. - - Analyze and answer QUERY. Use the best tool to ground computation questions. - - - Assume that your answer will be analyzed by an AI, not a human. - - Prefer math_eval for math expressions as it is much more efficient. - - To use file data in python, prefer copying data files using python_code_interpreter_copy_files rather than inline data in code. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: [ - "system", - "system.tools", - "system.explanations", - "system.math", - "system.python_code_interpreter", - ], - label: "agent interpreter", - } - ) - return res + model, + system: [ + "system", + "system.tools", + "system.explanations", + "system.math", + "system.python_code_interpreter", + ], } ) diff --git a/packages/core/src/genaisrc/system.agent_user_input.genai.mjs b/packages/core/src/genaisrc/system.agent_user_input.genai.mjs index 6f01b53ac4..60b30f532b 100644 --- a/packages/core/src/genaisrc/system.agent_user_input.genai.mjs +++ b/packages/core/src/genaisrc/system.agent_user_input.genai.mjs @@ -3,37 +3,13 @@ system({ }) const model = env.vars.agentInterpreterModel -defTool( - "agent_user_input", +defAgent( + "user_input", "Ask user for input to confirm, select or answer a question.", + `You are an agent that can ask questions to the user and receive answers. Use the tools to interact with the user. + - the message should be very clear. Add context from the conversation as needed.`, { - query: { - type: "string", - description: "Query to answer", - }, - }, - async (args) => { - const { context, query } = args - context.log(`agent user input: ${query}`) - const res = await runPrompt( - (_) => { - _.def("QUERY", query) - _.$`You are an agent that can ask questions to the user and receive answers. Use the tools to interact with the user. - - Analyze and answer QUERY. - - - the message should be very clear. Add context from the conversation as needed. - - Assume that your answer will be analyzed by an AI, not a human. - - If you are missing information, reply "MISSING_INFO: ". - - If you cannot answer the query, return "NO_ANSWER: ". - ` - }, - { - model, - system: ["system", "system.tools", "system.user_input"], - label: "agent user input", - } - ) - return res + model, + system: ["system", "system.tools", "system.user_input"], } ) diff --git a/packages/core/src/genaisrc/system.git.genai.mjs b/packages/core/src/genaisrc/system.git.genai.mjs index d42e5f65c0..a92bf3c5cb 100644 --- a/packages/core/src/genaisrc/system.git.genai.mjs +++ b/packages/core/src/genaisrc/system.git.genai.mjs @@ -18,7 +18,7 @@ defTool("git_branch_list", "List all branches using git.", {}, async () => { defTool( "git_diff", - "Computes file diffs using git. If the diff is too large, it returns the list of modified/added files.", + "Computes file diffs using the git diff command. If the diff is too large, it returns the list of modified/added files.", { type: "object", properties: { @@ -68,8 +68,8 @@ defTool( ) defTool( - "git_log", - "Generates a log of commits using git.", + "git_list_commits", + "Generates a history of commits using the git log command.", { type: "object", properties: { diff --git a/packages/core/src/genaisrc/system.github_actions.genai.mjs b/packages/core/src/genaisrc/system.github_actions.genai.mjs index 7bd7add02c..d7c2dda9ac 100644 --- a/packages/core/src/genaisrc/system.github_actions.genai.mjs +++ b/packages/core/src/genaisrc/system.github_actions.genai.mjs @@ -1,11 +1,12 @@ system({ title: "github workflows", - description: "Queries results from workflows in GitHub actions.", + description: + "Queries results from workflows in GitHub actions. Prefer using dffs to compare logs.", }) defTool( "github_actions_workflows_list", - "List all workflows as a list of 'id: name' pair.", + "List all github workflows.", {}, async (args) => { const { context } = args @@ -21,9 +22,9 @@ defTool( defTool( "github_actions_runs_list", `List all runs for a workflow or the entire repository. - Use 'git_actions_list_workflows' to list workflows. - Omit 'workflow_id' to list all runs. - head_sha is the commit hash.`, + - Use 'git_actions_list_workflows' to list workflows. + - Omit 'workflow_id' to list all runs. + - head_sha is the commit hash.`, { type: "object", properties: { @@ -71,7 +72,7 @@ defTool( defTool( "github_actions_jobs_list", - "List all jobs for a run.", + "List all jobs for a github workflow run.", { type: "object", properties: { @@ -96,7 +97,7 @@ defTool( defTool( "github_actions_job_logs_get", - "Download workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs.", + "Download github workflow job log. If the log is too large, use 'github_actions_job_logs_diff' to compare logs.", { type: "object", properties: { @@ -121,7 +122,7 @@ defTool( defTool( "github_actions_job_logs_diff", - "Diffs two workflow job logsr.", + "Diffs two github workflow job logs.", { type: "object", properties: { diff --git a/packages/core/src/genaisrc/system.github_info.genai.mjs b/packages/core/src/genaisrc/system.github_info.genai.mjs index b811611770..6b82682902 100644 --- a/packages/core/src/genaisrc/system.github_info.genai.mjs +++ b/packages/core/src/genaisrc/system.github_info.genai.mjs @@ -4,9 +4,7 @@ system({ const info = await github.info() if (info?.owner) { - const { auth, ...rest } = info - $`## GitHub information: - -${YAML.stringify(rest)} -` + const { auth, owner, repo, baseUrl } = info + $`- current github repository: ${owner}/${repo}` + if (baseUrl) $`- current github base url: ${baseUrl}` } diff --git a/packages/core/src/host.ts b/packages/core/src/host.ts index 403b401653..51d1a24273 100644 --- a/packages/core/src/host.ts +++ b/packages/core/src/host.ts @@ -3,6 +3,7 @@ import { CancellationToken } from "./cancellation" import { LanguageModel } from "./chat" import { Progress } from "./progress" import { AbortSignalOptions, MarkdownTrace, TraceOptions } from "./trace" +import { Project } from "./ast" // this is typically an instance of TextDecoder export interface UTF8Decoder { @@ -125,6 +126,7 @@ export interface Host { } export interface RuntimeHost extends Host { + project: Project models: ModelService workspace: Omit diff --git a/packages/core/src/pricing.json b/packages/core/src/pricing.json index 9dbc3f9bda..0d4f9007f6 100644 --- a/packages/core/src/pricing.json +++ b/packages/core/src/pricing.json @@ -1,166 +1,170 @@ { - "openai:gpt-4o": { - "price_per_million_input_tokens": 2.5, - "price_per_million_output_tokens": 10 - }, - "openai:gpt-4o-2024-08-06": { - "price_per_million_input_tokens": 2.5, - "price_per_million_output_tokens": 10 - }, - "openai:gpt-4o-2024-05-13": { - "price_per_million_input_tokens": 5, - "price_per_million_output_tokens": 15 - }, - "openai:gpt-4o-mini": { - "price_per_million_input_tokens": 0.15, - "price_per_million_output_tokens": 0.6 - }, - "openai:gpt-4o-mini-2024-07-18": { - "price_per_million_input_tokens": 0.15, - "price_per_million_output_tokens": 0.6 - }, - "openai:o1-preview": { - "price_per_million_input_tokens": 15, - "price_per_million_output_tokens": 60 - }, - "openai:o1-preview-2024-09-12": { - "price_per_million_input_tokens": 15, - "price_per_million_output_tokens": 60 - }, - "openai:o1-mini": { - "price_per_million_input_tokens": 3, - "price_per_million_output_tokens": 12 - }, - "openai:o1-mini-2024-09-12": { - "price_per_million_input_tokens": 3, - "price_per_million_output_tokens": 12 - }, - "openai:text-embedding-3-small": { - "price_per_million_input_tokens": 0.02, - "price_per_million_output_tokens": null - }, - "openai:text-embedding-3-large": { - "price_per_million_input_tokens": 0.13, - "price_per_million_output_tokens": null - }, - "openai:ada v2": { - "price_per_million_input_tokens": 0.1, - "price_per_million_output_tokens": null - }, - "openai:gpt-4o-realtime-preview": { - "price_per_million_input_tokens": 5, - "price_per_million_output_tokens": 20 - }, - "openai:gpt-4o-realtime-preview-2024-10-01": { - "price_per_million_input_tokens": 5, - "price_per_million_output_tokens": 20 - }, - "openai:chatgpt-4o-latest": { - "price_per_million_input_tokens": 5, - "price_per_million_output_tokens": 15 - }, - "openai:gpt-4-turbo": { - "price_per_million_input_tokens": 10, - "price_per_million_output_tokens": 30 - }, - "openai:gpt-4-turbo-2024-04-09": { - "price_per_million_input_tokens": 10, - "price_per_million_output_tokens": 30 - }, - "openai:gpt-4": { - "price_per_million_input_tokens": 30, - "price_per_million_output_tokens": 60 - }, - "openai:gpt-4-32k": { - "price_per_million_input_tokens": 60, - "price_per_million_output_tokens": 120 - }, - "openai:gpt-4-0125-preview": { - "price_per_million_input_tokens": 10, - "price_per_million_output_tokens": 30 - }, - "openai:gpt-4-1106-preview": { - "price_per_million_input_tokens": 10, - "price_per_million_output_tokens": 30 - }, - "openai:gpt-4-vision-preview": { - "price_per_million_input_tokens": 10, - "price_per_million_output_tokens": 30 - }, - "openai:gpt-3.5-turbo-0125": { - "price_per_million_input_tokens": 0.5, - "price_per_million_output_tokens": 1.5 - }, - "openai:gpt-3.5-turbo-instruct": { - "price_per_million_input_tokens": 1.5, - "price_per_million_output_tokens": 2 - }, - "openai:gpt-3.5-turbo-1106": { - "price_per_million_input_tokens": 1, - "price_per_million_output_tokens": 2 - }, - "openai:gpt-3.5-turbo-0613": { - "price_per_million_input_tokens": 1.5, - "price_per_million_output_tokens": 2 - }, - "openai:gpt-3.5-turbo-16k-0613": { - "price_per_million_input_tokens": 3, - "price_per_million_output_tokens": 4 - }, - "openai:gpt-3.5-turbo-0301": { - "price_per_million_input_tokens": 1.5, - "price_per_million_output_tokens": 2 - }, - "openai:davinci-002": { - "price_per_million_input_tokens": 2, - "price_per_million_output_tokens": 2 - }, - "openai:babbage-002": { - "price_per_million_input_tokens": 0.4, - "price_per_million_output_tokens": 0.4 - }, - "azure:gpt-4o-2024-08-06 global deployment": { - "price_per_million_input_tokens": 2.5, - "price_per_million_output_tokens": 10 - }, - "azure:gpt-4o global deployment": { - "price_per_million_input_tokens": 5, - "price_per_million_output_tokens": 15 - }, - "azure:gpt-4o-mini global deployment": { - "price_per_million_input_tokens": 0.15, - "price_per_million_output_tokens": 0.6 - }, - "azure:gpt-3.5-turbo-0301": { - "price_per_million_input_tokens": 2, - "price_per_million_output_tokens": 2 - }, - "azure:gpt-3.5-turbo-0613": { - "price_per_million_input_tokens": 1.5, - "price_per_million_output_tokens": 2 - }, - "azure:gpt-3.5-turbo-0613 16k": { - "price_per_million_input_tokens": 3, - "price_per_million_output_tokens": 4 - }, - "azure:gpt-3.5-turbo-1106": { - "price_per_million_input_tokens": 1, - "price_per_million_output_tokens": 2 - }, - "azure:gpt-3.5-turbo-0125": { - "price_per_million_input_tokens": 0.5, - "price_per_million_output_tokens": 1.5 - }, - "azure:gpt-3.5-turbo-instruct": { - "price_per_million_input_tokens": 1.5, - "price_per_million_output_tokens": 2 - }, - "azure:gpt-4": { - "price_per_million_input_tokens": 30, - "price_per_million_output_tokens": 60 - }, - "azure:gpt-4 32k": { - "price_per_million_input_tokens": 60, - "price_per_million_output_tokens": 120 - } -} \ No newline at end of file + "openai:gpt-4o": { + "price_per_million_input_tokens": 2.5, + "price_per_million_output_tokens": 10 + }, + "openai:gpt-4o-2024-08-06": { + "price_per_million_input_tokens": 2.5, + "price_per_million_output_tokens": 10 + }, + "openai:gpt-4o-2024-05-13": { + "price_per_million_input_tokens": 5, + "price_per_million_output_tokens": 15 + }, + "openai:gpt-4o-mini": { + "price_per_million_input_tokens": 0.15, + "price_per_million_output_tokens": 0.6 + }, + "openai:gpt-4o-mini-2024-07-18": { + "price_per_million_input_tokens": 0.15, + "price_per_million_output_tokens": 0.6 + }, + "openai:o1-preview": { + "price_per_million_input_tokens": 15, + "price_per_million_output_tokens": 60 + }, + "openai:o1-preview-2024-09-12": { + "price_per_million_input_tokens": 15, + "price_per_million_output_tokens": 60 + }, + "openai:o1-mini": { + "price_per_million_input_tokens": 3, + "price_per_million_output_tokens": 12 + }, + "openai:o1-mini-2024-09-12": { + "price_per_million_input_tokens": 3, + "price_per_million_output_tokens": 12 + }, + "openai:text-embedding-3-small": { + "price_per_million_input_tokens": 0.02, + "price_per_million_output_tokens": null + }, + "openai:text-embedding-3-large": { + "price_per_million_input_tokens": 0.13, + "price_per_million_output_tokens": null + }, + "openai:ada v2": { + "price_per_million_input_tokens": 0.1, + "price_per_million_output_tokens": null + }, + "openai:gpt-4o-realtime-preview": { + "price_per_million_input_tokens": 5, + "price_per_million_output_tokens": 20 + }, + "openai:gpt-4o-realtime-preview-2024-10-01": { + "price_per_million_input_tokens": 5, + "price_per_million_output_tokens": 20 + }, + "openai:chatgpt-4o-latest": { + "price_per_million_input_tokens": 5, + "price_per_million_output_tokens": 15 + }, + "openai:gpt-4-turbo": { + "price_per_million_input_tokens": 10, + "price_per_million_output_tokens": 30 + }, + "openai:gpt-4-turbo-2024-04-09": { + "price_per_million_input_tokens": 10, + "price_per_million_output_tokens": 30 + }, + "openai:gpt-4": { + "price_per_million_input_tokens": 30, + "price_per_million_output_tokens": 60 + }, + "openai:gpt-4-32k": { + "price_per_million_input_tokens": 60, + "price_per_million_output_tokens": 120 + }, + "openai:gpt-4-0125-preview": { + "price_per_million_input_tokens": 10, + "price_per_million_output_tokens": 30 + }, + "openai:gpt-4-1106-preview": { + "price_per_million_input_tokens": 10, + "price_per_million_output_tokens": 30 + }, + "openai:gpt-4-vision-preview": { + "price_per_million_input_tokens": 10, + "price_per_million_output_tokens": 30 + }, + "openai:gpt-3.5-turbo-0125": { + "price_per_million_input_tokens": 0.5, + "price_per_million_output_tokens": 1.5 + }, + "openai:gpt-3.5-turbo-instruct": { + "price_per_million_input_tokens": 1.5, + "price_per_million_output_tokens": 2 + }, + "openai:gpt-3.5-turbo-1106": { + "price_per_million_input_tokens": 1, + "price_per_million_output_tokens": 2 + }, + "openai:gpt-3.5-turbo-0613": { + "price_per_million_input_tokens": 1.5, + "price_per_million_output_tokens": 2 + }, + "openai:gpt-3.5-turbo": { + "price_per_million_input_tokens": 1.5, + "price_per_million_output_tokens": 2 + }, + "openai:gpt-3.5-turbo-16k-0613": { + "price_per_million_input_tokens": 3, + "price_per_million_output_tokens": 4 + }, + "openai:gpt-3.5-turbo-0301": { + "price_per_million_input_tokens": 1.5, + "price_per_million_output_tokens": 2 + }, + "openai:davinci-002": { + "price_per_million_input_tokens": 2, + "price_per_million_output_tokens": 2 + }, + "openai:babbage-002": { + "price_per_million_input_tokens": 0.4, + "price_per_million_output_tokens": 0.4 + }, + "azure:gpt-4o-2024-08-06 global deployment": { + "price_per_million_input_tokens": 2.5, + "price_per_million_output_tokens": 10 + }, + "azure:gpt-4o global deployment": { + "price_per_million_input_tokens": 5, + "price_per_million_output_tokens": 15 + }, + "azure:gpt-4o-mini global deployment": { + "price_per_million_input_tokens": 0.15, + "price_per_million_output_tokens": 0.6 + }, + "azure:gpt-3.5-turbo-0301": { + "price_per_million_input_tokens": 2, + "price_per_million_output_tokens": 2 + }, + "azure:gpt-3.5-turbo-0613": { + "price_per_million_input_tokens": 1.5, + "price_per_million_output_tokens": 2 + }, + "azure:gpt-3.5-turbo-0613 16k": { + "price_per_million_input_tokens": 3, + "price_per_million_output_tokens": 4 + }, + "azure:gpt-3.5-turbo-1106": { + "price_per_million_input_tokens": 1, + "price_per_million_output_tokens": 2 + }, + "azure:gpt-3.5-turbo-0125": { + "price_per_million_input_tokens": 0.5, + "price_per_million_output_tokens": 1.5 + }, + "azure:gpt-3.5-turbo-instruct": { + "price_per_million_input_tokens": 1.5, + "price_per_million_output_tokens": 2 + }, + "azure:gpt-4": { + "price_per_million_input_tokens": 30, + "price_per_million_output_tokens": 60 + }, + "azure:gpt-4 32k": { + "price_per_million_input_tokens": 60, + "price_per_million_output_tokens": 120 + } +} diff --git a/packages/core/src/promptrunner.ts b/packages/core/src/promptrunner.ts index 73942398c5..696333c568 100644 --- a/packages/core/src/promptrunner.ts +++ b/packages/core/src/promptrunner.ts @@ -111,6 +111,8 @@ export async function runTemplate( const version = CORE_VERSION assert(model !== undefined) + runtimeHost.project = prj + try { trace.heading(3, `🧠 running ${template.id} with model ${model ?? ""}`) if (cliInfo) traceCliArgs(trace, template, options) diff --git a/packages/core/src/runpromptcontext.ts b/packages/core/src/runpromptcontext.ts index 170948220f..a0ae7d72d8 100644 --- a/packages/core/src/runpromptcontext.ts +++ b/packages/core/src/runpromptcontext.ts @@ -25,7 +25,7 @@ import { renderShellOutput } from "./chatrender" import { jinjaRender } from "./jinja" import { mustacheRender } from "./mustache" import { imageEncodeForLLM } from "./image" -import { delay } from "es-toolkit" +import { delay, uniq } from "es-toolkit" import { executeChatSession, mergeGenerationOptions, @@ -43,12 +43,14 @@ import { SYSTEM_FENCE, } from "./constants" import { renderAICI } from "./aici" -import { resolveSystems } from "./systems" +import { resolveSystems, resolveTools } from "./systems" import { callExpander } from "./expander" import { isCancelError, NotSupportedError, serializeError } from "./error" import { resolveLanguageModel } from "./lm" import { concurrentLimit } from "./concurrency" import { Project } from "./ast" +import { dedent } from "./indent" +import { runtimeHost } from "./host" export function createChatTurnGenerationContext( options: GenerationOptions, @@ -280,6 +282,81 @@ export function createChatGenerationContext( ) } } + const defAgent = ( + name: string, + description: string, + fn: ( + agentCtx: ChatGenerationContext, + args: ChatFunctionArgs + ) => Promise, + options?: DefAgentOptions + ): void => { + const { tools, system, ...rest } = options || {} + + name = name.replace(/^agent_/i, "") + const agentName = `agent_${name}` + const agentLabel = `agent ${name}` + + const agentSystem = uniq([ + "system.tools", + "system.explanations", + ...arrayify(system), + ]) + const agentTools = resolveTools( + runtimeHost.project, + agentSystem, + arrayify(tools) + ) + const agentDescription = dedent`Agent uses LLM to ${description}. available tools: + ${agentTools.map((t) => `- ${t.description}`).join("\n")}` // DO NOT LEAK TOOL ID HERE + + defTool( + agentName, + agentDescription, + { + type: "object", + properties: { + query: { + type: "string", + description: "Query to answer by the LLM agent.", + }, + }, + required: ["query"], + }, + async (args) => { + const { context, query } = args + console.debug(`${agentLabel}: ${query}`) + const res = await runPrompt( + async (_) => { + if (typeof fn === "string") _.writeText(dedent(fn)) + else await fn(_, args) + + _.$` + ## Task + + Analyze and answer the task in QUERY. + + ` + _.def("QUERY", query) + + _.$` + - Assume that your answer will be analyzed by an LLM, not a human. + - If you are missing information, reply "MISSING_INFO: ". + - If you cannot answer the query, return "NO_ANSWER: ". + - Be concise. Minimize output to the most relevant information to save context tokens. + ` + }, + { + label: agentLabel, + system: agentSystem, + tools: agentTools.map(({ id }) => id), + ...rest, + } + ) + return res + } + ) + } const defSchema = ( name: string, @@ -561,6 +638,7 @@ export function createChatGenerationContext( const ctx = { ...turnCtx, + defAgent, defTool, defSchema, defImages, diff --git a/packages/core/src/schema.ts b/packages/core/src/schema.ts index af777fa81d..480a7a41b2 100644 --- a/packages/core/src/schema.ts +++ b/packages/core/src/schema.ts @@ -17,6 +17,30 @@ export function isJSONSchema(obj: any) { return false } +export function JSONSchemaToFunctionParameters(schema: JSONSchemaType): string { + if (!schema) return "" + else if (schema.type === "array") + return `args: (${JSONSchemaToFunctionParameters(schema.items)})[]` + else if (schema.type === "object") { + const required = schema.required || [] + return Object.entries(schema.properties) + .sort( + (l, r) => + (required.includes(l[0]) ? -1 : 1) - + (required.includes(r[0]) ? -1 : 1) + ) + .map( + ([name, prop]) => + `${name}${required.includes(name) ? "" : "?"}: ${JSONSchemaToFunctionParameters(prop)}` + ) + .join(", ") + } else if (schema.type === "string") return "string" + else if (schema.type === "boolean") return "boolean" + else if (schema.type === "number" || schema.type === "integer") + return "number" + else return "?" +} + /** * Converts a JSON Schema to a TypeScript type definition as a string * @param schema - The JSON Schema diff --git a/packages/core/src/systems.ts b/packages/core/src/systems.ts index 9591328812..f7f1cd252f 100644 --- a/packages/core/src/systems.ts +++ b/packages/core/src/systems.ts @@ -50,7 +50,7 @@ export function resolveSystems( systems.push("system.tools") // Resolve and add each tool's systems based on its definition in the project arrayify(script.tools).forEach((tool) => - systems.push(...resolveTools(prj, tool)) + systems.push(...resolveSystemFromTools(prj, tool)) ) } @@ -61,15 +61,31 @@ export function resolveSystems( // Helper function to resolve tools in the project and return their system IDs // Finds systems in the project associated with a specific tool -function resolveTools(prj: Project, tool: string): string[] { - // Create regular expression to match tool definition in jsSource - const toolsRx = new RegExp(`defTool\\s*\\(\\s*('|"|\`)${tool}`) - - // Filter project templates to find matching systems that define the tool +function resolveSystemFromTools(prj: Project, tool: string): string[] { const system = prj.templates.filter( - (t) => t.isSystem && toolsRx.test(t.jsSource) + (t) => t.isSystem && t.defTools?.find((to) => to.id === tool) ) - - // Return the IDs of matched systems return system.map(({ id }) => id) } + +export function resolveTools( + prj: Project, + systems: string[], + tools: string[] +): { id: string; description: string }[] { + const toolIds = uniq( + tools.concat( + ...systems + .map((s) => prj.templates.find((t) => t.id === s)?.defTools) + .filter((t) => !!t) + .flat() + .map((t) => t.id) + ) + ) + return toolIds + .map((id) => + prj.templates.map((t) => t.defTools.find((to) => to.id === id)) + ) + .flat() + .filter((t) => !!t) +} diff --git a/packages/core/src/template.ts b/packages/core/src/template.ts index 6a2122a675..c96a5ae591 100644 --- a/packages/core/src/template.ts +++ b/packages/core/src/template.ts @@ -12,6 +12,7 @@ import { JSON5TryParse } from "./json5" import { humanize } from "inflection" import { validateSchema } from "./schema" import { promptyParse, promptyToGenAIScript } from "./prompty" +import { kind } from "openai/_shims/index.mjs" /** * Extracts a template ID from the given filename by removing specific extensions @@ -329,14 +330,17 @@ export function parsePromptScriptMeta( return meta } -function parsePromptScriptTools( - jsSource: string -): { id: string; description: string }[] { - const tools: { id: string; description: string }[] = [] +function parsePromptScriptTools(jsSource: string) { + const tools: { id: string; description: string; kind: "tool" | "agent" }[] = + [] jsSource.replace( - /defTool\s*\(\s*"([^"]+?)"\s*,\s*"([^"]+?)"/g, - (m, id, description) => { - tools.push({ id, description }) + /def(?Tool|Agent)\s*\(\s*"(?[^"]+?)"\s*,\s*"(?[^"]+?)"/g, + (m, kind, id, description) => { + tools.push({ + id: kind === "Agent" ? "agent_" + id : id, + description, + kind: kind.toLocaleLowerCase(), + }) return "" } ) diff --git a/packages/core/src/testhost.ts b/packages/core/src/testhost.ts index 8ad223b334..2bf58359ae 100644 --- a/packages/core/src/testhost.ts +++ b/packages/core/src/testhost.ts @@ -32,6 +32,7 @@ import { isAbsolute, } from "node:path" import { LanguageModel } from "./chat" +import { Project } from "./ast" // Function to create a frozen object representing Node.js path methods // This object provides utility methods for path manipulations @@ -50,6 +51,7 @@ export function createNodePath(): Path { // Class representing a test host for runtime, implementing the RuntimeHost interface export class TestHost implements RuntimeHost { + project: Project // Path to the dotenv file (if used) dotEnvPath: string = undefined // State object to store user-specific data diff --git a/packages/core/src/types/prompt_template.d.ts b/packages/core/src/types/prompt_template.d.ts index bbb870997a..a993a3e45b 100644 --- a/packages/core/src/types/prompt_template.d.ts +++ b/packages/core/src/types/prompt_template.d.ts @@ -219,12 +219,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -390,7 +390,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1892,8 +1892,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2012,6 +2013,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2032,6 +2039,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions diff --git a/packages/core/src/types/prompt_type.d.ts b/packages/core/src/types/prompt_type.d.ts index f93410b154..9123564bcf 100644 --- a/packages/core/src/types/prompt_type.d.ts +++ b/packages/core/src/types/prompt_type.d.ts @@ -116,6 +116,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/genaisrc/blog/genaiscript.d.ts b/packages/sample/genaisrc/blog/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/genaisrc/blog/genaiscript.d.ts +++ b/packages/sample/genaisrc/blog/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/genaisrc/genaiscript.d.ts b/packages/sample/genaisrc/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/genaisrc/genaiscript.d.ts +++ b/packages/sample/genaisrc/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/genaisrc/github-agent.genai.mts b/packages/sample/genaisrc/github-agent.genai.mts index 0237beda88..84c3b22193 100644 --- a/packages/sample/genaisrc/github-agent.genai.mts +++ b/packages/sample/genaisrc/github-agent.genai.mts @@ -1,5 +1,5 @@ script({ - tools: ["agent_fs", "agent_git", "agent_github"], + tools: ["agent_fs", "agent_git", "agent_github", "agent_interpreter"], parameters: { workflow: { type: "string" }, // Workflow name failure_run_id: { type: "number" }, // ID of the failed run diff --git a/packages/sample/genaisrc/node/genaiscript.d.ts b/packages/sample/genaisrc/node/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/genaisrc/node/genaiscript.d.ts +++ b/packages/sample/genaisrc/node/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/genaisrc/python/genaiscript.d.ts b/packages/sample/genaisrc/python/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/genaisrc/python/genaiscript.d.ts +++ b/packages/sample/genaisrc/python/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/genaisrc/style/genaiscript.d.ts b/packages/sample/genaisrc/style/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/genaisrc/style/genaiscript.d.ts +++ b/packages/sample/genaisrc/style/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/src/aici/genaiscript.d.ts b/packages/sample/src/aici/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/src/aici/genaiscript.d.ts +++ b/packages/sample/src/aici/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/src/errors/genaiscript.d.ts b/packages/sample/src/errors/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/src/errors/genaiscript.d.ts +++ b/packages/sample/src/errors/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/src/genaiscript.d.ts b/packages/sample/src/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/src/genaiscript.d.ts +++ b/packages/sample/src/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/src/makecode/genaiscript.d.ts b/packages/sample/src/makecode/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/src/makecode/genaiscript.d.ts +++ b/packages/sample/src/makecode/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/src/tla/genaiscript.d.ts b/packages/sample/src/tla/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/src/tla/genaiscript.d.ts +++ b/packages/sample/src/tla/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/sample/src/vision/genaiscript.d.ts b/packages/sample/src/vision/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/sample/src/vision/genaiscript.d.ts +++ b/packages/sample/src/vision/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/packages/vscode/genaisrc/genaiscript.d.ts b/packages/vscode/genaisrc/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/packages/vscode/genaisrc/genaiscript.d.ts +++ b/packages/vscode/genaisrc/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn diff --git a/slides/genaisrc/genaiscript.d.ts b/slides/genaisrc/genaiscript.d.ts index 4e1671153e..964920c58a 100644 --- a/slides/genaisrc/genaiscript.d.ts +++ b/slides/genaisrc/genaiscript.d.ts @@ -121,7 +121,7 @@ type SystemToolId = OptionsOrString< | "git_branch_list" | "git_diff" | "git_last_tag" - | "git_log" + | "git_list_commits" | "git_status" | "github_actions_job_logs_diff" | "github_actions_job_logs_get" @@ -293,12 +293,12 @@ interface PromptSystemOptions { /** * List of system script ids used by the prompt. */ - system?: SystemPromptId | SystemPromptId[] + system?: ElementOrArray /** * List of tools used by the prompt. */ - tools?: SystemToolId | SystemToolId[] + tools?: ElementOrArray } interface ScriptRuntimeOptions { @@ -464,7 +464,7 @@ interface PromptScript /** * List of tools defined in the script */ - defTools?: { id: string, description: string }[] + defTools?: { id: string, description: string, kind: "tool" | "agent" }[] } /** @@ -1966,8 +1966,9 @@ interface DefSchemaOptions { format?: "typescript" | "json" | "yaml" } +type ChatFunctionArgs = { context: ToolCallContext } & Record type ChatFunctionHandler = ( - args: { context: ToolCallContext } & Record + args: ChatFunctionArgs ) => Awaitable interface WriteTextOptions extends ContextExpansionOptions { @@ -2086,6 +2087,12 @@ interface DefToolOptions { maxTokens?: number } +interface DefAgentOptions extends Omit { + +} + +type ChatAgentHandler = (ctx: ChatGenerationContext, args: ChatFunctionArgs) => Awaitable + interface ChatGenerationContext extends ChatTurnGenerationContext { defSchema( name: string, @@ -2106,6 +2113,9 @@ interface ChatGenerationContext extends ChatTurnGenerationContext { parameters: PromptParametersSchema | JSONSchema, fn: ChatFunctionHandler ): void + defAgent(name: string, description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions): void defChatParticipant( participant: ChatParticipantHandler, options?: ChatParticipantOptions @@ -3027,6 +3037,20 @@ declare function defTool( options?: DefToolOptions ): void +/** + * Declares a LLM agent tool that can be called from the prompt. + * @param name name of the agent, do not prefix with agent + * @param description description of the agent, used by the model to choose when and how to call the agent + * @param fn prompt generation context + * @param options additional options for the agent LLM + */ +declare function defAgent( + name: string, + description: string, + fn: string | ChatAgentHandler, + options?: DefAgentOptions +): void + /** * Registers a callback to be called when a file is being merged * @param fn