aia 0.9.11 → 0.9.13

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +2 -0
  3. data/.version +1 -1
  4. data/CHANGELOG.md +66 -2
  5. data/README.md +133 -4
  6. data/docs/advanced-prompting.md +721 -0
  7. data/docs/cli-reference.md +582 -0
  8. data/docs/configuration.md +347 -0
  9. data/docs/contributing.md +332 -0
  10. data/docs/directives-reference.md +490 -0
  11. data/docs/examples/index.md +277 -0
  12. data/docs/examples/mcp/index.md +479 -0
  13. data/docs/examples/prompts/analysis/index.md +78 -0
  14. data/docs/examples/prompts/automation/index.md +108 -0
  15. data/docs/examples/prompts/development/index.md +125 -0
  16. data/docs/examples/prompts/index.md +333 -0
  17. data/docs/examples/prompts/learning/index.md +127 -0
  18. data/docs/examples/prompts/writing/index.md +62 -0
  19. data/docs/examples/tools/index.md +292 -0
  20. data/docs/faq.md +414 -0
  21. data/docs/guides/available-models.md +366 -0
  22. data/docs/guides/basic-usage.md +477 -0
  23. data/docs/guides/chat.md +474 -0
  24. data/docs/guides/executable-prompts.md +417 -0
  25. data/docs/guides/first-prompt.md +454 -0
  26. data/docs/guides/getting-started.md +455 -0
  27. data/docs/guides/image-generation.md +507 -0
  28. data/docs/guides/index.md +46 -0
  29. data/docs/guides/models.md +507 -0
  30. data/docs/guides/tools.md +856 -0
  31. data/docs/index.md +173 -0
  32. data/docs/installation.md +238 -0
  33. data/docs/mcp-integration.md +612 -0
  34. data/docs/prompt_management.md +579 -0
  35. data/docs/security.md +629 -0
  36. data/docs/tools-and-mcp-examples.md +1186 -0
  37. data/docs/workflows-and-pipelines.md +563 -0
  38. data/examples/tools/mcp/github_mcp_server.json +11 -0
  39. data/examples/tools/mcp/imcp.json +7 -0
  40. data/lib/aia/chat_processor_service.rb +38 -7
  41. data/lib/aia/config/base.rb +224 -0
  42. data/lib/aia/config/cli_parser.rb +418 -0
  43. data/lib/aia/config/defaults.rb +88 -0
  44. data/lib/aia/config/file_loader.rb +131 -0
  45. data/lib/aia/config/validator.rb +184 -0
  46. data/lib/aia/config.rb +10 -860
  47. data/lib/aia/directive_processor.rb +27 -372
  48. data/lib/aia/directives/configuration.rb +114 -0
  49. data/lib/aia/directives/execution.rb +37 -0
  50. data/lib/aia/directives/models.rb +178 -0
  51. data/lib/aia/directives/registry.rb +120 -0
  52. data/lib/aia/directives/utility.rb +70 -0
  53. data/lib/aia/directives/web_and_file.rb +71 -0
  54. data/lib/aia/prompt_handler.rb +23 -3
  55. data/lib/aia/ruby_llm_adapter.rb +367 -130
  56. data/lib/aia/session.rb +54 -18
  57. data/lib/aia/ui_presenter.rb +206 -0
  58. data/lib/aia/utility.rb +12 -8
  59. data/lib/aia.rb +11 -2
  60. data/lib/extensions/ruby_llm/.irbrc +56 -0
  61. data/mkdocs.yml +165 -0
  62. metadata +79 -37
  63. data/_notes.txt +0 -231
  64. /data/{images → docs/assets/images}/aia.png +0 -0
data/lib/aia/session.rb CHANGED
@@ -313,26 +313,39 @@ module AIA
313
313
  def handle_piped_input
314
314
  return if STDIN.tty?
315
315
 
316
- original_stdin = STDIN.dup
317
- piped_input = STDIN.read.strip
318
- STDIN.reopen("/dev/tty")
316
+ # Additional check: see if /dev/tty is available before attempting to use it
317
+ return unless File.exist?("/dev/tty") && File.readable?("/dev/tty") && File.writable?("/dev/tty")
319
318
 
