mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-16 17:11:04 -07:00
93 lines
3.0 KiB
TypeScript
93 lines
3.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2026 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import { describe, it, expect } from 'vitest';
|
|
import { GeminiCliAgent } from './agent.js';
|
|
import { skillDir } from './skills.js';
|
|
import * as path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
// Set this to true locally when you need to update snapshots
|
|
const RECORD_MODE = process.env['RECORD_NEW_RESPONSES'] === 'true';
|
|
|
|
const getGoldenPath = (name: string) =>
|
|
path.resolve(__dirname, '../test-data', `${name}.json`);
|
|
|
|
const SKILL_DIR = path.resolve(__dirname, '../test-data/skills/pirate-skill');
|
|
const SKILL_ROOT = path.resolve(__dirname, '../test-data/skills');
|
|
|
|
describe('GeminiCliAgent Skills Integration', () => {
|
|
it('loads and activates a skill from a directory', async () => {
|
|
const goldenFile = getGoldenPath('skill-dir-success');
|
|
|
|
const agent = new GeminiCliAgent({
|
|
instructions: 'You are a helpful assistant.',
|
|
skills: [skillDir(SKILL_DIR)],
|
|
// If recording, use real model + record path.
|
|
// If testing, use auto model + fake path.
|
|
model: RECORD_MODE ? 'gemini-2.0-flash' : undefined,
|
|
recordResponses: RECORD_MODE ? goldenFile : undefined,
|
|
fakeResponses: RECORD_MODE ? undefined : goldenFile,
|
|
});
|
|
|
|
// 1. Ask to activate the skill
|
|
const events = [];
|
|
const session = agent.session();
|
|
// The prompt explicitly asks to activate the skill by name
|
|
const stream = session.sendStream(
|
|
'Activate the pirate-skill and then tell me a joke.',
|
|
);
|
|
|
|
for await (const event of stream) {
|
|
events.push(event);
|
|
}
|
|
|
|
const textEvents = events.filter((e) => e.type === 'content');
|
|
const responseText = textEvents
|
|
.map((e) => (typeof e.value === 'string' ? e.value : ''))
|
|
.join('');
|
|
|
|
// Expect pirate speak
|
|
expect(responseText.toLowerCase()).toContain('arrr');
|
|
}, 60000);
|
|
|
|
it('loads and activates a skill from a root', async () => {
|
|
const goldenFile = getGoldenPath('skill-root-success');
|
|
|
|
const agent = new GeminiCliAgent({
|
|
instructions: 'You are a helpful assistant.',
|
|
skills: [skillDir(SKILL_ROOT)],
|
|
// If recording, use real model + record path.
|
|
// If testing, use auto model + fake path.
|
|
model: RECORD_MODE ? 'gemini-2.0-flash' : undefined,
|
|
recordResponses: RECORD_MODE ? goldenFile : undefined,
|
|
fakeResponses: RECORD_MODE ? undefined : goldenFile,
|
|
});
|
|
|
|
// 1. Ask to activate the skill
|
|
const events = [];
|
|
const session = agent.session();
|
|
const stream = session.sendStream(
|
|
'Activate the pirate-skill and confirm it is active.',
|
|
);
|
|
|
|
for await (const event of stream) {
|
|
events.push(event);
|
|
}
|
|
|
|
const textEvents = events.filter((e) => e.type === 'content');
|
|
const responseText = textEvents
|
|
.map((e) => (typeof e.value === 'string' ? e.value : ''))
|
|
.join('');
|
|
|
|
// Expect confirmation or pirate speak
|
|
expect(responseText.toLowerCase()).toContain('arrr');
|
|
}, 60000);
|
|
});
|