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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -10
- data/README.cn.md +307 -64
- data/README.md +311 -64
- data/Rakefile +10 -1
- data/config/anthropic_config.yml +151 -0
- data/config/image_generation_config.yml +22 -0
- data/config/multimodal_config.yml +85 -0
- data/config/sensenova_config.yml +63 -0
- data/config/zhipu_config.yml +73 -0
- data/examples/anthropic_basic_chat.rb +143 -0
- data/examples/anthropic_example.rb +232 -0
- data/examples/anthropic_multimodal.rb +212 -0
- data/examples/anthropic_streaming.rb +312 -0
- data/examples/anthropic_tool_calling.rb +393 -0
- data/examples/automatic_cleanup_example.rb +109 -0
- data/examples/history_management_examples.rb +522 -0
- data/examples/image_generation_example.rb +130 -0
- data/examples/monitoring_example.rb +121 -0
- data/examples/multimodal_example.rb +63 -0
- data/examples/relevance_based_strategy_example.rb +87 -0
- data/examples/sensenova_example.rb +129 -0
- data/examples/stt_example.rb +287 -0
- data/examples/tts_example.rb +244 -0
- data/examples/video_generation_example.rb +189 -0
- data/examples/zhipu_example.rb +151 -0
- data/lib/smart_prompt/anthropic_adapter.rb +363 -281
- data/lib/smart_prompt/compression_engine.rb +201 -0
- data/lib/smart_prompt/context_strategy.rb +22 -0
- data/lib/smart_prompt/conversation.rb +81 -191
- data/lib/smart_prompt/engine.rb +36 -19
- data/lib/smart_prompt/history_manager.rb +596 -0
- data/lib/smart_prompt/hybrid_strategy.rb +222 -0
- data/lib/smart_prompt/image_generation_adapter.rb +297 -0
- data/lib/smart_prompt/lru_cache.rb +133 -0
- data/lib/smart_prompt/message.rb +57 -0
- data/lib/smart_prompt/multimodal_adapter.rb +277 -0
- data/lib/smart_prompt/openai_adapter.rb +1 -25
- data/lib/smart_prompt/persistence_layer.rb +197 -0
- data/lib/smart_prompt/relevance_based_strategy.rb +221 -0
- data/lib/smart_prompt/sensenova_adapter.rb +410 -0
- data/lib/smart_prompt/session.rb +140 -0
- data/lib/smart_prompt/sliding_window_strategy.rb +100 -0
- data/lib/smart_prompt/stt_adapter.rb +381 -0
- data/lib/smart_prompt/summary_based_strategy.rb +152 -0
- data/lib/smart_prompt/token_counter.rb +74 -0
- data/lib/smart_prompt/tts_adapter.rb +403 -0
- data/lib/smart_prompt/version.rb +1 -1
- data/lib/smart_prompt/video_generation_adapter.rb +330 -0
- data/lib/smart_prompt/worker.rb +25 -3
- data/lib/smart_prompt/zhipu_adapter.rb +616 -0
- data/lib/smart_prompt.rb +22 -2
- data/workers/history_management_examples.rb +407 -0
- data/workers/image_generation_workers.rb +119 -0
- data/workers/multimodal_workers.rb +110 -0
- data/workers/sensenova_workers.rb +62 -0
- data/workers/stt_workers.rb +195 -0
- data/workers/tts_workers.rb +388 -0
- data/workers/video_generation_workers.rb +264 -0
- data/workers/zhipu_workers.rb +113 -0
- 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
|