320
- return if piped_input.empty?
319
+ begin
320
+ original_stdin = STDIN.dup
321
+ piped_input = STDIN.read.strip
322
+ STDIN.reopen("/dev/tty")
321
323
 
322
- @chat_prompt.text = piped_input
323
- processed_input = @chat_prompt.to_s
324
+ return if piped_input.empty?
324
325
 
325
- @context_manager.add_to_context(role: "user", content: processed_input)
326
+ @chat_prompt.text = piped_input
327
+ processed_input = @chat_prompt.to_s
326
328
 
327
- @ui_presenter.display_thinking_animation
328
- response = @chat_processor.process_prompt(@context_manager.get_context)
329
+ @context_manager.add_to_context(role: "user", content: processed_input)
329
330
 
330
- @context_manager.add_to_context(role: "assistant", content: response)
331
- @chat_processor.output_response(response)
332
- @chat_processor.speak(response) if AIA.speak?
333
- @ui_presenter.display_separator
331
+ @ui_presenter.display_thinking_animation
332
+ response = @chat_processor.process_prompt(@context_manager.get_context)
333
+
334
+ @context_manager.add_to_context(role: "assistant", content: response)
335
+ @chat_processor.output_response(response)
336
+ @chat_processor.speak(response) if AIA.speak?
337
+ @ui_presenter.display_separator
334
338
 
335
- STDIN.reopen(original_stdin)
339
+ STDIN.reopen(original_stdin)
340
+ rescue Errno::ENXIO => e
341
+ # Handle case where /dev/tty is not available (e.g., in some containerized environments)
342
+ warn "Warning: Unable to handle piped input due to TTY unavailability: #{e.message}"
343
+ return
344
+ rescue StandardError => e
345
+ # Handle any other errors gracefully
346
+ warn "Warning: Error handling piped input: #{e.message}"
347
+ return
348
+ end
336
349
  end
337
350
 
338
351
  def run_chat_loop
@@ -359,11 +372,34 @@ module AIA
359
372
  conversation = @context_manager.get_context
360
373
 
361
374
  @ui_presenter.display_thinking_animation
362
- response = @chat_processor.process_prompt(conversation)
375
+ response_data = @chat_processor.process_prompt(conversation)
376
+
377
+ # Handle new response format with metrics
378
+ if response_data.is_a?(Hash)
379
+ content = response_data[:content]
380
+ metrics = response_data[:metrics]
381
+ multi_metrics = response_data[:multi_metrics]
382
+ else
383
+ content = response_data
384
+ metrics = nil
385
+ multi_metrics = nil
386
+ end
363
387
 
364
- @ui_presenter.display_ai_response(response)
365
- @context_manager.add_to_context(role: "assistant", content: response)
366
- @chat_processor.speak(response)
388
+ @ui_presenter.display_ai_response(content)
389
+
390
+ # Display metrics if enabled and available (chat mode only)
391
+ if AIA.config.show_metrics
392
+ if multi_metrics
393
+ # Display metrics for each model in multi-model mode
394
+ @ui_presenter.display_multi_model_metrics(multi_metrics)
395
+ elsif metrics
396
+ # Display metrics for single model
397
+ @ui_presenter.display_token_metrics(metrics)
398
+ end
399
+ end
400
+
401
+ @context_manager.add_to_context(role: "assistant", content: content)
402
+ @chat_processor.speak(content)
367
403
 
368
404
  @ui_presenter.display_separator
369
405
  end
@@ -117,5 +117,211 @@ module AIA
117
117
  yield
118
118
  end
119
119
  end
