From 5a3f7fa06fe98b0c42b51bbbcc9a2171be4f0dc7 Mon Sep 17 00:00:00 2001 From: Hugo Dutka Date: Thu, 4 Dec 2025 14:12:18 +0100 Subject: [PATCH] fix: scope workspaces to chats --- packages/scout-agent/lib/compute/common.ts | 4 +++- packages/scout-agent/lib/compute/tools.ts | 13 ++++++++----- packages/scout-agent/lib/core.test.ts | 6 ++++-- packages/scout-agent/lib/core.ts | 2 ++ packages/scout-agent/package.json | 2 +- 5 files changed, 18 insertions(+), 9 deletions(-) diff --git a/packages/scout-agent/lib/compute/common.ts b/packages/scout-agent/lib/compute/common.ts index 7cadc6c..18227c0 100644 --- a/packages/scout-agent/lib/compute/common.ts +++ b/packages/scout-agent/lib/compute/common.ts @@ -1,9 +1,11 @@ import { Client } from "@blink-sdk/compute-protocol/client"; import type { Stream } from "@blink-sdk/multiplexer"; import Multiplexer from "@blink-sdk/multiplexer"; +import type * as blink from "blink"; import type { WebSocket } from "ws"; -export const WORKSPACE_INFO_KEY = "__compute_workspace_id"; +export const getWorkspaceInfoKey = (chatID: blink.ID) => + `__compute_workspace_id-${chatID}`; export const newComputeClient = async (ws: WebSocket): Promise => { return new Promise((resolve, reject) => { diff --git a/packages/scout-agent/lib/compute/tools.ts b/packages/scout-agent/lib/compute/tools.ts index 541e1c2..601ecec 100644 --- a/packages/scout-agent/lib/compute/tools.ts +++ b/packages/scout-agent/lib/compute/tools.ts @@ -5,13 +5,14 @@ import { type Tool, tool } from "ai"; import * as blink from "blink"; import { z } from "zod"; import type { Message } from "../types"; -import { WORKSPACE_INFO_KEY } from "./common"; +import { getWorkspaceInfoKey } from "./common"; export const createComputeTools = ({ agent, githubAppContext, initializeWorkspace, createWorkspaceClient, + chatID, }: { agent: blink.Agent; initializeWorkspace: ( @@ -23,9 +24,10 @@ export const createComputeTools = ({ * If provided, the workspace_authenticate_git tool will be available. */ githubAppContext?: github.AppAuthOptions; + chatID: blink.ID; }): Record => { const newClient = async () => { - const workspaceInfo = await agent.store.get(WORKSPACE_INFO_KEY); + const workspaceInfo = await agent.store.get(getWorkspaceInfoKey(chatID)); if (!workspaceInfo) { throw new Error( "Workspace not initialized. Call initialize_workspace first." @@ -40,8 +42,9 @@ export const createComputeTools = ({ description: "Initialize a workspace for the user.", inputSchema: z.object({}), execute: async (_args, _opts) => { - const existingWorkspaceInfoRaw = - await agent.store.get(WORKSPACE_INFO_KEY); + const existingWorkspaceInfoRaw = await agent.store.get( + getWorkspaceInfoKey(chatID) + ); const existingWorkspaceInfo = existingWorkspaceInfoRaw ? JSON.parse(existingWorkspaceInfoRaw) : undefined; @@ -49,7 +52,7 @@ export const createComputeTools = ({ existingWorkspaceInfo ); await agent.store.set( - WORKSPACE_INFO_KEY, + getWorkspaceInfoKey(chatID), JSON.stringify(workspaceInfo) ); return message; diff --git a/packages/scout-agent/lib/core.test.ts b/packages/scout-agent/lib/core.test.ts index e3a65ff..1159b11 100644 --- a/packages/scout-agent/lib/core.test.ts +++ b/packages/scout-agent/lib/core.test.ts @@ -10,6 +10,7 @@ import { MockLanguageModelV2 } from "ai/test"; import * as blink from "blink"; import { Client } from "blink/client"; import { WebSocketServer } from "ws"; +import { getWorkspaceInfoKey } from "./compute/common"; import type { DaytonaClient, DaytonaSandbox } from "./compute/daytona/index"; import { type Message, Scout } from "./index"; import { @@ -576,8 +577,9 @@ describe("daytona integration", () => { }, }); + const chatID = "test-chat-id" as blink.ID; const params = await scout.buildStreamTextParams({ - chatID: "test-chat-id" as blink.ID, + chatID, messages: [], model: newMockModel({ textResponse: "test" }), }); @@ -610,7 +612,7 @@ describe("daytona integration", () => { }); // Verify workspace info was stored - expect(apiServer.storage.__compute_workspace_id).toBe( + expect(apiServer.storage[getWorkspaceInfoKey(chatID)]).toBe( JSON.stringify({ id: "new-daytona-workspace" }) ); }); diff --git a/packages/scout-agent/lib/core.ts b/packages/scout-agent/lib/core.ts index 634d61a..e919535 100644 --- a/packages/scout-agent/lib/core.ts +++ b/packages/scout-agent/lib/core.ts @@ -305,6 +305,7 @@ export class Scout { githubAppContext, initializeWorkspace: initializeDockerWorkspace, createWorkspaceClient: getDockerWorkspaceClient, + chatID, }); break; } @@ -313,6 +314,7 @@ export class Scout { computeTools = createComputeTools({ agent: this.agent, githubAppContext, + chatID, initializeWorkspace: (info) => initializeDaytonaWorkspace( this.logger, diff --git a/packages/scout-agent/package.json b/packages/scout-agent/package.json index c17b4e3..c93e3ab 100644 --- a/packages/scout-agent/package.json +++ b/packages/scout-agent/package.json @@ -1,7 +1,7 @@ { "name": "@blink-sdk/scout-agent", "description": "A general-purpose AI agent with GitHub, Slack, web search, and compute capabilities built on Blink SDK.", - "version": "0.0.7", + "version": "0.0.8", "type": "module", "keywords": [ "blink",