From 4dbd9f30b6df879661e968e493f817667954bfce Mon Sep 17 00:00:00 2001 From: Tommaso Sciortino Date: Fri, 18 Jul 2025 17:28:40 -0700 Subject: [PATCH] Revert background agent commits (#4479) --- package-lock.json | 58 ---- packages/cli/src/config/config.ts | 1 - packages/cli/src/config/settings.ts | 1 - .../cli/src/services/CommandService.test.ts | 1 - packages/cli/src/services/CommandService.ts | 2 - packages/cli/src/ui/App.test.tsx | 3 - .../cli/src/ui/commands/backgroundCommand.ts | 262 ------------------ .../core/src/background/backgroundAgent.ts | 126 --------- .../core/src/background/backgroundManager.ts | 40 --- packages/core/src/background/types.ts | 107 ------- packages/core/src/config/config.ts | 16 -- packages/core/src/index.ts | 3 - packages/core/src/tools/mcp-tool.ts | 4 +- packages/examples/background_agent/README.md | 16 -- .../background_agent/demo-background-agent.ts | 217 --------------- packages/examples/package.json | 17 -- 16 files changed, 3 insertions(+), 871 deletions(-) delete mode 100644 packages/cli/src/ui/commands/backgroundCommand.ts delete mode 100644 packages/core/src/background/backgroundAgent.ts delete mode 100644 packages/core/src/background/backgroundManager.ts delete mode 100644 packages/core/src/background/types.ts delete mode 100644 packages/examples/background_agent/README.md delete mode 100644 packages/examples/background_agent/demo-background-agent.ts delete mode 100644 packages/examples/package.json diff --git a/package-lock.json b/package-lock.json index 947eb6ab..d5d0e294 100644 --- a/package-lock.json +++ b/package-lock.json @@ -916,10 +916,6 @@ "resolved": "packages/core", "link": true }, - "node_modules/@google/gemini-cli-examples": { - "resolved": "packages/examples", - "link": true - }, "node_modules/@google/genai": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.9.0.tgz", @@ -5661,19 +5657,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -9207,16 +9190,6 @@ "node": ">=4" } }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, "node_modules/restore-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", @@ -10517,26 +10490,6 @@ "dev": true, "license": "0BSD" }, - "node_modules/tsx": { - "version": "4.20.3", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz", - "integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "~0.25.0", - "get-tsconfig": "^4.7.5" - }, - "bin": { - "tsx": "dist/cli.mjs" - }, - "engines": { - "node": ">=18.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -11907,17 +11860,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, - "packages/examples": { - "name": "@google/gemini-cli-examples", - "version": "0.1.0", - "dependencies": { - "@modelcontextprotocol/sdk": "1.15.1", - "zod": "^3.23.8" - }, - "devDependencies": { - "tsx": "^4.16.2" - } - }, "packages/vscode-ide-companion": { "name": "gemini-cli-vscode-ide-companion", "version": "0.0.1", diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 84ca6815..2d33daa3 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -382,7 +382,6 @@ export async function loadCliConfig( toolCallCommand: settings.toolCallCommand, mcpServerCommand: settings.mcpServerCommand, mcpServers, - backgroundAgents: settings.backgroundAgents, userMemory: memoryContent, geminiMdFileCount: fileCount, approvalMode: argv.yolo || false ? ApprovalMode.YOLO : ApprovalMode.DEFAULT, diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts index 2da2e592..604e89dc 100644 --- a/packages/cli/src/config/settings.ts +++ b/packages/cli/src/config/settings.ts @@ -64,7 +64,6 @@ export interface Settings { toolCallCommand?: string; mcpServerCommand?: string; mcpServers?: Record; - backgroundAgents?: Record; allowMCPServers?: string[]; excludeMCPServers?: string[]; showMemoryUsage?: boolean; diff --git a/packages/cli/src/services/CommandService.test.ts b/packages/cli/src/services/CommandService.test.ts index 5945e3f6..d03bf988 100644 --- a/packages/cli/src/services/CommandService.test.ts +++ b/packages/cli/src/services/CommandService.test.ts @@ -96,7 +96,6 @@ describe('CommandService', () => { mockConfig = { getIdeMode: vi.fn(), getCheckpointingEnabled: vi.fn(), - getBackgroundAgentManager: vi.fn(), } as unknown as Mocked; vi.mocked(ideCommand).mockReturnValue(null); vi.mocked(restoreCommand).mockReturnValue(null); diff --git a/packages/cli/src/services/CommandService.ts b/packages/cli/src/services/CommandService.ts index 9db4e9e6..def8cfcc 100644 --- a/packages/cli/src/services/CommandService.ts +++ b/packages/cli/src/services/CommandService.ts @@ -7,7 +7,6 @@ import { Config } from '@google/gemini-cli-core'; import { SlashCommand } from '../ui/commands/types.js'; import { memoryCommand } from '../ui/commands/memoryCommand.js'; -import { backgroundCommand } from '../ui/commands/backgroundCommand.js'; import { helpCommand } from '../ui/commands/helpCommand.js'; import { clearCommand } from '../ui/commands/clearCommand.js'; import { corgiCommand } from '../ui/commands/corgiCommand.js'; @@ -34,7 +33,6 @@ const loadBuiltInCommands = async ( const allCommands = [ aboutCommand, authCommand, - backgroundCommand(config), bugCommand, chatCommand, clearCommand, diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx index 24d30f74..e03c80ae 100644 --- a/packages/cli/src/ui/App.test.tsx +++ b/packages/cli/src/ui/App.test.tsx @@ -9,7 +9,6 @@ import { render } from 'ink-testing-library'; import { AppWrapper as App } from './App.js'; import { Config as ServerConfig, - BackgroundAgentManager, MCPServerConfig, ApprovalMode, ToolRegistry, @@ -52,7 +51,6 @@ interface MockServerConfig { getSandbox: Mock<() => SandboxConfig | undefined>; getTargetDir: Mock<() => string>; getToolRegistry: Mock<() => ToolRegistry>; // Use imported ToolRegistry type - getBackgroundAgentManager: Mock<() => BackgroundAgentManager>; getDebugMode: Mock<() => boolean>; getQuestion: Mock<() => string | undefined>; getFullContext: Mock<() => boolean>; @@ -119,7 +117,6 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => { getSandbox: vi.fn(() => opts.sandbox), getTargetDir: vi.fn(() => opts.targetDir || '/test/dir'), getToolRegistry: vi.fn(() => ({}) as ToolRegistry), // Simple mock - getBackgroundAgentManager: vi.fn(() => new BackgroundAgentManager([])), getDebugMode: vi.fn(() => opts.debugMode || false), getQuestion: vi.fn(() => opts.question), getFullContext: vi.fn(() => opts.fullContext ?? false), diff --git a/packages/cli/src/ui/commands/backgroundCommand.ts b/packages/cli/src/ui/commands/backgroundCommand.ts deleted file mode 100644 index cbeb18df..00000000 --- a/packages/cli/src/ui/commands/backgroundCommand.ts +++ /dev/null @@ -1,262 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { SlashCommand, CommandContext } from './types.js'; -import { - Config, - BackgroundAgentMessage, - partListUnionToString, -} from '@google/gemini-cli-core'; - -const MAX_STATUS_MESSAGE_LENGTH = 100; - -function toMessageString(message?: BackgroundAgentMessage): string { - return partListUnionToString(message?.parts ?? []).trim(); -} - -function toOneliner(input: string, maxlength: number) { - let output = input.replace(/\r?\n|\r/g, ' '); - if (output.length > maxlength) { - output = output.substring(0, maxlength) + '...'; - } - return output; -} - -function getActiveAgent(context: CommandContext) { - const agent = - context.services.config?.getBackgroundAgentManager()?.activeAgent; - if (!agent) { - throw Error('There is no active background agent.'); - } - return agent; -} - -function addClientHistory(context: CommandContext, text: string) { - context.services.config!.getGeminiClient().addHistory({ - role: 'user', - parts: [{ text }], - }); - - context.services.config!.getGeminiClient().addHistory({ - role: 'model', - parts: [{ text: 'Got it.' }], - }); -} - -const startSubcommand: SlashCommand = { - name: 'start', - description: - 'Start a new task with the provided prompt. Usage: /bg start ', - action: async (context, args) => { - if (!args || args.trim() === '') { - return { - type: 'message', - messageType: 'error', - content: 'The `start` command requires a prompt.', - }; - } - - const agent = getActiveAgent(context); - const task = await agent.startTask(args); - - addClientHistory( - context, - `I started a background task with id '${task.id}' and prompt:\n${args}`, - ); - - return { - type: 'message', - messageType: 'info', - content: `Started background task with id '${task.id}' and prompt:\n${args}`, - }; - }, -}; - -const stopSubcommand: SlashCommand = { - name: 'stop', - description: 'Stops a running task. Usage: /bg stop ', - action: async (context, args) => { - if (!args || args.trim() === '') { - return { - type: 'message', - messageType: 'error', - content: 'The `stop` command requires a task id.', - }; - } - const agent = getActiveAgent(context); - await agent.cancelTask(args); - addClientHistory(context, `I canceled the background task with id ${args}`); - return { - type: 'message', - messageType: 'info', - content: `Stopped background task with id ${args}.`, - }; - }, -}; - -const listSubcommand: SlashCommand = { - name: 'list', - description: 'List all tasks', - action: async (context, args) => { - if (args && args.trim() !== '') { - return { - type: 'message', - messageType: 'error', - content: 'The `list` command takes no arguments.', - }; - } - - const agent = getActiveAgent(context); - const tasks = await agent.listTasks(); - let content: string; - if (tasks.length === 0) { - content = 'No background tasks found.'; - } else { - const taskList = tasks - .map((task) => { - const shortStatus = toOneliner( - toMessageString(task.status.message), - MAX_STATUS_MESSAGE_LENGTH, - ); - return ` - ${task.id}: (${task.status.state}) ${shortStatus}`; - }) - .join('\n'); - content = `Background tasks:\n${taskList}`; - } - return { - type: 'message', - messageType: 'info', - content, - }; - }, -}; - -const getSubcommand: SlashCommand = { - name: 'get', - description: 'View a task. Usage: /bg get ', - action: async (context, args) => { - if (!args || args.trim() === '') { - return { - type: 'message', - messageType: 'error', - content: 'The `get` command requires a task id.', - }; - } - const agent = getActiveAgent(context); - const task = await agent.getTask(args); - const content = `Task Details for ${task.id}: -Status: (${task.status.state}) ${toMessageString(task.status.message)}}`; - - return { - type: 'message', - messageType: 'info', - content, - }; - }, -}; - -const logsSubcommand: SlashCommand = { - name: 'logs', - description: "View a task's recent logs. Usage: /bg log ", - action: async (context, args) => { - if (!args || args.trim() === '') { - return { - type: 'message', - messageType: 'error', - content: 'The `log` command requires a task id.', - }; - } - const agent = getActiveAgent(context); - const task = await agent.getTask(args, 5); - const contents = [ - `Task logs for ${task.id}. status: (${task.status.state})`, - ]; - (task.history ?? []).forEach((message) => { - contents.push(toMessageString(message)); - }); - return { - type: 'message', - messageType: 'info', - content: contents.join('\n\n'), - }; - }, -}; - -const messageSubcommand: SlashCommand = { - name: 'message', - description: - 'Send a message to a task. Usage: /bg message ', - action: async (context, args) => { - if (!args || args.trim() === '' || !args.trim().includes(' ')) { - return { - type: 'message', - messageType: 'error', - content: 'The `message` command requires a task id and a message.', - }; - } - - const firstSpaceIndex = args.indexOf(' '); - const id = args.substring(0, firstSpaceIndex); - const message = args.substring(firstSpaceIndex + 1); - - const agent = getActiveAgent(context); - await agent.messageTask(id, message); - addClientHistory( - context, - `I sent a message to the background task with id '${id}':\n${message}`, - ); - - return { - type: 'message', - messageType: 'info', - content: `Sent a message to the background task with id '${id}':\n${message}`, - }; - }, -}; - -const deleteSubcommand: SlashCommand = { - name: 'delete', - description: 'Deletes a task. Usage: /bg delete ', - action: async (context, args) => { - if (!args) { - return { - type: 'message', - messageType: 'error', - content: 'The `delete` command requires a task id.', - }; - } - const agent = getActiveAgent(context); - await agent.deleteTask(args); - addClientHistory(context, `I deleted the background task with id ${args}`); - return { - type: 'message', - messageType: 'info', - content: `Task ${args} deleted.`, - }; - }, -}; - -export const backgroundCommand = ( - config: Config | null, -): SlashCommand | null => { - if (!config?.getBackgroundAgentManager()?.activeAgent) { - return null; - } - return { - name: 'background', - altName: 'bg', - description: "Commands for managing the background agent's tasks", - subCommands: [ - startSubcommand, - stopSubcommand, - listSubcommand, - getSubcommand, - logsSubcommand, - messageSubcommand, - deleteSubcommand, - ], - }; -}; diff --git a/packages/core/src/background/backgroundAgent.ts b/packages/core/src/background/backgroundAgent.ts deleted file mode 100644 index 008010cd..00000000 --- a/packages/core/src/background/backgroundAgent.ts +++ /dev/null @@ -1,126 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { MCPServerConfig } from '../config/config.js'; -import { connectToMcpServer, discoverTools } from '../tools/mcp-client.js'; -import { DiscoveredMCPTool } from '../tools/mcp-tool.js'; -import { - BackgroundAgentTasksResponseSchema, - BackgroundAgentTaskResponseSchema, - BackgroundAgentTask, -} from './types.js'; - -export async function loadBackgroundAgent( - name: string, - config: MCPServerConfig, - debugMode: boolean, -): Promise { - const server = await connectToMcpServer(name, config, debugMode); - try { - const tools = await discoverTools(name, config, server); - return new BackgroundAgent(name, tools); - } catch (error) { - await server.close(); - throw error; - } -} - -export class BackgroundAgent { - readonly startTaskTool: DiscoveredMCPTool; - readonly getTaskTool: DiscoveredMCPTool; - readonly listTasksTool: DiscoveredMCPTool; - readonly messageTaskTool: DiscoveredMCPTool; - readonly deleteTaskTool: DiscoveredMCPTool; - readonly cancelTaskTool: DiscoveredMCPTool; - - constructor( - readonly serverName: string, - tools: DiscoveredMCPTool[], - ) { - const getToolOrFail = (name: string): DiscoveredMCPTool => { - for (const tool of tools) { - if (tool.serverToolName === name) { - return tool; - } - } - throw new Error(`missing expected tool: ${name}`); - }; - - this.startTaskTool = getToolOrFail('startTask'); - this.getTaskTool = getToolOrFail('getTask'); - this.listTasksTool = getToolOrFail('listTasks'); - this.messageTaskTool = getToolOrFail('messageTask'); - this.deleteTaskTool = getToolOrFail('deleteTask'); - this.cancelTaskTool = getToolOrFail('cancelTask'); - } - - async startTask(prompt: string): Promise { - const resp = await this.callTool(this.startTaskTool, { - prompt: { - role: 'user', - parts: [{ text: prompt }], - }, - }); - const taskResp = await BackgroundAgentTaskResponseSchema.parseAsync(resp); - return taskResp.structuredContent; - } - - async getTask( - id: string, - historyLength?: number, - ): Promise { - const resp = await this.callTool(this.getTaskTool, { - id, - historyLength, - }); - const taskResp = await BackgroundAgentTaskResponseSchema.parseAsync(resp); - return taskResp.structuredContent; - } - - async listTasks(): Promise { - const resp = await this.callTool(this.listTasksTool, {}); - const tasksResp = await BackgroundAgentTasksResponseSchema.parseAsync(resp); - return tasksResp.structuredContent; - } - - async messageTask(id: string, message: string) { - await this.callTool(this.messageTaskTool, { - id, - message: { - role: 'user', - parts: [{ text: message }], - }, - }); - } - - async deleteTask(id: string) { - await this.callTool(this.deleteTaskTool, { id }); - } - - async cancelTask(id: string) { - await this.callTool(this.cancelTaskTool, { id }); - } - - private async callTool( - tool: DiscoveredMCPTool, - params: Record, - ): Promise> { - const { llmContent: parts } = await tool.execute(params); - if ( - !Array.isArray(parts) || - parts.length !== 1 || - typeof parts[0] !== 'object' || - parts[0]?.functionResponse?.response === undefined - ) { - throw new Error('Expected exactly one part with a functionResponse'); - } - const resp = parts[0].functionResponse.response; - if ('isError' in resp && resp.isError) { - throw new Error(`Error calling ${tool.displayName}: ${resp}`); - } - return resp; - } -} diff --git a/packages/core/src/background/backgroundManager.ts b/packages/core/src/background/backgroundManager.ts deleted file mode 100644 index a3ec526c..00000000 --- a/packages/core/src/background/backgroundManager.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { MCPServerConfig } from '../config/config.js'; -import { BackgroundAgent, loadBackgroundAgent } from './backgroundAgent.js'; - -export async function loadBackgroundAgentManager( - backgroundAgentConfigs: Record | undefined, - debugMode: boolean, -): Promise { - const agents = await Promise.all( - Object.entries(backgroundAgentConfigs ?? {}).map(([name, config]) => - loadBackgroundAgent(name, config, debugMode).catch((error) => { - console.error(`Error loading background agent '${name}': ${error}`); - return null; - }), - ), - ).then((agents) => agents.filter((agent) => agent !== null)); - return new BackgroundAgentManager(agents); -} - -export class BackgroundAgentManager { - // The active agent. May be empty if none are confgured. - activeAgent?: BackgroundAgent; - - constructor(readonly backgroundAgents: BackgroundAgent[]) { - if (backgroundAgents.length !== 0) { - this.activeAgent = backgroundAgents[0]; - } - } - - setActiveAgentByName(name: string) { - this.activeAgent = this.backgroundAgents.find( - (agent) => agent.serverName === name, - ); - } -} diff --git a/packages/core/src/background/types.ts b/packages/core/src/background/types.ts deleted file mode 100644 index 60927af6..00000000 --- a/packages/core/src/background/types.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { z } from 'zod'; -import { Outcome, Language, FunctionResponseScheduling } from '@google/genai'; - -// Should conform to Part in @google/genai -export const PartSchema = z.object({ - videoMetadata: z - .object({ - fps: z.number().optional(), - endOffset: z.string().optional(), - startOffset: z.string().optional(), - }) - .optional(), - thought: z.boolean().optional(), - inlineData: z - .object({ - displayName: z.string().optional(), - data: z.string(), - mimeType: z.string(), - }) - .optional(), - fileData: z - .object({ - displayName: z.string().optional(), - fileUri: z.string(), - mimeType: z.string(), - }) - .optional(), - thoughtSignature: z.string().optional(), - codeExecutionResult: z - .object({ - outcome: z.nativeEnum(Outcome).optional(), - output: z.string().optional(), - }) - .optional(), - executableCode: z - .object({ - code: z.string().optional(), - language: z.nativeEnum(Language).optional(), - }) - .optional(), - functionCall: z - .object({ - id: z.string().optional(), - args: z.record(z.unknown()).optional(), - name: z.string(), - }) - .optional(), - functionResponse: z - .object({ - willContinue: z.boolean().optional(), - scheduling: z.nativeEnum(FunctionResponseScheduling).optional(), - id: z.string().optional(), - name: z.string(), - response: z.record(z.unknown()).optional(), - }) - .optional(), - text: z.string().optional(), -}); - -export const BackgroundAgentMessageSchema = z.object({ - role: z.enum(['user', 'agent']).describe('The role of the sender.'), - parts: z.array(PartSchema).describe('The parts of the message.'), -}); - -export const BackgroundAgentTaskStatusSchema = z.object({ - state: z.enum([ - 'submitted', - 'working', - 'input-required', - 'completed', - 'failed', - ]), - message: BackgroundAgentMessageSchema.describe( - 'Message describing the state of the task.', - ).optional(), -}); - -export const BackgroundAgentTaskSchema = z.object({ - id: z.string().describe('The id of the task. Must match `[a-zA-Z0-9.-_]+`'), - status: BackgroundAgentTaskStatusSchema.describe( - 'The current status of the task.', - ), - history: z - .array(BackgroundAgentMessageSchema) - .describe('Recent history of messages associated with this task') - .optional(), -}); - -export type BackgroundAgentMessage = z.infer< - typeof BackgroundAgentMessageSchema ->; - -export type BackgroundAgentTask = z.infer; - -export const BackgroundAgentTaskResponseSchema = z.object({ - structuredContent: BackgroundAgentTaskSchema, -}); - -export const BackgroundAgentTasksResponseSchema = z.object({ - structuredContent: z.array(BackgroundAgentTaskSchema), -}); diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 5d02f269..f81b3e32 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -45,10 +45,6 @@ import { DEFAULT_GEMINI_FLASH_MODEL, } from './models.js'; import { ClearcutLogger } from '../telemetry/clearcut-logger/clearcut-logger.js'; -import { - BackgroundAgentManager, - loadBackgroundAgentManager, -} from '../background/backgroundManager.js'; export enum ApprovalMode { DEFAULT = 'default', @@ -131,7 +127,6 @@ export interface ConfigParameters { toolCallCommand?: string; mcpServerCommand?: string; mcpServers?: Record; - backgroundAgents?: Record; userMemory?: string; geminiMdFileCount?: number; approvalMode?: ApprovalMode; @@ -163,7 +158,6 @@ export interface ConfigParameters { export class Config { private toolRegistry!: ToolRegistry; - private backgroundAgentManager?: BackgroundAgentManager; private readonly sessionId: string; private contentGeneratorConfig!: ContentGeneratorConfig; private readonly embeddingModel: string; @@ -178,7 +172,6 @@ export class Config { private readonly toolCallCommand: string | undefined; private readonly mcpServerCommand: string | undefined; private readonly mcpServers: Record | undefined; - private readonly backgroundAgents?: Record; private userMemory: string; private geminiMdFileCount: number; private approvalMode: ApprovalMode; @@ -231,7 +224,6 @@ export class Config { this.toolCallCommand = params.toolCallCommand; this.mcpServerCommand = params.mcpServerCommand; this.mcpServers = params.mcpServers; - this.backgroundAgents = params.backgroundAgents; this.userMemory = params.userMemory ?? ''; this.geminiMdFileCount = params.geminiMdFileCount ?? 0; this.approvalMode = params.approvalMode ?? ApprovalMode.DEFAULT; @@ -289,10 +281,6 @@ export class Config { if (this.getCheckpointingEnabled()) { await this.getGitService(); } - this.backgroundAgentManager = await loadBackgroundAgentManager( - this.backgroundAgents, - this.debugMode, - ); this.toolRegistry = await this.createToolRegistry(); } @@ -418,10 +406,6 @@ export class Config { return this.mcpServers; } - getBackgroundAgentManager(): BackgroundAgentManager | undefined { - return this.backgroundAgentManager; - } - getUserMemory(): string { return this.userMemory; } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a3d77ddc..24d8bdb2 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -24,9 +24,6 @@ export * from './code_assist/oauth2.js'; export * from './code_assist/server.js'; export * from './code_assist/types.js'; -export * from './background/types.js'; -export * from './background/backgroundManager.js'; - // Export utilities export * from './utils/paths.js'; export * from './utils/schemaValidator.js'; diff --git a/packages/core/src/tools/mcp-tool.ts b/packages/core/src/tools/mcp-tool.ts index 2cb124ed..9916d7f9 100644 --- a/packages/core/src/tools/mcp-tool.ts +++ b/packages/core/src/tools/mcp-tool.ts @@ -113,7 +113,9 @@ export class DiscoveredMCPTool extends BaseTool { args: params, }, ]; - const responseParts = await this.mcpTool.callTool(functionCalls); + + const responseParts: Part[] = await this.mcpTool.callTool(functionCalls); + return { llmContent: responseParts, returnDisplay: getStringifiedResultForDisplay(responseParts), diff --git a/packages/examples/background_agent/README.md b/packages/examples/background_agent/README.md deleted file mode 100644 index 0e5fd6dc..00000000 --- a/packages/examples/background_agent/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Demo Background Agent - -A pretend background agent that does not actually process tasks in the background. Configure in your settings.json with: - -```javascript - "backgroundAgents": { - "demo-background-agent": { - "command": "npm", - "args": [ - "run", - "start:demo-background-agent", - "--workspace=@google/gemini-cli-examples" - ] - } - }, -``` diff --git a/packages/examples/background_agent/demo-background-agent.ts b/packages/examples/background_agent/demo-background-agent.ts deleted file mode 100644 index 9ac568f4..00000000 --- a/packages/examples/background_agent/demo-background-agent.ts +++ /dev/null @@ -1,217 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; -import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; -import { z } from 'zod'; - -const BackgroundAgentMessageSchema = z.object({ - role: z.enum(['user', 'agent']), - parts: z.array(z.any()), -}); - -const BackgroundAgentTaskStatusSchema = z.object({ - state: z.enum([ - 'submitted', - 'working', - 'input-required', - 'completed', - 'canceled', - 'failed', - ]), - message: BackgroundAgentMessageSchema.optional(), -}); - -const BackgroundAgentTaskSchema = z.object({ - id: z.string(), - status: BackgroundAgentTaskStatusSchema, - history: z.array(BackgroundAgentMessageSchema).optional(), -}); -type BackgroundAgentTask = z.infer; - -const server = new McpServer({ - name: 'demo-background-agent', - version: '1.0.0', -}); - -const idToTask = new Map(); - -server.registerTool( - 'startTask', - { - title: 'Start a new task', - description: 'Launches a new task asynchronously.', - inputSchema: { prompt: BackgroundAgentMessageSchema }, - outputSchema: BackgroundAgentTaskSchema.shape, - }, - ({ prompt }) => { - const task: BackgroundAgentTask = { - id: crypto.randomUUID(), - status: { - state: 'submitted', - message: prompt, - }, - history: [], - }; - - idToTask.set(task.id, task); - - return { - content: [], - structuredContent: task, - }; - }, -); - -server.registerTool( - 'getTask', - { - title: 'Get a task', - inputSchema: { id: z.string() }, - outputSchema: BackgroundAgentTaskSchema.shape, - }, - ({ id }) => { - const task = idToTask.get(id); - if (!task) { - return { - isError: true, - content: [ - { - type: 'text', - text: 'No such task', - }, - ], - }; - } - - return { - content: [], - structuredContent: task, - }; - }, -); - -server.registerTool( - 'listTasks', - { - title: 'Lists tasks', - outputSchema: { - tasks: z.array(BackgroundAgentTaskSchema), - }, - }, - () => { - const out = { - tasks: Array.from(idToTask.values()), - }; - return { - content: [], - structuredContent: out, - }; - }, -); - -server.registerTool( - 'messageTask', - { - title: 'Send a message to a task', - inputSchema: { - id: z.string(), - message: BackgroundAgentMessageSchema, - }, - }, - ({ id, message }) => { - const task = idToTask.get(id); - if (!task) { - return { - isError: true, - content: [ - { - type: 'text', - text: 'No such task', - }, - ], - }; - } - - task.history?.push(message); - task.status.message = message; - - const statuses = BackgroundAgentTaskStatusSchema.shape.state.options; - const randomStatus = statuses[Math.floor(Math.random() * statuses.length)]; - task.status.state = randomStatus; - - return { - content: [], - }; - }, -); - -server.registerTool( - 'deleteTask', - { - title: 'Delete a task', - inputSchema: { id: z.string() }, - }, - ({ id }) => { - const task = idToTask.get(id); - if (!task) { - return { - isError: true, - content: [ - { - type: 'text', - text: 'No such task', - }, - ], - }; - } - idToTask.delete(id); - - return { - content: [ - { - type: 'text', - text: 'Task deleted', - }, - ], - }; - }, -); - -server.registerTool( - 'cancelTask', - { - title: 'Cancels a task', - inputSchema: { id: z.string() }, - }, - ({ id }) => { - const task = idToTask.get(id); - if (!task) { - return { - isError: true, - content: [ - { - type: 'text', - text: 'No such task', - }, - ], - }; - } - task.status.state = 'canceled'; - - return { - content: [ - { - type: 'text', - text: 'Task cancelled', - }, - ], - }; - }, -); - -const transport = new StdioServerTransport(); -await server.connect(transport); diff --git a/packages/examples/package.json b/packages/examples/package.json deleted file mode 100644 index 133d1b75..00000000 --- a/packages/examples/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "@google/gemini-cli-examples", - "version": "0.1.0", - "private": true, - "type": "module", - "scripts": { - "start:demo-background-agent": "tsx background_agent/demo-background-agent.ts", - "build": "echo 'nothing to build'" - }, - "dependencies": { - "@modelcontextprotocol/sdk": "1.15.1", - "zod": "^3.23.8" - }, - "devDependencies": { - "tsx": "^4.16.2" - } -}