120
+
121
+ def display_token_metrics(metrics)
122
+ return unless metrics
123
+
124
+ output_lines = []
125
+ output_lines << "═" * 55
126
+ output_lines << "Model: #{metrics[:model_id]}"
127
+
128
+ if AIA.config.show_cost
129
+ output_lines.concat(format_metrics_with_cost(metrics))
130
+ else
131
+ output_lines.concat(format_metrics_basic(metrics))
132
+ end
133
+
134
+ output_lines << "═" * 55
135
+
136
+ # Output to STDOUT
137
+ output_lines.each { |line| puts line }
138
+
139
+ # Also write to file if configured
140
+ if AIA.config.out_file && !AIA.config.out_file.nil?
141
+ File.open(AIA.config.out_file, 'a') do |file|
142
+ output_lines.each { |line| file.puts line }
143
+ end
144
+ end
145
+ end
146
+
147
+ def display_multi_model_metrics(metrics_list)
148
+ return unless metrics_list && !metrics_list.empty?
149
+
150
+ output_lines = []
151
+
152
+ # Determine table width based on whether costs are shown
153
+ if AIA.config.show_cost
154
+ table_width = 80
155
+ else
156
+ table_width = 60
157
+ end
158
+
159
+ output_lines << "═" * table_width
160
+ output_lines << "Multi-Model Token Usage"
161
+ output_lines << "─" * table_width
162
+
163
+ # Build header row
164
+ if AIA.config.show_cost
165
+ output_lines << sprintf("%-20s %10s %10s %10s %12s %10s",
166
+ "Model", "Input", "Output", "Total", "Cost", "x1000")
167
+ output_lines << "─" * table_width
168
+ else
169
+ output_lines << sprintf("%-20s %10s %10s %10s",
170
+ "Model", "Input", "Output", "Total")
171
+ output_lines << "─" * table_width
172
+ end
173
+
174
+ # Process each model
175
+ total_input = 0
176
+ total_output = 0
177
+ total_cost = 0.0
178
+
179
+ metrics_list.each do |metrics|
180
+ model_name = metrics[:model_id]
181
+ # Truncate model name if too long
182
+ model_name = model_name[0..17] + ".." if model_name.length > 19
183
+
184
+ input_tokens = metrics[:input_tokens] || 0
185
+ output_tokens = metrics[:output_tokens] || 0
186
+ total_tokens = input_tokens + output_tokens
187
+
188
+ if AIA.config.show_cost
189
+ cost_data = calculate_cost(metrics)
190
+ if cost_data[:available]
191
+ cost_str = "$#{'%.5f' % cost_data[:total_cost]}"
192
+ x1000_str = "$#{'%.2f' % (cost_data[:total_cost] * 1000)}"
193
+ total_cost += cost_data[:total_cost]
194
+ else
195
+ cost_str = "N/A"
196
+ x1000_str = "N/A"
197
+ end
198
+
199
+ output_lines << sprintf("%-20s %10d %10d %10d %12s %10s",
200
+ model_name, input_tokens, output_tokens, total_tokens, cost_str, x1000_str)
201
+ else
202
+ output_lines << sprintf("%-20s %10d %10d %10d",
203
+ model_name, input_tokens, output_tokens, total_tokens)
204
+ end
205
+
206
+ total_input += input_tokens
207
+ total_output += output_tokens
208
+ end
209
+
210
+ # Display totals row
211
+ output_lines << "─" * table_width
212
+ total_tokens = total_input + total_output
213
+
214
+ if AIA.config.show_cost && total_cost > 0
215
+ cost_str = "$#{'%.5f' % total_cost}"
216
+ x1000_str = "$#{'%.2f' % (total_cost * 1000)}"
217
+ output_lines << sprintf("%-20s %10d %10d %10d %12s %10s",
218
+ "TOTAL", total_input, total_output, total_tokens, cost_str, x1000_str)
219
+ else
220
+ output_lines << sprintf("%-20s %10d %10d %10d",
221
+ "TOTAL", total_input, total_output, total_tokens)
222
+ end
223
+
224
+ output_lines << "═" * table_width
225
+
226
+ # Output to STDOUT
227
+ output_lines.each { |line| puts line }
228
+
229
+ # Also write to file if configured
230
+ if AIA.config.out_file && !AIA.config.out_file.nil?
231
+ File.open(AIA.config.out_file, 'a') do |file|
232
+ output_lines.each { |line| file.puts line }
233
+ end
234
+ end
235
+ end
236
+
237
+ private
238
+
239
+ def display_metrics_basic(metrics)
240
+ puts "Input tokens: #{metrics[:input_tokens] || 'N/A'}"
241
+ puts "Output tokens: #{metrics[:output_tokens] || 'N/A'}"
242
+
243
+ if metrics[:input_tokens] && metrics[:output_tokens]
244
+ total = metrics[:input_tokens] + metrics[:output_tokens]
245
+ puts "Total tokens: #{total}"
246
+ end
247
+ end
248
+
249
+ def format_metrics_basic(metrics)
250
+ lines = []
251
+ lines << "Input tokens: #{metrics[:input_tokens] || 'N/A'}"
252
+ lines << "Output tokens: #{metrics[:output_tokens] || 'N/A'}"
253
+
254
+ if metrics[:input_tokens] && metrics[:output_tokens]
255
+ total = metrics[:input_tokens] + metrics[:output_tokens]
256
+ lines << "Total tokens: #{total}"
257
+ end
258
+
259
+ lines
260
+ end
261
+
262
+ def display_metrics_with_cost(metrics)
263
+ cost_data = calculate_cost(metrics)
264
+
265
+ if cost_data[:available]
266
+ puts "Input tokens: #{metrics[:input_tokens]} ($#{'%.5f' % cost_data[:input_cost]})"
267
+ puts "Output tokens: #{metrics[:output_tokens]} ($#{'%.5f' % cost_data[:output_cost]})"
268
+ puts "Total cost: $#{'%.5f' % cost_data[:total_cost]}"
269
+ puts "Cost x1000: $#{'%.2f' % (cost_data[:total_cost] * 1000)}"
270
+ else
271
+ puts "Input tokens: #{metrics[:input_tokens] || 'N/A'}"
272
+ puts "Output tokens: #{metrics[:output_tokens] || 'N/A'}"
273
+ total = (metrics[:input_tokens] || 0) + (metrics[:output_tokens] || 0)
274
+ puts "Total tokens: #{total}"
275
+ puts "Cost: N/A (pricing not available)"
276
+ end
277
+ end
278
+
279
+ def format_metrics_with_cost(metrics)
280
+ lines = []
281
+ cost_data = calculate_cost(metrics)
282
+
283
+ if cost_data[:available]
284
+ lines << "Input tokens: #{metrics[:input_tokens]} ($#{'%.5f' % cost_data[:input_cost]})"
285
+ lines << "Output tokens: #{metrics[:output_tokens]} ($#{'%.5f' % cost_data[:output_cost]})"
286
+ lines << "Total cost: $#{'%.5f' % cost_data[:total_cost]}"
287
+ lines << "Cost x1000: $#{'%.2f' % (cost_data[:total_cost] * 1000)}"
288
+ else
289
+ lines << "Input tokens: #{metrics[:input_tokens] || 'N/A'}"
290
+ lines << "Output tokens: #{metrics[:output_tokens] || 'N/A'}"
291
+ total = (metrics[:input_tokens] || 0) + (metrics[:output_tokens] || 0)
292
+ lines << "Total tokens: #{total}"
293
+ lines << "Cost: N/A (pricing not available)"
294
+ end
295
+
296
+ lines
297
+ end
298
+
299
+ def calculate_cost(metrics)
300
+ return { available: false } unless metrics[:model_id] && metrics[:input_tokens] && metrics[:output_tokens]
301
+
302
+ # Look up model info from RubyLLM
303
+ begin
304
+ model_info = RubyLLM::Models.find(metrics[:model_id])
305
+ return { available: false } unless model_info
306
+
307
+ input_price = model_info.input_price_per_million
308
+ output_price = model_info.output_price_per_million
309
+
310
+ return { available: false } unless input_price && output_price
311
+
312
+ input_cost = metrics[:input_tokens] * input_price / 1_000_000.0
313
+ output_cost = metrics[:output_tokens] * output_price / 1_000_000.0
314
+ total_cost = input_cost + output_cost
315
+
316
+ {
317
+ available: true,
318
+ input_cost: input_cost,
319
+ output_cost: output_cost,
320
+ total_cost: total_cost
321
+ }
322
+ rescue StandardError => e
323
+ { available: false, error: e.message }
324
+ end
325
+ end
120
326
  end
