cyrus-gemini-runner 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/README.md +411 -0
- package/dist/GeminiRunner.d.ts +136 -0
- package/dist/GeminiRunner.d.ts.map +1 -0
- package/dist/GeminiRunner.js +683 -0
- package/dist/GeminiRunner.js.map +1 -0
- package/dist/SimpleGeminiRunner.d.ts +27 -0
- package/dist/SimpleGeminiRunner.d.ts.map +1 -0
- package/dist/SimpleGeminiRunner.js +149 -0
- package/dist/SimpleGeminiRunner.js.map +1 -0
- package/dist/adapters.d.ts +37 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +317 -0
- package/dist/adapters.js.map +1 -0
- package/dist/formatter.d.ts +40 -0
- package/dist/formatter.d.ts.map +1 -0
- package/dist/formatter.js +363 -0
- package/dist/formatter.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/system.md +108 -0
- package/dist/schemas.d.ts +1472 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +678 -0
- package/dist/schemas.js.map +1 -0
- package/dist/settingsGenerator.d.ts +72 -0
- package/dist/settingsGenerator.d.ts.map +1 -0
- package/dist/settingsGenerator.js +255 -0
- package/dist/settingsGenerator.js.map +1 -0
- package/dist/systemPromptManager.d.ts +27 -0
- package/dist/systemPromptManager.d.ts.map +1 -0
- package/dist/systemPromptManager.js +65 -0
- package/dist/systemPromptManager.js.map +1 -0
- package/dist/types.d.ts +113 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
# @cyrus-ai/gemini-runner
|
|
2
|
+
|
|
3
|
+
A TypeScript wrapper around the Gemini CLI that provides a provider-agnostic interface for running Gemini AI sessions. This package mirrors the architecture of `@cyrus-ai/claude-runner` while adapting to Gemini CLI's streaming format and session management.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `gemini-runner` package provides two main classes:
|
|
8
|
+
|
|
9
|
+
- **GeminiRunner**: Full-featured wrapper around Gemini CLI with streaming support, event handling, and message format conversion
|
|
10
|
+
- **SimpleGeminiRunner**: Simplified interface for enumerated response use cases (yes/no, multiple choice, etc.)
|
|
11
|
+
|
|
12
|
+
Both classes implement standard interfaces from `cyrus-core`, making them interchangeable with other AI runner implementations like `ClaudeRunner`.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pnpm add @cyrus-ai/gemini-runner
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Prerequisites
|
|
21
|
+
|
|
22
|
+
1. **Gemini CLI**: Install the Gemini CLI and ensure it's in your PATH:
|
|
23
|
+
```bash
|
|
24
|
+
# Installation instructions depend on your platform
|
|
25
|
+
# Verify installation:
|
|
26
|
+
gemini --version
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
2. **Gemini API Credentials**: Configure your Gemini API credentials according to the Gemini CLI documentation.
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Basic Usage with GeminiRunner
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { GeminiRunner } from '@cyrus-ai/gemini-runner';
|
|
37
|
+
|
|
38
|
+
const runner = new GeminiRunner({
|
|
39
|
+
cyrusHome: '/path/to/.cyrus',
|
|
40
|
+
workingDirectory: '/path/to/project',
|
|
41
|
+
model: 'gemini-2.5-flash',
|
|
42
|
+
autoApprove: true // Enable --yolo flag
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Listen for events
|
|
46
|
+
runner.on('message', (message) => {
|
|
47
|
+
console.log('New message:', message);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
runner.on('complete', (messages) => {
|
|
51
|
+
console.log('Session complete! Total messages:', messages.length);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Start a session
|
|
55
|
+
await runner.start("Analyze this codebase and suggest improvements");
|
|
56
|
+
|
|
57
|
+
// Get all messages
|
|
58
|
+
const messages = runner.getMessages();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Simple Enumerated Responses with SimpleGeminiRunner
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { SimpleGeminiRunner } from '@cyrus-ai/gemini-runner';
|
|
65
|
+
|
|
66
|
+
const runner = new SimpleGeminiRunner({
|
|
67
|
+
validResponses: ['yes', 'no', 'maybe'],
|
|
68
|
+
cyrusHome: '/path/to/.cyrus',
|
|
69
|
+
workingDirectory: '/path/to/project',
|
|
70
|
+
model: 'gemini-2.5-flash',
|
|
71
|
+
maxTurns: 5,
|
|
72
|
+
onProgress: (event) => {
|
|
73
|
+
console.log(`Progress: ${event.type}`);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const result = await runner.query('Is this code correct?');
|
|
78
|
+
console.log(`Response: ${result.response}`); // Guaranteed to be 'yes', 'no', or 'maybe'
|
|
79
|
+
console.log(`Cost: $${result.cost.toFixed(4)}`);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Core Concepts
|
|
83
|
+
|
|
84
|
+
### GeminiRunner
|
|
85
|
+
|
|
86
|
+
`GeminiRunner` is the primary class for interacting with the Gemini CLI. It:
|
|
87
|
+
|
|
88
|
+
- Spawns the Gemini CLI process in headless mode (`--output-format stream-json`)
|
|
89
|
+
- Translates between Gemini CLI's JSON streaming format and Claude SDK message types
|
|
90
|
+
- Manages session lifecycle (start, stop, status)
|
|
91
|
+
- Provides event-based communication
|
|
92
|
+
- Creates detailed logs in both NDJSON and human-readable formats
|
|
93
|
+
- Supports both string prompts and streaming prompts
|
|
94
|
+
|
|
95
|
+
**Key Features**:
|
|
96
|
+
- **Provider-agnostic interface**: Implements `IAgentRunner` for compatibility with other runners
|
|
97
|
+
- **Event system**: Subscribe to `message`, `error`, `complete`, and `streamEvent` events
|
|
98
|
+
- **Streaming support**: Add messages incrementally with `addStreamMessage()`
|
|
99
|
+
- **Session management**: Track session state with `isRunning()` and `getMessages()`
|
|
100
|
+
- **MCP server support**: Configure Model Context Protocol servers (inherited from `IAgentRunner`)
|
|
101
|
+
|
|
102
|
+
### SimpleGeminiRunner
|
|
103
|
+
|
|
104
|
+
`SimpleGeminiRunner` extends `SimpleAgentRunner` to provide a streamlined interface for enumerated response scenarios:
|
|
105
|
+
|
|
106
|
+
- Validates responses against a predefined set of valid answers
|
|
107
|
+
- Handles timeout management automatically
|
|
108
|
+
- Cleans responses (removes markdown, code blocks, quotes)
|
|
109
|
+
- Emits progress events (thinking, tool-use, validating)
|
|
110
|
+
- Builds system prompts with valid response constraints
|
|
111
|
+
- Extracts cost information from result messages
|
|
112
|
+
|
|
113
|
+
**Use Cases**:
|
|
114
|
+
- Yes/No questions
|
|
115
|
+
- Multiple choice selection
|
|
116
|
+
- Status confirmations
|
|
117
|
+
- Classification tasks
|
|
118
|
+
|
|
119
|
+
## API Reference
|
|
120
|
+
|
|
121
|
+
### GeminiRunner
|
|
122
|
+
|
|
123
|
+
#### Constructor Options
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
interface GeminiRunnerConfig extends IAgentRunnerConfig {
|
|
127
|
+
// Gemini-specific options
|
|
128
|
+
geminiPath?: string; // Path to gemini CLI (default: 'gemini')
|
|
129
|
+
autoApprove?: boolean; // Enable --yolo flag (default: false)
|
|
130
|
+
approvalMode?: 'auto_edit' | 'auto' | 'manual'; // Approval mode
|
|
131
|
+
debug?: boolean; // Enable debug output
|
|
132
|
+
|
|
133
|
+
// Inherited from IAgentRunnerConfig
|
|
134
|
+
model?: string; // Model to use (e.g., 'gemini-2.5-flash')
|
|
135
|
+
cyrusHome: string; // Home directory for logs
|
|
136
|
+
workingDirectory: string; // Working directory for Gemini
|
|
137
|
+
systemPrompt?: string; // System prompt for session
|
|
138
|
+
mcpServers?: MCPServerConfig[]; // MCP server configurations
|
|
139
|
+
env?: Record<string, string>; // Environment variables
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Methods
|
|
144
|
+
|
|
145
|
+
**start(prompt: string): Promise<void>**
|
|
146
|
+
- Start a new session with a string prompt
|
|
147
|
+
- Throws if a session is already running
|
|
148
|
+
|
|
149
|
+
**startStreaming(initialPrompt?: string): Promise<void>**
|
|
150
|
+
- Start a new session with streaming input capability
|
|
151
|
+
- Optionally provide an initial prompt
|
|
152
|
+
- Use `addStreamMessage()` to add more messages
|
|
153
|
+
- Call `completeStream()` when done
|
|
154
|
+
|
|
155
|
+
**addStreamMessage(content: string): void**
|
|
156
|
+
- Add a message to an active streaming session
|
|
157
|
+
- Must be called after `startStreaming()`
|
|
158
|
+
|
|
159
|
+
**completeStream(): void**
|
|
160
|
+
- Signal the end of streaming input
|
|
161
|
+
- Session will continue processing
|
|
162
|
+
|
|
163
|
+
**stop(): Promise<void>**
|
|
164
|
+
- Terminate the current session
|
|
165
|
+
- Kills the Gemini CLI process
|
|
166
|
+
|
|
167
|
+
**getMessages(): SDKMessage[]**
|
|
168
|
+
- Retrieve all messages from the current session
|
|
169
|
+
- Returns both user and assistant messages
|
|
170
|
+
|
|
171
|
+
**isRunning(): boolean**
|
|
172
|
+
- Check if a session is currently active
|
|
173
|
+
|
|
174
|
+
#### Events
|
|
175
|
+
|
|
176
|
+
**'message'**: `(message: SDKMessage) => void`
|
|
177
|
+
- Emitted when a new message is received from Gemini
|
|
178
|
+
|
|
179
|
+
**'error'**: `(error: Error) => void`
|
|
180
|
+
- Emitted when an error occurs
|
|
181
|
+
|
|
182
|
+
**'complete'**: `(messages: SDKMessage[]) => void`
|
|
183
|
+
- Emitted when the session completes successfully
|
|
184
|
+
|
|
185
|
+
**'streamEvent'**: `(event: GeminiStreamEvent) => void`
|
|
186
|
+
- Emitted for raw Gemini CLI events (for debugging)
|
|
187
|
+
|
|
188
|
+
### SimpleGeminiRunner
|
|
189
|
+
|
|
190
|
+
#### Constructor Options
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
interface SimpleGeminiRunnerConfig {
|
|
194
|
+
validResponses: string[]; // REQUIRED: Valid response options
|
|
195
|
+
cyrusHome: string; // REQUIRED: Home directory for logs
|
|
196
|
+
workingDirectory?: string; // Working directory (default: cwd)
|
|
197
|
+
model?: string; // Model to use (default: 'gemini-2.5-flash')
|
|
198
|
+
systemPrompt?: string; // Additional system prompt
|
|
199
|
+
maxTurns?: number; // Max conversation turns (default: 10)
|
|
200
|
+
timeout?: number; // Timeout in ms (default: 300000)
|
|
201
|
+
onProgress?: (event: SimpleAgentProgressEvent) => void;
|
|
202
|
+
mcpServers?: MCPServerConfig[];
|
|
203
|
+
env?: Record<string, string>;
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Methods
|
|
208
|
+
|
|
209
|
+
**query(prompt: string, options?: SimpleAgentQueryOptions): Promise<SimpleAgentResult>**
|
|
210
|
+
- Execute a query and get a validated response
|
|
211
|
+
- Returns an object with `response`, `cost`, and `messages`
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
interface SimpleAgentResult {
|
|
215
|
+
response: string; // Validated response (one of validResponses)
|
|
216
|
+
cost: number; // Total cost in dollars
|
|
217
|
+
messages: SDKMessage[]; // All messages from session
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Adapter Pattern
|
|
222
|
+
|
|
223
|
+
The package uses an adapter pattern to translate between Gemini CLI's JSON streaming format and Claude SDK message types. This allows the runner to integrate seamlessly with other parts of the Cyrus ecosystem.
|
|
224
|
+
|
|
225
|
+
### Message Format Conversion
|
|
226
|
+
|
|
227
|
+
**Gemini Stream Events → SDK Messages**:
|
|
228
|
+
- `GeminiInitEvent` → Session ID extraction
|
|
229
|
+
- `GeminiMessageEvent` (user) → `SDKUserMessage`
|
|
230
|
+
- `GeminiMessageEvent` (assistant) → `SDKAssistantMessage`
|
|
231
|
+
- `GeminiToolUseEvent` → `SDKAssistantMessage` with `tool_use` content block
|
|
232
|
+
- `GeminiToolResultEvent` → `SDKUserMessage` with `tool_result` content block
|
|
233
|
+
- `GeminiResultEvent` (success) → `SDKAssistantMessage` with final response
|
|
234
|
+
|
|
235
|
+
**Key Differences from Claude**:
|
|
236
|
+
- Gemini uses simple `{type, role, content}` for messages
|
|
237
|
+
- SDK uses `{type, message: {role, content}, session_id, ...}` structure
|
|
238
|
+
- Tool use IDs are generated client-side for Gemini (`${tool_name}_${timestamp}`)
|
|
239
|
+
- Session ID is "pending" until init event is received from Gemini CLI
|
|
240
|
+
|
|
241
|
+
## Differences from ClaudeRunner
|
|
242
|
+
|
|
243
|
+
While `GeminiRunner` mirrors the architecture of `ClaudeRunner`, there are some key differences:
|
|
244
|
+
|
|
245
|
+
| Aspect | ClaudeRunner | GeminiRunner |
|
|
246
|
+
|--------|--------------|--------------|
|
|
247
|
+
| CLI Command | `claude --output-format ndjson` | `gemini --output-format stream-json` |
|
|
248
|
+
| Session ID | Generated client-side or via `--continue` | Assigned by CLI in init event |
|
|
249
|
+
| Stream Format | NDJSON with SDK-compatible messages | Custom JSON format requiring adapter |
|
|
250
|
+
| Tool Use IDs | Native SDK format | Generated client-side |
|
|
251
|
+
| Auto-Approval | Approval callbacks or flags | `--yolo` flag and `--approval-mode` |
|
|
252
|
+
| System Prompts | Native CLI support | Accepted in config (CLI handling TBD) |
|
|
253
|
+
|
|
254
|
+
## Supported Models
|
|
255
|
+
|
|
256
|
+
The package supports Gemini 2.5 and later models. Common model identifiers:
|
|
257
|
+
|
|
258
|
+
- `gemini-2.5-flash` - Fast, cost-effective model
|
|
259
|
+
- `gemini-2.5-pro` - Advanced reasoning and complex tasks
|
|
260
|
+
- Additional models as supported by the Gemini CLI
|
|
261
|
+
|
|
262
|
+
Specify the model in the configuration:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
const runner = new GeminiRunner({
|
|
266
|
+
model: 'gemini-2.5-flash',
|
|
267
|
+
// ... other options
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
## Configuration
|
|
272
|
+
|
|
273
|
+
### Environment Variables
|
|
274
|
+
|
|
275
|
+
The package respects standard Gemini CLI environment variables for API credentials. Refer to the Gemini CLI documentation for setup instructions.
|
|
276
|
+
|
|
277
|
+
### Log Files
|
|
278
|
+
|
|
279
|
+
Both runners create detailed logs in the `cyrusHome` directory:
|
|
280
|
+
|
|
281
|
+
- `{cyrusHome}/logs/{workspaceName}/{sessionId}.ndjson` - NDJSON event log
|
|
282
|
+
- `{cyrusHome}/logs/{workspaceName}/{sessionId}.log` - Human-readable log
|
|
283
|
+
|
|
284
|
+
### MCP Server Configuration
|
|
285
|
+
|
|
286
|
+
Configure Model Context Protocol servers for enhanced capabilities:
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
const runner = new GeminiRunner({
|
|
290
|
+
cyrusHome: '/path/to/.cyrus',
|
|
291
|
+
workingDirectory: '/path/to/project',
|
|
292
|
+
mcpServers: [
|
|
293
|
+
{
|
|
294
|
+
name: 'linear',
|
|
295
|
+
type: 'http',
|
|
296
|
+
url: 'https://mcp.linear.app',
|
|
297
|
+
headers: {
|
|
298
|
+
'Authorization': 'Bearer YOUR_TOKEN'
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
]
|
|
302
|
+
});
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Examples
|
|
306
|
+
|
|
307
|
+
See the `examples/` directory for complete working examples:
|
|
308
|
+
|
|
309
|
+
- `basic-usage.ts` - Basic GeminiRunner usage with event handling
|
|
310
|
+
- `simple-agent-example.ts` - SimpleGeminiRunner for enumerated responses
|
|
311
|
+
|
|
312
|
+
To run the examples:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
cd packages/gemini-runner
|
|
316
|
+
pnpm build
|
|
317
|
+
node examples/basic-usage.js # Or .ts with ts-node
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Troubleshooting
|
|
321
|
+
|
|
322
|
+
### Common Issues
|
|
323
|
+
|
|
324
|
+
**"gemini: command not found"**
|
|
325
|
+
- Ensure the Gemini CLI is installed and in your PATH
|
|
326
|
+
- Or specify the full path in the config: `geminiPath: '/path/to/gemini'`
|
|
327
|
+
|
|
328
|
+
**"Session already running"**
|
|
329
|
+
- You can only have one active session per GeminiRunner instance
|
|
330
|
+
- Call `stop()` before starting a new session, or create a new instance
|
|
331
|
+
|
|
332
|
+
**"Invalid response from Gemini"**
|
|
333
|
+
- Check that your validResponses match the expected output format
|
|
334
|
+
- Use the `onProgress` callback to see raw responses during validation
|
|
335
|
+
- Verify the system prompt is being respected by the model
|
|
336
|
+
|
|
337
|
+
**Empty messages array**
|
|
338
|
+
- The session may have errored before producing any messages
|
|
339
|
+
- Check the `error` event for details
|
|
340
|
+
- Review the log files in `{cyrusHome}/logs/`
|
|
341
|
+
|
|
342
|
+
**Response validation fails with SimpleGeminiRunner**
|
|
343
|
+
- Increase `maxTurns` to allow more attempts
|
|
344
|
+
- Simplify your `validResponses` list
|
|
345
|
+
- Check if the model is producing markdown or code blocks (automatically cleaned)
|
|
346
|
+
- Use `onProgress` to debug what responses are being received
|
|
347
|
+
|
|
348
|
+
**Timeout errors**
|
|
349
|
+
- Increase the `timeout` option (default: 300000ms / 5 minutes)
|
|
350
|
+
- Check if the Gemini CLI is hanging on approval prompts (use `autoApprove: true`)
|
|
351
|
+
- Verify your working directory is accessible and doesn't have permission issues
|
|
352
|
+
|
|
353
|
+
### Debug Mode
|
|
354
|
+
|
|
355
|
+
Enable debug mode for detailed logging:
|
|
356
|
+
|
|
357
|
+
```typescript
|
|
358
|
+
const runner = new GeminiRunner({
|
|
359
|
+
debug: true,
|
|
360
|
+
// ... other options
|
|
361
|
+
});
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Log Analysis
|
|
365
|
+
|
|
366
|
+
Check the NDJSON log files for detailed event information:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
cat ~/.cyrus/logs/my-workspace/{session-id}.ndjson | jq .
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Or the human-readable log:
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
cat ~/.cyrus/logs/my-workspace/{session-id}.log
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## Development
|
|
379
|
+
|
|
380
|
+
### Building
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
pnpm build
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Running Tests
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
pnpm test # Watch mode
|
|
390
|
+
pnpm test:run # Run once
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### Type Checking
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
pnpm typecheck
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Related Packages
|
|
400
|
+
|
|
401
|
+
- `@cyrus-ai/core` - Core types and interfaces
|
|
402
|
+
- `@cyrus-ai/claude-runner` - Claude CLI wrapper (similar architecture)
|
|
403
|
+
- `@cyrus-ai/simple-agent-runner` - Abstract base for simple enumerated responses
|
|
404
|
+
|
|
405
|
+
## License
|
|
406
|
+
|
|
407
|
+
MIT
|
|
408
|
+
|
|
409
|
+
## Support
|
|
410
|
+
|
|
411
|
+
For issues and feature requests, please use the project's issue tracker.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import { type IAgentRunner, type IMessageFormatter, type SDKAssistantMessage, type SDKMessage } from "cyrus-core";
|
|
3
|
+
import type { GeminiRunnerConfig, GeminiRunnerEvents, GeminiSessionInfo } from "./types.js";
|
|
4
|
+
export declare interface GeminiRunner {
|
|
5
|
+
on<K extends keyof GeminiRunnerEvents>(event: K, listener: GeminiRunnerEvents[K]): this;
|
|
6
|
+
emit<K extends keyof GeminiRunnerEvents>(event: K, ...args: Parameters<GeminiRunnerEvents[K]>): boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Manages Gemini CLI sessions and communication
|
|
10
|
+
*
|
|
11
|
+
* GeminiRunner implements the IAgentRunner interface to provide a provider-agnostic
|
|
12
|
+
* wrapper around the Gemini CLI. It spawns the Gemini CLI process in headless mode
|
|
13
|
+
* and translates between the CLI's JSON streaming format and Claude SDK message types.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const runner = new GeminiRunner({
|
|
18
|
+
* cyrusHome: '/home/user/.cyrus',
|
|
19
|
+
* workingDirectory: '/path/to/repo',
|
|
20
|
+
* model: 'gemini-2.5-flash',
|
|
21
|
+
* autoApprove: true
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // String mode
|
|
25
|
+
* await runner.start("Analyze this codebase");
|
|
26
|
+
*
|
|
27
|
+
* // Streaming mode
|
|
28
|
+
* await runner.startStreaming("Initial task");
|
|
29
|
+
* runner.addStreamMessage("Additional context");
|
|
30
|
+
* runner.completeStream();
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class GeminiRunner extends EventEmitter implements IAgentRunner {
|
|
34
|
+
/**
|
|
35
|
+
* GeminiRunner does not support true streaming input.
|
|
36
|
+
* While startStreaming() exists, it only accepts an initial prompt and does not support
|
|
37
|
+
* addStreamMessage() for adding messages after the session starts.
|
|
38
|
+
*/
|
|
39
|
+
readonly supportsStreamingInput = false;
|
|
40
|
+
private config;
|
|
41
|
+
private process;
|
|
42
|
+
private sessionInfo;
|
|
43
|
+
private logStream;
|
|
44
|
+
private readableLogStream;
|
|
45
|
+
private messages;
|
|
46
|
+
private streamingPrompt;
|
|
47
|
+
private cyrusHome;
|
|
48
|
+
private accumulatingMessage;
|
|
49
|
+
private accumulatingRole;
|
|
50
|
+
private lastAssistantMessage;
|
|
51
|
+
private settingsCleanup;
|
|
52
|
+
private systemPromptManager;
|
|
53
|
+
private formatter;
|
|
54
|
+
private readlineInterface;
|
|
55
|
+
private pendingResultMessage;
|
|
56
|
+
constructor(config: GeminiRunnerConfig);
|
|
57
|
+
/**
|
|
58
|
+
* Start a new Gemini session with string prompt (legacy mode)
|
|
59
|
+
*/
|
|
60
|
+
start(prompt: string): Promise<GeminiSessionInfo>;
|
|
61
|
+
/**
|
|
62
|
+
* Start a new Gemini session with streaming input
|
|
63
|
+
*/
|
|
64
|
+
startStreaming(initialPrompt?: string): Promise<GeminiSessionInfo>;
|
|
65
|
+
/**
|
|
66
|
+
* Add a message to the streaming prompt (only works when in streaming mode)
|
|
67
|
+
*/
|
|
68
|
+
addStreamMessage(content: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Complete the streaming prompt (no more messages will be added)
|
|
71
|
+
*/
|
|
72
|
+
completeStream(): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get the last assistant message (used for result coercion)
|
|
75
|
+
*/
|
|
76
|
+
getLastAssistantMessage(): SDKAssistantMessage | null;
|
|
77
|
+
/**
|
|
78
|
+
* Internal method to start a Gemini session with either string or streaming prompt
|
|
79
|
+
*/
|
|
80
|
+
private startWithPrompt;
|
|
81
|
+
/**
|
|
82
|
+
* Process a Gemini stream event and convert to SDK message
|
|
83
|
+
*/
|
|
84
|
+
private processStreamEvent;
|
|
85
|
+
/**
|
|
86
|
+
* Accumulate a delta message (message with delta: true)
|
|
87
|
+
*/
|
|
88
|
+
private accumulateDeltaMessage;
|
|
89
|
+
/**
|
|
90
|
+
* Flush the accumulated delta message
|
|
91
|
+
*/
|
|
92
|
+
private flushAccumulatedMessage;
|
|
93
|
+
/**
|
|
94
|
+
* Emit a message (add to messages array, log, and emit event)
|
|
95
|
+
*/
|
|
96
|
+
private emitMessage;
|
|
97
|
+
/**
|
|
98
|
+
* Stop the current Gemini session
|
|
99
|
+
*/
|
|
100
|
+
stop(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Check if the session is currently running
|
|
103
|
+
*/
|
|
104
|
+
isRunning(): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Get all messages from the current session
|
|
107
|
+
*/
|
|
108
|
+
getMessages(): SDKMessage[];
|
|
109
|
+
/**
|
|
110
|
+
* Get the message formatter for this runner
|
|
111
|
+
*/
|
|
112
|
+
getFormatter(): IMessageFormatter;
|
|
113
|
+
/**
|
|
114
|
+
* Build MCP servers configuration from config paths and inline config
|
|
115
|
+
*
|
|
116
|
+
* MCP configuration loading follows a layered approach:
|
|
117
|
+
* 1. Auto-detect .mcp.json in working directory (base config)
|
|
118
|
+
* 2. Load from explicitly configured paths via mcpConfigPath (extends/overrides)
|
|
119
|
+
* 3. Merge inline mcpConfig (highest priority, overrides file configs)
|
|
120
|
+
*
|
|
121
|
+
* HTTP-based MCP servers (like Linear's https://mcp.linear.app/mcp) are filtered out
|
|
122
|
+
* since Gemini CLI only supports stdio (command-based) MCP servers.
|
|
123
|
+
*
|
|
124
|
+
* @returns Record of MCP server name to GeminiMcpServerConfig
|
|
125
|
+
*/
|
|
126
|
+
private buildMcpServers;
|
|
127
|
+
/**
|
|
128
|
+
* Set up logging streams for this session
|
|
129
|
+
*/
|
|
130
|
+
private setupLogging;
|
|
131
|
+
/**
|
|
132
|
+
* Write a human-readable log entry for a message
|
|
133
|
+
*/
|
|
134
|
+
private writeReadableLogEntry;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=GeminiRunner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GeminiRunner.d.ts","sourceRoot":"","sources":["../src/GeminiRunner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAIf,MAAM,YAAY,CAAC;AAepB,OAAO,KAAK,EAEX,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,OAAO,WAAW,YAAY;IACpC,EAAE,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACpC,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC7B,IAAI,CAAC;IACR,IAAI,CAAC,CAAC,SAAS,MAAM,kBAAkB,EACtC,KAAK,EAAE,CAAC,EACR,GAAG,IAAI,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC;CACX;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,YAAa,SAAQ,YAAa,YAAW,YAAY;IACrE;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,SAAS;IAExC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,WAAW,CAAkC;IACrD,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,iBAAiB,CAA4B;IACrD,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO,CAAC,mBAAmB,CAA2B;IACtD,OAAO,CAAC,gBAAgB,CAAqC;IAE7D,OAAO,CAAC,oBAAoB,CAAoC;IAEhE,OAAO,CAAC,eAAe,CAA6B;IAEpD,OAAO,CAAC,mBAAmB,CAAsB;IAEjD,OAAO,CAAC,SAAS,CAAoB;IAErC,OAAO,CAAC,iBAAiB,CAAmD;IAE5E,OAAO,CAAC,oBAAoB,CAA2B;gBAE3C,MAAM,EAAE,kBAAkB;IAmBtC;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIvD;;OAEG;IACG,cAAc,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIxE;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAmBvC;;OAEG;IACH,cAAc,IAAI,IAAI;IAWtB;;OAEG;IACH,uBAAuB,IAAI,mBAAmB,GAAG,IAAI;IAIrD;;OAEG;YACW,eAAe;IAsU7B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgE1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAoD9B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAiB/B;;OAEG;IACH,OAAO,CAAC,WAAW;IAsBnB;;OAEG;IACH,IAAI,IAAI,IAAI;IAqCZ;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,WAAW,IAAI,UAAU,EAAE;IAI3B;;OAEG;IACH,YAAY,IAAI,iBAAiB;IAIjC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,eAAe;IA+CvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAgDpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAiB7B"}
|