tsikol 0.1.0

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 (75) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +22 -0
  3. data/CONTRIBUTING.md +84 -0
  4. data/LICENSE +21 -0
  5. data/README.md +579 -0
  6. data/Rakefile +12 -0
  7. data/docs/README.md +69 -0
  8. data/docs/api/middleware.md +721 -0
  9. data/docs/api/prompt.md +858 -0
  10. data/docs/api/resource.md +651 -0
  11. data/docs/api/server.md +509 -0
  12. data/docs/api/test-helpers.md +591 -0
  13. data/docs/api/tool.md +527 -0
  14. data/docs/cookbook/authentication.md +651 -0
  15. data/docs/cookbook/caching.md +877 -0
  16. data/docs/cookbook/dynamic-tools.md +970 -0
  17. data/docs/cookbook/error-handling.md +887 -0
  18. data/docs/cookbook/logging.md +1044 -0
  19. data/docs/cookbook/rate-limiting.md +717 -0
  20. data/docs/examples/code-assistant.md +922 -0
  21. data/docs/examples/complete-server.md +726 -0
  22. data/docs/examples/database-manager.md +1198 -0
  23. data/docs/examples/devops-tools.md +1382 -0
  24. data/docs/examples/echo-server.md +501 -0
  25. data/docs/examples/weather-service.md +822 -0
  26. data/docs/guides/completion.md +472 -0
  27. data/docs/guides/getting-started.md +462 -0
  28. data/docs/guides/middleware.md +823 -0
  29. data/docs/guides/project-structure.md +434 -0
  30. data/docs/guides/prompts.md +920 -0
  31. data/docs/guides/resources.md +720 -0
  32. data/docs/guides/sampling.md +804 -0
  33. data/docs/guides/testing.md +863 -0
  34. data/docs/guides/tools.md +627 -0
  35. data/examples/README.md +92 -0
  36. data/examples/advanced_features.rb +129 -0
  37. data/examples/basic-migrated/app/prompts/weather_chat.rb +44 -0
  38. data/examples/basic-migrated/app/resources/weather_alerts.rb +18 -0
  39. data/examples/basic-migrated/app/tools/get_current_weather.rb +34 -0
  40. data/examples/basic-migrated/app/tools/get_forecast.rb +30 -0
  41. data/examples/basic-migrated/app/tools/get_weather_by_coords.rb +48 -0
  42. data/examples/basic-migrated/server.rb +25 -0
  43. data/examples/basic.rb +73 -0
  44. data/examples/full_featured.rb +175 -0
  45. data/examples/middleware_example.rb +112 -0
  46. data/examples/sampling_example.rb +104 -0
  47. data/examples/weather-service/app/prompts/weather/chat.rb +90 -0
  48. data/examples/weather-service/app/resources/weather/alerts.rb +59 -0
  49. data/examples/weather-service/app/tools/weather/get_current.rb +82 -0
  50. data/examples/weather-service/app/tools/weather/get_forecast.rb +90 -0
  51. data/examples/weather-service/server.rb +28 -0
  52. data/exe/tsikol +6 -0
  53. data/lib/tsikol/cli/templates/Gemfile.erb +10 -0
  54. data/lib/tsikol/cli/templates/README.md.erb +38 -0
  55. data/lib/tsikol/cli/templates/gitignore.erb +49 -0
  56. data/lib/tsikol/cli/templates/prompt.rb.erb +53 -0
  57. data/lib/tsikol/cli/templates/resource.rb.erb +29 -0
  58. data/lib/tsikol/cli/templates/server.rb.erb +24 -0
  59. data/lib/tsikol/cli/templates/tool.rb.erb +60 -0
  60. data/lib/tsikol/cli.rb +203 -0
  61. data/lib/tsikol/error_handler.rb +141 -0
  62. data/lib/tsikol/health.rb +198 -0
  63. data/lib/tsikol/http_transport.rb +72 -0
  64. data/lib/tsikol/lifecycle.rb +149 -0
  65. data/lib/tsikol/middleware.rb +168 -0
  66. data/lib/tsikol/prompt.rb +101 -0
  67. data/lib/tsikol/resource.rb +53 -0
  68. data/lib/tsikol/router.rb +190 -0
  69. data/lib/tsikol/server.rb +660 -0
  70. data/lib/tsikol/stdio_transport.rb +108 -0
  71. data/lib/tsikol/test_helpers.rb +261 -0
  72. data/lib/tsikol/tool.rb +111 -0
  73. data/lib/tsikol/version.rb +5 -0
  74. data/lib/tsikol.rb +72 -0
  75. metadata +219 -0