121
327
  end
data/lib/aia/utility.rb CHANGED
@@ -6,11 +6,15 @@ module AIA
6
6
  class Utility
7
7
  class << self
8
8
  def tools?
9
- !AIA.config.tool_names.empty?
9
+ AIA.config&.tool_names && !AIA.config.tool_names.empty?
10
+ end
11
+
12
+ def user_tools?
13
+ AIA.config&.tool_paths && !AIA.config.tool_paths.empty?
10
14
  end
11
15
 
12
16
  def supports_tools?
13
- AIA.config.client.model.supports_functions?
17
+ AIA.config&.client&.model&.supports_functions? || false
14
18
  end
15
19
 
16
20
 
@@ -28,15 +32,15 @@ module AIA
28
32
 
29
33
  , ,
30
34
  (\\____/) AI Assistant (v#{AIA::VERSION}) is Online
31
- (_oo_) #{AIA.config.model}#{supports_tools? ? ' (supports tools)' : ''}
32
- (O) using #{AIA.config.adapter} (v#{RubyLLM::VERSION}#{mcp_version})
35
+ (_oo_) #{AIA.config&.model || 'unknown-model'}#{supports_tools? ? ' (supports tools)' : ''}
36
+ (O) using #{AIA.config&.adapter || 'unknown-adapter'} (v#{RubyLLM::VERSION}#{mcp_version})
33
37
  __||__ \\) model db was last refreshed on
