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,393 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require './lib/smart_prompt'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
# Example: Tool Calling (Function Calling) with Anthropic Claude
|
|
8
|
+
# This example demonstrates how to use Claude with external tools/functions
|
|
9
|
+
|
|
10
|
+
puts "=" * 60
|
|
11
|
+
puts "Anthropic Claude - Tool Calling Example"
|
|
12
|
+
puts "=" * 60
|
|
13
|
+
|
|
14
|
+
# Initialize the engine with Anthropic configuration
|
|
15
|
+
engine = SmartPrompt::Engine.new('config/anthropic_config.yml')
|
|
16
|
+
|
|
17
|
+
# Example 1: Simple Weather Tool
|
|
18
|
+
puts "\n1. Simple Weather Tool"
|
|
19
|
+
puts "-" * 60
|
|
20
|
+
|
|
21
|
+
# Define the weather tool
|
|
22
|
+
weather_tool = [
|
|
23
|
+
{
|
|
24
|
+
type: "function",
|
|
25
|
+
function: {
|
|
26
|
+
name: "get_weather",
|
|
27
|
+
description: "Get the current weather for a specific location",
|
|
28
|
+
parameters: {
|
|
29
|
+
type: "object",
|
|
30
|
+
properties: {
|
|
31
|
+
location: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "The city and state, e.g. San Francisco, CA"
|
|
34
|
+
},
|
|
35
|
+
unit: {
|
|
36
|
+
type: "string",
|
|
37
|
+
enum: ["celsius", "fahrenheit"],
|
|
38
|
+
description: "The temperature unit to use"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
required: ["location"]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
SmartPrompt.define_worker :weather_assistant do
|
|
48
|
+
use "claude"
|
|
49
|
+
sys_msg("You are a helpful weather assistant. Use the get_weather tool when users ask about weather.")
|
|
50
|
+
prompt(params[:message])
|
|
51
|
+
params.merge(tools: weather_tool)
|
|
52
|
+
send_msg
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
response = engine.call_worker(:weather_assistant, {
|
|
56
|
+
message: "What's the weather like in Tokyo?"
|
|
57
|
+
})
|
|
58
|
+
puts "User: What's the weather like in Tokyo?"
|
|
59
|
+
puts "Claude: #{response}\n"
|
|
60
|
+
|
|
61
|
+
# Example 2: Multiple Tools - Calculator
|
|
62
|
+
puts "\n2. Calculator Tools"
|
|
63
|
+
puts "-" * 60
|
|
64
|
+
|
|
65
|
+
calculator_tools = [
|
|
66
|
+
{
|
|
67
|
+
type: "function",
|
|
68
|
+
function: {
|
|
69
|
+
name: "add",
|
|
70
|
+
description: "Add two numbers together",
|
|
71
|
+
parameters: {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: {
|
|
74
|
+
a: { type: "number", description: "First number" },
|
|
75
|
+
b: { type: "number", description: "Second number" }
|
|
76
|
+
},
|
|
77
|
+
required: ["a", "b"]
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: "function",
|
|
83
|
+
function: {
|
|
84
|
+
name: "multiply",
|
|
85
|
+
description: "Multiply two numbers",
|
|
86
|
+
parameters: {
|
|
87
|
+
type: "object",
|
|
88
|
+
properties: {
|
|
89
|
+
a: { type: "number", description: "First number" },
|
|
90
|
+
b: { type: "number", description: "Second number" }
|
|
91
|
+
},
|
|
92
|
+
required: ["a", "b"]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
type: "function",
|
|
98
|
+
function: {
|
|
99
|
+
name: "divide",
|
|
100
|
+
description: "Divide two numbers",
|
|
101
|
+
parameters: {
|
|
102
|
+
type: "object",
|
|
103
|
+
properties: {
|
|
104
|
+
a: { type: "number", description: "Numerator" },
|
|
105
|
+
b: { type: "number", description: "Denominator" }
|
|
106
|
+
},
|
|
107
|
+
required: ["a", "b"]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
SmartPrompt.define_worker :calculator_assistant do
|
|
114
|
+
use "claude"
|
|
115
|
+
sys_msg("You are a helpful calculator assistant. Use the available math tools to help users with calculations.")
|
|
116
|
+
prompt(params[:message])
|
|
117
|
+
params.merge(tools: calculator_tools)
|
|
118
|
+
send_msg
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
response = engine.call_worker(:calculator_assistant, {
|
|
122
|
+
message: "What is 15 multiplied by 23, then divided by 5?"
|
|
123
|
+
})
|
|
124
|
+
puts "User: What is 15 multiplied by 23, then divided by 5?"
|
|
125
|
+
puts "Claude: #{response}\n"
|
|
126
|
+
|
|
127
|
+
# Example 3: Database Query Tool
|
|
128
|
+
puts "\n3. Database Query Tool"
|
|
129
|
+
puts "-" * 60
|
|
130
|
+
|
|
131
|
+
database_tools = [
|
|
132
|
+
{
|
|
133
|
+
type: "function",
|
|
134
|
+
function: {
|
|
135
|
+
name: "query_database",
|
|
136
|
+
description: "Query the customer database for information",
|
|
137
|
+
parameters: {
|
|
138
|
+
type: "object",
|
|
139
|
+
properties: {
|
|
140
|
+
query_type: {
|
|
141
|
+
type: "string",
|
|
142
|
+
enum: ["customer_info", "order_history", "product_details"],
|
|
143
|
+
description: "The type of query to perform"
|
|
144
|
+
},
|
|
145
|
+
customer_id: {
|
|
146
|
+
type: "string",
|
|
147
|
+
description: "The customer ID to query"
|
|
148
|
+
},
|
|
149
|
+
filters: {
|
|
150
|
+
type: "object",
|
|
151
|
+
description: "Additional filters for the query"
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
required: ["query_type"]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
SmartPrompt.define_worker :database_assistant do
|
|
161
|
+
use "claude"
|
|
162
|
+
sys_msg("You are a customer service assistant with access to the customer database. Use the query_database tool to help users.")
|
|
163
|
+
prompt(params[:message])
|
|
164
|
+
params.merge(tools: database_tools)
|
|
165
|
+
send_msg
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
response = engine.call_worker(:database_assistant, {
|
|
169
|
+
message: "Can you look up the order history for customer ID 12345?"
|
|
170
|
+
})
|
|
171
|
+
puts "User: Can you look up the order history for customer ID 12345?"
|
|
172
|
+
puts "Claude: #{response}\n"
|
|
173
|
+
|
|
174
|
+
# Example 4: File Operations Tool
|
|
175
|
+
puts "\n4. File Operations Tool"
|
|
176
|
+
puts "-" * 60
|
|
177
|
+
|
|
178
|
+
file_tools = [
|
|
179
|
+
{
|
|
180
|
+
type: "function",
|
|
181
|
+
function: {
|
|
182
|
+
name: "read_file",
|
|
183
|
+
description: "Read the contents of a file",
|
|
184
|
+
parameters: {
|
|
185
|
+
type: "object",
|
|
186
|
+
properties: {
|
|
187
|
+
file_path: {
|
|
188
|
+
type: "string",
|
|
189
|
+
description: "The path to the file to read"
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
required: ["file_path"]
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
type: "function",
|
|
198
|
+
function: {
|
|
199
|
+
name: "write_file",
|
|
200
|
+
description: "Write content to a file",
|
|
201
|
+
parameters: {
|
|
202
|
+
type: "object",
|
|
203
|
+
properties: {
|
|
204
|
+
file_path: {
|
|
205
|
+
type: "string",
|
|
206
|
+
description: "The path to the file to write"
|
|
207
|
+
},
|
|
208
|
+
content: {
|
|
209
|
+
type: "string",
|
|
210
|
+
description: "The content to write to the file"
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
required: ["file_path", "content"]
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
type: "function",
|
|
219
|
+
function: {
|
|
220
|
+
name: "list_files",
|
|
221
|
+
description: "List files in a directory",
|
|
222
|
+
parameters: {
|
|
223
|
+
type: "object",
|
|
224
|
+
properties: {
|
|
225
|
+
directory: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "The directory path to list files from"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
required: ["directory"]
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
|
|
236
|
+
SmartPrompt.define_worker :file_assistant do
|
|
237
|
+
use "claude"
|
|
238
|
+
sys_msg("You are a helpful file management assistant. Use the available file tools to help users manage their files.")
|
|
239
|
+
prompt(params[:message])
|
|
240
|
+
params.merge(tools: file_tools)
|
|
241
|
+
send_msg
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
response = engine.call_worker(:file_assistant, {
|
|
245
|
+
message: "Can you list all files in the /documents folder?"
|
|
246
|
+
})
|
|
247
|
+
puts "User: Can you list all files in the /documents folder?"
|
|
248
|
+
puts "Claude: #{response}\n"
|
|
249
|
+
|
|
250
|
+
# Example 5: API Integration Tool
|
|
251
|
+
puts "\n5. API Integration Tool"
|
|
252
|
+
puts "-" * 60
|
|
253
|
+
|
|
254
|
+
api_tools = [
|
|
255
|
+
{
|
|
256
|
+
type: "function",
|
|
257
|
+
function: {
|
|
258
|
+
name: "fetch_stock_price",
|
|
259
|
+
description: "Fetch the current stock price for a given ticker symbol",
|
|
260
|
+
parameters: {
|
|
261
|
+
type: "object",
|
|
262
|
+
properties: {
|
|
263
|
+
ticker: {
|
|
264
|
+
type: "string",
|
|
265
|
+
description: "The stock ticker symbol (e.g., AAPL, GOOGL)"
|
|
266
|
+
}
|
|
267
|
+
},
|
|
268
|
+
required: ["ticker"]
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
type: "function",
|
|
274
|
+
function: {
|
|
275
|
+
name: "fetch_news",
|
|
276
|
+
description: "Fetch recent news articles about a company or topic",
|
|
277
|
+
parameters: {
|
|
278
|
+
type: "object",
|
|
279
|
+
properties: {
|
|
280
|
+
query: {
|
|
281
|
+
type: "string",
|
|
282
|
+
description: "The search query for news articles"
|
|
283
|
+
},
|
|
284
|
+
limit: {
|
|
285
|
+
type: "number",
|
|
286
|
+
description: "Maximum number of articles to return"
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
required: ["query"]
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
]
|
|
294
|
+
|
|
295
|
+
SmartPrompt.define_worker :market_assistant do
|
|
296
|
+
use "claude"
|
|
297
|
+
sys_msg("You are a financial market assistant. Use the available tools to provide stock prices and news.")
|
|
298
|
+
prompt(params[:message])
|
|
299
|
+
params.merge(tools: api_tools)
|
|
300
|
+
send_msg
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
response = engine.call_worker(:market_assistant, {
|
|
304
|
+
message: "What's the current price of Apple stock and any recent news about the company?"
|
|
305
|
+
})
|
|
306
|
+
puts "User: What's the current price of Apple stock and any recent news about the company?"
|
|
307
|
+
puts "Claude: #{response}\n"
|
|
308
|
+
|
|
309
|
+
# Example 6: Complex Tool with Nested Parameters
|
|
310
|
+
puts "\n6. Complex Tool with Nested Parameters"
|
|
311
|
+
puts "-" * 60
|
|
312
|
+
|
|
313
|
+
search_tool = [
|
|
314
|
+
{
|
|
315
|
+
type: "function",
|
|
316
|
+
function: {
|
|
317
|
+
name: "search_products",
|
|
318
|
+
description: "Search for products in the catalog with advanced filters",
|
|
319
|
+
parameters: {
|
|
320
|
+
type: "object",
|
|
321
|
+
properties: {
|
|
322
|
+
query: {
|
|
323
|
+
type: "string",
|
|
324
|
+
description: "The search query"
|
|
325
|
+
},
|
|
326
|
+
filters: {
|
|
327
|
+
type: "object",
|
|
328
|
+
properties: {
|
|
329
|
+
category: {
|
|
330
|
+
type: "string",
|
|
331
|
+
description: "Product category"
|
|
332
|
+
},
|
|
333
|
+
price_range: {
|
|
334
|
+
type: "object",
|
|
335
|
+
properties: {
|
|
336
|
+
min: { type: "number", description: "Minimum price" },
|
|
337
|
+
max: { type: "number", description: "Maximum price" }
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
in_stock: {
|
|
341
|
+
type: "boolean",
|
|
342
|
+
description: "Only show in-stock items"
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
sort_by: {
|
|
347
|
+
type: "string",
|
|
348
|
+
enum: ["price_asc", "price_desc", "popularity", "newest"],
|
|
349
|
+
description: "How to sort the results"
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
required: ["query"]
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
]
|
|
357
|
+
|
|
358
|
+
SmartPrompt.define_worker :shopping_assistant do
|
|
359
|
+
use "claude"
|
|
360
|
+
sys_msg("You are a helpful shopping assistant. Use the search_products tool to help users find products.")
|
|
361
|
+
prompt(params[:message])
|
|
362
|
+
params.merge(tools: search_tool)
|
|
363
|
+
send_msg
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
response = engine.call_worker(:shopping_assistant, {
|
|
367
|
+
message: "Find me laptops under $1000 that are in stock, sorted by popularity"
|
|
368
|
+
})
|
|
369
|
+
puts "User: Find me laptops under $1000 that are in stock, sorted by popularity"
|
|
370
|
+
puts "Claude: #{response}\n"
|
|
371
|
+
|
|
372
|
+
# Example 7: Tool Calling Best Practices
|
|
373
|
+
puts "\n7. Tool Calling Best Practices"
|
|
374
|
+
puts "-" * 60
|
|
375
|
+
|
|
376
|
+
puts "Best Practices for Tool Calling with Claude:"
|
|
377
|
+
puts "1. Provide clear, descriptive function names"
|
|
378
|
+
puts "2. Write detailed descriptions for functions and parameters"
|
|
379
|
+
puts "3. Use appropriate parameter types (string, number, boolean, object, array)"
|
|
380
|
+
puts "4. Mark required parameters explicitly"
|
|
381
|
+
puts "5. Use enums for parameters with limited valid values"
|
|
382
|
+
puts "6. Include examples in parameter descriptions when helpful"
|
|
383
|
+
puts "7. Keep tool definitions focused and single-purpose"
|
|
384
|
+
puts "8. Test tools with various user queries"
|
|
385
|
+
puts "9. Handle tool errors gracefully in your implementation"
|
|
386
|
+
puts "10. Consider tool execution order for complex workflows\n"
|
|
387
|
+
|
|
388
|
+
puts "\n" + "=" * 60
|
|
389
|
+
puts "Tool calling examples completed!"
|
|
390
|
+
puts "=" * 60
|
|
391
|
+
puts "\nNote: These examples show tool definitions. In a real application,"
|
|
392
|
+
puts "you would implement the actual tool functions and handle the tool"
|
|
393
|
+
puts "calls returned by Claude to execute the requested operations."
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# Example demonstrating automatic cleanup functionality in HistoryManager
|
|
3
|
+
|
|
4
|
+
require_relative '../lib/smart_prompt'
|
|
5
|
+
|
|
6
|
+
puts "=== Automatic Cleanup Example ==="
|
|
7
|
+
puts
|
|
8
|
+
|
|
9
|
+
# Example 1: Manual cleanup with TTL
|
|
10
|
+
puts "1. Manual cleanup with TTL"
|
|
11
|
+
puts "-" * 50
|
|
12
|
+
|
|
13
|
+
manager = SmartPrompt::HistoryManager.new(
|
|
14
|
+
cleanup: {
|
|
15
|
+
auto_cleanup: false, # Manual cleanup
|
|
16
|
+
session_ttl: 5, # 5 seconds TTL
|
|
17
|
+
cleanup_interval: 10
|
|
18
|
+
}
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Create some sessions
|
|
22
|
+
manager.add_message("session1", { role: "user", content: "Message in session 1" })
|
|
23
|
+
manager.add_message("session2", { role: "user", content: "Message in session 2" })
|
|
24
|
+
|
|
25
|
+
puts "Created 2 sessions"
|
|
26
|
+
puts "Active sessions: #{manager.session_ids.join(', ')}"
|
|
27
|
+
puts
|
|
28
|
+
|
|
29
|
+
# Wait for sessions to expire
|
|
30
|
+
puts "Waiting 6 seconds for sessions to expire..."
|
|
31
|
+
sleep(6)
|
|
32
|
+
|
|
33
|
+
# Manually trigger cleanup
|
|
34
|
+
expired = manager.cleanup_expired_sessions
|
|
35
|
+
puts "Cleaned up #{expired.length} expired sessions: #{expired.join(', ')}"
|
|
36
|
+
puts "Active sessions: #{manager.session_ids.join(', ')}"
|
|
37
|
+
puts
|
|
38
|
+
|
|
39
|
+
manager.shutdown
|
|
40
|
+
|
|
41
|
+
# Example 2: Automatic cleanup with background thread
|
|
42
|
+
puts "\n2. Automatic cleanup with background thread"
|
|
43
|
+
puts "-" * 50
|
|
44
|
+
|
|
45
|
+
manager2 = SmartPrompt::HistoryManager.new(
|
|
46
|
+
cleanup: {
|
|
47
|
+
auto_cleanup: true, # Automatic cleanup enabled
|
|
48
|
+
session_ttl: 3, # 3 seconds TTL
|
|
49
|
+
cleanup_interval: 2 # Check every 2 seconds
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Create a session
|
|
54
|
+
manager2.add_message("auto_session", { role: "user", content: "This will be auto-cleaned" })
|
|
55
|
+
puts "Created session: auto_session"
|
|
56
|
+
puts "Active sessions: #{manager2.session_ids.join(', ')}"
|
|
57
|
+
puts
|
|
58
|
+
|
|
59
|
+
# Wait for automatic cleanup to occur
|
|
60
|
+
puts "Waiting 5 seconds for automatic cleanup..."
|
|
61
|
+
sleep(5)
|
|
62
|
+
|
|
63
|
+
puts "Active sessions after automatic cleanup: #{manager2.session_ids.join(', ')}"
|
|
64
|
+
puts
|
|
65
|
+
|
|
66
|
+
manager2.shutdown
|
|
67
|
+
|
|
68
|
+
# Example 3: Custom cleanup callback
|
|
69
|
+
puts "\n3. Custom cleanup callback"
|
|
70
|
+
puts "-" * 50
|
|
71
|
+
|
|
72
|
+
# Custom callback that cleans up sessions with more than 3 messages
|
|
73
|
+
custom_callback = lambda do |session, age|
|
|
74
|
+
# Cleanup if session has more than 3 messages OR is older than 10 seconds
|
|
75
|
+
session.message_count > 3 || age > 10
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
manager3 = SmartPrompt::HistoryManager.new(
|
|
79
|
+
cleanup: {
|
|
80
|
+
auto_cleanup: false,
|
|
81
|
+
session_ttl: 100, # Long TTL, callback will decide
|
|
82
|
+
cleanup_callback: custom_callback
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
# Create sessions with different message counts
|
|
87
|
+
manager3.add_message("small_session", { role: "user", content: "Message 1" })
|
|
88
|
+
manager3.add_message("small_session", { role: "user", content: "Message 2" })
|
|
89
|
+
|
|
90
|
+
manager3.add_message("large_session", { role: "user", content: "Message 1" })
|
|
91
|
+
manager3.add_message("large_session", { role: "user", content: "Message 2" })
|
|
92
|
+
manager3.add_message("large_session", { role: "user", content: "Message 3" })
|
|
93
|
+
manager3.add_message("large_session", { role: "user", content: "Message 4" })
|
|
94
|
+
manager3.add_message("large_session", { role: "user", content: "Message 5" })
|
|
95
|
+
|
|
96
|
+
puts "Created 2 sessions:"
|
|
97
|
+
puts " - small_session: 2 messages"
|
|
98
|
+
puts " - large_session: 5 messages"
|
|
99
|
+
puts
|
|
100
|
+
|
|
101
|
+
# Trigger cleanup with custom callback
|
|
102
|
+
expired = manager3.cleanup_expired_sessions
|
|
103
|
+
puts "Custom callback cleaned up: #{expired.join(', ')}"
|
|
104
|
+
puts "Remaining sessions: #{manager3.session_ids.join(', ')}"
|
|
105
|
+
puts
|
|
106
|
+
|
|
107
|
+
manager3.shutdown
|
|
108
|
+
|
|
109
|
+
puts "\n=== Example Complete ==="
|