swarm_sdk 2.7.0 → 2.7.2
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/lib/swarm_sdk/agent/chat.rb +8 -0
- data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +106 -3
- data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +7 -0
- data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +5 -2
- data/lib/swarm_sdk/models.json +296 -238
- data/lib/swarm_sdk/swarm/logging_callbacks.rb +20 -2
- data/lib/swarm_sdk/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 204f0173ac046d5eae63cf3ddca318e3ab0e76a88661e7f4a106d5079a68ee63
|
|
4
|
+
data.tar.gz: 515a43fac5824b6fab886901449ef808288e8e5e2beaacd02502c0e337a3d98f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 94b2a3d8ee2d4cd61ec45a075b5e9cc370d992e47ae2da7e478abe7aa7f81ebaf2c0cd3571072ed02fdfac1eefc07c8eb5bcfd65aefa46c0cc60298b7e2b30ae
|
|
7
|
+
data.tar.gz: 7e527394023723bfabd8fa18c1696b0dc10b14499fe4c2ba3db46e3c8518158d1d5de8553c41d2139eba3c800f17a739c86503a7366c470ccb9e616446695510
|
data/lib/swarm_sdk/agent/chat.rb
CHANGED
|
@@ -207,6 +207,13 @@ module SwarmSDK
|
|
|
207
207
|
# --- SwarmSDK Abstraction API ---
|
|
208
208
|
# These methods provide SwarmSDK-specific semantics without exposing RubyLLM internals
|
|
209
209
|
|
|
210
|
+
# Check if streaming is enabled for this agent
|
|
211
|
+
#
|
|
212
|
+
# @return [Boolean] true if streaming is enabled
|
|
213
|
+
def streaming_enabled?
|
|
214
|
+
@streaming_enabled
|
|
215
|
+
end
|
|
216
|
+
|
|
210
217
|
# Model information
|
|
211
218
|
def model_id
|
|
212
219
|
@llm_chat.model.id
|
|
@@ -681,6 +688,7 @@ module SwarmSDK
|
|
|
681
688
|
if @streaming_enabled
|
|
682
689
|
# Reset chunk type tracking for new streaming request
|
|
683
690
|
@last_chunk_type = nil
|
|
691
|
+
|
|
684
692
|
@llm_chat.complete(**options) do |chunk|
|
|
685
693
|
emit_content_chunk(chunk)
|
|
686
694
|
end
|
|
@@ -82,6 +82,88 @@ module SwarmSDK
|
|
|
82
82
|
|
|
83
83
|
private
|
|
84
84
|
|
|
85
|
+
# Format citations for appending to response content
|
|
86
|
+
#
|
|
87
|
+
# Creates a markdown-formatted citations section with numbered links.
|
|
88
|
+
#
|
|
89
|
+
# @param citations [Array<String>] Array of citation URLs
|
|
90
|
+
# @return [String] Formatted citations section
|
|
91
|
+
def format_citations(citations)
|
|
92
|
+
return "" if citations.nil? || citations.empty?
|
|
93
|
+
|
|
94
|
+
formatted = "\n\n# Citations\n"
|
|
95
|
+
citations.each_with_index do |citation, index|
|
|
96
|
+
formatted += "- [#{index + 1}] #{citation}\n"
|
|
97
|
+
end
|
|
98
|
+
formatted
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Emit citations as a content_chunk event
|
|
102
|
+
#
|
|
103
|
+
# @param formatted_citations [String] Formatted citations text
|
|
104
|
+
# @param model_id [String] Model identifier
|
|
105
|
+
# @return [void]
|
|
106
|
+
def emit_citations_chunk(formatted_citations, model_id)
|
|
107
|
+
LogStream.emit(
|
|
108
|
+
type: "content_chunk",
|
|
109
|
+
agent: @agent_context.name,
|
|
110
|
+
chunk_type: "citations",
|
|
111
|
+
content: formatted_citations,
|
|
112
|
+
tool_calls: nil,
|
|
113
|
+
model: model_id,
|
|
114
|
+
)
|
|
115
|
+
rescue StandardError => e
|
|
116
|
+
RubyLLM.logger.debug("SwarmSDK: Failed to emit citations chunk: #{e.message}")
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Extract citations and search results from an assistant message
|
|
120
|
+
#
|
|
121
|
+
# These fields are provided by some LLM providers (e.g., Perplexity's sonar models)
|
|
122
|
+
# when the model performs web search or cites sources.
|
|
123
|
+
#
|
|
124
|
+
# @param message [RubyLLM::Message] Assistant message with potential citations
|
|
125
|
+
# @return [Hash] Citations and search results (empty if not present)
|
|
126
|
+
def extract_citations_and_search(message)
|
|
127
|
+
return {} unless message.raw&.body
|
|
128
|
+
|
|
129
|
+
body = message.raw.body
|
|
130
|
+
|
|
131
|
+
# For streaming responses, body might be empty - check Fiber-local
|
|
132
|
+
# (set by LLMInstrumentationMiddleware with accumulated SSE chunks)
|
|
133
|
+
if body.is_a?(String) && body.empty?
|
|
134
|
+
fiber_body = Fiber[:last_sse_body]
|
|
135
|
+
body = fiber_body if fiber_body
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
return {} unless body
|
|
139
|
+
|
|
140
|
+
# Handle SSE streaming responses (body is a string starting with "data:")
|
|
141
|
+
if body.is_a?(String) && body.start_with?("data:")
|
|
142
|
+
# Parse the LAST SSE event which contains citations
|
|
143
|
+
last_data_line = body.split("\n").reverse.find { |l| l.start_with?("data:") && !l.include?("[DONE]") && !l.include?("message_stop") }
|
|
144
|
+
if last_data_line
|
|
145
|
+
body = JSON.parse(last_data_line.sub(/^data:\s*/, ""))
|
|
146
|
+
end
|
|
147
|
+
elsif body.is_a?(String)
|
|
148
|
+
# Regular JSON string response
|
|
149
|
+
body = JSON.parse(body)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Handle Faraday::Response objects (has .body method)
|
|
153
|
+
body = body.body if body.respond_to?(:body) && !body.is_a?(Hash)
|
|
154
|
+
|
|
155
|
+
return {} unless body.is_a?(Hash)
|
|
156
|
+
|
|
157
|
+
result = {}
|
|
158
|
+
result[:citations] = body["citations"] if body["citations"]
|
|
159
|
+
result[:search_results] = body["search_results"] if body["search_results"]
|
|
160
|
+
result
|
|
161
|
+
rescue StandardError => e
|
|
162
|
+
# Includes JSON::ParserError and other parsing errors
|
|
163
|
+
RubyLLM.logger.debug("SwarmSDK: Failed to extract citations: #{e.message}")
|
|
164
|
+
{}
|
|
165
|
+
end
|
|
166
|
+
|
|
85
167
|
# Extract usage information from an assistant message
|
|
86
168
|
#
|
|
87
169
|
# @param message [RubyLLM::Message] Assistant message with usage data
|
|
@@ -202,6 +284,7 @@ module SwarmSDK
|
|
|
202
284
|
return unless @chat.hook_executor
|
|
203
285
|
|
|
204
286
|
usage_info = extract_usage_info(message)
|
|
287
|
+
citations_data = extract_citations_and_search(message)
|
|
205
288
|
|
|
206
289
|
context = Hooks::Context.new(
|
|
207
290
|
event: :agent_step,
|
|
@@ -213,9 +296,11 @@ module SwarmSDK
|
|
|
213
296
|
tool_calls: format_tool_calls(message.tool_calls),
|
|
214
297
|
finish_reason: "tool_calls",
|
|
215
298
|
usage: usage_info,
|
|
299
|
+
citations: citations_data[:citations],
|
|
300
|
+
search_results: citations_data[:search_results],
|
|
216
301
|
tool_executions: tool_executions.empty? ? nil : tool_executions,
|
|
217
302
|
timestamp: Time.now.utc.iso8601,
|
|
218
|
-
},
|
|
303
|
+
}.compact,
|
|
219
304
|
)
|
|
220
305
|
|
|
221
306
|
agent_hooks = @chat.hook_agent_hooks[:agent_step] || []
|
|
@@ -238,6 +323,22 @@ module SwarmSDK
|
|
|
238
323
|
return unless @chat.hook_executor
|
|
239
324
|
|
|
240
325
|
usage_info = extract_usage_info(message)
|
|
326
|
+
citations_data = extract_citations_and_search(message)
|
|
327
|
+
|
|
328
|
+
# Format content with citations appended
|
|
329
|
+
content_with_citations = message.content
|
|
330
|
+
if citations_data[:citations] && !citations_data[:citations].empty?
|
|
331
|
+
formatted_citations = format_citations(citations_data[:citations])
|
|
332
|
+
content_with_citations = message.content + formatted_citations
|
|
333
|
+
|
|
334
|
+
# Also modify the original message for Result.content
|
|
335
|
+
message.content = content_with_citations
|
|
336
|
+
|
|
337
|
+
# Emit citations chunk if streaming is enabled
|
|
338
|
+
if @chat.streaming_enabled?
|
|
339
|
+
emit_citations_chunk(formatted_citations, message.model_id)
|
|
340
|
+
end
|
|
341
|
+
end
|
|
241
342
|
|
|
242
343
|
# Use override if set (e.g., "finish_agent"), otherwise default to "stop"
|
|
243
344
|
finish_reason = @finish_reason_override || "stop"
|
|
@@ -249,13 +350,15 @@ module SwarmSDK
|
|
|
249
350
|
swarm: @chat.hook_swarm,
|
|
250
351
|
metadata: {
|
|
251
352
|
model: message.model_id,
|
|
252
|
-
content:
|
|
353
|
+
content: content_with_citations, # Content with citations appended
|
|
253
354
|
tool_calls: nil, # Final response has no tool calls
|
|
254
355
|
finish_reason: finish_reason,
|
|
255
356
|
usage: usage_info,
|
|
357
|
+
citations: citations_data[:citations],
|
|
358
|
+
search_results: citations_data[:search_results],
|
|
256
359
|
tool_executions: tool_executions.empty? ? nil : tool_executions,
|
|
257
360
|
timestamp: Time.now.utc.iso8601,
|
|
258
|
-
},
|
|
361
|
+
}.compact,
|
|
259
362
|
)
|
|
260
363
|
|
|
261
364
|
agent_hooks = @chat.hook_agent_hooks[:agent_stop] || []
|
|
@@ -13,10 +13,15 @@ module SwarmSDK
|
|
|
13
13
|
#
|
|
14
14
|
# @return [void]
|
|
15
15
|
def inject_llm_instrumentation
|
|
16
|
+
puts "=== inject_llm_instrumentation called ===" if ENV["DEBUG_CITATIONS"]
|
|
16
17
|
return unless @provider
|
|
17
18
|
|
|
19
|
+
puts "=== Has provider ===" if ENV["DEBUG_CITATIONS"]
|
|
20
|
+
|
|
18
21
|
faraday_conn = @provider.connection&.connection
|
|
19
22
|
return unless faraday_conn
|
|
23
|
+
|
|
24
|
+
puts "=== Has faraday connection ===" if ENV["DEBUG_CITATIONS"]
|
|
20
25
|
return if @llm_instrumentation_injected
|
|
21
26
|
|
|
22
27
|
provider_name = @provider.class.name.split("::").last.downcase
|
|
@@ -31,8 +36,10 @@ module SwarmSDK
|
|
|
31
36
|
|
|
32
37
|
@llm_instrumentation_injected = true
|
|
33
38
|
|
|
39
|
+
puts "=== MIDDLEWARE INJECTED ===" if ENV["DEBUG_CITATIONS"]
|
|
34
40
|
RubyLLM.logger.debug("SwarmSDK: Injected LLM instrumentation middleware for agent #{@agent_name}")
|
|
35
41
|
rescue StandardError => e
|
|
42
|
+
puts "=== MIDDLEWARE INJECTION ERROR: #{e.message} ===" if ENV["DEBUG_CITATIONS"]
|
|
36
43
|
LogStream.emit_error(e, source: "instrumentation", context: "inject_middleware", agent: @agent_name)
|
|
37
44
|
RubyLLM.logger.debug("SwarmSDK: Failed to inject LLM instrumentation: #{e.message}")
|
|
38
45
|
end
|
|
@@ -39,8 +39,6 @@ module SwarmSDK
|
|
|
39
39
|
emit_request_event(env, start_time)
|
|
40
40
|
|
|
41
41
|
# Wrap existing on_data to capture raw SSE chunks for streaming
|
|
42
|
-
# This allows us to capture the full streaming response for instrumentation
|
|
43
|
-
# Check if env.request exists and has on_data (only set for streaming requests)
|
|
44
42
|
if env.request&.on_data
|
|
45
43
|
original_on_data = env.request.on_data
|
|
46
44
|
env.request.on_data = proc do |chunk, bytes, response_env|
|
|
@@ -64,6 +62,11 @@ module SwarmSDK
|
|
|
64
62
|
response_env.body
|
|
65
63
|
end
|
|
66
64
|
|
|
65
|
+
# Store SSE body in Fiber-local for citation extraction
|
|
66
|
+
# This allows append_citations_to_content to access the full SSE body
|
|
67
|
+
# even though response.body is empty for streaming responses
|
|
68
|
+
Fiber[:last_sse_body] = raw_body if accumulated_raw_chunks.any?
|
|
69
|
+
|
|
67
70
|
# Emit response event
|
|
68
71
|
emit_response_event(response_env, start_time, end_time, duration, raw_body)
|
|
69
72
|
end
|
data/lib/swarm_sdk/models.json
CHANGED
|
@@ -61,68 +61,6 @@
|
|
|
61
61
|
},
|
|
62
62
|
"metadata": {}
|
|
63
63
|
},
|
|
64
|
-
{
|
|
65
|
-
"id": "claude-opus-4-1",
|
|
66
|
-
"name": "Claude Opus 4.1",
|
|
67
|
-
"provider": "anthropic",
|
|
68
|
-
"family": "claude-opus-4-1",
|
|
69
|
-
"created_at": null,
|
|
70
|
-
"context_window": 200000,
|
|
71
|
-
"max_output_tokens": 32000,
|
|
72
|
-
"knowledge_cutoff": null,
|
|
73
|
-
"modalities": {
|
|
74
|
-
"input": [
|
|
75
|
-
"image",
|
|
76
|
-
"text"
|
|
77
|
-
],
|
|
78
|
-
"output": [
|
|
79
|
-
"text"
|
|
80
|
-
]
|
|
81
|
-
},
|
|
82
|
-
"capabilities": [
|
|
83
|
-
"function_calling"
|
|
84
|
-
],
|
|
85
|
-
"pricing": {
|
|
86
|
-
"text_tokens": {
|
|
87
|
-
"standard": {
|
|
88
|
-
"input_per_million": 15.0,
|
|
89
|
-
"output_per_million": 75.0
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
"metadata": {}
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
"id": "claude-opus-4-1-20250805",
|
|
97
|
-
"name": "Claude Opus 4.1",
|
|
98
|
-
"provider": "anthropic",
|
|
99
|
-
"family": "claude-opus-4-1",
|
|
100
|
-
"created_at": null,
|
|
101
|
-
"context_window": 200000,
|
|
102
|
-
"max_output_tokens": 32000,
|
|
103
|
-
"knowledge_cutoff": null,
|
|
104
|
-
"modalities": {
|
|
105
|
-
"input": [
|
|
106
|
-
"image",
|
|
107
|
-
"text"
|
|
108
|
-
],
|
|
109
|
-
"output": [
|
|
110
|
-
"text"
|
|
111
|
-
]
|
|
112
|
-
},
|
|
113
|
-
"capabilities": [
|
|
114
|
-
"function_calling"
|
|
115
|
-
],
|
|
116
|
-
"pricing": {
|
|
117
|
-
"text_tokens": {
|
|
118
|
-
"standard": {
|
|
119
|
-
"input_per_million": 15.0,
|
|
120
|
-
"output_per_million": 75.0
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
"metadata": {}
|
|
125
|
-
},
|
|
126
64
|
{
|
|
127
65
|
"id": "claude-opus-4-5",
|
|
128
66
|
"name": "Claude Opus 4.5",
|
|
@@ -537,40 +475,6 @@
|
|
|
537
475
|
},
|
|
538
476
|
"metadata": {}
|
|
539
477
|
},
|
|
540
|
-
{
|
|
541
|
-
"id": "gemini-2.0-flash-live-001",
|
|
542
|
-
"name": "Gemini 2.0 Flash Live",
|
|
543
|
-
"provider": "gemini",
|
|
544
|
-
"family": "gemini-2.0-flash-live-001",
|
|
545
|
-
"created_at": null,
|
|
546
|
-
"context_window": 1048576,
|
|
547
|
-
"max_output_tokens": 8192,
|
|
548
|
-
"knowledge_cutoff": null,
|
|
549
|
-
"modalities": {
|
|
550
|
-
"input": [
|
|
551
|
-
"audio",
|
|
552
|
-
"text"
|
|
553
|
-
],
|
|
554
|
-
"output": [
|
|
555
|
-
"audio",
|
|
556
|
-
"text"
|
|
557
|
-
]
|
|
558
|
-
},
|
|
559
|
-
"capabilities": [
|
|
560
|
-
"function_calling",
|
|
561
|
-
"structured_output"
|
|
562
|
-
],
|
|
563
|
-
"pricing": {
|
|
564
|
-
"text_tokens": {
|
|
565
|
-
"standard": {
|
|
566
|
-
"input_per_million": 0.1,
|
|
567
|
-
"cached_input_per_million": 0.025,
|
|
568
|
-
"output_per_million": 0.4
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
},
|
|
572
|
-
"metadata": {}
|
|
573
|
-
},
|
|
574
478
|
{
|
|
575
479
|
"id": "gemini-2.0-flash-preview-image-generation",
|
|
576
480
|
"name": "Gemini 2.0 Flash Preview Image Generation",
|
|
@@ -766,9 +670,9 @@
|
|
|
766
670
|
},
|
|
767
671
|
{
|
|
768
672
|
"id": "gemini-2.5-flash-lite-preview-09-2025",
|
|
769
|
-
"name": "Gemini 2.5 Flash-Lite
|
|
673
|
+
"name": "Gemini 2.5 Flash-Lite",
|
|
770
674
|
"provider": "gemini",
|
|
771
|
-
"family": "gemini-2.5-flash-lite
|
|
675
|
+
"family": "gemini-2.5-flash-lite",
|
|
772
676
|
"created_at": null,
|
|
773
677
|
"context_window": 1048576,
|
|
774
678
|
"max_output_tokens": 65536,
|
|
@@ -807,7 +711,40 @@
|
|
|
807
711
|
"id": "gemini-2.5-flash-native-audio-preview-09-2025",
|
|
808
712
|
"name": "Gemini 2.5 Flash Native Audio Preview",
|
|
809
713
|
"provider": "gemini",
|
|
810
|
-
"family": "gemini-2.5-flash-native-audio-preview
|
|
714
|
+
"family": "gemini-2.5-flash-native-audio-preview",
|
|
715
|
+
"created_at": null,
|
|
716
|
+
"context_window": 131072,
|
|
717
|
+
"max_output_tokens": 8192,
|
|
718
|
+
"knowledge_cutoff": null,
|
|
719
|
+
"modalities": {
|
|
720
|
+
"input": [
|
|
721
|
+
"audio",
|
|
722
|
+
"text"
|
|
723
|
+
],
|
|
724
|
+
"output": [
|
|
725
|
+
"audio",
|
|
726
|
+
"text"
|
|
727
|
+
]
|
|
728
|
+
},
|
|
729
|
+
"capabilities": [
|
|
730
|
+
"function_calling"
|
|
731
|
+
],
|
|
732
|
+
"pricing": {
|
|
733
|
+
"text_tokens": {
|
|
734
|
+
"standard": {
|
|
735
|
+
"input_per_million": 0.3,
|
|
736
|
+
"cached_input_per_million": 0.03,
|
|
737
|
+
"output_per_million": 2.5
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
},
|
|
741
|
+
"metadata": {}
|
|
742
|
+
},
|
|
743
|
+
{
|
|
744
|
+
"id": "gemini-2.5-flash-native-audio-preview-12-2025",
|
|
745
|
+
"name": "Gemini 2.5 Flash Native Audio Preview",
|
|
746
|
+
"provider": "gemini",
|
|
747
|
+
"family": "gemini-2.5-flash-native-audio-preview",
|
|
811
748
|
"created_at": null,
|
|
812
749
|
"context_window": 131072,
|
|
813
750
|
"max_output_tokens": 8192,
|
|
@@ -838,9 +775,9 @@
|
|
|
838
775
|
},
|
|
839
776
|
{
|
|
840
777
|
"id": "gemini-2.5-flash-preview-09-2025",
|
|
841
|
-
"name": "Gemini 2.5 Flash
|
|
778
|
+
"name": "Gemini 2.5 Flash",
|
|
842
779
|
"provider": "gemini",
|
|
843
|
-
"family": "gemini-2.5-flash
|
|
780
|
+
"family": "gemini-2.5-flash",
|
|
844
781
|
"created_at": null,
|
|
845
782
|
"context_window": 1048576,
|
|
846
783
|
"max_output_tokens": 65536,
|
|
@@ -945,28 +882,38 @@
|
|
|
945
882
|
},
|
|
946
883
|
{
|
|
947
884
|
"id": "gemini-2.5-pro-preview-tts",
|
|
948
|
-
"name": "Gemini 2.5 Pro
|
|
885
|
+
"name": "Gemini 2.5 Pro",
|
|
949
886
|
"provider": "gemini",
|
|
950
|
-
"family": "gemini-2.5-pro
|
|
887
|
+
"family": "gemini-2.5-pro",
|
|
951
888
|
"created_at": null,
|
|
952
|
-
"context_window":
|
|
953
|
-
"max_output_tokens":
|
|
889
|
+
"context_window": 1048576,
|
|
890
|
+
"max_output_tokens": 65536,
|
|
954
891
|
"knowledge_cutoff": null,
|
|
955
892
|
"modalities": {
|
|
956
893
|
"input": [
|
|
894
|
+
"audio",
|
|
895
|
+
"image",
|
|
957
896
|
"text"
|
|
958
897
|
],
|
|
959
898
|
"output": [
|
|
960
|
-
"
|
|
899
|
+
"text"
|
|
961
900
|
]
|
|
962
901
|
},
|
|
963
|
-
"capabilities": [
|
|
902
|
+
"capabilities": [
|
|
903
|
+
"batch",
|
|
904
|
+
"function_calling",
|
|
905
|
+
"structured_output"
|
|
906
|
+
],
|
|
964
907
|
"pricing": {
|
|
965
908
|
"text_tokens": {
|
|
966
909
|
"standard": {
|
|
967
910
|
"input_per_million": 1.25,
|
|
968
911
|
"cached_input_per_million": 0.125,
|
|
969
912
|
"output_per_million": 10.0
|
|
913
|
+
},
|
|
914
|
+
"batch": {
|
|
915
|
+
"input_per_million": 0.625,
|
|
916
|
+
"output_per_million": 5.0
|
|
970
917
|
}
|
|
971
918
|
}
|
|
972
919
|
},
|
|
@@ -1048,39 +995,6 @@
|
|
|
1048
995
|
},
|
|
1049
996
|
"metadata": {}
|
|
1050
997
|
},
|
|
1051
|
-
{
|
|
1052
|
-
"id": "gemini-live-2.5-flash-preview",
|
|
1053
|
-
"name": "Gemini 2.5 Flash Native Audio Preview",
|
|
1054
|
-
"provider": "gemini",
|
|
1055
|
-
"family": "gemini-2.5-flash-native-audio-preview-09-2025",
|
|
1056
|
-
"created_at": null,
|
|
1057
|
-
"context_window": 131072,
|
|
1058
|
-
"max_output_tokens": 8192,
|
|
1059
|
-
"knowledge_cutoff": null,
|
|
1060
|
-
"modalities": {
|
|
1061
|
-
"input": [
|
|
1062
|
-
"audio",
|
|
1063
|
-
"text"
|
|
1064
|
-
],
|
|
1065
|
-
"output": [
|
|
1066
|
-
"audio",
|
|
1067
|
-
"text"
|
|
1068
|
-
]
|
|
1069
|
-
},
|
|
1070
|
-
"capabilities": [
|
|
1071
|
-
"function_calling"
|
|
1072
|
-
],
|
|
1073
|
-
"pricing": {
|
|
1074
|
-
"text_tokens": {
|
|
1075
|
-
"standard": {
|
|
1076
|
-
"input_per_million": 0.3,
|
|
1077
|
-
"cached_input_per_million": 0.03,
|
|
1078
|
-
"output_per_million": 2.5
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
},
|
|
1082
|
-
"metadata": {}
|
|
1083
|
-
},
|
|
1084
998
|
{
|
|
1085
999
|
"id": "babbage-002",
|
|
1086
1000
|
"name": "babbage-002",
|
|
@@ -1140,40 +1054,6 @@
|
|
|
1140
1054
|
},
|
|
1141
1055
|
"metadata": {}
|
|
1142
1056
|
},
|
|
1143
|
-
{
|
|
1144
|
-
"id": "codex-mini-latest",
|
|
1145
|
-
"name": "codex-mini-latest",
|
|
1146
|
-
"provider": "openai",
|
|
1147
|
-
"family": "codex-mini-latest",
|
|
1148
|
-
"created_at": null,
|
|
1149
|
-
"context_window": 200000,
|
|
1150
|
-
"max_output_tokens": 100000,
|
|
1151
|
-
"knowledge_cutoff": null,
|
|
1152
|
-
"modalities": {
|
|
1153
|
-
"input": [
|
|
1154
|
-
"image",
|
|
1155
|
-
"text"
|
|
1156
|
-
],
|
|
1157
|
-
"output": [
|
|
1158
|
-
"embeddings",
|
|
1159
|
-
"text"
|
|
1160
|
-
]
|
|
1161
|
-
},
|
|
1162
|
-
"capabilities": [
|
|
1163
|
-
"function_calling",
|
|
1164
|
-
"structured_output"
|
|
1165
|
-
],
|
|
1166
|
-
"pricing": {
|
|
1167
|
-
"text_tokens": {
|
|
1168
|
-
"standard": {
|
|
1169
|
-
"input_per_million": 1.5,
|
|
1170
|
-
"cached_input_per_million": 0.375,
|
|
1171
|
-
"output_per_million": 6.0
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
},
|
|
1175
|
-
"metadata": {}
|
|
1176
|
-
},
|
|
1177
1057
|
{
|
|
1178
1058
|
"id": "computer-use-preview",
|
|
1179
1059
|
"name": "computer-use-preview",
|
|
@@ -1248,28 +1128,6 @@
|
|
|
1248
1128
|
},
|
|
1249
1129
|
"metadata": {}
|
|
1250
1130
|
},
|
|
1251
|
-
{
|
|
1252
|
-
"id": "dall-e-2",
|
|
1253
|
-
"name": "DALL·E 2",
|
|
1254
|
-
"provider": "openai",
|
|
1255
|
-
"family": "dall-e-2",
|
|
1256
|
-
"created_at": null,
|
|
1257
|
-
"context_window": null,
|
|
1258
|
-
"max_output_tokens": null,
|
|
1259
|
-
"knowledge_cutoff": null,
|
|
1260
|
-
"modalities": {
|
|
1261
|
-
"input": [
|
|
1262
|
-
"text"
|
|
1263
|
-
],
|
|
1264
|
-
"output": [
|
|
1265
|
-
"embeddings",
|
|
1266
|
-
"image"
|
|
1267
|
-
]
|
|
1268
|
-
},
|
|
1269
|
-
"capabilities": [],
|
|
1270
|
-
"pricing": {},
|
|
1271
|
-
"metadata": {}
|
|
1272
|
-
},
|
|
1273
1131
|
{
|
|
1274
1132
|
"id": "dall-e-3",
|
|
1275
1133
|
"name": "DALL·E 3",
|
|
@@ -1292,35 +1150,6 @@
|
|
|
1292
1150
|
"pricing": {},
|
|
1293
1151
|
"metadata": {}
|
|
1294
1152
|
},
|
|
1295
|
-
{
|
|
1296
|
-
"id": "davinci-002",
|
|
1297
|
-
"name": "davinci-002",
|
|
1298
|
-
"provider": "openai",
|
|
1299
|
-
"family": "davinci-002",
|
|
1300
|
-
"created_at": null,
|
|
1301
|
-
"context_window": null,
|
|
1302
|
-
"max_output_tokens": 16384,
|
|
1303
|
-
"knowledge_cutoff": null,
|
|
1304
|
-
"modalities": {
|
|
1305
|
-
"input": [
|
|
1306
|
-
"text"
|
|
1307
|
-
],
|
|
1308
|
-
"output": [
|
|
1309
|
-
"embeddings",
|
|
1310
|
-
"text"
|
|
1311
|
-
]
|
|
1312
|
-
},
|
|
1313
|
-
"capabilities": [],
|
|
1314
|
-
"pricing": {
|
|
1315
|
-
"text_tokens": {
|
|
1316
|
-
"standard": {
|
|
1317
|
-
"input_per_million": 2.0,
|
|
1318
|
-
"output_per_million": 2.0
|
|
1319
|
-
}
|
|
1320
|
-
}
|
|
1321
|
-
},
|
|
1322
|
-
"metadata": {}
|
|
1323
|
-
},
|
|
1324
1153
|
{
|
|
1325
1154
|
"id": "gpt-3.5-turbo",
|
|
1326
1155
|
"name": "GPT-3.5 Turbo",
|
|
@@ -2245,7 +2074,9 @@
|
|
|
2245
2074
|
"text"
|
|
2246
2075
|
]
|
|
2247
2076
|
},
|
|
2248
|
-
"capabilities": [
|
|
2077
|
+
"capabilities": [
|
|
2078
|
+
"structured_output"
|
|
2079
|
+
],
|
|
2249
2080
|
"pricing": {
|
|
2250
2081
|
"text_tokens": {
|
|
2251
2082
|
"standard": {
|
|
@@ -2400,7 +2231,9 @@
|
|
|
2400
2231
|
"text"
|
|
2401
2232
|
]
|
|
2402
2233
|
},
|
|
2403
|
-
"capabilities": [
|
|
2234
|
+
"capabilities": [
|
|
2235
|
+
"structured_output"
|
|
2236
|
+
],
|
|
2404
2237
|
"pricing": {
|
|
2405
2238
|
"text_tokens": {
|
|
2406
2239
|
"standard": {
|
|
@@ -2430,7 +2263,9 @@
|
|
|
2430
2263
|
"text"
|
|
2431
2264
|
]
|
|
2432
2265
|
},
|
|
2433
|
-
"capabilities": [
|
|
2266
|
+
"capabilities": [
|
|
2267
|
+
"structured_output"
|
|
2268
|
+
],
|
|
2434
2269
|
"pricing": {
|
|
2435
2270
|
"text_tokens": {
|
|
2436
2271
|
"standard": {
|
|
@@ -2956,10 +2791,10 @@
|
|
|
2956
2791
|
"metadata": {}
|
|
2957
2792
|
},
|
|
2958
2793
|
{
|
|
2959
|
-
"id": "gpt-5.1-codex-
|
|
2960
|
-
"name": "GPT-5.1
|
|
2794
|
+
"id": "gpt-5.1-codex-max",
|
|
2795
|
+
"name": "GPT-5.1-Codex-Max",
|
|
2961
2796
|
"provider": "openai",
|
|
2962
|
-
"family": "gpt-5.1-codex-
|
|
2797
|
+
"family": "gpt-5.1-codex-max",
|
|
2963
2798
|
"created_at": null,
|
|
2964
2799
|
"context_window": 400000,
|
|
2965
2800
|
"max_output_tokens": 128000,
|
|
@@ -2981,9 +2816,175 @@
|
|
|
2981
2816
|
"pricing": {
|
|
2982
2817
|
"text_tokens": {
|
|
2983
2818
|
"standard": {
|
|
2984
|
-
"input_per_million":
|
|
2985
|
-
"cached_input_per_million": 0.
|
|
2986
|
-
"output_per_million":
|
|
2819
|
+
"input_per_million": 1.25,
|
|
2820
|
+
"cached_input_per_million": 0.125,
|
|
2821
|
+
"output_per_million": 10.0
|
|
2822
|
+
}
|
|
2823
|
+
}
|
|
2824
|
+
},
|
|
2825
|
+
"metadata": {}
|
|
2826
|
+
},
|
|
2827
|
+
{
|
|
2828
|
+
"id": "gpt-5.2",
|
|
2829
|
+
"name": "GPT-5.2",
|
|
2830
|
+
"provider": "openai",
|
|
2831
|
+
"family": "gpt-5.2",
|
|
2832
|
+
"created_at": null,
|
|
2833
|
+
"context_window": 400000,
|
|
2834
|
+
"max_output_tokens": 128000,
|
|
2835
|
+
"knowledge_cutoff": null,
|
|
2836
|
+
"modalities": {
|
|
2837
|
+
"input": [
|
|
2838
|
+
"image",
|
|
2839
|
+
"text"
|
|
2840
|
+
],
|
|
2841
|
+
"output": [
|
|
2842
|
+
"embeddings",
|
|
2843
|
+
"text"
|
|
2844
|
+
]
|
|
2845
|
+
},
|
|
2846
|
+
"capabilities": [
|
|
2847
|
+
"function_calling",
|
|
2848
|
+
"structured_output"
|
|
2849
|
+
],
|
|
2850
|
+
"pricing": {
|
|
2851
|
+
"text_tokens": {
|
|
2852
|
+
"standard": {
|
|
2853
|
+
"input_per_million": 1.75,
|
|
2854
|
+
"cached_input_per_million": 0.175,
|
|
2855
|
+
"output_per_million": 14.0
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
},
|
|
2859
|
+
"metadata": {}
|
|
2860
|
+
},
|
|
2861
|
+
{
|
|
2862
|
+
"id": "gpt-5.2-2025-12-11",
|
|
2863
|
+
"name": "GPT-5.2",
|
|
2864
|
+
"provider": "openai",
|
|
2865
|
+
"family": "gpt-5.2",
|
|
2866
|
+
"created_at": null,
|
|
2867
|
+
"context_window": 400000,
|
|
2868
|
+
"max_output_tokens": 128000,
|
|
2869
|
+
"knowledge_cutoff": null,
|
|
2870
|
+
"modalities": {
|
|
2871
|
+
"input": [
|
|
2872
|
+
"image",
|
|
2873
|
+
"text"
|
|
2874
|
+
],
|
|
2875
|
+
"output": [
|
|
2876
|
+
"embeddings",
|
|
2877
|
+
"text"
|
|
2878
|
+
]
|
|
2879
|
+
},
|
|
2880
|
+
"capabilities": [
|
|
2881
|
+
"function_calling",
|
|
2882
|
+
"structured_output"
|
|
2883
|
+
],
|
|
2884
|
+
"pricing": {
|
|
2885
|
+
"text_tokens": {
|
|
2886
|
+
"standard": {
|
|
2887
|
+
"input_per_million": 1.75,
|
|
2888
|
+
"cached_input_per_million": 0.175,
|
|
2889
|
+
"output_per_million": 14.0
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
},
|
|
2893
|
+
"metadata": {}
|
|
2894
|
+
},
|
|
2895
|
+
{
|
|
2896
|
+
"id": "gpt-5.2-chat-latest",
|
|
2897
|
+
"name": "GPT-5.2 Chat",
|
|
2898
|
+
"provider": "openai",
|
|
2899
|
+
"family": "gpt-5.2-chat-latest",
|
|
2900
|
+
"created_at": null,
|
|
2901
|
+
"context_window": 128000,
|
|
2902
|
+
"max_output_tokens": 16384,
|
|
2903
|
+
"knowledge_cutoff": null,
|
|
2904
|
+
"modalities": {
|
|
2905
|
+
"input": [
|
|
2906
|
+
"image",
|
|
2907
|
+
"text"
|
|
2908
|
+
],
|
|
2909
|
+
"output": [
|
|
2910
|
+
"embeddings",
|
|
2911
|
+
"text"
|
|
2912
|
+
]
|
|
2913
|
+
},
|
|
2914
|
+
"capabilities": [
|
|
2915
|
+
"function_calling",
|
|
2916
|
+
"structured_output"
|
|
2917
|
+
],
|
|
2918
|
+
"pricing": {
|
|
2919
|
+
"text_tokens": {
|
|
2920
|
+
"standard": {
|
|
2921
|
+
"input_per_million": 1.75,
|
|
2922
|
+
"cached_input_per_million": 0.175,
|
|
2923
|
+
"output_per_million": 14.0
|
|
2924
|
+
}
|
|
2925
|
+
}
|
|
2926
|
+
},
|
|
2927
|
+
"metadata": {}
|
|
2928
|
+
},
|
|
2929
|
+
{
|
|
2930
|
+
"id": "gpt-5.2-pro",
|
|
2931
|
+
"name": "GPT-5.2 pro",
|
|
2932
|
+
"provider": "openai",
|
|
2933
|
+
"family": "gpt-5.2-pro",
|
|
2934
|
+
"created_at": null,
|
|
2935
|
+
"context_window": 400000,
|
|
2936
|
+
"max_output_tokens": 128000,
|
|
2937
|
+
"knowledge_cutoff": null,
|
|
2938
|
+
"modalities": {
|
|
2939
|
+
"input": [
|
|
2940
|
+
"image",
|
|
2941
|
+
"text"
|
|
2942
|
+
],
|
|
2943
|
+
"output": [
|
|
2944
|
+
"embeddings",
|
|
2945
|
+
"text"
|
|
2946
|
+
]
|
|
2947
|
+
},
|
|
2948
|
+
"capabilities": [
|
|
2949
|
+
"function_calling"
|
|
2950
|
+
],
|
|
2951
|
+
"pricing": {
|
|
2952
|
+
"text_tokens": {
|
|
2953
|
+
"standard": {
|
|
2954
|
+
"input_per_million": 21.0,
|
|
2955
|
+
"output_per_million": 168.0
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
},
|
|
2959
|
+
"metadata": {}
|
|
2960
|
+
},
|
|
2961
|
+
{
|
|
2962
|
+
"id": "gpt-5.2-pro-2025-12-11",
|
|
2963
|
+
"name": "GPT-5.2 pro",
|
|
2964
|
+
"provider": "openai",
|
|
2965
|
+
"family": "gpt-5.2-pro",
|
|
2966
|
+
"created_at": null,
|
|
2967
|
+
"context_window": 400000,
|
|
2968
|
+
"max_output_tokens": 128000,
|
|
2969
|
+
"knowledge_cutoff": null,
|
|
2970
|
+
"modalities": {
|
|
2971
|
+
"input": [
|
|
2972
|
+
"image",
|
|
2973
|
+
"text"
|
|
2974
|
+
],
|
|
2975
|
+
"output": [
|
|
2976
|
+
"embeddings",
|
|
2977
|
+
"text"
|
|
2978
|
+
]
|
|
2979
|
+
},
|
|
2980
|
+
"capabilities": [
|
|
2981
|
+
"function_calling"
|
|
2982
|
+
],
|
|
2983
|
+
"pricing": {
|
|
2984
|
+
"text_tokens": {
|
|
2985
|
+
"standard": {
|
|
2986
|
+
"input_per_million": 21.0,
|
|
2987
|
+
"output_per_million": 168.0
|
|
2987
2988
|
}
|
|
2988
2989
|
}
|
|
2989
2990
|
},
|
|
@@ -4152,12 +4153,46 @@
|
|
|
4152
4153
|
],
|
|
4153
4154
|
"output": [
|
|
4154
4155
|
"audio",
|
|
4155
|
-
"embeddings"
|
|
4156
|
-
"image"
|
|
4156
|
+
"embeddings"
|
|
4157
4157
|
]
|
|
4158
4158
|
},
|
|
4159
4159
|
"capabilities": [],
|
|
4160
|
-
"pricing": {
|
|
4160
|
+
"pricing": {
|
|
4161
|
+
"text_tokens": {
|
|
4162
|
+
"standard": {
|
|
4163
|
+
"output_per_million": 100000.0
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
4166
|
+
},
|
|
4167
|
+
"metadata": {}
|
|
4168
|
+
},
|
|
4169
|
+
{
|
|
4170
|
+
"id": "sora-2-2025-10-06",
|
|
4171
|
+
"name": "Sora 2",
|
|
4172
|
+
"provider": "openai",
|
|
4173
|
+
"family": "sora-2",
|
|
4174
|
+
"created_at": null,
|
|
4175
|
+
"context_window": null,
|
|
4176
|
+
"max_output_tokens": null,
|
|
4177
|
+
"knowledge_cutoff": null,
|
|
4178
|
+
"modalities": {
|
|
4179
|
+
"input": [
|
|
4180
|
+
"image",
|
|
4181
|
+
"text"
|
|
4182
|
+
],
|
|
4183
|
+
"output": [
|
|
4184
|
+
"audio",
|
|
4185
|
+
"embeddings"
|
|
4186
|
+
]
|
|
4187
|
+
},
|
|
4188
|
+
"capabilities": [],
|
|
4189
|
+
"pricing": {
|
|
4190
|
+
"text_tokens": {
|
|
4191
|
+
"standard": {
|
|
4192
|
+
"output_per_million": 100000.0
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
},
|
|
4161
4196
|
"metadata": {}
|
|
4162
4197
|
},
|
|
4163
4198
|
{
|
|
@@ -4183,6 +4218,29 @@
|
|
|
4183
4218
|
"pricing": {},
|
|
4184
4219
|
"metadata": {}
|
|
4185
4220
|
},
|
|
4221
|
+
{
|
|
4222
|
+
"id": "sora-2-pro-2025-10-06",
|
|
4223
|
+
"name": "Sora 2 Pro",
|
|
4224
|
+
"provider": "openai",
|
|
4225
|
+
"family": "sora-2-pro",
|
|
4226
|
+
"created_at": null,
|
|
4227
|
+
"context_window": null,
|
|
4228
|
+
"max_output_tokens": null,
|
|
4229
|
+
"knowledge_cutoff": null,
|
|
4230
|
+
"modalities": {
|
|
4231
|
+
"input": [
|
|
4232
|
+
"image",
|
|
4233
|
+
"text"
|
|
4234
|
+
],
|
|
4235
|
+
"output": [
|
|
4236
|
+
"audio",
|
|
4237
|
+
"embeddings"
|
|
4238
|
+
]
|
|
4239
|
+
},
|
|
4240
|
+
"capabilities": [],
|
|
4241
|
+
"pricing": {},
|
|
4242
|
+
"metadata": {}
|
|
4243
|
+
},
|
|
4186
4244
|
{
|
|
4187
4245
|
"id": "text-embedding-3-large",
|
|
4188
4246
|
"name": "text-embedding-3-large",
|
|
@@ -4361,6 +4419,7 @@
|
|
|
4361
4419
|
"knowledge_cutoff": null,
|
|
4362
4420
|
"modalities": {
|
|
4363
4421
|
"input": [
|
|
4422
|
+
"audio",
|
|
4364
4423
|
"text"
|
|
4365
4424
|
],
|
|
4366
4425
|
"output": [
|
|
@@ -4420,7 +4479,6 @@
|
|
|
4420
4479
|
"audio"
|
|
4421
4480
|
],
|
|
4422
4481
|
"output": [
|
|
4423
|
-
"audio",
|
|
4424
4482
|
"embeddings",
|
|
4425
4483
|
"text"
|
|
4426
4484
|
]
|
|
@@ -238,7 +238,14 @@ module SwarmSDK
|
|
|
238
238
|
return unless LogStream.emitter
|
|
239
239
|
|
|
240
240
|
metadata_without_duplicates = context.metadata.except(
|
|
241
|
-
:model,
|
|
241
|
+
:model,
|
|
242
|
+
:content,
|
|
243
|
+
:tool_calls,
|
|
244
|
+
:finish_reason,
|
|
245
|
+
:usage,
|
|
246
|
+
:tool_executions,
|
|
247
|
+
:citations,
|
|
248
|
+
:search_results,
|
|
242
249
|
)
|
|
243
250
|
|
|
244
251
|
LogStream.emit(
|
|
@@ -251,6 +258,8 @@ module SwarmSDK
|
|
|
251
258
|
tool_calls: context.metadata[:tool_calls],
|
|
252
259
|
finish_reason: context.metadata[:finish_reason],
|
|
253
260
|
usage: context.metadata[:usage],
|
|
261
|
+
citations: context.metadata[:citations],
|
|
262
|
+
search_results: context.metadata[:search_results],
|
|
254
263
|
tool_executions: context.metadata[:tool_executions],
|
|
255
264
|
metadata: metadata_without_duplicates,
|
|
256
265
|
)
|
|
@@ -261,7 +270,14 @@ module SwarmSDK
|
|
|
261
270
|
return unless LogStream.emitter
|
|
262
271
|
|
|
263
272
|
metadata_without_duplicates = context.metadata.except(
|
|
264
|
-
:model,
|
|
273
|
+
:model,
|
|
274
|
+
:content,
|
|
275
|
+
:tool_calls,
|
|
276
|
+
:finish_reason,
|
|
277
|
+
:usage,
|
|
278
|
+
:tool_executions,
|
|
279
|
+
:citations,
|
|
280
|
+
:search_results,
|
|
265
281
|
)
|
|
266
282
|
|
|
267
283
|
LogStream.emit(
|
|
@@ -274,6 +290,8 @@ module SwarmSDK
|
|
|
274
290
|
tool_calls: context.metadata[:tool_calls],
|
|
275
291
|
finish_reason: context.metadata[:finish_reason],
|
|
276
292
|
usage: context.metadata[:usage],
|
|
293
|
+
citations: context.metadata[:citations],
|
|
294
|
+
search_results: context.metadata[:search_results],
|
|
277
295
|
tool_executions: context.metadata[:tool_executions],
|
|
278
296
|
metadata: metadata_without_duplicates,
|
|
279
297
|
)
|
data/lib/swarm_sdk/version.rb
CHANGED