@@ -0,0 +1,472 @@
1
+ # Completion Guide
2
+
3
+ Completion (autocomplete) provides intelligent suggestions for tool parameters and prompt arguments, enhancing the user experience.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Overview](#overview)
8
+ 2. [Basic Completion](#basic-completion)
9
+ 3. [Dynamic Completion](#dynamic-completion)
10
+ 4. [Advanced Patterns](#advanced-patterns)
11
+ 5. [CLI Generation](#cli-generation)
12
+ 6. [Best Practices](#best-practices)
13
+
14
+ ## Overview
15
+
16
+ Completion helps users by:
17
+ - Suggesting valid values for parameters
18
+ - Reducing typing errors
19
+ - Improving discoverability
20
+ - Providing context-aware suggestions
21
+
22
+ ## Basic Completion
23
+
24
+ ### Tool Parameter Completion
25
+
26
+ ```ruby
27
+ class FileManager < Tsikol::Tool
28
+ description "Manage files in the project"
29
+
30
+ parameter :action do
31
+ type :string
32
+ required
33
+ description "Action to perform"
34
+
35
+ # Static completion
36
+ complete do |partial|
37
+ actions = ["create", "delete", "rename", "copy", "move"]
38
+ actions.select { |a| a.start_with?(partial.downcase) }
39
+ end
40
+ end
41
+
42
+ parameter :file_type do
43
+ type :string
44
+ optional
45
+ description "Type of file"
46
+
47
+ # Filtered completion
48
+ complete do |partial|
49
+ types = ["ruby", "javascript", "python", "markdown", "json", "yaml"]
50
+ types.select { |t| t.include?(partial.downcase) }
51
+ end
52
+ end
53
+
54
+ def execute(action:, file_type: nil)
55
+ "Performing #{action} on #{file_type || 'all'} files"
56
+ end
57
+ end
58
+ ```
59
+
60
+ ### Prompt Argument Completion
61
+
62
+ ```ruby
63
+ class CodeAssistant < Tsikol::Prompt
64
+ name "code_assistant"
65
+ description "AI coding assistant"
66
+
67
+ argument :language do
68
+ type :string
69
+ required
70
+
71
+ complete do |partial|
72
+ languages = [
73
+ "ruby", "python", "javascript", "typescript",
74
+ "go", "rust", "java", "c++", "swift"
75
+ ]
76
+ languages.select { |lang| lang.start_with?(partial.downcase) }
77
+ end
78
+ end
79
+
80
+ argument :task do
81
+ type :string
82
+ required
83
+
84
+ complete do |partial|
85
+ tasks = [
86
+ "debug", "refactor", "optimize", "document",
87
+ "test", "review", "explain", "convert"
88
+ ]
89
+ tasks.select { |task| task.include?(partial.downcase) }
90
+ end
91
+ end
92
+
93
+ def get_messages(language:, task:)
94
+ [{
95
+ role: "user",
96
+ content: {
97
+ type: "text",
98
+ text: "Help me #{task} this #{language} code"
99
+ }
100
+ }]
101
+ end
102
+ end
103
+ ```
104
+
105
+ ## Dynamic Completion
106
+
107
+ ### File System Completion
108
+
109
+ ```ruby
110
+ class ProjectNavigator < Tsikol::Tool
111
+ description "Navigate project files"
112
+
113
+ parameter :path do
114
+ type :string
115
+ required
116
+
117
+ # Dynamic file system completion
118
+ complete do |partial|
119
+ # Expand home directory
120
+ expanded = partial.gsub('~', Dir.home)
121
+
122
+ # Get directory and file pattern
123
+ if expanded.include?('/')
124
+ dir = File.dirname(expanded)
125
+ pattern = File.basename(expanded)
126
+ else
127
+ dir = '.'
128
+ pattern = expanded
129
+ end
130
+
131
+ # Find matching files/directories
132
+ Dir.glob("#{dir}/#{pattern}*").map do |path|
133
+ # Add trailing slash for directories
134
+ File.directory?(path) ? "#{path}/" : path
135
+ end
136
+ end
137
+ end
138
+
139
+ def execute(path:)
140
+ File.read(path)
141
+ end
142
+ end
143
+ ```
144
+
145
+ ### Database-Driven Completion
146
+
147
+ ```ruby
148
+ class DatabaseQuery < Tsikol::Tool
149
+ description "Query the database"
150
+
151
+ parameter :table do
152
+ type :string
153
+ required
154
+
155
+ # Complete from database schema
156
+ complete do |partial|
157
+ # In real app, query database for table names
158
+ tables = fetch_table_names
159
+ tables.select { |t| t.downcase.start_with?(partial.downcase) }
160
+ end
161
+ end
162
+
163
+ parameter :column do
164
+ type :string
165
+ optional
166
+
167
+ # Context-aware completion based on selected table
168
+ complete do |partial, context|
169
+ # Context contains previously entered parameters
170
+ table = context[:table]
171
+ return [] unless table
172
+
173
+ columns = fetch_columns_for_table(table)
174
+ columns.select { |c| c.downcase.include?(partial.downcase) }
175
+ end
176
+ end
177
+
178
+ private
179
+
180
+ def fetch_table_names
181
+ # Mock implementation
182
+ ["users", "posts", "comments", "categories", "tags"]
183
+ end
184
+
185
+ def fetch_columns_for_table(table)
186
+ # Mock implementation
187
+ case table
188
+ when "users"
189
+ ["id", "name", "email", "created_at", "updated_at"]
190
+ when "posts"
191
+ ["id", "title", "content", "user_id", "published_at"]
192
+ else
193
+ ["id", "created_at", "updated_at"]
194
+ end
195
+ end
196
+ end
197
+ ```
198
+
199
+ ## Advanced Patterns
200
+
201
+ ### Hierarchical Completion
202
+
203
+ ```ruby
204
+ class CloudManager < Tsikol::Tool
205
+ description "Manage cloud resources"
206
+
207
+ parameter :provider do
208
+ type :string
209
+ required
210
+
211
+ complete do |partial|
212
+ ["aws", "gcp", "azure", "digitalocean"].select { |p|
213
+ p.start_with?(partial.downcase)
214
+ }
215
+ end
216
+ end
217
+
218
+ parameter :service do
219
+ type :string
220
+ required
221
+
222
+ # Completion depends on provider
223
+ complete do |partial, context|
224
+ services = case context[:provider]
225
+ when "aws"
226
+ ["ec2", "s3", "lambda", "rds", "dynamodb"]
227
+ when "gcp"
228
+ ["compute", "storage", "functions", "sql", "firestore"]
229
+ when "azure"
230
+ ["vm", "blob", "functions", "sql", "cosmos"]
231
+ else
232
+ []
233
+ end
234
+
235
+ services.select { |s| s.include?(partial.downcase) }
236
+ end
237
+ end
238
+
239
+ parameter :action do
240
+ type :string
241
+ required
242
+
243
+ # Multi-level context
244
+ complete do |partial, context|
245
+ actions = case [context[:provider], context[:service]]
246
+ when ["aws", "ec2"]
247
+ ["start", "stop", "reboot", "terminate", "describe"]
248
+ when ["aws", "s3"]
249
+ ["create-bucket", "delete-bucket", "upload", "download", "list"]
250
+ else
251
+ ["list", "describe", "create", "delete"]
252
+ end
253
+
254
+ actions.select { |a| a.start_with?(partial.downcase) }
255
+ end
256
+ end
257
+ end
258
+ ```
259
+
260
+ ### Async Completion
261
+
262
+ ```ruby
263
+ class APIClient < Tsikol::Tool
264
+ description "Call external APIs"
265
+
266
+ parameter :endpoint do
267
+ type :string
268
+ required
269
+
270
+ # Async completion from API
271
+ complete do |partial|
272
+ begin
273
+ # Cache results for performance
274
+ @endpoints_cache ||= fetch_available_endpoints
275
+ @endpoints_cache.select { |e| e.include?(partial) }
276
+ rescue => e
277
+ log :error, "Failed to fetch endpoints", data: { error: e.message }
278
+ [] # Return empty array on error
279
+ end
280
+ end
281
+ end
282
+
283
+ private
284
+
285
+ def fetch_available_endpoints
286
+ # In real app, this might call an API
287
+ [
288
+ "/api/v1/users",
289
+ "/api/v1/posts",
290
+ "/api/v1/comments",
291
+ "/api/v2/graphql"
292
+ ]
293
+ end
294
+ end
295
+ ```
296
+
297
+ ### Fuzzy Matching Completion
298
+
299
+ ```ruby
300
+ class CommandRunner < Tsikol::Tool
301
+ description "Run project commands"
302
+
303
+ parameter :command do
304
+ type :string
305
+ required
306
+
307
+ complete do |partial|
308
+ commands = [
309
+ "build:development",
310
+ "build:production",
311
+ "test:unit",
312
+ "test:integration",
313
+ "deploy:staging",
314
+ "deploy:production"
315
+ ]
316
+
317
+ # Fuzzy matching
318
+ commands.select do |cmd|
319
+ # Match if all characters in partial appear in order
320
+ pattern = partial.chars.join('.*')
321
+ cmd.match?(/#{pattern}/i)
322
+ end.sort_by do |cmd|
323
+ # Sort by similarity
324
+ levenshtein_distance(partial.downcase, cmd.downcase)
325
+ end
326
+ end
327
+ end
328
+
329
+ private
330
+
331
+ def levenshtein_distance(s, t)
332
+ # Simple implementation
333
+ m = s.length
334
+ n = t.length
335
+ return m if n == 0
336
+ return n if m == 0
337
+
338
+ d = Array.new(m+1) { Array.new(n+1) }
339
+
340
+ (0..m).each { |i| d[i][0] = i }
341
+ (0..n).each { |j| d[0][j] = j }
342
+
343
+ (1..n).each do |j|
344
+ (1..m).each do |i|
345
+ cost = s[i-1] == t[j-1] ? 0 : 1
346
+ d[i][j] = [
347
+ d[i-1][j] + 1,
348
+ d[i][j-1] + 1,
349
+ d[i-1][j-1] + cost
350
+ ].min
351
+ end
352
+ end
353
+
354
+ d[m][n]
355
+ end
356
+ end
357
+ ```
358
+
359
+ ## CLI Generation
360
+
361
+ When using the Tsikol CLI, completion hints are automatically added:
362
+
363
+ ```bash
364
+ # Generate a tool with string parameters
365
+ tsikol g tool file_manager action:string path:string
366
+
367
+ # The generated file includes completion templates:
368
+ parameter :action do
369
+ type :string
370
+ required
371
+ description "TODO: Add description for action"
372
+
373
+ # Add completion for better UX
374
+ # complete do |partial|
375
+ # # Return array of possible values
376
+ # options = ["option1", "option2", "option3"]
377
+ # options.select { |opt| opt.start_with?(partial) }
378
+ # end
379
+ end
380
+ ```
381
+
382
+ ## Best Practices
383
+
384
+ ### 1. Performance
385
+
386
+ ```ruby
387
+ # Cache expensive operations
388
+ complete do |partial|
389
+ @cached_values ||= expensive_fetch_operation
390
+ @cached_values.select { |v| v.include?(partial) }
391
+ end
392
+ ```
393
+
394
+ ### 2. Error Handling
395
+
396
+ ```ruby
397
+ complete do |partial|
398
+ begin
399
+ fetch_suggestions(partial)
400
+ rescue => e
401
+ log :error, "Completion failed", data: { error: e.message }
402
+ [] # Always return array
403
+ end
404
+ end
405
+ ```
406
+
407
+ ### 3. Limit Results
408
+
409
+ ```ruby
410
+ complete do |partial|
411
+ all_suggestions = fetch_all_suggestions
412
+ filtered = all_suggestions.select { |s| s.include?(partial) }
413
+ filtered.first(20) # Limit to prevent UI overload
414
+ end
415
+ ```
416
+
417
+ ### 4. Context Awareness
418
+
419
+ ```ruby
420
+ # Use context for dependent completions
421
+ complete do |partial, context|
422
+ # Access other parameter values
423
+ previous_value = context[:other_param]
424
+
425
+ suggestions_for(previous_value, partial)
426
+ end
427
+ ```
428
+
429
+ ### 5. User-Friendly Suggestions
430
+
431
+ ```ruby
432
+ complete do |partial|
433
+ suggestions = fetch_suggestions
434
+
435
+ # Sort by relevance
436
+ exact_matches = suggestions.select { |s| s.start_with?(partial) }
437
+ partial_matches = suggestions.select { |s|
438
+ s.include?(partial) && !s.start_with?(partial)
439
+ }
440
+
441
+ # Exact matches first, then partial matches
442
+ (exact_matches + partial_matches).uniq
443
+ end
444
+ ```
445
+
446
+ ## Testing Completions
447
+
448
+ ```ruby
449
+ require 'tsikol/test_helpers'
450
+
451
+ class CompletionTest < Minitest::Test
452
+ def test_tool_completion
453
+ client = Tsikol::TestHelpers::TestClient.new(server)
454
+
455
+ # Test completion
456
+ response = client.complete(
457
+ { type: "ref/tool", name: "file_manager" },
458
+ { name: "action", value: "cr" }
459
+ )
460
+
461
+ suggestions = response.dig(:result, :completion, :values)
462
+ assert_includes suggestions, "create"
463
+ assert_includes suggestions, "copy"
464
+ end
465
+ end
466
+ ```
467
+
468
+ ## Next Steps
469
+
470
+ - Learn about [Sampling](sampling.md) for AI assistance
471
+ - Explore [Advanced Features](../advanced-features.md)
472
+ - See [Complete Examples](../examples/)