-
Notifications
You must be signed in to change notification settings - Fork 88
Expand file tree
/
Copy pathgemini.go
More file actions
152 lines (132 loc) · 4.31 KB
/
Copy pathgemini.go
File metadata and controls
152 lines (132 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
package agents
import (
"context"
_ "embed"
"time"
"github.com/kandev/kandev/internal/agent/usage"
"github.com/kandev/kandev/pkg/agent"
)
//go:embed logos/gemini_light.svg
var geminiLogoLight []byte
//go:embed logos/gemini_dark.svg
var geminiLogoDark []byte
const geminiPackage = "@google/gemini-cli"
var (
_ Agent = (*Gemini)(nil)
_ PassthroughAgent = (*Gemini)(nil)
_ InferenceAgent = (*Gemini)(nil)
_ ManagedNPMRuntimeAgent = (*Gemini)(nil)
)
type Gemini struct {
StandardPassthrough
}
func NewGemini() *Gemini {
return &Gemini{
StandardPassthrough: StandardPassthrough{
PermSettings: emptyPermSettings,
Cfg: PassthroughConfig{
Supported: true,
Label: "CLI Passthrough",
Description: "Show terminal directly instead of chat interface",
PassthroughCmd: NewCommand("npx", "--yes", "--prefer-offline", geminiPackage),
ModelFlag: NewParam("--model", "{model}"),
PromptFlag: NewParam("--prompt-interactive", "{prompt}"),
IdleTimeout: 3 * time.Second,
BufferMaxBytes: DefaultBufferMaxBytes,
ResumeFlag: NewParam("--resume", "latest"),
},
},
}
}
func (a *Gemini) ID() string { return "gemini" }
func (a *Gemini) Name() string { return "Google Gemini CLI Agent" }
func (a *Gemini) DisplayName() string { return "Gemini" }
func (a *Gemini) Description() string {
return "Google Gemini CLI-powered autonomous coding agent using ACP protocol."
}
func (a *Gemini) Enabled() bool { return true }
func (a *Gemini) DisplayOrder() int { return 5 }
func (a *Gemini) Logo(v LogoVariant) []byte {
if v == LogoDark {
return geminiLogoDark
}
return geminiLogoLight
}
func (a *Gemini) IsInstalled(ctx context.Context) (*DiscoveryResult, error) {
// Check for the gemini CLI on PATH. Auth state is surfaced later by the
// ACP probe, not by scanning ~/.gemini.
result, err := Detect(ctx, WithCommand("gemini"))
if err != nil {
return result, err
}
result.SupportsMCP = true
result.Capabilities = DiscoveryCapabilities{
SupportsSessionResume: true,
}
return result, nil
}
func (a *Gemini) BuildCommand(opts CommandOptions) Command {
return a.ManagedNPMRuntime().CachedACPCommand()
}
func (a *Gemini) ManagedNPMRuntime() ManagedNPMRuntimeSpec {
return ManagedNPMRuntimeSpec{Package: geminiPackage, ACPArgs: []string{"--acp"}}
}
func (a *Gemini) Runtime() *RuntimeConfig {
canRecover := false
return &RuntimeConfig{
Cmd: a.ManagedNPMRuntime().CachedACPCommand(),
WorkingDir: "{workspace}",
Env: map[string]string{},
ResourceLimits: ResourceLimits{MemoryMB: 4096, CPUCores: 2.0, Timeout: time.Hour},
Protocol: agent.ProtocolACP,
ProjectSkillDir: ".agents/skills",
SessionConfig: SessionConfig{
CanRecover: &canRecover,
SessionDirTemplate: "{home}/.gemini",
},
}
}
func (a *Gemini) RemoteAuth() *RemoteAuth {
return &RemoteAuth{
Methods: []RemoteAuthMethod{
{
Type: "files",
Label: "Copy auth files",
SourceFiles: map[string][]string{
"darwin": {".gemini/oauth_creds.json", ".gemini/settings.json", ".gemini/google_accounts.json"},
"linux": {".gemini/oauth_creds.json", ".gemini/settings.json", ".gemini/google_accounts.json"},
},
TargetRelDir: ".gemini",
},
{
Type: "env",
EnvVar: "GEMINI_API_KEY",
},
},
}
}
// Gemini has no dedicated login subcommand — the first run of `gemini` drops
// the user into the TUI's "Sign in with Google" flow. Spawn the bare CLI
// under the PTY so the user can complete that flow inline.
func (a *Gemini) LoginCommand() *LoginCommand {
return &LoginCommand{
Cmd: []string{"gemini"},
Description: "Sign in with your Google account (use the TUI's Sign in option, then quit).",
}
}
func (a *Gemini) InstallScript() string {
return "npm install -g " + geminiPackage
}
func (a *Gemini) BillingType() usage.BillingType { return defaultBillingType() }
func (a *Gemini) PermissionSettings() map[string]PermissionSetting {
return emptyPermSettings
}
// InferenceConfig returns configuration for one-shot inference using ACP.
// Gemini CLI speaks ACP natively via the --acp flag, so there's no separate
// _acp variant.
func (a *Gemini) InferenceConfig() *InferenceConfig {
return &InferenceConfig{
Supported: true,
Command: a.ManagedNPMRuntime().CachedACPCommand(),
}
}