diff --git a/docs/genaisrc/image-alt-text.genai.js b/docs/genaisrc/image-alt-text.genai.mjs
similarity index 94%
rename from docs/genaisrc/image-alt-text.genai.js
rename to docs/genaisrc/image-alt-text.genai.mjs
index 9a06ecfa13..b10dadd16a 100644
--- a/docs/genaisrc/image-alt-text.genai.js
+++ b/docs/genaisrc/image-alt-text.genai.mjs
@@ -1,7 +1,7 @@
script({
title: "Image Alt Text generator",
description: "Generate alt text for images",
- model: "openai:gpt-4o",
+ model: "large",
group: "docs",
maxTokens: 4000,
temperature: 0,
diff --git a/docs/src/assets/chat-participant.png b/docs/src/assets/chat-participant.png
new file mode 100644
index 0000000000..1524e242db
Binary files /dev/null and b/docs/src/assets/chat-participant.png differ
diff --git a/docs/src/assets/chat-participant.png.txt b/docs/src/assets/chat-participant.png.txt
new file mode 100644
index 0000000000..374bc7423f
--- /dev/null
+++ b/docs/src/assets/chat-participant.png.txt
@@ -0,0 +1 @@
+A screenshot of the chat participant window.
\ No newline at end of file
diff --git a/docs/src/content/docs/reference/scripts/system.mdx b/docs/src/content/docs/reference/scripts/system.mdx
index f61ff569cb..b91538a697 100644
--- a/docs/src/content/docs/reference/scripts/system.mdx
+++ b/docs/src/content/docs/reference/scripts/system.mdx
@@ -78,84 +78,6 @@ script({ ...,
GenAIScript comes with a number of system prompt that support features like creating files, extracting diffs or
generating annotations. If unspecified, GenAIScript looks for specific keywords to activate the various system prompts.
-### `copilot_chat_participant`
-
-
-
-
-
-
-
-`````js wrap title="copilot_chat_participant"
-script({
- system: [
- // List of system components and tools available for the script
- "system",
- "system.tools",
- "system.files",
- "system.diagrams",
- "system.annotations",
- "system.git_info",
- "system.github_info",
- "system.safety_harmful_content",
- ],
- tools: ["agent"], // Tools that the script can use
- group: "infrastructure", // Group categorization for the script
- parameters: {
- question: {
- type: "string", // Type of the parameter
- description: "the user question", // Description of the parameter
- },
- "copilot.editor": {
- type: "string",
- description: "the content of the opened editor",
- default: "",
- },
- "copilot.selection": {
- type: "string",
- description: "the content of the opened editor",
- default: "",
- },
- },
- flexTokens: 20000, // Flexible token limit for the script
-})
-
-// Extract the 'question' parameter from the environment variables
-const { question } = env.vars
-const editor = env.vars["copilot.editor"]
-const selection = env.vars["copilot.selection"]
-
-$`## task
-
-- make a plan to answer the QUESTION step by step using the information in the Context section
-- answer the QUESTION
-
-## output
-
-- The final output will be inserted into the Visual Studio Code Copilot Chat window.
-- do NOT include the plan in the output
-
-## guidance:
-- use the agent tools to help you
-- do NOT be lazy, always finish the tasks
-- do NOT skip any steps
-`
-
-// Define a variable QUESTION with the value of 'question'
-def("QUESTION", question, { lineNumbers: false })
-
-$`## Context`
-
-// Define a variable FILE with the file data from the environment variables
-// The { ignoreEmpty: true, flex: 1 } options specify to ignore empty files and to use flexible token allocation
-def("FILE", env.files, { lineNumbers: false, ignoreEmpty: true, flex: 1 })
-
-if (editor) writeText(editor, { flex: 4 })
-if (selection) writeText(selection, { flex: 5 })
-
-`````
-
-
### `system`
Base system prompt
diff --git a/docs/src/content/docs/reference/vscode/github-copilot-chat.mdx b/docs/src/content/docs/reference/vscode/github-copilot-chat.mdx
new file mode 100644
index 0000000000..613fa64009
--- /dev/null
+++ b/docs/src/content/docs/reference/vscode/github-copilot-chat.mdx
@@ -0,0 +1,53 @@
+---
+title: GitHub Copilot Chat
+sidebar:
+ order: 3
+---
+
+import { Image } from "astro:assets"
+import { Code } from "@astrojs/starlight/components"
+import scriptSource from "../../../../../../packages/vscode/genaisrc/copilotchat.genai.mjs?raw"
+import src from "../../../../assets/chat-participant.png"
+import alt from "../../../../assets/chat-participant.png.txt?raw"
+
+The `@genaiscript` [chat participant](https://code.visualstudio.com/api/extension-guides/chat#parts-of-the-chat-user-experience) lets your run scripts without the context
+of a [GitHub Copilot Chat](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot-chat) conversation.
+This is useful for leverage existing scripts in an interactive chat session.
+
+
+
+## Choosing which script to run
+
+The `/run` command expects a script id as the first argument (e.g., `/run poem`). The rest of the query is
+passed to the script as the `env.vars.question` variable.
+
+```sh
+@genaiscript /run summarize
+```
+
+If you omit the `/run` command, GenAIScript will look for a script named `copilotchat`. If it finds one, it will run it.
+Otherwise, it will propose you to create a new script.
+
+```sh
+@genaiscript add comments to the current editor
+```
+
+## Context
+
+The context selected by the user in Copilot Chat is converted to variables and passed to the script:
+
+- the prompt content is passed in `env.vars.question`. The script id is removed in the case of `/run`.
+- the current editor text is passed in `env.vars["copilot.editor"]`
+- the current editor selection is passed in `env.vars["copilot.selection"]`
+- the file references are passed in `env.files`
+
+## Default script
+
+The following script can used as a starter template to create the default script when the user does not use the `/run` command.
+
+
diff --git a/docs/src/content/docs/reference/vscode/index.mdx b/docs/src/content/docs/reference/vscode/index.mdx
index 99875b80e2..10a776e561 100644
--- a/docs/src/content/docs/reference/vscode/index.mdx
+++ b/docs/src/content/docs/reference/vscode/index.mdx
@@ -14,3 +14,4 @@ contains the latest stable release of the [extension](https://marketplace.visual
- [Download](https://marketplace.visualstudio.com/items?itemName=genaiscript.genaiscript-vscode)
- [Installation instructions](/genaiscript/getting-started/installation/#visual-studio-code-extension)
+- [Copilot Chat Integration](/genaiscript/reference/copilot-chat/)
\ No newline at end of file
diff --git a/packages/core/src/annotations.ts b/packages/core/src/annotations.ts
index 41e2d15b1d..16dc7152f3 100644
--- a/packages/core/src/annotations.ts
+++ b/packages/core/src/annotations.ts
@@ -18,6 +18,13 @@ const AZURE_DEVOPS_ANNOTATIONS_RX =
// Example: foo.ts:10:error TS1005: ';' expected.
const TYPESCRIPT_ANNOTATIONS_RX =
/^(?[^:\s].*?):(?\d+)(?::(?\d+))?(?::\d+)?\s+-\s+(?error|warning)\s+(?[^:]+)\s*:\s*(?.*)$/gim
+// Maps severity strings to `DiagnosticSeverity`.
+const SEV_MAP: Record = Object.freeze({
+ ["info"]: "info",
+ ["notice"]: "info", // Maps 'notice' to 'info' severity
+ ["warning"]: "warning",
+ ["error"]: "error",
+})
/**
* Parses annotations from TypeScript, GitHub Actions, and Azure DevOps.
@@ -28,20 +35,12 @@ const TYPESCRIPT_ANNOTATIONS_RX =
export function parseAnnotations(text: string): Diagnostic[] {
if (!text) return []
- // Maps severity strings to `DiagnosticSeverity`.
- const sevMap: Record = {
- ["info"]: "info",
- ["notice"]: "info", // Maps 'notice' to 'info' severity
- ["warning"]: "warning",
- ["error"]: "error",
- }
-
// Helper function to add an annotation to the set.
// Extracts groups from the regex match and constructs a `Diagnostic` object.
const addAnnotation = (m: RegExpMatchArray) => {
const { file, line, endLine, severity, code, message } = m.groups
const annotation: Diagnostic = {
- severity: sevMap[severity?.toLowerCase()] ?? "info", // Default to "info" if severity is missing
+ severity: SEV_MAP[severity?.toLowerCase()] ?? "info", // Default to "info" if severity is missing
filename: file,
range: [
[parseInt(line) - 1, 0], // Start of range, 0-based index
@@ -72,6 +71,23 @@ export function eraseAnnotations(text: string) {
].reduce((t, rx) => t.replace(rx, ""), text)
}
+export function convertAnnotationsToItems(text: string) {
+ return [
+ TYPESCRIPT_ANNOTATIONS_RX,
+ GITHUB_ANNOTATIONS_RX,
+ AZURE_DEVOPS_ANNOTATIONS_RX,
+ ].reduce(
+ (t, rx) =>
+ t.replace(rx, (s) => {
+ const m = rx.exec(s)
+ if (!m) return s
+ const { file, line, severity, code, message } = m.groups
+ return `- ${SEV_MAP[severity?.toLowerCase()] ?? "info"}: ${message} (${file}#L${line} ${code || ""})`
+ }),
+ text
+ )
+}
+
/**
* Converts a `Diagnostic` to a GitHub Action command string.
*
diff --git a/packages/core/src/chat.ts b/packages/core/src/chat.ts
index 6abb09bb0c..510fa3ff96 100644
--- a/packages/core/src/chat.ts
+++ b/packages/core/src/chat.ts
@@ -833,7 +833,7 @@ export function appendSystemMessage(
if (last?.role !== "system") {
last = {
role: "system",
- content,
+ content: "",
} as ChatCompletionSystemMessageParam
messages.unshift(last)
}
diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts
index cad5a57a1c..6d6373b2d0 100644
--- a/packages/core/src/constants.ts
+++ b/packages/core/src/constants.ts
@@ -84,7 +84,8 @@ export const CACHE_LLMREQUEST_PREFIX = "genaiscript/cache/llm/"
export const CACHE_AIREQUEST_PREFIX = "genaiscript/cache/ai/"
export const TRACE_NODE_PREFIX = "genaiscript/trace/"
export const EXTENSION_ID = "genaiscript.genaiscript-vscode"
-export const CHAT_PARTICIPANT_ID = TOOL_ID
+export const COPILOT_CHAT_PARTICIPANT_ID = TOOL_ID
+export const COPILOT_CHAT_PARTICIPANT_SCRIPT_ID = "copilotchat"
export const BING_SEARCH_ENDPOINT = "https://api.bing.microsoft.com/v7.0/search"
export const SYSTEM_FENCE = "\n"
export const MAX_DATA_REPAIRS = 1
diff --git a/packages/core/src/promptdom.ts b/packages/core/src/promptdom.ts
index 6079da628d..36a89e7dc1 100644
--- a/packages/core/src/promptdom.ts
+++ b/packages/core/src/promptdom.ts
@@ -11,20 +11,19 @@ import {
MARKDOWN_PROMPT_FENCE,
PROMPT_FENCE,
PROMPTY_REGEX,
- SYSTEM_FENCE,
TEMPLATE_ARG_DATA_SLICE_SAMPLE,
TEMPLATE_ARG_FILE_MAX_TOKENS,
} from "./constants"
import { parseModelIdentifier } from "./models"
-import { appendAssistantMessage, appendUserMessage } from "./chat"
+import {
+ appendAssistantMessage,
+ appendSystemMessage,
+ appendUserMessage,
+} from "./chat"
import { errorMessage } from "./error"
import { tidyData } from "./tidy"
import { dedent } from "./indent"
-import {
- ChatCompletionMessageParam,
- ChatCompletionSystemMessageParam,
- ChatCompletionUserMessageParam,
-} from "./chattypes"
+import { ChatCompletionMessageParam } from "./chattypes"
import { resolveTokenEncoder } from "./encoders"
import { expandFiles } from "./fs"
import { interpolateVariables } from "./mustache"
@@ -938,17 +937,8 @@ export async function renderPromptNode(
if (truncated) await tracePromptNode(trace, node, { label: "truncated" })
const messages: ChatCompletionMessageParam[] = []
- const appendSystem = (content: string) => {
- const last = messages.find(
- ({ role }) => role === "system"
- ) as ChatCompletionSystemMessageParam
- if (last) last.content += content + SYSTEM_FENCE
- else
- messages.push({
- role: "system",
- content,
- } as ChatCompletionSystemMessageParam)
- }
+ const appendSystem = (content: string) =>
+ appendSystemMessage(messages, content)
const appendUser = (content: string) => appendUserMessage(messages, content)
const appendAssistant = (content: string) =>
appendAssistantMessage(messages, content)
diff --git a/packages/sample/genaisrc/bicep-best-practices.genai.mjs b/packages/sample/genaisrc/bicep-best-practices.genai.mjs
index f1682b67aa..ff70946515 100644
--- a/packages/sample/genaisrc/bicep-best-practices.genai.mjs
+++ b/packages/sample/genaisrc/bicep-best-practices.genai.mjs
@@ -1,13 +1,14 @@
script({
title: "Bicep Best Practices",
temperature: 0,
+ system: ["system", "system.annotations"]
})
def("FILE", env.files, { endsWith: ".bicep" })
$`You are an expert at Azure Bicep.
-Review the bicep in FILE and generate annotations to enhance the script base on best practices
+Review the bicep in FILE and generate errors to enhance the script base on best practices
(https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/best-practices).
- Generate the top 3 most important annotations.
diff --git a/packages/core/src/genaisrc/copilot_chat_participant.genai.mjs b/packages/vscode/genaisrc/copilotchat.genai.mts
similarity index 69%
rename from packages/core/src/genaisrc/copilot_chat_participant.genai.mjs
rename to packages/vscode/genaisrc/copilotchat.genai.mts
index 20c91f0ba8..70d1f151d0 100644
--- a/packages/core/src/genaisrc/copilot_chat_participant.genai.mjs
+++ b/packages/vscode/genaisrc/copilotchat.genai.mts
@@ -1,30 +1,39 @@
script({
+ model: "large",
system: [
// List of system components and tools available for the script
"system",
+ "system.safety_harmful_content",
+ "system.safety_jailbreak",
+ "system.safety_protected_material",
"system.tools",
"system.files",
+ "system.files_schema",
"system.diagrams",
"system.annotations",
"system.git_info",
"system.github_info",
"system.safety_harmful_content",
+ "system.agent_fs",
+ "system.agent_git",
+ "system.agent_github",
+ "system.agent_interpreter",
+ "system.agent_docs",
],
- tools: ["agent"], // Tools that the script can use
- group: "infrastructure", // Group categorization for the script
+ group: "copilot", // Group categorization for the script
parameters: {
question: {
- type: "string", // Type of the parameter
- description: "the user question", // Description of the parameter
+ type: "string",
+ description: "the user question",
},
"copilot.editor": {
type: "string",
- description: "the content of the opened editor",
+ description: "the content of the opened editor, if any",
default: "",
},
"copilot.selection": {
type: "string",
- description: "the content of the opened editor",
+ description: "the content of the opened editor, if any",
default: "",
},
},
@@ -60,6 +69,5 @@ $`## Context`
// Define a variable FILE with the file data from the environment variables
// The { ignoreEmpty: true, flex: 1 } options specify to ignore empty files and to use flexible token allocation
def("FILE", env.files, { lineNumbers: false, ignoreEmpty: true, flex: 1 })
-
-if (editor) writeText(editor, { flex: 4 })
-if (selection) writeText(selection, { flex: 5 })
+def("EDITOR", editor, { flex: 4, ignoreEmpty: true })
+def("SELECTION", selection, { flex: 5, ignoreEmpty: true })
diff --git a/packages/vscode/package.json b/packages/vscode/package.json
index 4524eb7dff..d302da30e1 100644
--- a/packages/vscode/package.json
+++ b/packages/vscode/package.json
@@ -59,11 +59,12 @@
"name": "genaiscript",
"fullName": "GenAIScript",
"isSticky": false,
- "disambiguation": [
+ "commands": [
{
- "category": "workspace_question",
- "description": "Runs GenAIScript agents defined in the current respository.",
- "examples": []
+ "name": "run",
+ "description": "Runs a GenAIScript script. The query should start with the script filename without the extension.",
+ "isSticky": false,
+ "sampleRequest": "/run poem"
}
]
}
@@ -249,6 +250,10 @@
{
"command": "genaiscript.request.status",
"when": "false"
+ },
+ {
+ "command": "genaiscript.samples.download",
+ "when": "false"
}
],
"view/title": [
diff --git a/packages/vscode/postpackage.mjs b/packages/vscode/postpackage.mjs
index 397fe82208..be7fa8eb3b 100644
--- a/packages/vscode/postpackage.mjs
+++ b/packages/vscode/postpackage.mjs
@@ -2,9 +2,7 @@ import "zx/globals"
const pkg = await fs.readJSON("./package.json")
pkg.enabledApiProposals = pkg._enabledApiProposals
-pkg.contributes.chatParticipants = pkg._chatParticipants
pkg.displayName = "GenAIScript Insiders"
delete pkg._enabledApiProposals
-delete pkg._chatParticipants
await fs.writeJSON("./package.json", pkg, { spaces: 4 })
console.log(`cleaned package.json`)
diff --git a/packages/vscode/prepackage.mjs b/packages/vscode/prepackage.mjs
index c1bc41d56f..e0c0d452c3 100644
--- a/packages/vscode/prepackage.mjs
+++ b/packages/vscode/prepackage.mjs
@@ -2,7 +2,6 @@ import "zx/globals"
const pkg = await fs.readJSON("./package.json")
pkg._enabledApiProposals = pkg.enabledApiProposals
-pkg._chatParticipants = pkg.contributes.chatParticipants
pkg.displayName = "GenAIScript"
delete pkg.enabledApiProposals
await fs.writeJSON("./package.json", pkg, { spaces: 4 })
diff --git a/packages/vscode/src/chatparticipant.ts b/packages/vscode/src/chatparticipant.ts
index 058afc9e60..991cda5db2 100644
--- a/packages/vscode/src/chatparticipant.ts
+++ b/packages/vscode/src/chatparticipant.ts
@@ -1,9 +1,14 @@
import * as vscode from "vscode"
import { ExtensionState } from "./state"
-import { TOOL_ID } from "../../core/src/constants"
+import {
+ COPILOT_CHAT_PARTICIPANT_SCRIPT_ID,
+ COPILOT_CHAT_PARTICIPANT_ID,
+ ICON_LOGO_NAME,
+} from "../../core/src/constants"
import { Fragment } from "../../core/src/generation"
-import { prettifyMarkdown } from "../../core/src/markdown"
-import { eraseAnnotations } from "../../core/src/annotations"
+import { cleanMarkdown } from "../../core/src/markdown"
+import { convertAnnotationsToItems } from "../../core/src/annotations"
+import { dedent } from "../../core/src/indent"
export async function activateChatParticipant(state: ExtensionState) {
const { context } = state
@@ -26,21 +31,48 @@ export async function activateChatParticipant(state: ExtensionState) {
}
const participant = vscode.chat.createChatParticipant(
- TOOL_ID,
+ COPILOT_CHAT_PARTICIPANT_ID,
async (
request: vscode.ChatRequest,
context: vscode.ChatContext,
response: vscode.ChatResponseStream,
token: vscode.CancellationToken
) => {
- const { command, prompt, references } = request
- if (command) throw new Error("Command not supported")
+ let { command, prompt, references, model } = request
if (!state.project) await state.parseWorkspace()
if (token.isCancellationRequested) return
- const template = state.project.templates.find(
- (t) => t.id === "copilot_chat_participant"
- )
+ let template: PromptScript
+ if (command === "run") {
+ const scriptid = prompt.split(" ")[0]
+ prompt = prompt.slice(scriptid.length).trim()
+ template = state.project.templates.find(
+ (t) => t.id === scriptid
+ )
+ if (!template) {
+ response.markdown(dedent`Oops, I could not find any genaiscript matching \`${scriptid}\`. Try one of the following:
+ ${state.project.templates
+ .filter((s) => !s.system && !s.unlisted)
+ .map((s) => `- \`${s.id}\`: ${s.title}`)
+ .join("\n")}
+ `)
+ return
+ }
+ } else {
+ template = state.project.templates.find(
+ (t) => t.id === COPILOT_CHAT_PARTICIPANT_SCRIPT_ID
+ )
+ if (!template) {
+ response.markdown(
+ dedent`
+ The \`${COPILOT_CHAT_PARTICIPANT_SCRIPT_ID}\` script has not been configured yet in this workspace.
+
+ Save [starter template](https://microsoft.github.io/genaiscript/reference/vscode/github-copilot-chat#copilotchat) in your workspace to get started.
+ `
+ )
+ return
+ }
+ }
const { files, vars } = resolveReference(references)
const fragment: Fragment = {
files,
@@ -65,12 +97,13 @@ export async function activateChatParticipant(state: ExtensionState) {
const { text = "" } = res || {}
response.markdown(
new vscode.MarkdownString(
- prettifyMarkdown(eraseAnnotations(text)),
+ cleanMarkdown(convertAnnotationsToItems(text)),
true
)
)
}
)
+ participant.iconPath = new vscode.ThemeIcon(ICON_LOGO_NAME)
subscriptions.push(participant)
}
diff --git a/packages/vscode/src/extension.ts b/packages/vscode/src/extension.ts
index 53e14f2052..a37be7f923 100644
--- a/packages/vscode/src/extension.ts
+++ b/packages/vscode/src/extension.ts
@@ -30,7 +30,7 @@ export async function activate(context: ExtensionContext) {
const state = new ExtensionState(context)
activatePromptCommands(state)
activateFragmentCommands(state)
- // activateSamplesCommands(state)
+ activateSamplesCommands(state)
activateMarkdownTextDocumentContentProvider(state)
activatePromptTreeDataProvider(state)
activateConnectionInfoTree(state)
diff --git a/packages/vscode/src/promptcommands.ts b/packages/vscode/src/promptcommands.ts
index cc741e9a71..6efec3c84b 100644
--- a/packages/vscode/src/promptcommands.ts
+++ b/packages/vscode/src/promptcommands.ts
@@ -37,7 +37,7 @@ export function activatePromptCommands(state: ExtensionState) {
),
registerCommand(
"genaiscript.prompt.fork",
- async (template: PromptScript) => {
+ async (template: PromptScript | string) => {
if (!template) {
if (!state.project) await state.parseWorkspace()
const templates = state.project?.templates
@@ -50,14 +50,17 @@ export function activatePromptCommands(state: ExtensionState) {
)
if (picked === undefined) return
template = picked.template
+ } else if (typeof template === "string") {
+ if (!state.project) await state.parseWorkspace()
+ template = state.project?.templates.find(
+ (t) => t.id === template
+ )
}
- const name = await vscode.window.showInputBox({
- title: `Pick a file name for the new GenAIScript script.`,
- value: template.id,
- })
- if (name === undefined) return
await showPrompt(
- await copyPrompt(template, { fork: true, name })
+ await copyPrompt(template, {
+ fork: true,
+ name: template.id,
+ })
)
}
),
diff --git a/packages/vscode/src/samplescommands.ts b/packages/vscode/src/samplescommands.ts
index 0c5b347156..f15a51d862 100644
--- a/packages/vscode/src/samplescommands.ts
+++ b/packages/vscode/src/samplescommands.ts
@@ -9,7 +9,7 @@ import { writeFile } from "./fs"
export function activateSamplesCommands(state: ExtensionState) {
const { context, host } = state
- registerCommand("genaiscript.samples.download", async () => {
+ 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)
@@ -31,16 +31,18 @@ export function activateSamplesCommands(state: ExtensionState) {
)
).map((s) => ({ ...s, meta: parsePromptScriptMeta(s.jsSource) }))
- const res = 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" }
- )
+ 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
diff --git a/packages/vscode/src/state.ts b/packages/vscode/src/state.ts
index 595d89f76b..fe268a4bb6 100644
--- a/packages/vscode/src/state.ts
+++ b/packages/vscode/src/state.ts
@@ -342,7 +342,7 @@ stats/
vscode.commands.executeCommand(
"workbench.view.extension.genaiscript"
)
- if (options.mode !== "notebook" && !hasOutputOrTraceOpened())
+ if (!options.mode && !hasOutputOrTraceOpened())
vscode.commands.executeCommand("genaiscript.request.open.output")
r.request
.then((resp) => {