diff --git a/.github/workflows/genai-blog-post.yml b/.github/workflows/genai-blog-post.yml index 209b555120..fa0568a023 100644 --- a/.github/workflows/genai-blog-post.yml +++ b/.github/workflows/genai-blog-post.yml @@ -4,6 +4,12 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +env: + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/genai-commander.yml b/.github/workflows/genai-commander.yml index db61091ab9..d0ad58b1ac 100644 --- a/.github/workflows/genai-commander.yml +++ b/.github/workflows/genai-commander.yml @@ -3,11 +3,11 @@ on: issue_comment: types: [created] env: - # Configure default GenAIScript models - # using Ollama's models - GENAISCRIPT_DEFAULT_MODEL: ollama:qwen2.5-coder:7b - GENAISCRIPT_DEFAULT_SMALL_MODEL: ollama:qwen2.5-coder:1.5b - GENAISCRIPT_DEFAULT_VISION_MODEL: ollama:llama3.2-vision:11b + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: pr_commented: # must be PR and have a comment starting with /genai diff --git a/.github/workflows/genai-investigator.yml b/.github/workflows/genai-investigator.yml index 3d55e587b3..0227665bef 100644 --- a/.github/workflows/genai-investigator.yml +++ b/.github/workflows/genai-investigator.yml @@ -12,11 +12,11 @@ permissions: actions: read pull-requests: write env: - # Configure default GenAIScript models - # using Ollama's models - GENAISCRIPT_DEFAULT_MODEL: ollama:qwen2.5-coder:7b - GENAISCRIPT_DEFAULT_SMALL_MODEL: ollama:qwen2.5-coder:1.5b - GENAISCRIPT_DEFAULT_VISION_MODEL: ollama:llama3.2-vision:11b + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: investigate: # Only run this job if the workflow run concluded with a failure diff --git a/.github/workflows/genai-issue-review.yml b/.github/workflows/genai-issue-review.yml index a506c8db22..b321c7d3ff 100644 --- a/.github/workflows/genai-issue-review.yml +++ b/.github/workflows/genai-issue-review.yml @@ -6,11 +6,11 @@ concurrency: group: issues-${{ github.event.issue.number }} cancel-in-progress: true env: - # Configure default GenAIScript models - # using Ollama's models - GENAISCRIPT_DEFAULT_MODEL: ollama:qwen2.5-coder:7b - GENAISCRIPT_DEFAULT_SMALL_MODEL: ollama:qwen2.5-coder:1.5b - GENAISCRIPT_DEFAULT_VISION_MODEL: ollama:llama3.2-vision:11b + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/genai-pr-commit-review.yml b/.github/workflows/genai-pr-commit-review.yml index 8299bd0b9c..91ad511936 100644 --- a/.github/workflows/genai-pr-commit-review.yml +++ b/.github/workflows/genai-pr-commit-review.yml @@ -8,11 +8,11 @@ on: - "packages/cli/**/*" - "packages/samples/**/*" env: - # Configure default GenAIScript models - # using Ollama's models - GENAISCRIPT_DEFAULT_MODEL: ollama:qwen2.5-coder:7b - GENAISCRIPT_DEFAULT_SMALL_MODEL: ollama:qwen2.5-coder:1.5b - GENAISCRIPT_DEFAULT_VISION_MODEL: ollama:llama3.2-vision:11b + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/genai-pr-docs-commit-review.yml b/.github/workflows/genai-pr-docs-commit-review.yml index e4b56b6d9c..47d5d6ed47 100644 --- a/.github/workflows/genai-pr-docs-commit-review.yml +++ b/.github/workflows/genai-pr-docs-commit-review.yml @@ -5,11 +5,11 @@ on: - docs/**/*.md - docs/**/*.mdx env: - # Configure default GenAIScript models - # using Ollama's models - GENAISCRIPT_DEFAULT_MODEL: ollama:qwen2.5-coder:7b - GENAISCRIPT_DEFAULT_SMALL_MODEL: ollama:qwen2.5-coder:1.5b - GENAISCRIPT_DEFAULT_VISION_MODEL: ollama:llama3.2-vision:11b + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/genai-pr-review.yml b/.github/workflows/genai-pr-review.yml index eaf7a1fd5f..c3859ed077 100644 --- a/.github/workflows/genai-pr-review.yml +++ b/.github/workflows/genai-pr-review.yml @@ -1,5 +1,6 @@ name: genai pull request review on: + workflow_dispatch: pull_request: types: [opened, ready_for_review, reopened] paths: @@ -12,11 +13,11 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: - # Configure default GenAIScript models - # using Ollama's models - GENAISCRIPT_DEFAULT_MODEL: ollama:qwen2.5-coder:7b - GENAISCRIPT_DEFAULT_SMALL_MODEL: ollama:qwen2.5-coder:1.5b - GENAISCRIPT_DEFAULT_VISION_MODEL: ollama:llama3.2-vision:11b + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: build: runs-on: ubuntu-latest @@ -40,11 +41,11 @@ jobs: run: git fetch origin && git pull origin main:main - name: genaiscript pr-describe continue-on-error: true - run: node packages/cli/built/genaiscript.cjs run pr-describe --out ./temp/genai/pr-describe -prd --out-trace $GITHUB_STEP_SUMMARY + run: node packages/cli/built/genaiscript.cjs run pr-describe --out ./temp/genai/pr-describe -prd -m reasoning --out-trace $GITHUB_STEP_SUMMARY env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: genaiscript pr-review - run: node packages/cli/built/genaiscript.cjs run pr-review --out ./temp/genai/pr-review -prc --out-trace $GITHUB_STEP_SUMMARY + run: node packages/cli/built/genaiscript.cjs run pr-review --out ./temp/genai/pr-review -prc -m reasoning --out-trace $GITHUB_STEP_SUMMARY continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ollama.yml b/.github/workflows/ollama.yml index 62b925818f..6c85fd50d7 100644 --- a/.github/workflows/ollama.yml +++ b/.github/workflows/ollama.yml @@ -14,6 +14,12 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }}-ollama cancel-in-progress: true +env: + GENAISCRIPT_DEFAULT_REASONING_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_MODEL }} + GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_REASONING_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_MODEL }} + GENAISCRIPT_DEFAULT_SMALL_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_SMALL_MODEL }} + GENAISCRIPT_DEFAULT_VISION_MODEL: ${{ vars.GENAISCRIPT_DEFAULT_VISION_MODEL }} jobs: tests: runs-on: ubuntu-latest diff --git a/README.md b/README.md index f6f7ba4cb7..d25bf81c35 100644 --- a/README.md +++ b/README.md @@ -208,7 +208,7 @@ const { files } = await retrieval.vectorSearch("cats", "**/*.md") ### 🐙 GitHub Models and GitHub Copilot -Run models through [GitHub Models](https://microsoft.github.io/genaiscript/getting-started/configuration#github) or [GitHub Copilot](https://microsoft.github.io/genaiscript/getting-started/configuration/#github-copilot). +Run models through [GitHub Models](https://microsoft.github.io/genaiscript/getting-started/configuration#github) or [GitHub Copilot](https://microsoft.github.io/genaiscript/getting-started/configuration/#github_copilot_chat). ```js script({ ..., model: "github:gpt-4o" }) diff --git a/docs/src/content/docs/getting-started/configuration.mdx b/docs/src/content/docs/getting-started/configuration.mdx index c7f2307a92..34a50b8d3b 100644 --- a/docs/src/content/docs/getting-started/configuration.mdx +++ b/docs/src/content/docs/getting-started/configuration.mdx @@ -833,7 +833,7 @@ script({ model: "google:gemini-1.5-pro-latest" }) -## GitHub Copilot Chat Models +## GitHub Copilot Chat Models If you have access to **GitHub Copilot Chat in Visual Studio Code**, GenAIScript will be able to leverage those [language models](https://code.visualstudio.com/api/extension-guides/language-model) as well. @@ -1256,7 +1256,7 @@ script({ -## LMStudio +## LM Studio The `lmstudio` provider connects to the [LMStudio](https://lmstudio.ai/) headless server. and allows to run local LLMs. @@ -1319,7 +1319,7 @@ script({ -### LMStudio and Hugging Face Models +### LM Studio and Hugging Face Models Follow [this guide](https://huggingface.co/blog/yagilb/lms-hf) to load Hugging Face models into LMStudio. @@ -1461,6 +1461,16 @@ OPENROUTER_SITE_URL=... # populates HTTP-Referer header OPENROUTER_SITE_NAME=... # populate X-Title header ``` +## LiteLLM + +The [LiteLLM](https://docs.litellm.ai/) proxy gateway provides a OpenAI compatible API for running models locally. +Configure the `LITELLM_...` keys to set the key and optionally the base url. + +```txt title=".env" +LITELLM_API_KEY="..." +#LITELLM_API_BASE="..." +``` + ## Hugging Face Transformer.js This `transformers` provider runs models on device using [Hugging Face Transformers.js](https://huggingface.co/docs/transformers.js/index). diff --git a/docs/src/content/docs/index.mdx b/docs/src/content/docs/index.mdx index fe3026c5e5..e10fd51fdb 100644 --- a/docs/src/content/docs/index.mdx +++ b/docs/src/content/docs/index.mdx @@ -373,7 +373,7 @@ const res = await safety.detectPromptInjection(env.vars.input) Run models through GitHub using [GitHub Models](/genaiscript/getting-started/configuration#github) -or [GitHub Copilot](/genaiscript/getting-started/configuration/#github-copilot). +or [GitHub Copilot](/genaiscript/getting-started/configuration/#github_copilot_chat). ```js wrap script({ ..., model: "github:gpt-4o" }) diff --git a/docs/src/content/docs/reference/scripts/system.mdx b/docs/src/content/docs/reference/scripts/system.mdx index 8eb55068d8..b0651fa063 100644 --- a/docs/src/content/docs/reference/scripts/system.mdx +++ b/docs/src/content/docs/reference/scripts/system.mdx @@ -722,6 +722,24 @@ DIFF ./file4.ts: ````` +### `system.english` + +Use english output + + + + + +`````js wrap title="system.english" +system({ + title: "Use english output", +}) +$`## English output +Use English in the output of the system. Use English in the reasoning output as well.` + +````` + + ### `system.explanations` Explain your answers diff --git a/packages/cli/README.md b/packages/cli/README.md index c249ab1d4e..6652ffe8f4 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -205,7 +205,7 @@ const { files } = await retrieval.vectorSearch("cats", "**/*.md") ### 🐙 GitHub Models and GitHub Copilot -Run models through [GitHub Models](https://microsoft.github.io/genaiscript/getting-started/configuration#github) or [GitHub Copilot](https://microsoft.github.io/genaiscript/getting-started/configuration/#github-copilot-in-visual-studio-code). +Run models through [GitHub Models](https://microsoft.github.io/genaiscript/getting-started/configuration#github) or [GitHub Copilot](https://microsoft.github.io/genaiscript/getting-started/configuration/#github_copilot_chat). ```js script({ ..., model: "github:gpt-4o" }) diff --git a/packages/cli/src/run.ts b/packages/cli/src/run.ts index a6472a4f89..45c2dd51ab 100644 --- a/packages/cli/src/run.ts +++ b/packages/cli/src/run.ts @@ -195,7 +195,7 @@ export async function runScriptInternal( const removeOut = options.removeOut const cancellationToken = options.cancellationToken const jsSource = options.jsSource - const fallbackTools = !!options.fallbackTools + const fallbackTools = options.fallbackTools const logprobs = options.logprobs const topLogprobs = normalizeInt(options.topLogprobs) const fenceFormat = options.fenceFormat diff --git a/packages/cli/src/server.ts b/packages/cli/src/server.ts index 5ff8d5d9e8..b5a7a4e487 100644 --- a/packages/cli/src/server.ts +++ b/packages/cli/src/server.ts @@ -189,7 +189,9 @@ export async function startServer(options: { providers: await resolveLanguageModelConfigurations(undefined, { token: false, error: true, + models: true, }), + modelAliases: runtimeHost.modelAliases, remote: remote ? { url: remote, diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 4f0072a74e..96fb91e4c0 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -18,6 +18,7 @@ import { deleteEmptyValues } from "./cleaners" import { errorMessage } from "./error" import schema from "../../../docs/public/schemas/config.json" import defaultConfig from "./config.json" +import { CancellationOptions } from "./cancellation" export async function resolveGlobalConfiguration( dotEnvPath?: string @@ -100,7 +101,11 @@ export async function resolveGlobalConfiguration( */ export async function resolveLanguageModelConfigurations( provider: string, - options?: { token?: boolean; error?: boolean; models?: boolean } + options?: { + token?: boolean + error?: boolean + models?: boolean + } & CancellationOptions ): Promise { const { token, error, models } = options || {} const res: ResolvedLanguageModelConfiguration[] = [] @@ -118,19 +123,19 @@ export async function resolveLanguageModelConfigurations( if (conn) { // Mask the token if the option is set let listError = "" - if (!token && conn.token) conn.token = "***" if (models) { const lm = await resolveLanguageModel(modelProvider.id) if (lm.listModels) { - const models = await lm.listModels(conn, {}) + const models = await lm.listModels(conn, options) if (models.ok) conn.models = models.models else listError = - errorMessage(listError) || - "failed to llist models" + errorMessage(models.error) || + "failed to list models" } } - if (!listError || error) + if (!token && conn.token) conn.token = "***" + if (!listError || error || provider) res.push( deleteEmptyValues({ provider: conn.provider, @@ -143,7 +148,7 @@ export async function resolveLanguageModelConfigurations( ) } } catch (e) { - if (error) + if (error || provider) // Capture and store any errors encountered res.push({ provider: modelProvider.id, diff --git a/packages/core/src/expander.ts b/packages/core/src/expander.ts index da428c9af2..57833aefe1 100644 --- a/packages/core/src/expander.ts +++ b/packages/core/src/expander.ts @@ -21,7 +21,7 @@ import { addToolDefinitionsMessage, appendSystemMessage } from "./chat" import { importPrompt } from "./importprompt" import { parseModelIdentifier } from "./models" import { runtimeHost } from "./host" -import { resolveSystems } from "./systems" +import { addFallbackToolSystems, resolveSystems } from "./systems" import { GenerationOptions } from "./generation" import { AICIRequest, @@ -356,7 +356,7 @@ export async function expandTemplate( trace.endDetails() } - if (systems.includes("system.tool_calls")) { + if (addFallbackToolSystems(systems, tools, template, options)) { addToolDefinitionsMessage(messages, tools) options.fallbackTools = true } diff --git a/packages/core/src/genaisrc/system.english.genai.js b/packages/core/src/genaisrc/system.english.genai.js new file mode 100644 index 0000000000..35799d8f80 --- /dev/null +++ b/packages/core/src/genaisrc/system.english.genai.js @@ -0,0 +1,5 @@ +system({ + title: "Use english output", +}) +$`## English output +Use English in the output of the system. Use English in the reasoning output as well.` diff --git a/packages/core/src/llms.json b/packages/core/src/llms.json index 49482a0a0a..133b0c7cbb 100644 --- a/packages/core/src/llms.json +++ b/packages/core/src/llms.json @@ -7,6 +7,7 @@ "bearerToken": true, "transcribe": true, "speech": true, + "listModels": true, "aliases": { "large": "gpt-4o", "small": "gpt-4o-mini", diff --git a/packages/core/src/openai.ts b/packages/core/src/openai.ts index eea2b74243..22af0031cf 100644 --- a/packages/core/src/openai.ts +++ b/packages/core/src/openai.ts @@ -456,7 +456,7 @@ export const OpenAIListModels: ListModelsFunction = async (cfg, options) => { return { ok: false, status: res.status, - error: serializeError(res.statusText), + error: serializeError(await res.json()), } const { data } = (await res.json()) as { object: "list" diff --git a/packages/core/src/runpromptcontext.ts b/packages/core/src/runpromptcontext.ts index cc2e7199c9..dfe2b31beb 100644 --- a/packages/core/src/runpromptcontext.ts +++ b/packages/core/src/runpromptcontext.ts @@ -66,7 +66,7 @@ import { SPEECH_MODEL_ID, } from "./constants" import { renderAICI } from "./aici" -import { resolveSystems, resolveTools } from "./systems" +import { addFallbackToolSystems, resolveSystems, resolveTools } from "./systems" import { callExpander } from "./expander" import { errorMessage, @@ -992,19 +992,24 @@ export function createChatGenerationContext( } finally { runTrace.endDetails() } - if (systemScripts.includes("system.tool_calls")) { + + if ( + addFallbackToolSystems( + systemScripts, + tools, + runOptions, + genOptions + ) + ) { addToolDefinitionsMessage(messages, tools) genOptions.fallbackTools = true } - finalizeMessages( - messages, - { - ...(runOptions || {}), - fileOutputs, - trace, - } - ) + finalizeMessages(messages, { + ...(runOptions || {}), + fileOutputs, + trace, + }) const { completer } = await resolveLanguageModel( configuration.provider ) diff --git a/packages/core/src/server/wsclient.ts b/packages/core/src/server/wsclient.ts index 20bb128458..a5a9475885 100644 --- a/packages/core/src/server/wsclient.ts +++ b/packages/core/src/server/wsclient.ts @@ -21,6 +21,7 @@ import type { RequestMessage, ResponseStatus, ServerEnv, + ServerEnvResponse, ServerResponse, ServerVersion, } from "./messages" @@ -202,9 +203,9 @@ export class WebSocketClient extends EventTarget { return res.response as ServerResponse } - async infoEnv(): Promise { + async infoEnv(): Promise { const res = await this.queue({ type: "server.env" }) - return res.response + return res.response as ServerEnvResponse } async listScripts(): Promise { diff --git a/packages/core/src/systems.ts b/packages/core/src/systems.ts index b09e138e93..9e9e70c368 100644 --- a/packages/core/src/systems.ts +++ b/packages/core/src/systems.ts @@ -114,17 +114,27 @@ export function resolveSystems( .filter((s) => !!s) .filter((s) => !excludedSystem.includes(s)) - const fallbackTools = - isToolsSupported(options?.model) === false || options?.fallbackTools - if (fallbackTools && (tools.length || resolvedTools?.length)) - systems.push("system.tool_calls") - // Return a unique list of non-empty systems // Filters out duplicates and empty entries using unique utility const res = uniq(systems) return res } +export function addFallbackToolSystems( + systems: string[], + tools: ToolCallback[], + options?: ModelOptions, + genOptions?: GenerationOptions +) { + if (!tools?.length || systems.includes("system.tool_calls")) return false + + const fallbackTools = + isToolsSupported(options?.model || genOptions?.model) === false || + genOptions?.fallbackTools + if (fallbackTools) systems.push("system.tool_calls") + return fallbackTools +} + /** * Helper function to resolve tools in the project and return their system IDs. * Finds systems in the project associated with a specific tool. diff --git a/packages/core/src/tools.ts b/packages/core/src/tools.ts index 8974b2b415..3d7ad970ff 100644 --- a/packages/core/src/tools.ts +++ b/packages/core/src/tools.ts @@ -10,12 +10,12 @@ import { parseModelIdentifier } from "./models" export function isToolsSupported(modelId: string): boolean | undefined { if (!modelId) return undefined - const { provider, model } = parseModelIdentifier(modelId) + const { provider, family } = parseModelIdentifier(modelId) const info = MODEL_PROVIDERS.find(({ id }) => provider === id) if (info?.tools === false) return false - if (/^o1-(mini|preview)/.test(model)) return false + if (/^o1-(mini|preview)/.test(family)) return false const oai = { "o1-preview": false, @@ -39,6 +39,7 @@ export function isToolsSupported(modelId: string): boolean | undefined { ["llama2"]: false, ["codellama"]: false, ["phi"]: false, + ["deepseek-r1"]: false, }, [MODEL_PROVIDER_OPENAI]: oai, [MODEL_PROVIDER_AZURE_OPENAI]: oai, @@ -48,5 +49,6 @@ export function isToolsSupported(modelId: string): boolean | undefined { }, } - return data[provider]?.[model] + const res = data[provider]?.[family] + return res } diff --git a/packages/sample/genaisrc/pr-describe.genai.mjs b/packages/sample/genaisrc/pr-describe.genai.mjs index 5fffb1bd42..8b12f337fe 100644 --- a/packages/sample/genaisrc/pr-describe.genai.mjs +++ b/packages/sample/genaisrc/pr-describe.genai.mjs @@ -7,6 +7,7 @@ script({ "system.assistant", "system.fs_find_files", "system.fs_read_file", + "system.english" ], parameters: { defaultBranch: { @@ -38,10 +39,11 @@ def("GIT_DIFF", changes, { }) $`You are an expert software developer and architect. +You are an expert at writing English technical documentation. ## Task -- Describe a high level summary of the changes in GIT_DIFF in a way that a software engineer will understand. +- Describe a high level summary of the changes in GIT_DIFF for a pull request in a way that a software engineer will understand. ## Instructions diff --git a/packages/sample/genaisrc/samples/prd.genai.mts b/packages/sample/genaisrc/samples/prd.genai.mts index 664d4987a9..22053a49f1 100644 --- a/packages/sample/genaisrc/samples/prd.genai.mts +++ b/packages/sample/genaisrc/samples/prd.genai.mts @@ -22,10 +22,17 @@ const changes = await git.diff({ }) console.log(changes) +def("GIT_DIFF", changes, { + maxTokens: 30000, + detectPromptInjection: "available", +}) + // task $`## Task -Describe a high level summary of the changes in GIT_DIFF in a way that a software engineer will understand. +You are an expert code reviewer with great English technical writing skills. + +Your task is to generate a high level summary of the changes in for a pull request in a way that a software engineer will understand. This description will be used as the pull request description. ## Instructions @@ -35,7 +42,6 @@ This description will be used as the pull request description. - use bullet points to list the changes - use emojis to make the description more engaging - focus on the most important changes +- do not try to fix issues, only describe the changes - ignore comments about imports (like added, remove, changed, etc.) ` - -def("GIT_DIFF", changes, { maxTokens: 30000, detectPromptInjection: "available" }) diff --git a/packages/vscode/package.json b/packages/vscode/package.json index 9d0dec3e07..743afa3e1d 100644 --- a/packages/vscode/package.json +++ b/packages/vscode/package.json @@ -256,10 +256,6 @@ { "command": "genaiscript.request.status", "when": "false" - }, - { - "command": "genaiscript.samples.download", - "when": "false" } ], "view/title": [ @@ -415,21 +411,6 @@ "command": "genaiscript.request.status", "title": "Show information message about OpenAI request status", "category": "GenAIScript" - }, - { - "command": "genaiscript.openIssueReporter", - "title": "Report Issue...", - "category": "GenAIScript" - }, - { - "command": "genaiscript.info.env", - "title": "Configuration information...", - "category": "GenAIScript" - }, - { - "command": "genaiscript.samples.download", - "title": "Download sample...", - "category": "GenAIScript" } ] }, diff --git a/packages/vscode/src/connectioninfotree.ts b/packages/vscode/src/connectioninfotree.ts index b7456570b0..4a46574ae6 100644 --- a/packages/vscode/src/connectioninfotree.ts +++ b/packages/vscode/src/connectioninfotree.ts @@ -1,57 +1,85 @@ import * as vscode from "vscode" import { ExtensionState } from "./state" -import { MODEL_PROVIDERS } from "../../core/src/constants" import { YAMLStringify } from "../../core/src/yaml" -import { OpenAIAPIType } from "../../core/src/server/messages" +import { + LanguageModelInfo, + ResolvedLanguageModelConfiguration, + ServerEnvResponse, +} from "../../core/src/server/messages" +import { deleteUndefinedValues } from "../../core/src/cleaners" -class ConnectionInfoTreeData { - provider: string - apiType?: OpenAIAPIType +interface ConnectionInfoTreeData { + provider?: ResolvedLanguageModelConfiguration + model?: LanguageModelInfo } class ConnectionInfoTreeDataProvider implements vscode.TreeDataProvider { - constructor(readonly state: ExtensionState) { - const { context } = state - const { subscriptions } = context - subscriptions.push( - vscode.workspace.onDidChangeConfiguration(() => { - this.refresh() - }) - ) + private _info: ServerEnvResponse | undefined + + constructor(readonly state: ExtensionState) {} + + private async fetchConnections() { + const client = await this.state.host.server.client() + this._info = await client.infoEnv() + this.refresh() } async getTreeItem( element: ConnectionInfoTreeData ): Promise { - const item = new vscode.TreeItem(element.provider) - const client = await this.state.host.server.client() - const res = await client.getLanguageModelConfiguration( - element.provider + ":*", - { token: false } - ) - if (res) { - item.iconPath = "check" - item.description = res.base || "" - item.tooltip = YAMLStringify(res) + if (element.model) { + const { id, details, url } = element.model + const item = new vscode.TreeItem(id) + const tt: vscode.MarkdownString = (item.tooltip = + new vscode.MarkdownString(`\`${element.provider.provider}:${id}\` + +${details} + +${url ? `[${url}](${url})` : ""} +`)) + tt.isTrusted = true + return item + } else if (element.provider) { + const { provider, base, models, error, ...rest } = element.provider + const item = new vscode.TreeItem(provider) + item.collapsibleState = models?.length + ? vscode.TreeItemCollapsibleState.Collapsed + : vscode.TreeItemCollapsibleState.None + item.description = base || "" + const docsUrl = + "https://microsoft.github.io/genaiscript/getting-started/configuration/#" + + provider + if (error) item.iconPath = new vscode.ThemeIcon("error") + item.tooltip = YAMLStringify( + deleteUndefinedValues({ error, ...rest }) + ) item.command = { - command: "vscode.open", - arguments: [ - this.state.host.toUri( - "https://microsoft.github.io/genaiscript/getting-started/configuration/#" + - element.provider - ), - ], + command: "simpleBrowser.show", + arguments: [this.state.host.toUri(docsUrl)], } + return item } - return item + return undefined } - getChildren( + async getChildren( element?: ConnectionInfoTreeData - ): vscode.ProviderResult { - if (!element) return MODEL_PROVIDERS.map(({ id }) => ({ provider: id })) + ): Promise { + if (!this._info) await this.fetchConnections() + + if (!element) { + const providers = this._info?.providers || [] + return providers.map((provider) => ({ provider })) + } + if (element.provider) + return ( + element.provider.models?.map((model) => ({ + provider: element.provider, + model, + })) || [] + ) return undefined } diff --git a/packages/vscode/src/extension.ts b/packages/vscode/src/extension.ts index 9b3ff658c6..91fa099fe8 100644 --- a/packages/vscode/src/extension.ts +++ b/packages/vscode/src/extension.ts @@ -21,7 +21,6 @@ import type MarkdownIt from "markdown-it" import MarkdownItGitHubAlerts from "markdown-it-github-alerts" import { activateConnectionInfoTree } from "./connectioninfotree" import { activeTaskProvider } from "./taskprovider" -import { activateSamplesCommands } from "./samplescommands" import { activateChatParticipant } from "./chatparticipant" import { activeWebview } from "./webview" @@ -29,7 +28,6 @@ export async function activate(context: ExtensionContext) { const state = new ExtensionState(context) activatePromptCommands(state) activateFragmentCommands(state) - activateSamplesCommands(state) activateMarkdownTextDocumentContentProvider(state) activatePromptTreeDataProvider(state) activateConnectionInfoTree(state) @@ -62,10 +60,6 @@ export async function activate(context: ExtensionContext) { }) if (res) vscode.commands.executeCommand(res.cmd) }), - registerCommand("genaiscript.info.env", async () => { - const client = await state.host.server.client() - await client.infoEnv() - }), registerCommand( "genaiscript.openIssueReporter", async (body: string[]) => { diff --git a/packages/vscode/src/samplescommands.ts b/packages/vscode/src/samplescommands.ts deleted file mode 100644 index f15a51d862..0000000000 --- a/packages/vscode/src/samplescommands.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as vscode from "vscode" -import { ExtensionState } from "./state" -import { registerCommand } from "./commands" -import { Utils } from "vscode-uri" -import { GENAI_SRC } from "../../core/src/constants" -import { parsePromptScriptMeta } from "../../core/src/template" -import { writeFile } from "./fs" - -export function activateSamplesCommands(state: ExtensionState) { - const { context, host } = state - - registerCommand("genaiscript.samples.download", async (name: string) => { - const dir = Utils.joinPath(context.extensionUri, GENAI_SRC) - const files = await vscode.workspace.fs.readDirectory( - Utils.joinPath(context.extensionUri, GENAI_SRC) - ) - const utf8 = host.createUTF8Decoder() - const samples = ( - await Promise.all( - files - .map((f) => f[0]) - .filter((f) => f.endsWith(".genai.mts")) - .map(async (filename) => ({ - filename, - jsSource: utf8.decode( - await vscode.workspace.fs.readFile( - Utils.joinPath(dir, filename) - ) - ), - })) - ) - ).map((s) => ({ ...s, meta: parsePromptScriptMeta(s.jsSource) })) - - const res = - samples.find((s) => s.filename === name) || - (await vscode.window.showQuickPick< - vscode.QuickPickItem & { filename: string; jsSource: string } - >( - samples.map((s) => ({ - label: s.meta.title, - detail: s.meta.description, - ...s, - })), - { title: "Pick a sample to download" } - )) - if (res === undefined) return - - const { jsSource, filename } = res - await writeFile(host.toUri(GENAI_SRC), filename, jsSource, { - open: true, - }) - await state.parseWorkspace() - }) -}