girb 0.2.0 → 0.3.1

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.
data/README_ja.md CHANGED
@@ -1,38 +1,75 @@
1
1
  # girb (Generative IRB)
2
2
 
3
- IRBセッションに組み込まれたAIアシスタント。実行中のコンテキストを理解し、デバッグや開発を支援します。
3
+ Ruby開発のためのAIアシスタント。IRB、Rails console、debug gemで動作します。
4
4
 
5
5
  ## 特徴
6
6
 
7
- - **コンテキスト認識**: ローカル変数、インスタンス変数、selfオブジェクトなどを自動的に把握
8
- - **例外キャプチャ**: 直前の例外を自動キャプチャ - エラー後に「なぜ失敗した?」と聞くだけでOK
9
- - **セッション履歴の理解**: IRBでの入力履歴を追跡し、会話の流れを理解
10
- - **ツール実行**: コードの実行、オブジェクトの検査、ソースコードの取得などをAIが自律的に実行
11
- - **自律的な調査**: `continue_analysis`を使って、調査→実行→分析のサイクルをAIが自律的にループ可能
12
- - **debug gem統合**: Rubyのdebug gemと連携し、AIアシスタント付きのステップ実行デバッグが可能
13
- - **多言語対応**: ユーザーの言語を検出し、同じ言語で応答
14
- - **カスタマイズ可能**: 独自のプロンプトを追加して、プロジェクト固有の指示を設定可能
15
- - **プロバイダー非依存**: 任意のLLMプロバイダーを使用、または独自実装が可能
7
+ - **コンテキスト認識**: ローカル変数、インスタンス変数、実行時の状態を理解
8
+ - **ツール実行**: コード実行、オブジェクト検査、ファイル読み取りをAIが自律的に実行
9
+ - **自律的な調査**: 調査→実行→分析のサイクルをAIがループ
10
+ - **マルチ環境対応**: IRB、Rails console、debug gem (rdbg) で動作
11
+ - **プロバイダー非依存**: 任意のLLM(OpenAI、Anthropic、Gemini、Ollama等)を使用可能
16
12
 
17
- ## インストール
13
+ ## クイックスタート
18
14
 
19
- ### Railsプロジェクトの場合
15
+ ```bash
16
+ # 1. インストール
17
+ gem install girb girb-ruby_llm
20
18
 
21
- Gemfileに追加:
19
+ # 2. APIキーを設定
20
+ export GEMINI_API_KEY="your-api-key" # または OPENAI_API_KEY, ANTHROPIC_API_KEY
22
21
 
22
+ # 3. ~/.girbrc を作成
23
23
  ```ruby
24
- group :development do
25
- gem 'girb-ruby_llm' # または girb-gemini
24
+ require 'girb-ruby_llm'
25
+ Girb.configure do |c|
26
+ c.provider = Girb::Providers::RubyLlm.new(model: 'gemini-2.5-flash')
26
27
  end
