smart_prompt 0.4.4 → 0.5.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +16 -0
- data/README.cn.md +305 -11
- data/README.md +309 -11
- 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/docs/ANTHROPIC_EXAMPLES.md +559 -0
- data/docs/CONVERSATION_INTEGRATION_SUMMARY.md +155 -0
- data/docs/HISTORY_EXAMPLES_README.md +533 -0
- data/docs/HISTORY_MANAGEMENT_GUIDE.md +797 -0
- data/docs/MONITORING_GUIDE.md +278 -0
- data/docs/MULTIMODAL_README.md +265 -0
- data/docs/RELEVANCE_BASED_STRATEGY_IMPLEMENTATION.md +124 -0
- data/docs/STT_README.md +302 -0
- data/docs/TTS_README.md +303 -0
- data/docs/VIDEO_GENERATION_README.md +246 -0
- data/docs/delete_files_list.md +124 -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 +407 -298
- data/lib/smart_prompt/compression_engine.rb +201 -0
- data/lib/smart_prompt/context_strategy.rb +22 -0
- data/lib/smart_prompt/conversation.rb +47 -4
- data/lib/smart_prompt/engine.rb +29 -2
- 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/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 +28 -3
- data/lib/smart_prompt/zhipu_adapter.rb +616 -0
- data/lib/smart_prompt.rb +21 -0
- 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 +88 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Video Generation Example for SmartPrompt
|
|
2
|
+
# This example demonstrates how to use the new VideoGenerationAdapter
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/smart_prompt'
|
|
5
|
+
|
|
6
|
+
# Configuration for video generation capabilities
|
|
7
|
+
config = {
|
|
8
|
+
"adapters" => {
|
|
9
|
+
"multimodal" => "MultimodalAdapter",
|
|
10
|
+
"image_generation" => "ImageGenerationAdapter",
|
|
11
|
+
"video_generation" => "VideoGenerationAdapter"
|
|
12
|
+
},
|
|
13
|
+
"llms" => {
|
|
14
|
+
"qwen_vl" => {
|
|
15
|
+
"adapter" => "multimodal",
|
|
16
|
+
"url" => "https://api.siliconflow.cn/v1/",
|
|
17
|
+
"api_key" => ENV["SILICONFLOW_API_KEY"],
|
|
18
|
+
"model" => "Qwen/Qwen2.5-VL-7B-Instruct"
|
|
19
|
+
},
|
|
20
|
+
"image_gen" => {
|
|
21
|
+
"adapter" => "image_generation",
|
|
22
|
+
"url" => "https://api.siliconflow.cn/v1/",
|
|
23
|
+
"api_key" => ENV["SILICONFLOW_API_KEY"],
|
|
24
|
+
"model" => "stabilityai/stable-diffusion-xl-base-1.0"
|
|
25
|
+
},
|
|
26
|
+
"video_gen" => {
|
|
27
|
+
"adapter" => "video_generation",
|
|
28
|
+
"url" => "https://api.siliconflow.cn/v1/",
|
|
29
|
+
"api_key" => ENV["SILICONFLOW_API_KEY"],
|
|
30
|
+
"model" => "Wan-AI/Wan2.2-T2V-A14B"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"default_llm" => "qwen_vl",
|
|
34
|
+
"template_path" => "./templates",
|
|
35
|
+
"worker_path" => "./workers",
|
|
36
|
+
"logger_file" => "./logs/smart_prompt.log"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Write config to file
|
|
40
|
+
File.write('video_generation_config.yml', config.to_yaml)
|
|
41
|
+
|
|
42
|
+
# Initialize engine
|
|
43
|
+
engine = SmartPrompt::Engine.new('video_generation_config.yml')
|
|
44
|
+
|
|
45
|
+
puts "=== SmartPrompt Video Generation Demo ==="
|
|
46
|
+
|
|
47
|
+
# Example 1: Simple text-to-video generation
|
|
48
|
+
puts "\n=== Example 1: Text-to-Video Generation ==="
|
|
49
|
+
begin
|
|
50
|
+
result = engine.call_worker(:video_generator, {
|
|
51
|
+
prompt: "A beautiful sunset over ocean waves, cinematic quality, slow motion",
|
|
52
|
+
duration: 4,
|
|
53
|
+
resolution: "720p",
|
|
54
|
+
fps: 24,
|
|
55
|
+
wait_for_completion: false, # Set to true to wait for completion
|
|
56
|
+
download_to_file: false, # Set to true to download video
|
|
57
|
+
output_dir: "./generated_videos",
|
|
58
|
+
filename_prefix: "sunset_video"
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
puts "Video generation job submitted successfully!"
|
|
62
|
+
puts "Job ID: #{result[:video_data][:job_id]}"
|
|
63
|
+
puts "Status: #{result[:video_data][:status]}"
|
|
64
|
+
puts "Created at: #{result[:video_data][:created_at]}"
|
|
65
|
+
|
|
66
|
+
rescue => e
|
|
67
|
+
puts "Error in video generation: #{e.message}"
|
|
68
|
+
puts "Note: This example requires a valid SILICONFLOW_API_KEY environment variable"
|
|
69
|
+
puts "Note: Video generation may take several minutes to complete"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Example 2: Creative video generation with style
|
|
73
|
+
puts "\n=== Example 2: Creative Video Generation ==="
|
|
74
|
+
begin
|
|
75
|
+
result = engine.call_worker(:creative_video_generator, {
|
|
76
|
+
prompt: "A magical forest with glowing fairies and sparkling lights",
|
|
77
|
+
video_style: "fantasy animation, Studio Ghibli style",
|
|
78
|
+
duration: 4,
|
|
79
|
+
resolution: "720p",
|
|
80
|
+
fps: 24,
|
|
81
|
+
wait_for_completion: false,
|
|
82
|
+
download_to_file: false
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
puts "Creative video generation job submitted successfully!"
|
|
86
|
+
puts "Job ID: #{result[:video_data][:job_id]}"
|
|
87
|
+
puts "Status: #{result[:video_data][:status]}"
|
|
88
|
+
|
|
89
|
+
rescue => e
|
|
90
|
+
puts "Error in creative video generation: #{e.message}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Example 3: Product video generation
|
|
94
|
+
puts "\n=== Example 3: Product Video Generation ==="
|
|
95
|
+
begin
|
|
96
|
+
result = engine.call_worker(:product_video_generator, {
|
|
97
|
+
prompt: "A modern smartphone rotating slowly on a marble surface",
|
|
98
|
+
duration: 4,
|
|
99
|
+
resolution: "720p",
|
|
100
|
+
fps: 24,
|
|
101
|
+
wait_for_completion: false,
|
|
102
|
+
download_to_file: false
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
puts "Product video generation job submitted successfully!"
|
|
106
|
+
puts "Job ID: #{result[:video_data][:job_id]}"
|
|
107
|
+
puts "Status: #{result[:video_data][:status]}"
|
|
108
|
+
|
|
109
|
+
rescue => e
|
|
110
|
+
puts "Error in product video generation: #{e.message}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Example 4: Check video status (if we have a job ID from previous examples)
|
|
114
|
+
puts "\n=== Example 4: Video Status Check ==="
|
|
115
|
+
begin
|
|
116
|
+
# This example requires a valid job_id from a previous video generation
|
|
117
|
+
# For demonstration, we'll show the method but skip execution
|
|
118
|
+
puts "To check video status, use:"
|
|
119
|
+
puts "result = engine.call_worker(:video_status_checker, {"
|
|
120
|
+
puts " job_id: 'YOUR_JOB_ID_HERE',"
|
|
121
|
+
puts " download_to_file: true"
|
|
122
|
+
puts "})"
|
|
123
|
+
|
|
124
|
+
rescue => e
|
|
125
|
+
puts "Error in status check: #{e.message}"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Example 5: Direct adapter usage (without worker)
|
|
129
|
+
puts "\n=== Example 5: Direct Adapter Usage ==="
|
|
130
|
+
begin
|
|
131
|
+
# Get the adapter directly
|
|
132
|
+
adapter = engine.llms["video_gen"]
|
|
133
|
+
|
|
134
|
+
# Generate video directly
|
|
135
|
+
video_data = adapter.generate_video(
|
|
136
|
+
"A butterfly flying through a flower garden, nature documentary style",
|
|
137
|
+
duration: 4,
|
|
138
|
+
resolution: "720p",
|
|
139
|
+
fps: 24
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
puts "Direct adapter usage successful!"
|
|
143
|
+
puts "Job ID: #{video_data[:job_id]}"
|
|
144
|
+
puts "Status: #{video_data[:status]}"
|
|
145
|
+
|
|
146
|
+
# Example of checking status
|
|
147
|
+
# status = adapter.check_video_status(video_data[:job_id])
|
|
148
|
+
# puts "Current status: #{status[:status]}, Progress: #{status[:progress]}"
|
|
149
|
+
|
|
150
|
+
rescue => e
|
|
151
|
+
puts "Error in direct adapter usage: #{e.message}"
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Example 6: Batch video generation
|
|
155
|
+
puts "\n=== Example 6: Batch Video Generation ==="
|
|
156
|
+
begin
|
|
157
|
+
result = engine.call_worker(:batch_video_generator, {
|
|
158
|
+
prompts: [
|
|
159
|
+
"A cat playing with a ball of yarn",
|
|
160
|
+
"A dog running through a field",
|
|
161
|
+
"A bird flying in the sky"
|
|
162
|
+
],
|
|
163
|
+
duration: 3,
|
|
164
|
+
resolution: "720p",
|
|
165
|
+
fps: 24,
|
|
166
|
+
wait_for_completion: false
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
puts "Batch video generation submitted successfully!"
|
|
170
|
+
puts "Generated #{result[:batch_results].size} video jobs"
|
|
171
|
+
result[:batch_results].each do |result|
|
|
172
|
+
puts " - Prompt: #{result[:prompt][0..50]}..."
|
|
173
|
+
puts " Job ID: #{result[:video_data][:job_id]}"
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
rescue => e
|
|
177
|
+
puts "Error in batch video generation: #{e.message}"
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
puts "\n=== All examples completed ==="
|
|
181
|
+
puts "\nImportant Notes:"
|
|
182
|
+
puts "1. Video generation is an asynchronous process"
|
|
183
|
+
puts "2. Jobs may take several minutes to complete"
|
|
184
|
+
puts "3. Use wait_for_completion: true to wait for completion"
|
|
185
|
+
puts "4. Use download_to_file: true to automatically download videos"
|
|
186
|
+
puts "5. Check status periodically using video_status_checker worker"
|
|
187
|
+
|
|
188
|
+
# Clean up
|
|
189
|
+
File.delete('video_generation_config.yml') if File.exist?('video_generation_config.yml')
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# 智谱 AI (BigModel / GLM) Example for SmartPrompt
|
|
2
|
+
#
|
|
3
|
+
# Demonstrates every Zhipu model category through one ZhipuAIAdapter:
|
|
4
|
+
# 1. 文本对话 (chat) — sync + streaming
|
|
5
|
+
# 2. 图文多模态 (vision)
|
|
6
|
+
# 3. 向量模型 (embeddings)
|
|
7
|
+
# 4. 文生图 (CogView)
|
|
8
|
+
# 5. 文生视频 (CogVideoX, async submit -> poll -> download)
|
|
9
|
+
# 6. 语音合成 (GLM-TTS)
|
|
10
|
+
# 7. 语音识别 (GLM-ASR-2512)
|
|
11
|
+
#
|
|
12
|
+
# Requires a valid Zhipu API key in ZHIPUAI_API_KEY (https://open.bigmodel.cn/).
|
|
13
|
+
# Defaults use free-tier models so it works out-of-box once the key is set.
|
|
14
|
+
|
|
15
|
+
require_relative "../lib/smart_prompt"
|
|
16
|
+
|
|
17
|
+
api_key = ENV["ZHIPUAI_API_KEY"]
|
|
18
|
+
base = "https://open.bigmodel.cn/api/paas/v4"
|
|
19
|
+
|
|
20
|
+
config = {
|
|
21
|
+
"adapters" => { "zhipu" => "ZhipuAIAdapter" },
|
|
22
|
+
"llms" => {
|
|
23
|
+
"glm" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "glm-4-flash" },
|
|
24
|
+
"glm_vision" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "glm-4v-flash" },
|
|
25
|
+
"embedding" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "embedding-3", "dimensions" => 1024 },
|
|
26
|
+
"cogview" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "cogview-3-flash" },
|
|
27
|
+
"cogvideo" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "cogvideox-flash" },
|
|
28
|
+
"glm_tts" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "glm-tts" },
|
|
29
|
+
"glm_asr" => { "adapter" => "zhipu", "url" => base, "api_key" => api_key, "model" => "glm-asr-2512" },
|
|
30
|
+
},
|
|
31
|
+
"default_llm" => "glm",
|
|
32
|
+
"template_path" => "./templates",
|
|
33
|
+
"worker_path" => "./workers",
|
|
34
|
+
"logger_file" => "./logs/smart_prompt.log",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
File.write("zhipu_config.yml", config.to_yaml)
|
|
38
|
+
engine = SmartPrompt::Engine.new("zhipu_config.yml")
|
|
39
|
+
|
|
40
|
+
puts "=== SmartPrompt 智谱 GLM Demo ==="
|
|
41
|
+
unless api_key
|
|
42
|
+
puts "Note: ZHIPUAI_API_KEY is not set — the API calls below will fail at the network layer."
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# 1. Chat (sync)
|
|
46
|
+
puts "\n=== Example 1: 文本对话 (sync) ==="
|
|
47
|
+
begin
|
|
48
|
+
result = engine.call_worker(:glm_chat, { prompt: "用一句话介绍智谱GLM。" })
|
|
49
|
+
puts "Reply: #{result}"
|
|
50
|
+
rescue => e
|
|
51
|
+
puts "Error: #{e.message}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# 2. Chat (streaming)
|
|
55
|
+
puts "\n=== Example 2: 文本对话 (streaming) ==="
|
|
56
|
+
begin
|
|
57
|
+
engine.call_worker_by_stream(:glm_chat, { prompt: "写两句关于春天的诗。" }) do |chunk, _|
|
|
58
|
+
print chunk.dig("choices", 0, "delta", "content").to_s
|
|
59
|
+
end
|
|
60
|
+
puts
|
|
61
|
+
rescue => e
|
|
62
|
+
puts "Error: #{e.message}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# 3. Multimodal vision
|
|
66
|
+
puts "\n=== Example 3: 图文多模态 ==="
|
|
67
|
+
begin
|
|
68
|
+
result = engine.call_worker(:glm_vision, {
|
|
69
|
+
image_url: "https://img1.baidu.com/it/u=1966616150,2146512490&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=282",
|
|
70
|
+
question: "图片里有什么?",
|
|
71
|
+
})
|
|
72
|
+
puts "Vision result: #{result}"
|
|
73
|
+
rescue => e
|
|
74
|
+
puts "Error: #{e.message}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# 4. Embeddings (embedding-3)
|
|
78
|
+
puts "\n=== Example 4: 向量模型 ==="
|
|
79
|
+
begin
|
|
80
|
+
vector = engine.call_worker(:glm_embed, { text: "智谱GLM大模型", length: 1024 })
|
|
81
|
+
puts "Embedding dim: #{vector.is_a?(Array) ? vector.size : vector} (first 5: #{vector.first(5) rescue vector})"
|
|
82
|
+
rescue => e
|
|
83
|
+
puts "Error: #{e.message}"
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# 5. Text-to-image (CogView)
|
|
87
|
+
puts "\n=== Example 5: 文生图 ==="
|
|
88
|
+
begin
|
|
89
|
+
result = engine.call_worker(:cogview_image, {
|
|
90
|
+
prompt: "一只在书房里读书的猫,水墨画风格",
|
|
91
|
+
size: "1024x1024",
|
|
92
|
+
save_to_file: true,
|
|
93
|
+
output_dir: "./generated_images",
|
|
94
|
+
filename_prefix: "zhipu_cat",
|
|
95
|
+
})
|
|
96
|
+
if result.is_a?(Hash) && result[:images]
|
|
97
|
+
puts "Generated #{result[:images].size} image(s); first URL: #{result[:images].first[:url]}"
|
|
98
|
+
puts "Saved files: #{result[:saved_files]}"
|
|
99
|
+
else
|
|
100
|
+
puts "Result: #{result}"
|
|
101
|
+
end
|
|
102
|
+
rescue => e
|
|
103
|
+
puts "Error: #{e.message}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# 6. Text-to-video (CogVideoX, async) — may take a minute or two.
|
|
107
|
+
puts "\n=== Example 6: 文生视频 (async) ==="
|
|
108
|
+
begin
|
|
109
|
+
result = engine.call_worker(:cogvideo_video, {
|
|
110
|
+
prompt: "一只猫在阳光下打盹",
|
|
111
|
+
wait_for_completion: true,
|
|
112
|
+
download_to_file: true,
|
|
113
|
+
output_dir: "./generated_videos",
|
|
114
|
+
timeout: 600,
|
|
115
|
+
})
|
|
116
|
+
if result[:video]
|
|
117
|
+
puts "Video ready: #{result[:video][:video_url]}"
|
|
118
|
+
puts "Downloaded: #{result[:downloaded_file]}" if result[:downloaded_file]
|
|
119
|
+
else
|
|
120
|
+
puts "Submitted task: #{result[:submitted]}"
|
|
121
|
+
end
|
|
122
|
+
rescue => e
|
|
123
|
+
puts "Error: #{e.message}"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# 7. TTS (GLM-TTS)
|
|
127
|
+
puts "\n=== Example 7: 语音合成 (TTS) ==="
|
|
128
|
+
begin
|
|
129
|
+
info = engine.call_worker(:glm_tts, { text: "你好,这是智谱语音合成的测试。", output_path: "./generated_audio/zhipu_tts.wav" })
|
|
130
|
+
puts "Audio saved: #{info[:file_path]}"
|
|
131
|
+
rescue => e
|
|
132
|
+
puts "Error: #{e.message}"
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# 8. ASR (GLM-ASR-2512) — needs a real audio file path.
|
|
136
|
+
puts "\n=== Example 8: 语音识别 (ASR) ==="
|
|
137
|
+
audio = ENV["ZHIPU_ASR_SAMPLE"] || "./generated_audio/zhipu_tts.wav"
|
|
138
|
+
if File.exist?(audio)
|
|
139
|
+
begin
|
|
140
|
+
result = engine.call_worker(:glm_asr, { audio_file: audio })
|
|
141
|
+
puts "Transcription: #{result[:text]}"
|
|
142
|
+
rescue => e
|
|
143
|
+
puts "Error: #{e.message}"
|
|
144
|
+
end
|
|
145
|
+
else
|
|
146
|
+
puts "Skipped: set ZHIPU_ASR_SAMPLE to an audio file path (or run TTS first) to test ASR."
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
puts "\n=== All examples completed ==="
|
|
150
|
+
|
|
151
|
+
File.delete("zhipu_config.yml") if File.exist?("zhipu_config.yml")
|