34
- [/______\\] / #{AIA.config.last_refresh}
35
- / \\__AI__/ \\/ #{tools? ? 'You can share my tools' : 'I did not bring any tools'}
38
+ [/______\\] / #{AIA.config&.last_refresh || 'unknown'}
39
+ / \\__AI__/ \\/ #{user_tools? ? 'I will also use your tools' : (tools? ? 'You can share my tools' : 'I did not bring any tools')}
36
40
  / /__\\
37
- (\\ /____\\ #{tools? ? 'My Toolbox contains:' : ''}
41
+ (\\ /____\\ #{user_tools? && tools? ? 'My Toolbox contains:' : ''}
38
42
  ROBOT
39
- if tools?
43
+ if user_tools? && tools?
40
44
  tool_names = AIA.config.respond_to?(:tool_names) ? AIA.config.tool_names : AIA.config.tools
41
45
  if tool_names && !tool_names.to_s.empty?
42
46
  puts WordWrapper::MinimumRaggedness.new(
data/lib/aia.rb CHANGED
@@ -89,8 +89,17 @@ module AIA
89
89
  build_flags
90
90
 
91
91
  # Load Fzf if fuzzy search is enabled and fzf is installed
92
- if @config.fuzzy && system('which fzf >/dev/null 2>&1')
93
- require_relative 'aia/fzf'
92
+ if @config.fuzzy
93
+ begin
94
+ # Cache fzf availability check for better performance
95
+ if system('which fzf >/dev/null 2>&1')
96
+ require_relative 'aia/fzf'
97
+ else
98
+ warn "Warning: Fuzzy search enabled but fzf not found. Install fzf for enhanced search capabilities."
99
+ end
100
+ rescue StandardError => e
101
+ warn "Warning: Failed to load fzf: #{e.message}"
102
+ end
94
103
  end
95
104
 
96
105
  prompt_handler = PromptHandler.new
@@ -0,0 +1,56 @@
1
+ require 'ruby_llm'
2
+ require_relative 'modalities'
3
+
4
+ RubyLLM.configure do |config|
5
+ config.openai_api_key = ENV['OPENAI_API_KEY']
6
+ end
7
+
8
+ C = RubyLLM::Chat.new
9
+ M = C.model.modalities
10
+
11
+ __END__
12
+
13
+ # I = ["text", "image", "pdf", "audio", "file"]
14
+ # O = ["text", "embeddings", "audio", "image", "moderation"]
15
+
16
+ # I.each do |i|
17
+ # puts '#'
18
+ # O.each do |o|
19
+ # puts <<~HEREDOC
20
+ # def #{i}_to_#{o}? = input.include?('#{i}') && output.include?('#{o}')
21
+ # HEREDOC
22
+ # end
23
+ # end
24
+
25
+
26
+
27
+ #
28
+ def text_to_text? = input.include?('text') && output.include?('text')
29
+ def text_to_embeddings? = input.include?('text') && output.include?('embeddings')
30
+ def text_to_audio? = input.include?('text') && output.include?('audio')
31
+ def text_to_image? = input.include?('text') && output.include?('image')
32
+ def text_to_moderation? = input.include?('text') && output.include?('moderation')
33
+ #
34
+ def image_to_text? = input.include?('image') && output.include?('text')
35
+ def image_to_embeddings? = input.include?('image') && output.include?('embeddings')
36
+ def image_to_audio? = input.include?('image') && output.include?('audio')
37
+ def image_to_image? = input.include?('image') && output.include?('image')
38
+ def image_to_moderation? = input.include?('image') && output.include?('moderation')
39
+ #
40
+ def pdf_to_text? = input.include?('pdf') && output.include?('text')
41
+ def pdf_to_embeddings? = input.include?('pdf') && output.include?('embeddings')
42
+ def pdf_to_audio? = input.include?('pdf') && output.include?('audio')
43
+ def pdf_to_image? = input.include?('pdf') && output.include?('image')
44
+ def pdf_to_moderation? = input.include?('pdf') && output.include?('moderation')
45
+ #
46
+ def audio_to_text? = input.include?('audio') && output.include?('text')
47
+ def audio_to_embeddings? = input.include?('audio') && output.include?('embeddings')
48
+ def audio_to_audio? = input.include?('audio') && output.include?('audio')
49
+ def audio_to_image? = input.include?('audio') && output.include?('image')
50
+ def audio_to_moderation? = input.include?('audio') && output.include?('moderation')
51
+ #
52
+ def file_to_text? = input.include?('file') && output.include?('text')
53
+ def file_to_embeddings? = input.include?('file') && output.include?('embeddings')
54
+ def file_to_audio? = input.include?('file') && output.include?('audio')
55
+ def file_to_image? = input.include?('file') && output.include?('image')
56
+ def file_to_moderation? = input.include?('file') && output.include?('moderation')
data/mkdocs.yml ADDED
@@ -0,0 +1,165 @@
1
+ # MkDocs Configuration for AIA Documentation
2
+ site_name: AIA - AI Assistant
3
+ site_description: A powerful CLI tool for dynamic prompt management and AI interaction
4
+ site_author: Dewayne VanHoozer
5
+ site_url: https://madbomber.github.io/aia
6
+ copyright: Copyright &copy; 2024 Dewayne VanHoozer
7
+
8
+ # Repository information
9
+ repo_name: madbomber/aia
10
+ repo_url: https://github.com/madbomber/aia
11
+ edit_uri: edit/main/docs/
12
+
13
+ # Configuration
14
+ theme:
15
+ name: material
16
+
17
+ # Color scheme - Default to light mode
18
+ palette:
19
+ # Palette toggle for light mode (default)
20
+ - scheme: default
21
+ primary: blue
22
+ accent: blue
23
+ toggle:
24
+ icon: material/brightness-7
25
+ name: Switch to dark mode
26
+
27
+ # Palette toggle for dark mode
28
+ - scheme: slate
29
+ primary: blue
30
+ accent: blue
31
+ toggle:
32
+ icon: material/brightness-4
33
+ name: Switch to light mode
34
+
35
+ # Typography
36
+ font:
37
+ text: Roboto
38
+ code: Roboto Mono
39
+
40
+ # Theme features
41
+ features:
42
+ # Navigation
43
+ - navigation.instant
44
+ - navigation.tracking
45
+ - navigation.tabs
46
+ - navigation.tabs.sticky
47
+ - navigation.sections
48
+ - navigation.path
49
+ - navigation.indexes
50
+ - navigation.top
51
+
52
+ # Table of contents
53
+ - toc.follow
54
+
55
+ # Search
56
+ - search.suggest
57
+ - search.highlight
58
+ - search.share
59
+
60
+ # Header
61
+ - header.autohide
62
+
63
+ # Content
64
+ - content.code.copy
65
+ - content.code.annotate
66
+ - content.tabs.link
67
+ - content.tooltips
68
+ - content.action.edit
69
+ - content.action.view
70
+
71
+ # Plugins
72
+ plugins:
73
+ - search:
74
+ separator: '[\s\-,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
75
+
76
+ # Extensions
77
+ markdown_extensions:
78
+ # Python Markdown
79
+ - abbr
80
+ - admonition
81
+ - attr_list
82
+ - def_list
83
+ - footnotes
84
+ - md_in_html
85
+ - toc:
86
+ permalink: true
87
+ title: On this page
88
+
89
+ # Python Markdown Extensions
90
+ - pymdownx.arithmatex:
91
+ generic: true
92
+ - pymdownx.betterem:
93
+ smart_enable: all
94
+ - pymdownx.caret
95
+ - pymdownx.details
96
+ - pymdownx.emoji:
97
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
98
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
99
+ - pymdownx.highlight:
100
+ anchor_linenums: true
101
+ line_spans: __span
102
+ pygments_lang_class: true
103
+ - pymdownx.inlinehilite
104
+ - pymdownx.keys
105
+ - pymdownx.magiclink:
106
+ repo_url_shorthand: true
107
+ user: madbomber
108
+ repo: aia
109
+ - pymdownx.mark
110
+ - pymdownx.smartsymbols
111
+ - pymdownx.superfences:
112
+ custom_fences:
113
+ - name: mermaid
114
+ class: mermaid
115
+ format: !!python/name:pymdownx.superfences.fence_code_format
116
+ - pymdownx.tabbed:
117
+ alternate_style: true
118
+ - pymdownx.tasklist:
119
+ custom_checkbox: true
120
+ - pymdownx.tilde
121
+
122
+ # Extra CSS and JavaScript
123
+ extra_css:
124
+ - assets/css/custom.css
125
+
126
+ extra_javascript:
127
+ - assets/js/mathjax.js
128
+ - https://polyfill.io/v3/polyfill.min.js?features=es6
129
+ - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js
130
+
131
+ # Social media and extra configuration
132
+ extra:
133
+ social:
134
+ - icon: fontawesome/brands/github
135
+ link: https://github.com/madbomber/aia
136
+ name: AIA on GitHub
137
+ - icon: fontawesome/solid/gem
138
+ link: https://rubygems.org/gems/aia
139
+ name: AIA on RubyGems
140
+
141
+ version:
142
+ provider: mike
143
+
144
+ # Navigation
145
+ nav:
146
+ - Home: index.md
147
+ - Installation: installation.md
148
+ - Configuration: configuration.md
149
+ - Guides:
150
+ - guides/index.md
151
+ - Getting Started: guides/getting-started.md
152
+ - Chat Mode: guides/chat.md
153
+ - Working with Models: guides/models.md
154
+ - Available Models: guides/available-models.md
155
+ - Image Generation: guides/image-generation.md
156
+ - Tools Integration: guides/tools.md
157
+ - Reference:
158
+ - CLI Parameters: cli-reference.md
159
+ - Directives: directives-reference.md
160
+ - Advanced:
161
+ - Prompt Management: prompt_management.md
162
+ - Advanced Prompting: advanced-prompting.md
163
+ - Workflows & Pipelines: workflows-and-pipelines.md
164
+ - MCP Integration: mcp-integration.md
165
+ - Tools & MCP Examples: tools-and-mcp-examples.md