27
28
  ```
28
29
 
29
- そして実行:
30
+ # 4. 実行
31
+ girb
32
+ ```
33
+
34
+ 質問を入力して **Ctrl+Space** を押すか、`qq <質問>` を使用します。
35
+
36
+ ## 目次
37
+
38
+ 1. [設定](#1-設定) - 全環境共通のセットアップ
39
+ 2. [Rubyスクリプト (IRB)](#2-rubyスクリプト-irb) - 純粋なRubyでの使用
40
+ 3. [Rails](#3-rails) - Rails consoleでの使用
41
+ 4. [Debug Gem (rdbg)](#4-debug-gem-rdbg) - AIアシスタント付きステップ実行デバッグ
42
+
43
+ ---
44
+
45
+ ## 1. 設定
46
+
47
+ ### インストール
30
48
 
31
49
  ```bash
32
- bundle install
50
+ gem install girb girb-ruby_llm
51
+ ```
52
+
53
+ 利用可能なプロバイダーgem:
54
+ - [girb-ruby_llm](https://github.com/rira100000000/girb-ruby_llm) - OpenAI、Anthropic、Gemini、Ollama等(推奨)
55
+ - [girb-gemini](https://github.com/rira100000000/girb-gemini) - Google Geminiのみ
56
+
57
+ ### APIキー
58
+
59
+ 使用するLLMプロバイダーのAPIキーを環境変数に設定:
60
+
61
+ ```bash
62
+ export GEMINI_API_KEY="your-api-key"
63
+ # または OPENAI_API_KEY, ANTHROPIC_API_KEY など
33
64
  ```
34
65
 
35
- プロジェクトルートに `.girbrc` ファイルを作成:
66
+ 詳細な設定方法(Ollama、その他のプロバイダー、高度なオプション)は、プロバイダーgemのドキュメントを参照してください:
67
+ - [girb-ruby_llm](https://github.com/rira100000000/girb-ruby_llm)
68
+ - [girb-gemini](https://github.com/rira100000000/girb-gemini)
69
+
70
+ ### .girbrcの作成
71
+
72
+ プロジェクトルート(またはホームディレクトリ)に `.girbrc` ファイルを作成:
36
73
 
37
74
  ```ruby
38
75
  # .girbrc
@@ -43,70 +80,104 @@ Girb.configure do |c|
43
80
  end
44
81
  ```
45
82
 
46
- これで `rails console` が自動的にgirbを読み込みます!
83
+ girbは以下の順序で `.girbrc` を探します:
84
+ 1. カレントディレクトリ → 親ディレクトリ(ルートまで)
85
+ 2. `~/.girbrc` にフォールバック
47
86
 
48
- ### 非Railsプロジェクトの場合
87
+ ### モデルの例
49
88
 
50
- グローバルにインストール:
89
+ ```ruby
90
+ # Google Gemini
91
+ c.provider = Girb::Providers::RubyLlm.new(model: 'gemini-2.5-flash')
51
92
 
52
- ```bash
53
- gem install girb girb-ruby_llm
93
+ # OpenAI
94
+ c.provider = Girb::Providers::RubyLlm.new(model: 'gpt-5.2-2025-12-11')
95
+
96
+ # Anthropic
97
+ c.provider = Girb::Providers::RubyLlm.new(model: 'claude-opus-4-5')
54
98
  ```
55
99
 
56
- プロジェクトディレクトリに `.girbrc` ファイルを作成:
100
+ ### 設定オプション
57
101
 
58
102
  ```ruby
59
- # .girbrc
60
- require 'girb-ruby_llm'
61
-
62
103
  Girb.configure do |c|
104
+ # 必須: LLMプロバイダー
63
105
  c.provider = Girb::Providers::RubyLlm.new(model: 'gemini-2.5-flash')
106
+
107
+ # オプション: デバッグ出力
108
+ c.debug = true
109
+
110
+ # オプション: カスタムシステムプロンプト
111
+ c.custom_prompt = <<~PROMPT
112
+ 破壊的操作の前に必ず確認してください。
113
+ PROMPT
64
114
  end
65
115
  ```
66
116
 
67
- `irb` の代わりに `girb` コマンドを使用します。
117
+ ### 環境変数(フォールバック)
68
118
 
69
- ## .girbrc の仕組み
119
+ `.girbrc` に設定がない場合に使用:
70
120
 
71
- girbは以下の順序で `.girbrc` を探します:
121
+ | 変数 | 説明 |
122
+ |------|------|
123
+ | `GIRB_PROVIDER` | プロバイダーgem(例: `girb-ruby_llm`) |
124
+ | `GIRB_MODEL` | モデル名(例: `gemini-2.5-flash`) |
125
+ | `GIRB_DEBUG` | `1` でデバッグ出力有効化 |
72
126
 
73
- 1. カレントディレクトリから親ディレクトリを遡って探索(ルートまで)
74
- 2. `~/.girbrc` にフォールバック
127
+ ### セッション永続化(オプション)
75
128
 
76
- これにより:
129
+ AIとの会話履歴をセッション間で保持できます。明示的にセッションIDを指定した場合のみ有効になります。
77
130
 
78
- - **プロジェクト固有の設定**: プロジェクトルートに `.girbrc` を配置
79
- - **共有設定**: 親ディレクトリに `.girbrc` を配置(例: `~/work/.girbrc` で仕事用プロジェクト全体に適用)
80
- - **グローバルデフォルト**: ホームディレクトリに `.girbrc` を配置
131
+ #### 有効化
81
132
 
82
- ## プロバイダー
133
+ `.girbrc` でセッションIDを設定:
83
134
 
84
- 現在利用可能なプロバイダー:
135
+ ```ruby
136
+ Girb.configure do |c|
137
+ c.provider = Girb::Providers::RubyLlm.new(model: 'gemini-2.5-flash')
138
+ end
85
139
 
86
- - [girb-ruby_llm](https://github.com/rira100000000/girb-ruby_llm) - RubyLLM経由で複数プロバイダー対応(OpenAI、Anthropic、Gemini、Ollama等)
87
- - [girb-gemini](https://github.com/rira100000000/girb-gemini) - Google Gemini
140
+ # セッション永続化を有効化(オプション)
141
+ Girb.debug_session = "my-project"
142
+ ```
88
143
 
89
- [独自プロバイダーの作成](#カスタムプロバイダー)も可能です。
144
+ または、コード内で動的に設定:
90
145
 
91
- ## 使い方
146
+ ```ruby
147
+ Girb.debug_session = "debug-user-auth"
148
+ debugger # このセッションの会話が保存される
149
+ ```
92
150
 
93
- ### Railsプロジェクトの場合
151
+ #### セッション管理コマンド
152
+
153
+ IRBまたはデバッグモードで使用:
94
154
 
95
- ```bash
96
- rails console
97
155
  ```
156
+ qq session status # 現在のセッション状態を表示
157
+ qq session list # 保存されたセッション一覧
158
+ qq session clear # 現在のセッションをクリア
159
+ ```
160
+
161
+ #### 動作
162
+
163
+ - セッションは `.girb/sessions/<session_id>.json` に保存
164
+ - 7日以上アクセスのないセッションは自動削除
165
+ - 同じセッションIDで再開すると、過去の会話を引き継ぎ
166
+ - `get_session_history` ツールで過去の会話を参照可能
167
+
168
+ ---
169
+
170
+ ## 2. Rubyスクリプト (IRB)
98
171
 
99
- Railtieにより自動的にgirbが読み込まれます。
172
+ ### 使い方
100
173
 
101
- ### 非Railsプロジェクトの場合
174
+ `irb` の代わりに `girb` コマンドを使用:
102
175
 
103
176
  ```bash
104
177
  girb
105
178
  ```
106
179
 
107
- ### binding.girbでデバッグ
108
-
109
- コード内に `binding.girb` を挿入:
180
+ または、コード内に `binding.girb` を挿入:
110
181
 
111
182
  ```ruby
112
183
  def problematic_method
@@ -116,111 +187,192 @@ def problematic_method
116
187
  end
117
188
  ```
118
189
 
119
- ### debug gem (rdbg) でデバッグ
190
+ ### AIへの質問方法
120
191
 
121
- AIアシスタント付きのステップ実行デバッグを行うには、スクリプトに `require "girb"` を追加:
192
+ **Ctrl+Space**: 質問を入力した後に押す
122
193
 
123
- ```ruby
124
- require "girb"
194
+ ```
195
+ irb(main):001> なぜ失敗したの?[Ctrl+Space]
196
+ ```
125
197
 
126
- def problematic_method
127
- result = some_calculation
128
- result
129
- end
198
+ **qqコマンド**: qqメソッドを使用
130
199
 
131
- problematic_method
132
200
  ```
201
+ irb(main):001> qq このメソッドの使い方を教えて
202
+ ```
203
+
204
+ ### 利用可能なツール (IRB)
205
+
206
+ | ツール | 説明 |
207
+ |--------|------|
208
+ | `evaluate_code` | Rubyコードを実行 |
209
+ | `inspect_object` | オブジェクトの詳細を検査 |
210
+ | `get_source` | メソッド/クラスのソースコードを取得 |
211
+ | `list_methods` | オブジェクトのメソッド一覧を取得 |
212
+ | `find_file` | ファイルを検索 |
213
+ | `read_file` | ファイル内容を読み取り |
214
+ | `get_session_history` | IRBセッション履歴を取得 |
215
+ | `continue_analysis` | 自律調査のためのコンテキスト更新をリクエスト |
216
+
217
+ ### 使用例
218
+
219
+ ```
220
+ irb(main):001> x = [1, 2, 3]
221
+ irb(main):002> 合計を求めるメソッドは?[Ctrl+Space]
222
+ `x.sum` で合計6が得られます。他にも `x.reduce(:+)` や `x.inject(0, :+)` が使えます。
223
+ ```
224
+
225
+ ---
226
+
227
+ ## 3. Rails
228
+
229
+ ### インストール
230
+
231
+ Gemfileに追加:
133
232
 
134
- rdbgで起動:
233
+ ```ruby
234
+ group :development do
235
+ gem 'girb'
236
+ gem 'girb-ruby_llm'
237
+ end
238
+ ```
135
239
 
136
240
  ```bash
137
- rdbg your_script.rb
241
+ bundle install
138
242
  ```
139
243
 
140
- デバッガ内では以下の方法でAIに質問できます:
141
- - `ai <質問>` - AIに質問
142
- - `Ctrl+Space` - 入力内容をAIに送信
143
- - 日本語(非ASCII文字)の入力は自動的にAIにルーティング
244
+ ### 設定
144
245
 
145
- AIは `step`、`next`、`continue` などのデバッガコマンドを実行したり、ブレークポイントを設定することもできます。
246
+ Railsプロジェクトルートに `.girbrc` を作成。詳細は[設定](#1-設定)を参照。
146
247
 
147
- ### AIへの質問方法
248
+ ### 使い方
249
+
250
+ `rails console` を実行するだけ - Railtieで自動的にgirbが読み込まれます:
148
251
 
149
- #### 方法1: Ctrl+Space
252
+ ```bash
253
+ rails console
254
+ ```
150
255
 
151
- 入力後に `Ctrl+Space` を押すと、その入力がAIへの質問として送信されます。
256
+ ### 追加ツール (Rails)
257
+
258
+ | ツール | 説明 |
259
+ |--------|------|
260
+ | `query_model` | ActiveRecordクエリを実行 |
261
+ | `model_info` | モデルのスキーマ情報を取得 |
262
+
263
+ ### 使用例
152
264
 
153
265
  ```
154
- irb(main):001> このエラーの原因は?[Ctrl+Space]
266
+ irb(main):001> user = User.find(1)
267
+ irb(main):002> user.update(name: "test")
268
+ => false
269
+ irb(main):003> なぜ更新に失敗したの?[Ctrl+Space]
270
+ `user.errors.full_messages` を確認したところ:
271
+ - "Email can't be blank"
272
+ 更新時にemail属性が空になっています。
155
273
  ```
156
274
 
157
- #### 方法2: qqコマンド
275
+ ---
158
276
 
277
+ ## 4. Debug Gem (rdbg)
278
+
279
+ AIアシスタント付きのステップ実行デバッグ。
280
+
281
+ ### 設定
282
+
283
+ 上記と同じ `.girbrc` を使用。
284
+
285
+ ### Rubyスクリプトの場合
286
+
287
+ `require "debug"` と `require "girb"` を追加し、`debugger`ステートメントを使用:
288
+
289
+ **注意:** `require "debug"` は必ず `require "girb"` より先に記述してください。
290
+
291
+ ```ruby
292
+ require "debug"
293
+ require "girb"
294
+
295
+ def calculate(x)
296
+ result = x * 2
297
+ debugger # ここでAIアシスタント付きで停止
298
+ result + 1
299
+ end
300
+
301
+ calculate(5)
159
302
  ```
160
- irb(main):001> qq "このメソッドの使い方を教えて"
303
+
304
+ rubyで実行:
305
+
306
+ ```bash
307
+ ruby your_script.rb
161
308
  ```
162
309
 
163
- ## 設定オプション
310
+ ### Railsの場合
164
311
 
165
- `.girbrc` に追加:
312
+ debug gemより後にgirbを読み込むためinitializerを作成:
166
313
 
167
314
  ```ruby
168
- require 'girb-ruby_llm'
315
+ # config/initializers/girb.rb
316
+ require "girb" if Rails.env.development? || Rails.env.test?
317
+ ```
169
318
 
170
- Girb.configure do |c|
171
- # デバッグ出力(デフォルト: false)
172
- c.debug = true
319
+ コード内で`debugger`ステートメントを使用:
173
320
 
174
- # カスタムプロンプト(オプション)
175
- c.custom_prompt = <<~PROMPT
176
- 本番環境です。破壊的操作の前に必ず確認してください。
177
- PROMPT
321
+ ```ruby
322
+ def show
323
+ @user = User.find(params[:id])
324
+ debugger # ここでAIアシスタント付きで停止
178
325
  end
179
326
  ```
180
327
 
181
- ### コマンドラインオプション
328
+ ### AIへの質問方法 (デバッグモード)
329
+
330
+ - **`qq <質問>`** - AIに質問
331
+ - **Ctrl+Space** - 現在の入力をAIに送信
332
+ - **日本語入力** - 非ASCII文字は自動的にAIにルーティング
182
333
 
183
- ```bash
184
- girb --debug # デバッグ出力を有効化
185
- girb -d # 同上
186
- girb --help # ヘルプを表示
334
+ ```
335
+ (rdbg) qq ここでのresultの値は?
336
+ (rdbg) 次の行に進んで[Ctrl+Space]
187
337
  ```
188
338
 
189
- ### 環境変数
339
+ ### AIがデバッガコマンドを実行
190
340
 
191
- `girb` コマンドでは、`.girbrc` が見つからない場合に環境変数で設定することもできます:
341
+ AIがデバッガコマンドを自動で実行できます:
192
342
 
193
- | 変数 | 説明 |
194
- |------|------|
195
- | `GIRB_PROVIDER` | 読み込むプロバイダーgem(例: `girb-ruby_llm`、`girb-gemini`) |
196
- | `GIRB_MODEL` | 使用するモデル(例: `gemini-2.5-flash`、`gpt-4o`) |
197
- | `GIRB_DEBUG` | `1`に設定するとデバッグ出力を有効化 |
343
+ ```
344
+ (rdbg) qq このループを実行して、xが1になるタイミングを教えて
345
+ ```
346
+
347
+ AIは `step`、`next`、`continue`、`break` などを自動的に使用します。
348
+
349
+ ### Ctrl+Cで中断
350
+
351
+ Ctrl+Cで長時間実行中のAI操作を中断できます。AIは進捗を要約します。
198
352
 
199
- ## AIが使用できるツール
353
+ ### 利用可能なツール (デバッグモード)
200
354
 
201
355
  | ツール | 説明 |
202
356
  |--------|------|
203
- | `evaluate_code` | IRBのコンテキストでRubyコードを実行 |
357
+ | `evaluate_code` | 現在のコンテキストでRubyコードを実行 |
204
358
  | `inspect_object` | オブジェクトの詳細を検査 |
205
- | `get_source` | メソッドやクラスのソースコードを取得 |
206
- | `list_methods` | オブジェクトのメソッド一覧を取得 |
207
- | `find_file` | プロジェクト内のファイルを検索 |
208
- | `read_file` | ファイルの内容を読み取り |
209
- | `session_history` | IRBセッションの履歴を取得 |
210
- | `continue_analysis` | 自律調査のためのコンテキスト更新をリクエスト |
359
+ | `get_source` | メソッド/クラスのソースコードを取得 |
360
+ | `read_file` | ソースファイルを読み取り |
361
+ | `run_debug_command` | デバッガコマンドを実行 |
362
+ | `get_session_history` | デバッグセッション履歴を取得 |
211
363
 
212
- ### Rails環境での追加ツール
364
+ ### 使用例: 変数の追跡
213
365
 
214
- | ツール | 説明 |
215
- |--------|------|
216
- | `query_model` | ActiveRecordモデルへのクエリ実行 |
217
- | `model_info` | モデルのスキーマ情報を取得 |
366
+ ```
367
+ (rdbg) qq このループでxの全ての値を追跡して、完了したら報告して
218
368
 
219
- ### デバッグモード (rdbg) での追加ツール
369
+ [AIがブレークポイントを設定、continueを実行、値を収集]
220
370
 
221
- | ツール | 説明 |
222
- |--------|------|
223
- | `run_debug_command` | デバッガコマンドを実行(step、next、continue、breakなど) |
371
+ 追跡したxの値: [7, 66, 85, 11, 53, 42, 99, 23]
372
+ ループが完了しました。
373
+ ```
374
+
375
+ ---
224
376
 
225
377
  ## カスタムプロバイダー
226
378
 
@@ -232,61 +384,26 @@ class MyProvider < Girb::Providers::Base
232
384
  @api_key = api_key
233
385
  end
234
386
 
235
- def chat(messages:, system_prompt:, tools:)
236
- # messages: { role: :user/:assistant/:tool_call/:tool_result, content: "..." } の配列
237
- # tools: { name: "...", description: "...", parameters: {...} } の配列
238
-
387
+ def chat(messages:, system_prompt:, tools:, binding: nil)
239
388
  # LLM APIを呼び出す
240
389
  response = call_my_llm(messages, system_prompt, tools)
241
390
 
242
- # Responseオブジェクトを返す
243
391
  Girb::Providers::Base::Response.new(
244
392
  text: response.text,
245
393
  function_calls: response.tool_calls&.map { |tc| { name: tc.name, args: tc.args } }
246
394
  )
247
395
  end
248
396
  end
249
-
250
- Girb.configure do |c|
251
- c.provider = MyProvider.new(api_key: ENV['MY_API_KEY'])
252
- end
253
397
  ```
254
398
 
255
- ## 使用例
256
-
257
- ### デバッグ支援
258
-
259
- ```
260
- irb(main):001> user = User.find(1)
261
- irb(main):002> user.update(name: "test")
262
- => false
263
- irb(main):003> なぜ更新に失敗したの?[Ctrl+Space]
264
- `user.errors.full_messages` を確認したところ、バリデーションエラーが発生しています:
265
- - "Email can't be blank"
266
- nameの更新時にemailが空になっている可能性があります。
267
- ```
268
-
269
- ### コードの理解
270
-
271
- ```
272
- irb(main):001> このプロジェクトでUserモデルはどこで定義されてる?[Ctrl+Space]
273
- app/models/user.rb で定義されています。
274
- ```
275
-
276
- ### パターン認識
277
-
278
- ```
279
- irb(main):001> a = 1
280
- irb(main):002> b = 2
281
- irb(main):003> c = 3以降も続けるとzはいくつ?[Ctrl+Space]
282
- パターン a=1, b=2, c=3... を続けると、z=26 になります。
283
- ```
399
+ ---
284
400
 
285
401
  ## 動作要件
286
402
 
287
403
  - Ruby 3.2.0以上
288
- - IRB 1.6.0以上
289
- - LLMプロバイダーgem(girb-ruby_llm または girb-gemini)
404
+ - IRB 1.6.0以上(IRB/Rails使用時)
405
+ - debug gem(rdbg使用時)
406
+ - LLMプロバイダーgem
290
407
 
291
408
  ## ライセンス
292
409
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative "auto_continue"
4
4
  require_relative "conversation_history"
5
+ require_relative "session_persistence"
5
6
  require_relative "providers/base"
6
7
  require_relative "debug_context_builder"
7
8
  require_relative "debug_prompt_builder"
@@ -35,6 +36,7 @@ module Girb
35
36
  else
36
37
  auto_continue_count = 0
37
38
  original_int_handler = setup_interrupt_handler
39
+ @debug_command_queued = false
38
40
 
39
41
  begin
40
42
  loop do
@@ -47,6 +49,12 @@ module Girb
47
49
 
48
50
  process_with_tools(tools)
49
51
 
52
+ # If a debug command was queued, exit immediately
53
+ # The command needs to be executed by IRB first, then DebugIntegration handles auto-continue
54
+ if @debug_command_queued
55
+ break
56
+ end
57
+
50
58
  # Check for interrupt after API call (Ctrl+C during request)
51
59
  if Girb::AutoContinue.interrupted?
52
60
  Girb::AutoContinue.clear_interrupt!
@@ -73,10 +81,17 @@ module Girb
73
81
  end
74
82
  ensure
75
83
  restore_interrupt_handler(original_int_handler)
76
- Girb::AutoContinue.reset!
84
+ # Only reset AutoContinue if no debug command was queued
85
+ # (it will be transferred to DebugIntegration in IrbDebugHook)
86
+ unless @debug_command_queued
87
+ Girb::AutoContinue.reset!
88
+ end
77
89
  Girb::AutoContinue.clear_interrupt!
78
90
  end
79
91
  end
92
+ ensure
93
+ # 毎ターン会話履歴を保存(クラッシュやexitでの消失を防止)
94
+ SessionPersistence.save_session
80
95
  end
81
96
 
82
97
  private
@@ -190,16 +205,19 @@ module Girb
190
205
  result: result
191
206
  }
192
207
 
193
- ConversationHistory.add_tool_call(tool_name, tool_args, result, id: tool_id)
208
+ ConversationHistory.add_tool_call(tool_name, tool_args, result, id: tool_id, metadata: function_call[:metadata])
194
209
 
195
210
  if Girb.configuration.debug && result.is_a?(Hash) && result[:error]
196
211
  puts "[girb] Tool error: #{result[:error]}"
197
212
  end
198
213
 
199
- # In debug mode, if run_debug_command was called, we need to exit
200
- # the tool loop so the debugger can execute the pending commands
201
- if @debug_mode && tool_name == "run_debug_command"
214
+ # If run_debug_command was called, we need to exit the tool loop
215
+ # so the debugger/IRB can execute the pending commands
216
+ if tool_name == "run_debug_command"
202
217
  debug_command_called = true
218
+ # In IRB mode, mark that we've queued a debug command
219
+ # This will prevent the auto-continue loop from continuing
220
+ @debug_command_queued = true unless @debug_mode
203
221
  end
204
222
  end
205
223
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Girb
4
4
  module AutoContinue
5
- MAX_ITERATIONS = 2
5
+ MAX_ITERATIONS = 20
6
6
 
7
7
  class << self
8
8
  def active?
@@ -22,8 +22,8 @@ module Girb
22
22
  instance.add_assistant_message(content)
23
23
  end
24
24
 
25
- def add_tool_call(tool_name, args, result, id: nil)
26
- instance.add_tool_call(tool_name, args, result, id: id)
25
+ def add_tool_call(tool_name, args, result, id: nil, metadata: nil)
26
+ instance.add_tool_call(tool_name, args, result, id: id, metadata: metadata)
27
27
  end
28
28
 
29
29
  def to_contents
@@ -72,13 +72,14 @@ module Girb
72
72
  end
73
73
  end
74
74
 
75
- def add_tool_call(tool_name, args, result, id: nil)
75
+ def add_tool_call(tool_name, args, result, id: nil, metadata: nil)
76
76
  @pending_tool_calls << {
77
77
  id: id || "call_#{SecureRandom.hex(12)}",
78
78
  name: tool_name,
79
79
  args: args,
80
- result: result
81
- }
80
+ result: result,
81
+ metadata: metadata
82
+ }.compact
82
83
  end
83
84
 
84
85
  def clear!
@@ -106,14 +107,18 @@ module Girb
106
107
 
107
108
  # Add tool calls and results if present
108
109
  msg.tool_calls&.each do |tc|
109
- result << { role: :tool_call, id: tc[:id], name: tc[:name], args: tc[:args] }
110
+ tool_call = { role: :tool_call, id: tc[:id], name: tc[:name], args: tc[:args] }
111
+ tool_call[:metadata] = tc[:metadata] if tc[:metadata]
112
+ result << tool_call
110
113
  result << { role: :tool_result, id: tc[:id], name: tc[:name], result: tc[:result] }
111
114
  end
112
115
  end
113
116
 
114
117
  # Add pending tool calls
115
118
  @pending_tool_calls.each do |tc|
116
- result << { role: :tool_call, id: tc[:id], name: tc[:name], args: tc[:args] }
119
+ tool_call = { role: :tool_call, id: tc[:id], name: tc[:name], args: tc[:args] }
120
+ tool_call[:metadata] = tc[:metadata] if tc[:metadata]
121
+ result << tool_call
117
122
  result << { role: :tool_result, id: tc[:id], name: tc[:name], result: tc[:result] }
118
123
  end
119
124