smart_prompt 0.4.4 → 0.5.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 (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -10
  3. data/README.cn.md +307 -64
  4. data/README.md +311 -64
  5. data/Rakefile +10 -1
  6. data/config/anthropic_config.yml +151 -0
  7. data/config/image_generation_config.yml +22 -0
  8. data/config/multimodal_config.yml +85 -0
  9. data/config/sensenova_config.yml +63 -0
  10. data/config/zhipu_config.yml +73 -0
  11. data/examples/anthropic_basic_chat.rb +143 -0
  12. data/examples/anthropic_example.rb +232 -0
  13. data/examples/anthropic_multimodal.rb +212 -0
  14. data/examples/anthropic_streaming.rb +312 -0
  15. data/examples/anthropic_tool_calling.rb +393 -0
  16. data/examples/automatic_cleanup_example.rb +109 -0
  17. data/examples/history_management_examples.rb +522 -0
  18. data/examples/image_generation_example.rb +130 -0
  19. data/examples/monitoring_example.rb +121 -0
  20. data/examples/multimodal_example.rb +63 -0
  21. data/examples/relevance_based_strategy_example.rb +87 -0
  22. data/examples/sensenova_example.rb +129 -0
  23. data/examples/stt_example.rb +287 -0
  24. data/examples/tts_example.rb +244 -0
  25. data/examples/video_generation_example.rb +189 -0
  26. data/examples/zhipu_example.rb +151 -0
  27. data/lib/smart_prompt/anthropic_adapter.rb +363 -281
  28. data/lib/smart_prompt/compression_engine.rb +201 -0
  29. data/lib/smart_prompt/context_strategy.rb +22 -0
  30. data/lib/smart_prompt/conversation.rb +81 -191
  31. data/lib/smart_prompt/engine.rb +36 -19
  32. data/lib/smart_prompt/history_manager.rb +596 -0
  33. data/lib/smart_prompt/hybrid_strategy.rb +222 -0
  34. data/lib/smart_prompt/image_generation_adapter.rb +297 -0
  35. data/lib/smart_prompt/lru_cache.rb +133 -0
  36. data/lib/smart_prompt/message.rb +57 -0
  37. data/lib/smart_prompt/multimodal_adapter.rb +277 -0
  38. data/lib/smart_prompt/openai_adapter.rb +1 -25
  39. data/lib/smart_prompt/persistence_layer.rb +197 -0
  40. data/lib/smart_prompt/relevance_based_strategy.rb +221 -0
  41. data/lib/smart_prompt/sensenova_adapter.rb +410 -0
  42. data/lib/smart_prompt/session.rb +140 -0
  43. data/lib/smart_prompt/sliding_window_strategy.rb +100 -0
  44. data/lib/smart_prompt/stt_adapter.rb +381 -0
  45. data/lib/smart_prompt/summary_based_strategy.rb +152 -0
  46. data/lib/smart_prompt/token_counter.rb +74 -0
  47. data/lib/smart_prompt/tts_adapter.rb +403 -0
  48. data/lib/smart_prompt/version.rb +1 -1
  49. data/lib/smart_prompt/video_generation_adapter.rb +330 -0
  50. data/lib/smart_prompt/worker.rb +25 -3
  51. data/lib/smart_prompt/zhipu_adapter.rb +616 -0
  52. data/lib/smart_prompt.rb +22 -2
  53. data/workers/history_management_examples.rb +407 -0
  54. data/workers/image_generation_workers.rb +119 -0
  55. data/workers/multimodal_workers.rb +110 -0
  56. data/workers/sensenova_workers.rb +62 -0
  57. data/workers/stt_workers.rb +195 -0
  58. data/workers/tts_workers.rb +388 -0
  59. data/workers/video_generation_workers.rb +264 -0
  60. data/workers/zhipu_workers.rb +113 -0
  61. metadata +84 -8
@@ -0,0 +1,22 @@
1
+ # Configuration for SiliconFlow image generation.
2
+ #
3
+ # Get an API key from https://siliconflow.cn and export it as SILICONFLOW_API_KEY.
4
+ # Available image models: Kwai-Kolors/Kolors, Qwen/Qwen-Image,
5
+ # Qwen/Qwen-Image-Edit (image editing). See:
6
+ # https://api-docs.siliconflow.cn/docs/api/images-generations-post
7
+
8
+ adapters:
9
+ image_generation: "ImageGenerationAdapter"
10
+
11
+ llms:
12
+ image_gen:
13
+ adapter: "image_generation"
14
+ url: "https://api.siliconflow.cn/v1/"
15
+ api_key: ENV["SILICONFLOW_API_KEY"]
16
+ # Kolors supports batch_size, guidance_scale and a range of image_size values.
17
+ model: "Kwai-Kolors/Kolors"
18
+
19
+ default_llm: "image_gen"
20
+ template_path: "./templates"
21
+ worker_path: "./workers"
22
+ logger_file: "./logs/smart_prompt.log"
@@ -0,0 +1,85 @@
1
+ # Multimodal Configuration for SmartPrompt
2
+ # This configuration enables multimodal capabilities with SiliconFlow
3
+
4
+ # Adapter definitions
5
+ adapters:
6
+ openai: "OpenAIAdapter"
7
+ multimodal: "MultimodalAdapter"
8
+
9
+ # LLM configurations
10
+ llms:
11
+ # Multimodal models for vision and video understanding
12
+ qwen_vl:
13
+ adapter: "multimodal"
14
+ url: "https://api.siliconflow.cn/v1/"
15
+ api_key: ENV["SILICONFLOW_API_KEY"]
16
+ default_model: "Qwen/Qwen2.5-VL-7B-Instruct"
17
+ temperature: 0.7
18
+
19
+ qwen_omni:
20
+ adapter: "multimodal"
21
+ url: "https://api.siliconflow.cn/v1/"
22
+ api_key: ENV["SILICONFLOW_API_KEY"]
23
+ default_model: "Qwen/Qwen3-Omni-7B-Instruct"
24
+ temperature: 0.7
25
+
26
+ deepseek_vl:
27
+ adapter: "multimodal"
28
+ url: "https://api.siliconflow.cn/v1/"
29
+ api_key: ENV["SILICONFLOW_API_KEY"]
30
+ default_model: "deepseek-ai/DeepSeek-VL2"
31
+ temperature: 0.7
32
+
33
+ # Text-only models for comparison
34
+ siliconflow_text:
35
+ adapter: "openai"
36
+ url: "https://api.siliconflow.cn/v1/"
37
+ api_key: ENV["SILICONFLOW_API_KEY"]
38
+ default_model: "Qwen/Qwen2.5-7B-Instruct"
39
+ temperature: 0.7
40
+
41
+ # Default settings
42
+ default_llm: "qwen_vl"
43
+
44
+ # Path configurations
45
+ template_path: "./templates"
46
+ worker_path: "./workers"
47
+ logger_file: "./logs/smart_prompt.log"
48
+
49
+ # Multimodal specific settings
50
+ multimodal:
51
+ # Default image detail level ("low", "high", "auto")
52
+ default_image_detail: "auto"
53
+
54
+ # Default video extraction settings
55
+ default_max_frames: 10
56
+ default_fps: 1
57
+
58
+ # Supported file formats
59
+ supported_image_formats:
60
+ - "jpg"
61
+ - "jpeg"
62
+ - "png"
63
+ - "gif"
64
+ - "bmp"
65
+ - "webp"
66
+
67
+ supported_video_formats:
68
+ - "mp4"
69
+ - "mov"
70
+ - "avi"
71
+ - "mkv"
72
+ - "webm"
73
+
74
+ # Advanced settings
75
+ advanced:
76
+ # Timeout settings (in seconds)
77
+ request_timeout: 240
78
+ connection_timeout: 30
79
+
80
+ # Retry settings
81
+ max_retries: 3
82
+ retry_delay: 2
83
+
84
+ # Rate limiting
85
+ requests_per_minute: 60
@@ -0,0 +1,63 @@
1
+ # SenseNova (商汤 日日新) Configuration for SmartPrompt
2
+ #
3
+ # Get an API key from https://platform.sensenova.cn/console and export it as
4
+ # SENSENOVA_API_KEY. A single SenseNovaAdapter covers all four model categories —
5
+ # just point a different llm entry at each model.
6
+ #
7
+ # Two base hosts are in play (verified 2026-06-19):
8
+ # * token.sensenova.cn/v1 — the free-tier models (sensenova-6.7-flash-lite
9
+ # chat/vision, sensenova-u1-fast image). Works
10
+ # out-of-the-box with a free key.
11
+ # * api.sensenova.cn/compatible-mode/v2 — paid models (SenseChat-5, SenseNova-V6-Pro).
12
+ # Returns 403 if your key lacks that model.
13
+ # * api.sensenova.cn/v1/llm/embeddings — Cupido embeddings (native; paid).
14
+ #
15
+ # The image endpoint is NOT under compatible-mode (it 404s there) — it lives on
16
+ # token.sensenova.cn/v1/images/generations and only accepts specific sizes
17
+ # (see VALID_IMAGE_SIZES in sensenova_adapter.rb; default 2048x2048).
18
+
19
+ adapters:
20
+ sensenova: "SenseNovaAdapter"
21
+
22
+ llms:
23
+ # 1. 商量 文本对话 (free-tier; works with a free key)
24
+ sensechat:
25
+ adapter: "sensenova"
26
+ url: "https://token.sensenova.cn/v1"
27
+ api_key: ENV["SENSENOVA_API_KEY"]
28
+ model: "sensenova-6.7-flash-lite"
29
+ temperature: 0.7
30
+ # Optional SenseNova sampling extras (forwarded to /chat/completions):
31
+ # reasoning_effort: "medium"
32
+ # max_completion_tokens: 4096
33
+ # Paid alternative: url https://api.sensenova.cn/compatible-mode/v2, model SenseChat-5
34
+
35
+ # 2. 商量 图文多模态 (sensenova-6.7-flash-lite is natively multimodal)
36
+ sensevision:
37
+ adapter: "sensenova"
38
+ url: "https://token.sensenova.cn/v1"
39
+ api_key: ENV["SENSENOVA_API_KEY"]
40
+ model: "sensenova-6.7-flash-lite"
41
+ # Paid alternative: url https://api.sensenova.cn/compatible-mode/v2, model SenseNova-V6-Pro
42
+
43
+ # 3. Cupido 向量模型 (paid; native endpoint, non-OpenAI response shape)
44
+ senseembedding:
45
+ adapter: "sensenova"
46
+ url: "https://api.sensenova.cn/compatible-mode/v2"
47
+ embeddings_url: "https://api.sensenova.cn/v1/llm/embeddings"
48
+ api_key: ENV["SENSENOVA_API_KEY"]
49
+ model: "Cupido"
50
+
51
+ # 4. 秒画 文生图 (free-tier sensenova-u1-fast; native token.sensenova.cn base)
52
+ senseimage:
53
+ adapter: "sensenova"
54
+ url: "https://token.sensenova.cn/v1"
55
+ image_url: "https://token.sensenova.cn/v1/images/generations"
56
+ api_key: ENV["SENSENOVA_API_KEY"]
57
+ model: "sensenova-u1-fast"
58
+
59
+ default_llm: "sensechat"
60
+
61
+ template_path: "./templates"
62
+ worker_path: "./workers"
63
+ logger_file: "./logs/smart_prompt.log"
@@ -0,0 +1,73 @@
1
+ # 智谱 AI (BigModel / GLM) Configuration for SmartPrompt
2
+ #
3
+ # Get an API key from https://open.bigmodel.cn/ and export it as ZHIPUAI_API_KEY.
4
+ # A single ZhipuAIAdapter covers all REST model categories — just point a different
5
+ # llm entry at each model. Defaults use the free-tier models so it runs out-of-box.
6
+ #
7
+ # Base URL: https://open.bigmodel.cn/api/paas/v4 (coding models: .../api/coding/paas/v4)
8
+ # Auth: Authorization: Bearer <API_KEY>
9
+
10
+ adapters:
11
+ zhipu: "ZhipuAIAdapter"
12
+
13
+ llms:
14
+ # 1. 文本对话 (free-tier glm-4-flash; paid: glm-4-plus / glm-4-long / glm-5.2)
15
+ glm:
16
+ adapter: "zhipu"
17
+ url: "https://open.bigmodel.cn/api/paas/v4"
18
+ api_key: ENV["ZHIPUAI_API_KEY"]
19
+ model: "glm-4-flash"
20
+ temperature: 0.7
21
+ # Optional sampling extras (forwarded to /chat/completions):
22
+ # top_p: 0.7
23
+ # max_tokens: 2048
24
+ # CodeGeeX-4: set `coding: true` (uses the coding base) and model: codegeex-4
25
+
26
+ # 2. 图文多模态 (free-tier glm-4v-flash; paid: glm-4v-plus)
27
+ glm_vision:
28
+ adapter: "zhipu"
29
+ url: "https://open.bigmodel.cn/api/paas/v4"
30
+ api_key: ENV["ZHIPUAI_API_KEY"]
31
+ model: "glm-4v-flash"
32
+
33
+ # 3. 向量模型 (embedding-3 supports custom dimensions: 256/512/1024/2048)
34
+ embedding:
35
+ adapter: "zhipu"
36
+ url: "https://open.bigmodel.cn/api/paas/v4"
37
+ api_key: ENV["ZHIPUAI_API_KEY"]
38
+ model: "embedding-3"
39
+ dimensions: 1024
40
+
41
+ # 4. 文生图 (free-tier cogview-3-flash; paid: cogview-4 / glm-image)
42
+ cogview:
43
+ adapter: "zhipu"
44
+ url: "https://open.bigmodel.cn/api/paas/v4"
45
+ api_key: ENV["ZHIPUAI_API_KEY"]
46
+ model: "cogview-3-flash"
47
+
48
+ # 5. 文生视频 (async: submit -> poll -> download; free-tier cogvideox-flash)
49
+ cogvideo:
50
+ adapter: "zhipu"
51
+ url: "https://open.bigmodel.cn/api/paas/v4"
52
+ api_key: ENV["ZHIPUAI_API_KEY"]
53
+ model: "cogvideox-flash"
54
+
55
+ # 6. 语音合成 (GLM-TTS)
56
+ glm_tts:
57
+ adapter: "zhipu"
58
+ url: "https://open.bigmodel.cn/api/paas/v4"
59
+ api_key: ENV["ZHIPUAI_API_KEY"]
60
+ model: "glm-tts"
61
+
62
+ # 7. 语音识别 (GLM-ASR-2512)
63
+ glm_asr:
64
+ adapter: "zhipu"
65
+ url: "https://open.bigmodel.cn/api/paas/v4"
66
+ api_key: ENV["ZHIPUAI_API_KEY"]
67
+ model: "glm-asr-2512"
68
+
69
+ default_llm: "glm"
70
+
71
+ template_path: "./templates"
72
+ worker_path: "./workers"
73
+ logger_file: "./logs/smart_prompt.log"
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require './lib/smart_prompt'
5
+
6
+ # Example: Basic Chat with Anthropic Claude
7
+ # This example demonstrates simple text-based conversations with Claude
8
+
9
+ puts "=" * 60
10
+ puts "Anthropic Claude - Basic Chat Example"
11
+ puts "=" * 60
12
+
13
+ # Initialize the engine with Anthropic configuration
14
+ engine = SmartPrompt::Engine.new('config/anthropic_config.yml')
15
+
16
+ # Example 1: Simple Question-Answer
17
+ puts "\n1. Simple Question-Answer"
18
+ puts "-" * 60
19
+
20
+ SmartPrompt.define_worker :simple_chat do
21
+ use "claude"
22
+ sys_msg("You are a helpful AI assistant.")
23
+ prompt(params[:message])
24
+ send_msg
25
+ end
26
+
27
+ response = engine.call_worker(:simple_chat, {
28
+ message: "What is the capital of France?"
29
+ })
30
+ puts "User: What is the capital of France?"
31
+ puts "Claude: #{response}\n"
32
+
33
+ # Example 2: Multi-turn Conversation with History
34
+ puts "\n2. Multi-turn Conversation"
35
+ puts "-" * 60
36
+
37
+ SmartPrompt.define_worker :conversation do
38
+ use "claude"
39
+ sys_msg("You are a knowledgeable history teacher.")
40
+ prompt(params[:message], with_history: true)
41
+ send_msg
42
+ end
43
+
44
+ response1 = engine.call_worker(:conversation, {
45
+ message: "Who was the first president of the United States?"
46
+ })
47
+ puts "User: Who was the first president of the United States?"
48
+ puts "Claude: #{response1}\n"
49
+
50
+ response2 = engine.call_worker(:conversation, {
51
+ message: "What were his major accomplishments?"
52
+ })
53
+ puts "User: What were his major accomplishments?"
54
+ puts "Claude: #{response2}\n"
55
+
56
+ # Example 3: Using Different Models
57
+ puts "\n3. Comparing Different Claude Models"
58
+ puts "-" * 60
59
+
60
+ question = "Explain quantum entanglement in one sentence."
61
+
62
+ # Claude 3.5 Sonnet (balanced)
63
+ SmartPrompt.define_worker :sonnet_chat do
64
+ use "claude"
65
+ model "claude-3-5-sonnet-20241022"
66
+ prompt(params[:message])
67
+ send_msg
68
+ end
69
+
70
+ sonnet_response = engine.call_worker(:sonnet_chat, { message: question })
71
+ puts "Question: #{question}"
72
+ puts "\nClaude 3.5 Sonnet: #{sonnet_response}\n"
73
+
74
+ # Claude 3.5 Haiku (faster)
75
+ SmartPrompt.define_worker :haiku_chat do
76
+ use "claude_haiku"
77
+ model "claude-3-5-haiku-20241022"
78
+ prompt(params[:message])
79
+ send_msg
80
+ end
81
+
82
+ haiku_response = engine.call_worker(:haiku_chat, { message: question })
83
+ puts "Claude 3.5 Haiku: #{haiku_response}\n"
84
+
85
+ # Example 4: Temperature Control
86
+ puts "\n4. Temperature Control for Creativity"
87
+ puts "-" * 60
88
+
89
+ # Creative response (high temperature)
90
+ SmartPrompt.define_worker :creative_chat do
91
+ use "claude_creative" # temperature: 0.9
92
+ sys_msg("You are a creative writer.")
93
+ prompt("Write a creative tagline for a coffee shop.")
94
+ send_msg
95
+ end
96
+
97
+ creative = engine.call_worker(:creative_chat, {})
98
+ puts "Creative (temp=0.9): #{creative}\n"
99
+
100
+ # Precise response (low temperature)
101
+ SmartPrompt.define_worker :precise_chat do
102
+ use "claude_precise" # temperature: 0.3
103
+ sys_msg("You are a precise analyst.")
104
+ prompt("Write a tagline for a coffee shop.")
105
+ send_msg
106
+ end
107
+
108
+ precise = engine.call_worker(:precise_chat, {})
109
+ puts "Precise (temp=0.3): #{precise}\n"
110
+
111
+ # Example 5: System Message Variations
112
+ puts "\n5. System Message Variations"
113
+ puts "-" * 60
114
+
115
+ question = "Should I invest in cryptocurrency?"
116
+
117
+ # As a financial advisor
118
+ SmartPrompt.define_worker :advisor_chat do
119
+ use "claude"
120
+ sys_msg("You are a conservative financial advisor.")
121
+ prompt(params[:message])
122
+ send_msg
123
+ end
124
+
125
+ advisor_response = engine.call_worker(:advisor_chat, { message: question })
126
+ puts "As Financial Advisor:"
127
+ puts advisor_response[0..150] + "...\n"
128
+
129
+ # As a tech enthusiast
130
+ SmartPrompt.define_worker :enthusiast_chat do
131
+ use "claude"
132
+ sys_msg("You are an enthusiastic technology advocate.")
133
+ prompt(params[:message])
134
+ send_msg
135
+ end
136
+
137
+ enthusiast_response = engine.call_worker(:enthusiast_chat, { message: question })
138
+ puts "\nAs Tech Enthusiast:"
139
+ puts enthusiast_response[0..150] + "...\n"
140
+
141
+ puts "\n" + "=" * 60
142
+ puts "Basic chat examples completed!"
143
+ puts "=" * 60
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "./lib/smart_prompt"
5
+
6
+ # Example: Using Anthropic Claude with SmartPrompt
7
+ # This example demonstrates various features of the AnthropicAdapter
8
+
9
+ # Initialize the engine with Anthropic configuration
10
+ engine = SmartPrompt::Engine.new("config/anthropic_config.yml")
11
+
12
+ puts "=" * 60
13
+ puts "Anthropic Claude Examples with SmartPrompt"
14
+ puts "=" * 60
15
+
16
+ =begin
17
+ # Example 1: Basic Chat
18
+ puts "\n1. Basic Chat Example"
19
+ puts "-" * 60
20
+
21
+ SmartPrompt.define_worker :basic_chat do
22
+ use "deepseek_anthropic"
23
+ model "deepseek-chat"
24
+ sys_msg("You are a helpful AI assistant.")
25
+ prompt(params[:message])
26
+ send_msg
27
+ end
28
+
29
+ response = engine.call_worker(:basic_chat, {
30
+ message: "What is the capital of France?",
31
+ })
32
+ puts "User: What is the capital of France?"
33
+ puts "DeepSeek: #{response}"
34
+
35
+ # Example 2: Multi-turn Conversation
36
+ puts "\n2. Multi-turn Conversation Example"
37
+ puts "-" * 60
38
+
39
+ SmartPrompt.define_worker :conversation do
40
+ use "deepseek_anthropic"
41
+ model "deepseek-chat"
42
+ sys_msg("You are a knowledgeable history teacher.")
43
+ prompt(params[:message], with_history: true)
44
+ send_msg
45
+ end
46
+
47
+ response1 = engine.call_worker(:conversation, {
48
+ message: "Who was the first president of the United States?",
49
+ with_history: true,
50
+ })
51
+ puts "User: Who was the first president of the United States?"
52
+ puts "Claude: #{response1}"
53
+
54
+ response2 = engine.call_worker(:conversation, {
55
+ message: "What were his major accomplishments?",
56
+ with_history: true,
57
+ })
58
+ puts "\nUser: What were his major accomplishments?"
59
+ puts "Claude: #{response2}"
60
+
61
+ # Example 3: Code Generation
62
+ puts "\n3. Code Generation Example"
63
+ puts "-" * 60
64
+
65
+ SmartPrompt.define_worker :code_generator do
66
+ use "deepseek_anthropic"
67
+ model "deepseek-chat"
68
+ sys_msg("You are an expert programmer. Generate clean, well-documented code.")
69
+ prompt("Write a Ruby function that #{params[:task]}")
70
+ send_msg
71
+ end
72
+
73
+ code = engine.call_worker(:code_generator, {
74
+ task: "calculates the factorial of a number using recursion",
75
+ })
76
+ puts "Task: Write a Ruby function that calculates the factorial of a number using recursion"
77
+ puts "Generated Code:\n#{code}"
78
+
79
+ # Example 4: Streaming Response
80
+ puts "\n4. Streaming Response Example"
81
+ puts "-" * 60
82
+
83
+ SmartPrompt.define_worker :streaming_chat do
84
+ use "deepseek_anthropic"
85
+ model "deepseek-chat"
86
+ sys_msg("You are a storyteller.")
87
+ prompt(params[:message])
88
+ send_msg
89
+ end
90
+
91
+ print "User: Tell me a short story about a brave knight.\n"
92
+ print "Claude (streaming): "
93
+
94
+ engine.call_worker_by_stream(:streaming_chat, {
95
+ message: "Tell me a short story about a brave knight.",
96
+ }) do |chunk, bytesize|
97
+ # Handle Anthropic streaming format
98
+ if chunk.is_a?(Hash)
99
+ if chunk["type"] == "content_block_delta"
100
+ text = chunk.dig("delta", "text")
101
+ print text if text
102
+ end
103
+ end
104
+ end
105
+
106
+ puts "\n"
107
+ =end
108
+
109
+ # Example 7: Tool Calling (Function Calling)
110
+ puts "\n7. Tool Calling Example"
111
+ puts "-" * 60
112
+
113
+ # Define tools
114
+ weather_tools = [
115
+ {
116
+ type: "function",
117
+ function: {
118
+ name: "get_weather",
119
+ description: "Get the current weather for a location",
120
+ parameters: {
121
+ type: "object",
122
+ properties: {
123
+ location: {
124
+ type: "string",
125
+ description: "The city and state, e.g. San Francisco, CA",
126
+ },
127
+ unit: {
128
+ type: "string",
129
+ enum: ["celsius", "fahrenheit"],
130
+ description: "The temperature unit",
131
+ },
132
+ },
133
+ required: ["location"],
134
+ },
135
+ },
136
+ },
137
+ ]
138
+
139
+ SmartPrompt.define_worker :weather_assistant do
140
+ use "deepseek_anthropic"
141
+ model "deepseek-chat"
142
+ sys_msg("You are a helpful weather assistant. Use the get_weather tool when users ask about weather.")
143
+ prompt(params[:message])
144
+ send_msg
145
+ end
146
+
147
+ response = engine.call_worker(:weather_assistant, {
148
+ message: "What's the weather like in Tokyo?",
149
+ tools: weather_tools,
150
+ })
151
+ puts "User: What's the weather like in Tokyo?"
152
+ puts "Claude: #{response}"
153
+
154
+ =begin
155
+
156
+ # Example 8: Image Analysis (Multimodal)
157
+ puts "\n8. Image Analysis Example (Multimodal)"
158
+ puts "-" * 60
159
+
160
+ SmartPrompt.define_worker :image_analyzer do
161
+ use "claude"
162
+ sys_msg("You are an expert at analyzing images and describing what you see.")
163
+ prompt(params[:message])
164
+ send_msg
165
+ end
166
+
167
+ # Using a public image URL
168
+ image_url = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"
169
+
170
+ response = engine.call_worker(:image_analyzer, {
171
+ message: [
172
+ { type: "text", text: "What do you see in this image? Describe it in detail." },
173
+ { type: "image_url", image_url: image_url }
174
+ ]
175
+ })
176
+ puts "User: [Sends image of a cat]"
177
+ puts "Claude: #{response}"
178
+
179
+ # Example 9: Different Models Comparison
180
+ puts "\n9. Different Models Comparison"
181
+ puts "-" * 60
182
+
183
+ question = "Explain quantum entanglement in simple terms."
184
+
185
+ # Using Claude 3.5 Sonnet
186
+ SmartPrompt.define_worker :sonnet_chat do
187
+ use "claude"
188
+ model "claude-3-5-sonnet-20241022"
189
+ prompt(params[:message])
190
+ send_msg
191
+ end
192
+
193
+ sonnet_response = engine.call_worker(:sonnet_chat, { message: question })
194
+ puts "Question: #{question}"
195
+ puts "\nClaude 3.5 Sonnet Response:"
196
+ puts sonnet_response[0..200] + "..."
197
+
198
+ # Using Claude 3.5 Haiku (faster)
199
+ SmartPrompt.define_worker :haiku_chat do
200
+ use "claude_haiku"
201
+ model "claude-3-5-haiku-20241022"
202
+ prompt(params[:message])
203
+ send_msg
204
+ end
205
+
206
+ haiku_response = engine.call_worker(:haiku_chat, { message: question })
207
+ puts "\nClaude 3.5 Haiku Response:"
208
+ puts haiku_response[0..200] + "..."
209
+
210
+ # Example 10: Error Handling
211
+ puts "\n10. Error Handling Example"
212
+ puts "-" * 60
213
+
214
+ begin
215
+ # Try to use a non-existent model
216
+ SmartPrompt.define_worker :error_test do
217
+ use "claude"
218
+ model "non-existent-model"
219
+ prompt(params[:message])
220
+ send_msg
221
+ end
222
+
223
+ engine.call_worker(:error_test, { message: "Hello" })
224
+ rescue SmartPrompt::LLMAPIError => e
225
+ puts "Caught API Error: #{e.message}"
226
+ puts "Error handling works correctly!"
227
+ end
228
+
229
+ puts "\n" + "=" * 60
230
+ puts "All examples completed!"
231
+ puts "=" * 60
232
+ =end