feat(a2a): Introduce /memory command for a2a server (#14456)

Co-authored-by: Shreya Keshive <shreyakeshive@google.com>
This commit is contained in:
Coco Sheng
2026-01-12 16:46:42 -05:00
committed by GitHub
parent e049d5e4e8
commit d7bff8610f
9 changed files with 703 additions and 77 deletions

View File

@@ -5,8 +5,10 @@
*/
import {
getErrorMessage,
refreshServerHierarchicalMemory,
addMemory,
listMemoryFiles,
refreshMemory,
showMemory,
} from '@google/gemini-cli-core';
import { MessageType } from '../types.js';
import type { SlashCommand, SlashCommandActionReturn } from './types.js';
@@ -24,18 +26,14 @@ export const memoryCommand: SlashCommand = {
kind: CommandKind.BUILT_IN,
autoExecute: true,
action: async (context) => {
const memoryContent = context.services.config?.getUserMemory() || '';
const fileCount = context.services.config?.getGeminiMdFileCount() || 0;
const messageContent =
memoryContent.length > 0
? `Current memory content from ${fileCount} file(s):\n\n---\n${memoryContent}\n---`
: 'Memory is currently empty.';
const config = context.services.config;
if (!config) return;
const result = showMemory(config);
context.ui.addItem(
{
type: MessageType.INFO,
text: messageContent,
text: result.content,
},
Date.now(),
);
@@ -47,12 +45,10 @@ export const memoryCommand: SlashCommand = {
kind: CommandKind.BUILT_IN,
autoExecute: false,
action: (context, args): SlashCommandActionReturn | void => {
if (!args || args.trim() === '') {
return {
type: 'message',
messageType: 'error',
content: 'Usage: /memory add <text to remember>',
};
const result = addMemory(args);
if (result.type === 'message') {
return result;
}
context.ui.addItem(
@@ -63,11 +59,7 @@ export const memoryCommand: SlashCommand = {
Date.now(),
);
return {
type: 'tool',
toolName: 'save_memory',
toolArgs: { fact: args.trim() },
};
return result;
},
},
{
@@ -87,40 +79,21 @@ export const memoryCommand: SlashCommand = {
try {
const config = context.services.config;
if (config) {
let memoryContent = '';
let fileCount = 0;
if (config.isJitContextEnabled()) {
await config.getContextManager()?.refresh();
memoryContent = config.getUserMemory();
fileCount = config.getGeminiMdFileCount();
} else {
const result = await refreshServerHierarchicalMemory(config);
memoryContent = result.memoryContent;
fileCount = result.fileCount;
}
await config.updateSystemInstructionIfInitialized();
const successMessage =
memoryContent.length > 0
? `Memory refreshed successfully. Loaded ${memoryContent.length} characters from ${fileCount} file(s).`
: 'Memory refreshed successfully. No memory content found.';
const result = await refreshMemory(config);
context.ui.addItem(
{
type: MessageType.INFO,
text: successMessage,
text: result.content,
},
Date.now(),
);
}
} catch (error) {
const errorMessage = getErrorMessage(error);
context.ui.addItem(
{
type: MessageType.ERROR,
text: `Error refreshing memory: ${errorMessage}`,
text: `Error refreshing memory: ${(error as Error).message}`,
},
Date.now(),
);
@@ -133,18 +106,14 @@ export const memoryCommand: SlashCommand = {
kind: CommandKind.BUILT_IN,
autoExecute: true,
action: async (context) => {
const filePaths = context.services.config?.getGeminiMdFilePaths() || [];
const fileCount = filePaths.length;
const messageContent =
fileCount > 0
? `There are ${fileCount} GEMINI.md file(s) in use:\n\n${filePaths.join('\n')}`
: 'No GEMINI.md files in use.';
const config = context.services.config;
if (!config) return;
const result = listMemoryFiles(config);
context.ui.addItem(
{
type: MessageType.INFO,
text: messageContent,
text: result.content,
},
Date.now(),
);