swarm_memory 2.1.4 → 2.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. checksums.yaml +4 -4
  2. data/lib/swarm_memory/version.rb +1 -1
  3. data/lib/swarm_memory.rb +7 -2
  4. metadata +6 -185
  5. data/lib/claude_swarm/base_executor.rb +0 -133
  6. data/lib/claude_swarm/claude_code_executor.rb +0 -349
  7. data/lib/claude_swarm/claude_mcp_server.rb +0 -78
  8. data/lib/claude_swarm/cli.rb +0 -697
  9. data/lib/claude_swarm/commands/ps.rb +0 -215
  10. data/lib/claude_swarm/commands/show.rb +0 -139
  11. data/lib/claude_swarm/configuration.rb +0 -373
  12. data/lib/claude_swarm/hooks/session_start_hook.rb +0 -42
  13. data/lib/claude_swarm/json_handler.rb +0 -91
  14. data/lib/claude_swarm/mcp_generator.rb +0 -243
  15. data/lib/claude_swarm/openai/chat_completion.rb +0 -256
  16. data/lib/claude_swarm/openai/executor.rb +0 -256
  17. data/lib/claude_swarm/openai/responses.rb +0 -319
  18. data/lib/claude_swarm/orchestrator.rb +0 -878
  19. data/lib/claude_swarm/process_tracker.rb +0 -78
  20. data/lib/claude_swarm/session_cost_calculator.rb +0 -209
  21. data/lib/claude_swarm/session_path.rb +0 -42
  22. data/lib/claude_swarm/settings_generator.rb +0 -77
  23. data/lib/claude_swarm/system_utils.rb +0 -46
  24. data/lib/claude_swarm/templates/generation_prompt.md.erb +0 -230
  25. data/lib/claude_swarm/tools/reset_session_tool.rb +0 -24
  26. data/lib/claude_swarm/tools/session_info_tool.rb +0 -24
  27. data/lib/claude_swarm/tools/task_tool.rb +0 -63
  28. data/lib/claude_swarm/version.rb +0 -5
  29. data/lib/claude_swarm/worktree_manager.rb +0 -475
  30. data/lib/claude_swarm/yaml_loader.rb +0 -22
  31. data/lib/claude_swarm.rb +0 -67
  32. data/lib/swarm_cli/cli.rb +0 -201
  33. data/lib/swarm_cli/command_registry.rb +0 -61
  34. data/lib/swarm_cli/commands/mcp_serve.rb +0 -130
  35. data/lib/swarm_cli/commands/mcp_tools.rb +0 -148
  36. data/lib/swarm_cli/commands/migrate.rb +0 -55
  37. data/lib/swarm_cli/commands/run.rb +0 -173
  38. data/lib/swarm_cli/config_loader.rb +0 -98
  39. data/lib/swarm_cli/formatters/human_formatter.rb +0 -781
  40. data/lib/swarm_cli/formatters/json_formatter.rb +0 -51
  41. data/lib/swarm_cli/interactive_repl.rb +0 -924
  42. data/lib/swarm_cli/mcp_serve_options.rb +0 -44
  43. data/lib/swarm_cli/mcp_tools_options.rb +0 -59
  44. data/lib/swarm_cli/migrate_options.rb +0 -54
  45. data/lib/swarm_cli/migrator.rb +0 -132
  46. data/lib/swarm_cli/options.rb +0 -151
  47. data/lib/swarm_cli/ui/components/agent_badge.rb +0 -33
  48. data/lib/swarm_cli/ui/components/content_block.rb +0 -120
  49. data/lib/swarm_cli/ui/components/divider.rb +0 -57
  50. data/lib/swarm_cli/ui/components/panel.rb +0 -62
  51. data/lib/swarm_cli/ui/components/usage_stats.rb +0 -70
  52. data/lib/swarm_cli/ui/formatters/cost.rb +0 -49
  53. data/lib/swarm_cli/ui/formatters/number.rb +0 -58
  54. data/lib/swarm_cli/ui/formatters/text.rb +0 -77
  55. data/lib/swarm_cli/ui/formatters/time.rb +0 -73
  56. data/lib/swarm_cli/ui/icons.rb +0 -36
  57. data/lib/swarm_cli/ui/renderers/event_renderer.rb +0 -188
  58. data/lib/swarm_cli/ui/state/agent_color_cache.rb +0 -45
  59. data/lib/swarm_cli/ui/state/depth_tracker.rb +0 -40
  60. data/lib/swarm_cli/ui/state/spinner_manager.rb +0 -170
  61. data/lib/swarm_cli/ui/state/usage_tracker.rb +0 -62
  62. data/lib/swarm_cli/version.rb +0 -5
  63. data/lib/swarm_cli.rb +0 -46
  64. data/lib/swarm_sdk/agent/RETRY_LOGIC.md +0 -127
  65. data/lib/swarm_sdk/agent/builder.rb +0 -552
  66. data/lib/swarm_sdk/agent/chat.rb +0 -774
  67. data/lib/swarm_sdk/agent/chat_helpers/context_tracker.rb +0 -268
  68. data/lib/swarm_sdk/agent/chat_helpers/event_emitter.rb +0 -204
  69. data/lib/swarm_sdk/agent/chat_helpers/hook_integration.rb +0 -480
  70. data/lib/swarm_sdk/agent/chat_helpers/instrumentation.rb +0 -78
  71. data/lib/swarm_sdk/agent/chat_helpers/llm_configuration.rb +0 -233
  72. data/lib/swarm_sdk/agent/chat_helpers/logging_helpers.rb +0 -116
  73. data/lib/swarm_sdk/agent/chat_helpers/serialization.rb +0 -83
  74. data/lib/swarm_sdk/agent/chat_helpers/system_reminder_injector.rb +0 -136
  75. data/lib/swarm_sdk/agent/chat_helpers/system_reminders.rb +0 -79
  76. data/lib/swarm_sdk/agent/chat_helpers/token_tracking.rb +0 -98
  77. data/lib/swarm_sdk/agent/context.rb +0 -116
  78. data/lib/swarm_sdk/agent/context_manager.rb +0 -315
  79. data/lib/swarm_sdk/agent/definition.rb +0 -477
  80. data/lib/swarm_sdk/agent/llm_instrumentation_middleware.rb +0 -182
  81. data/lib/swarm_sdk/agent/system_prompt_builder.rb +0 -161
  82. data/lib/swarm_sdk/builders/base_builder.rb +0 -409
  83. data/lib/swarm_sdk/claude_code_agent_adapter.rb +0 -205
  84. data/lib/swarm_sdk/concerns/cleanupable.rb +0 -39
  85. data/lib/swarm_sdk/concerns/snapshotable.rb +0 -67
  86. data/lib/swarm_sdk/concerns/validatable.rb +0 -55
  87. data/lib/swarm_sdk/configuration/parser.rb +0 -353
  88. data/lib/swarm_sdk/configuration/translator.rb +0 -255
  89. data/lib/swarm_sdk/configuration.rb +0 -135
  90. data/lib/swarm_sdk/context_compactor/metrics.rb +0 -147
  91. data/lib/swarm_sdk/context_compactor/token_counter.rb +0 -106
  92. data/lib/swarm_sdk/context_compactor.rb +0 -335
  93. data/lib/swarm_sdk/context_management/builder.rb +0 -128
  94. data/lib/swarm_sdk/context_management/context.rb +0 -328
  95. data/lib/swarm_sdk/defaults.rb +0 -196
  96. data/lib/swarm_sdk/events_to_messages.rb +0 -199
  97. data/lib/swarm_sdk/hooks/adapter.rb +0 -359
  98. data/lib/swarm_sdk/hooks/context.rb +0 -197
  99. data/lib/swarm_sdk/hooks/definition.rb +0 -80
  100. data/lib/swarm_sdk/hooks/error.rb +0 -29
  101. data/lib/swarm_sdk/hooks/executor.rb +0 -146
  102. data/lib/swarm_sdk/hooks/registry.rb +0 -147
  103. data/lib/swarm_sdk/hooks/result.rb +0 -150
  104. data/lib/swarm_sdk/hooks/shell_executor.rb +0 -255
  105. data/lib/swarm_sdk/hooks/tool_call.rb +0 -35
  106. data/lib/swarm_sdk/hooks/tool_result.rb +0 -62
  107. data/lib/swarm_sdk/log_collector.rb +0 -227
  108. data/lib/swarm_sdk/log_stream.rb +0 -127
  109. data/lib/swarm_sdk/markdown_parser.rb +0 -75
  110. data/lib/swarm_sdk/model_aliases.json +0 -8
  111. data/lib/swarm_sdk/models.json +0 -1
  112. data/lib/swarm_sdk/models.rb +0 -120
  113. data/lib/swarm_sdk/node_context.rb +0 -245
  114. data/lib/swarm_sdk/observer/builder.rb +0 -81
  115. data/lib/swarm_sdk/observer/config.rb +0 -45
  116. data/lib/swarm_sdk/observer/manager.rb +0 -236
  117. data/lib/swarm_sdk/patterns/agent_observer.rb +0 -160
  118. data/lib/swarm_sdk/permissions/config.rb +0 -239
  119. data/lib/swarm_sdk/permissions/error_formatter.rb +0 -121
  120. data/lib/swarm_sdk/permissions/path_matcher.rb +0 -35
  121. data/lib/swarm_sdk/permissions/validator.rb +0 -173
  122. data/lib/swarm_sdk/permissions_builder.rb +0 -122
  123. data/lib/swarm_sdk/plugin.rb +0 -309
  124. data/lib/swarm_sdk/plugin_registry.rb +0 -101
  125. data/lib/swarm_sdk/proc_helpers.rb +0 -53
  126. data/lib/swarm_sdk/prompts/base_system_prompt.md.erb +0 -117
  127. data/lib/swarm_sdk/restore_result.rb +0 -65
  128. data/lib/swarm_sdk/result.rb +0 -123
  129. data/lib/swarm_sdk/snapshot.rb +0 -156
  130. data/lib/swarm_sdk/snapshot_from_events.rb +0 -397
  131. data/lib/swarm_sdk/state_restorer.rb +0 -476
  132. data/lib/swarm_sdk/state_snapshot.rb +0 -334
  133. data/lib/swarm_sdk/swarm/agent_initializer.rb +0 -683
  134. data/lib/swarm_sdk/swarm/all_agents_builder.rb +0 -167
  135. data/lib/swarm_sdk/swarm/builder.rb +0 -249
  136. data/lib/swarm_sdk/swarm/executor.rb +0 -213
  137. data/lib/swarm_sdk/swarm/hook_triggers.rb +0 -150
  138. data/lib/swarm_sdk/swarm/logging_callbacks.rb +0 -340
  139. data/lib/swarm_sdk/swarm/mcp_configurator.rb +0 -154
  140. data/lib/swarm_sdk/swarm/swarm_registry_builder.rb +0 -67
  141. data/lib/swarm_sdk/swarm/tool_configurator.rb +0 -358
  142. data/lib/swarm_sdk/swarm.rb +0 -717
  143. data/lib/swarm_sdk/swarm_loader.rb +0 -145
  144. data/lib/swarm_sdk/swarm_registry.rb +0 -136
  145. data/lib/swarm_sdk/tools/bash.rb +0 -282
  146. data/lib/swarm_sdk/tools/clock.rb +0 -44
  147. data/lib/swarm_sdk/tools/delegate.rb +0 -267
  148. data/lib/swarm_sdk/tools/document_converters/base_converter.rb +0 -83
  149. data/lib/swarm_sdk/tools/document_converters/docx_converter.rb +0 -99
  150. data/lib/swarm_sdk/tools/document_converters/html_converter.rb +0 -101
  151. data/lib/swarm_sdk/tools/document_converters/pdf_converter.rb +0 -78
  152. data/lib/swarm_sdk/tools/document_converters/xlsx_converter.rb +0 -194
  153. data/lib/swarm_sdk/tools/edit.rb +0 -145
  154. data/lib/swarm_sdk/tools/glob.rb +0 -166
  155. data/lib/swarm_sdk/tools/grep.rb +0 -235
  156. data/lib/swarm_sdk/tools/image_extractors/docx_image_extractor.rb +0 -43
  157. data/lib/swarm_sdk/tools/image_extractors/pdf_image_extractor.rb +0 -163
  158. data/lib/swarm_sdk/tools/image_formats/tiff_builder.rb +0 -65
  159. data/lib/swarm_sdk/tools/multi_edit.rb +0 -236
  160. data/lib/swarm_sdk/tools/path_resolver.rb +0 -92
  161. data/lib/swarm_sdk/tools/read.rb +0 -261
  162. data/lib/swarm_sdk/tools/registry.rb +0 -205
  163. data/lib/swarm_sdk/tools/scratchpad/scratchpad_list.rb +0 -117
  164. data/lib/swarm_sdk/tools/scratchpad/scratchpad_read.rb +0 -97
  165. data/lib/swarm_sdk/tools/scratchpad/scratchpad_write.rb +0 -108
  166. data/lib/swarm_sdk/tools/stores/read_tracker.rb +0 -96
  167. data/lib/swarm_sdk/tools/stores/scratchpad_storage.rb +0 -272
  168. data/lib/swarm_sdk/tools/stores/storage.rb +0 -142
  169. data/lib/swarm_sdk/tools/stores/todo_manager.rb +0 -65
  170. data/lib/swarm_sdk/tools/think.rb +0 -98
  171. data/lib/swarm_sdk/tools/todo_write.rb +0 -235
  172. data/lib/swarm_sdk/tools/web_fetch.rb +0 -262
  173. data/lib/swarm_sdk/tools/write.rb +0 -112
  174. data/lib/swarm_sdk/utils.rb +0 -68
  175. data/lib/swarm_sdk/validation_result.rb +0 -33
  176. data/lib/swarm_sdk/version.rb +0 -5
  177. data/lib/swarm_sdk/workflow/agent_config.rb +0 -79
  178. data/lib/swarm_sdk/workflow/builder.rb +0 -143
  179. data/lib/swarm_sdk/workflow/executor.rb +0 -497
  180. data/lib/swarm_sdk/workflow/node_builder.rb +0 -555
  181. data/lib/swarm_sdk/workflow/transformer_executor.rb +0 -249
  182. data/lib/swarm_sdk/workflow.rb +0 -554
  183. data/lib/swarm_sdk.rb +0 -524
  184. /data/lib/swarm_memory/{errors.rb → error.rb} +0 -0
@@ -1,227 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # LogCollector manages subscriber callbacks for log events with filtering support.
5
- #
6
- # This module acts as an emitter implementation that forwards events
7
- # to user-registered callbacks. It's designed to be set as the LogStream
8
- # emitter during swarm execution.
9
- #
10
- # ## Features
11
- #
12
- # - **Filtered Subscriptions**: Subscribe to specific agents, event types, or swarm IDs
13
- # - **Unsubscribe Support**: Remove subscriptions by ID to prevent memory leaks
14
- # - **Error Isolation**: One subscriber's error doesn't break others
15
- # - **Thread Safety**: Fiber-local storage for multi-threaded environments
16
- #
17
- # ## Thread Safety for Multi-Threaded Environments (Puma, Sidekiq)
18
- #
19
- # Subscriptions are stored in Fiber-local storage (Fiber[:log_subscriptions]) instead
20
- # of class instance variables. This ensures callbacks registered in the parent
21
- # thread/fiber are accessible to child fibers created by Async reactor.
22
- #
23
- # Why: In Puma/Sidekiq, class instance variables (@subscriptions) are thread-isolated
24
- # and don't properly propagate to child fibers. Using Fiber-local storage ensures
25
- # events emitted from within Async blocks can reach registered subscriptions.
26
- #
27
- # Child fibers inherit parent fiber-local storage automatically, so events
28
- # emitted from agent callbacks (on_tool_call, on_end_message, etc.) executing
29
- # in child fibers can still reach the parent's registered subscriptions.
30
- #
31
- # ## Usage
32
- #
33
- # # Subscribe to all events
34
- # sub_id = LogCollector.subscribe { |event| puts event }
35
- #
36
- # # Subscribe to specific agent
37
- # sub_id = LogCollector.subscribe(filter: { agent: :backend }) { |event|
38
- # puts "Backend: #{event}"
39
- # }
40
- #
41
- # # Subscribe to specific event types
42
- # sub_id = LogCollector.subscribe(filter: { type: ["tool_call", "tool_result"] }) { |event|
43
- # log_tool_activity(event)
44
- # }
45
- #
46
- # # Subscribe with regex matching
47
- # sub_id = LogCollector.subscribe(filter: { type: /^tool_/ }) { |event|
48
- # track_tool_usage(event)
49
- # }
50
- #
51
- # # Unsubscribe when done
52
- # LogCollector.unsubscribe(sub_id)
53
- #
54
- # # After execution, reset for next use
55
- # LogCollector.reset!
56
- #
57
- module LogCollector
58
- # Subscription object with filtering capabilities
59
- #
60
- # Encapsulates a callback with optional filters. Filters can match
61
- # against agent name, event type, swarm_id, or any event field.
62
- class Subscription
63
- attr_reader :id, :filter, :callback
64
-
65
- # Initialize a subscription
66
- #
67
- # @param filter [Hash] Filter criteria
68
- # @param callback [Proc] Block to call when event matches
69
- def initialize(filter: {}, &callback)
70
- @id = SecureRandom.uuid
71
- @filter = normalize_filter(filter)
72
- @callback = callback
73
- end
74
-
75
- # Check if event matches filter criteria
76
- #
77
- # Empty filter matches all events. Multiple filter keys are AND'd together.
78
- #
79
- # @param event [Hash] Event entry with :type, :agent, etc.
80
- # @return [Boolean] True if event matches filter
81
- def matches?(event)
82
- return true if @filter.empty?
83
-
84
- @filter.all? do |key, matcher|
85
- value = event[key]
86
- case matcher
87
- when Array
88
- # Match if value is in array (handles symbols/strings)
89
- matcher.include?(value) || matcher.map(&:to_s).include?(value.to_s)
90
- when Regexp
91
- # Regex matching
92
- value.to_s.match?(matcher)
93
- when Proc
94
- # Custom matcher
95
- matcher.call(value)
96
- else
97
- # Exact match (handles symbols/strings)
98
- matcher == value || matcher.to_s == value.to_s
99
- end
100
- end
101
- end
102
-
103
- private
104
-
105
- # Normalize filter keys to symbols for consistent matching
106
- #
107
- # @param filter [Hash] Raw filter
108
- # @return [Hash] Normalized filter with symbol keys
109
- def normalize_filter(filter)
110
- filter.transform_keys(&:to_sym)
111
- end
112
- end
113
-
114
- class << self
115
- # Subscribe to log events with optional filtering
116
- #
117
- # Registers a callback that will receive events matching the filter criteria.
118
- # Returns a subscription ID that can be used to unsubscribe later.
119
- #
120
- # @param filter [Hash] Filter criteria (empty = all events)
121
- # - :agent [Symbol, String, Array, Regexp] Agent name(s) to observe
122
- # - :type [String, Array, Regexp] Event type(s) to receive
123
- # - :swarm_id [String] Specific swarm instance
124
- # - Any other key matches against event fields
125
- # @yield [Hash] Log event entry
126
- # @return [String] Subscription ID for unsubscribe
127
- #
128
- # @example Subscribe to all events
129
- # LogCollector.subscribe { |event| puts event }
130
- #
131
- # @example Subscribe to specific agent's tool calls
132
- # sub_id = LogCollector.subscribe(
133
- # filter: { agent: :backend, type: /^tool_/ }
134
- # ) do |event|
135
- # puts "Backend used tool: #{event[:tool]}"
136
- # end
137
- #
138
- # @example Subscribe to multiple agents
139
- # LogCollector.subscribe(
140
- # filter: { agent: [:backend, :frontend], type: "agent_stop" }
141
- # ) { |e| record_completion(e) }
142
- def subscribe(filter: {}, &block)
143
- subscription = Subscription.new(filter: filter, &block)
144
- subscriptions << subscription
145
- subscription.id
146
- end
147
-
148
- # Unsubscribe by ID
149
- #
150
- # Removes a subscription to prevent memory leaks and stop receiving events.
151
- #
152
- # @param subscription_id [String] ID returned from subscribe
153
- # @return [Subscription, nil] Removed subscription or nil if not found
154
- def unsubscribe(subscription_id)
155
- index = subscriptions.find_index { |s| s.id == subscription_id }
156
- return unless index
157
-
158
- subscriptions.delete_at(index)
159
- end
160
-
161
- # Clear all subscriptions
162
- #
163
- # Removes all subscriptions. Useful for testing or execution cleanup.
164
- #
165
- # @return [void]
166
- def clear_subscriptions
167
- subscriptions.clear
168
- end
169
-
170
- # Get current subscription count
171
- #
172
- # @return [Integer] Number of active subscriptions
173
- def subscription_count
174
- subscriptions.size
175
- end
176
-
177
- # Emit an event to all matching subscribers
178
- #
179
- # Automatically adds a timestamp if one doesn't exist.
180
- # Errors in individual subscribers are isolated - one bad subscriber
181
- # won't prevent others from receiving events.
182
- #
183
- # @param entry [Hash] Log event entry
184
- # @return [void]
185
- def emit(entry)
186
- entry_with_timestamp = ensure_timestamp(entry)
187
-
188
- subscriptions.each do |subscription|
189
- next unless subscription.matches?(entry_with_timestamp)
190
-
191
- begin
192
- subscription.callback.call(entry_with_timestamp)
193
- rescue StandardError => e
194
- # Error isolation - don't let one subscriber break others
195
- RubyLLM.logger.error("SwarmSDK: Subscription #{subscription.id} error: #{e.message}")
196
- end
197
- end
198
- end
199
-
200
- # Reset the collector (clears subscriptions for next execution)
201
- #
202
- # @return [void]
203
- def reset!
204
- Fiber[:log_subscriptions] = []
205
- end
206
-
207
- private
208
-
209
- # Get subscriptions from Fiber-local storage
210
- #
211
- # @return [Array<Subscription>] Current subscriptions
212
- def subscriptions
213
- Fiber[:log_subscriptions] ||= []
214
- end
215
-
216
- # Ensure event has a timestamp
217
- #
218
- # @param entry [Hash] Event entry
219
- # @return [Hash] Entry with timestamp
220
- def ensure_timestamp(entry)
221
- return entry if entry.key?(:timestamp)
222
-
223
- entry.merge(timestamp: Time.now.utc.iso8601(6))
224
- end
225
- end
226
- end
227
- end
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # LogStream provides a module-level singleton for emitting log events.
5
- #
6
- # This allows any component (tools, providers, agents) to emit structured
7
- # log events without needing references to logger instances.
8
- #
9
- # ## Usage
10
- #
11
- # # Emit an event from anywhere in the SDK
12
- # LogStream.emit(
13
- # type: "user_prompt",
14
- # agent: :backend,
15
- # model: "claude-sonnet-4",
16
- # message_count: 5
17
- # )
18
- #
19
- # ## Thread Safety
20
- #
21
- # LogStream is thread-safe and fiber-safe:
22
- # - Uses Fiber storage for per-request isolation in multi-threaded servers (Puma, Sidekiq)
23
- # - Each thread/request has its own emitter instance
24
- # - Child fibers inherit the emitter from their parent fiber
25
- # - No cross-thread contamination of log events
26
- #
27
- # Usage pattern:
28
- # 1. Set emitter BEFORE starting Async execution
29
- # 2. During Async execution, only emit() (reads emitter)
30
- # 3. Each event includes agent context for identification
31
- #
32
- # ## Testing
33
- #
34
- # # Inject a test emitter
35
- # LogStream.emitter = TestEmitter.new
36
- # # ... run tests ...
37
- # LogStream.reset!
38
- #
39
- module LogStream
40
- class << self
41
- # Emit a log event
42
- #
43
- # Adds timestamp and forwards to the registered emitter.
44
- # Auto-injects execution_id, swarm_id, and parent_swarm_id from Fiber storage.
45
- # Explicit values in data override auto-injected ones.
46
- #
47
- # @param data [Hash] Event data (type, agent, and event-specific fields)
48
- # @return [void]
49
- def emit(**data)
50
- emitter = Fiber[:log_stream_emitter]
51
- return unless emitter
52
-
53
- # Auto-inject execution context from Fiber storage
54
- # Explicit values in data override auto-injected ones
55
- auto_injected = {
56
- execution_id: Fiber[:execution_id],
57
- swarm_id: Fiber[:swarm_id],
58
- parent_swarm_id: Fiber[:parent_swarm_id],
59
- }.compact
60
-
61
- entry = auto_injected.merge(data).merge(timestamp: Time.now.utc.iso8601(6)).compact
62
-
63
- emitter.emit(entry)
64
- end
65
-
66
- # Set the emitter (for dependency injection in tests)
67
- #
68
- # Stores emitter in Fiber storage for thread-safe, per-request isolation.
69
- #
70
- # @param emitter [#emit] Object responding to emit(Hash)
71
- # @return [void]
72
- def emitter=(emitter)
73
- Fiber[:log_stream_emitter] = emitter
74
- end
75
-
76
- # Get the current emitter
77
- #
78
- # @return [#emit, nil] Current emitter or nil if not set
79
- def emitter
80
- Fiber[:log_stream_emitter]
81
- end
82
-
83
- # Reset the emitter (for test cleanup)
84
- #
85
- # @return [void]
86
- def reset!
87
- Fiber[:log_stream_emitter] = nil
88
- end
89
-
90
- # Check if logging is enabled
91
- #
92
- # @return [Boolean] true if an emitter is configured
93
- def enabled?
94
- !Fiber[:log_stream_emitter].nil?
95
- end
96
-
97
- # Emit an internal error event
98
- #
99
- # Provides consistent error event emission for all internal errors.
100
- # These are errors that occur during execution but are handled gracefully
101
- # (with fallback behavior) rather than causing failures.
102
- #
103
- # @param error [Exception] The caught exception
104
- # @param source [String] Source module/class (e.g., "hook_triggers", "context_compactor")
105
- # @param context [String] Specific operation context (e.g., "swarm_stop", "summarization")
106
- # @param agent [Symbol, String, nil] Agent name if applicable
107
- # @param metadata [Hash] Additional context data
108
- # @return [void]
109
- def emit_error(error, source:, context:, agent: nil, **metadata)
110
- emit(
111
- type: "internal_error",
112
- source: source,
113
- context: context,
114
- agent: agent,
115
- error_class: error.class.name,
116
- error_message: error.message,
117
- backtrace: error.backtrace&.first(5),
118
- **metadata,
119
- )
120
- rescue StandardError
121
- # Absolute fallback - if emit_error itself fails, don't break execution
122
- # This should never happen, but we must be defensive
123
- nil
124
- end
125
- end
126
- end
127
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SwarmSDK
4
- # Parser for agent markdown files with YAML frontmatter
5
- #
6
- # Supports two formats:
7
- # 1. SwarmSDK format - YAML frontmatter with array-based tools
8
- # 2. Claude Code format - Detected and converted via ClaudeCodeAgentAdapter
9
- #
10
- # Format detection is automatic based on frontmatter structure.
11
- class MarkdownParser
12
- FRONTMATTER_PATTERN = /\A---\s*\n(.*?)\n---\s*\n(.*)\z/m
13
-
14
- class << self
15
- # Parse markdown content into an Agent::Definition
16
- #
17
- # Automatically detects format (SwarmSDK or Claude Code) and routes
18
- # to appropriate parser.
19
- #
20
- # @param content [String] Markdown content with YAML frontmatter
21
- # @param agent_name [Symbol, String, nil] Name of the agent
22
- # @return [Agent::Definition] Parsed agent definition
23
- # @raise [ConfigurationError] if format is invalid
24
- def parse(content, agent_name = nil)
25
- # Detect Claude Code format and route to adapter
26
- if ClaudeCodeAgentAdapter.claude_code_format?(content)
27
- config = ClaudeCodeAgentAdapter.parse(content, agent_name)
28
- # For Claude Code format, agent_name parameter is required since
29
- # the 'name' field in frontmatter is Claude Code specific and not used
30
- unless agent_name
31
- raise ConfigurationError, "Agent name must be provided when parsing Claude Code format"
32
- end
33
-
34
- Agent::Definition.new(agent_name.to_sym, config)
35
- else
36
- # Use standard SwarmSDK format parsing
37
- new(content, agent_name).parse
38
- end
39
- end
40
- end
41
-
42
- def initialize(content, agent_name = nil)
43
- @content = content
44
- @agent_name = agent_name
45
- end
46
-
47
- def parse
48
- if @content =~ FRONTMATTER_PATTERN
49
- frontmatter_yaml = Regexp.last_match(1)
50
- prompt_content = Regexp.last_match(2).strip
51
-
52
- frontmatter = YAML.safe_load(frontmatter_yaml, permitted_classes: [Symbol], aliases: true)
53
-
54
- unless frontmatter.is_a?(Hash)
55
- raise ConfigurationError, "Invalid frontmatter format in agent definition"
56
- end
57
-
58
- # Symbolize keys for AgentDefinition
59
- config = Utils.symbolize_keys(frontmatter).merge(system_prompt: prompt_content)
60
-
61
- name = @agent_name || frontmatter["name"]
62
- unless name
63
- raise ConfigurationError, "Agent definition must include 'name' in frontmatter or be specified externally"
64
- end
65
-
66
- # Convert name to symbol
67
- name = name.to_sym
68
-
69
- Agent::Definition.new(name, config)
70
- else
71
- raise ConfigurationError, "Invalid Markdown agent definition format. Expected YAML frontmatter followed by prompt content."
72
- end
73
- end
74
- end
75
- end
@@ -1,8 +0,0 @@
1
- {
2
- "sonnet": "claude-sonnet-4-5-20250929",
3
- "opus": "claude-opus-4-1-20250805",
4
- "haiku": "claude-haiku-4-5-20251001",
5
- "claude-sonnet-4-5": "claude-sonnet-4-5-20250929",
6
- "claude-opus-4-1": "claude-opus-4-1-20250805",
7
- "claude-haiku-4-5": "claude-haiku-4-5-20251001"
8
- }
@@ -1 +0,0 @@
1
- [{"name":"Claude Sonnet 4.5","id":"claude-sonnet-4-5-20250929","provider":"anthropic","family":"claude-sonnet-4-5","context_window":200000,"max_output_tokens":64000,"modalities":{"input":["image","text"],"output":["text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":3.0,"cached_input_per_million":3.75,"output_per_million":15.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Claude Haiku 4.5","id":"claude-haiku-4-5-20251001","provider":"anthropic","family":"claude-haiku-4-5","context_window":200000,"max_output_tokens":64000,"modalities":{"input":["image","text"],"output":["text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.0,"cached_input_per_million":1.25,"output_per_million":5.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Claude Opus 4.1","id":"claude-opus-4-1-20250805","provider":"anthropic","family":"claude-opus-4-1","context_window":200000,"max_output_tokens":32000,"modalities":{"input":["image","text"],"output":["text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":18.75,"output_per_million":75.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.5 Pro","id":"gemini-2.5-pro","provider":"gemini","family":"gemini-2.5-pro","context_window":1048576,"max_output_tokens":65536,"modalities":{"input":["audio","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.25,"cached_input_per_million":0.125,"output_per_million":10.0},"batch":{"input_per_million":0.625,"output_per_million":5.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.5 Flash","id":"gemini-2.5-flash","provider":"gemini","family":"gemini-2.5-flash","context_window":1048576,"max_output_tokens":65536,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.3,"cached_input_per_million":0.03,"output_per_million":2.5},"batch":{"input_per_million":0.15,"output_per_million":1.25}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.5 Flash-Lite","id":"gemini-2.5-flash-lite","provider":"gemini","family":"gemini-2.5-flash-lite","context_window":1048576,"max_output_tokens":65536,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.3,"cached_input_per_million":0.03,"output_per_million":2.5},"batch":{"input_per_million":0.15,"output_per_million":1.25}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.0 Flash","id":"gemini-2.0-flash","provider":"gemini","family":"gemini-2.0-flash","context_window":1048576,"max_output_tokens":8192,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.0 Flash","id":"gemini-2.0-flash-001","provider":"gemini","family":"gemini-2.0-flash","context_window":1048576,"max_output_tokens":8192,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.0 Flash","id":"gemini-2.0-flash-exp","provider":"gemini","family":"gemini-2.0-flash","context_window":1048576,"max_output_tokens":8192,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.0 Flash-Lite","id":"gemini-2.0-flash-lite","provider":"gemini","family":"gemini-2.0-flash-lite","context_window":1048576,"max_output_tokens":8192,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Gemini 2.0 Flash-Lite","id":"gemini-2.0-flash-lite-001","provider":"gemini","family":"gemini-2.0-flash-lite","context_window":1048576,"max_output_tokens":8192,"modalities":{"input":["audio","image","text"],"output":["text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"deepseek-chat","id":"deepseek-chat","provider":"deepseek","family":"deepseek-chat","context_window":128000,"max_output_tokens":8000,"modalities":{"input":["text"],"output":["text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.28,"cached_input_per_million":0.028,"output_per_million":0.42},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"deepseek-reasoner","id":"deepseek-reasoner","provider":"deepseek","family":"deepseek-reasoner","context_window":null,"max_output_tokens":64000,"modalities":{"input":["text"],"output":["text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5","family":"gpt-5","provider":"openai","id":"gpt-5-2025-08-07","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.25,"cached_input_per_million":0.125,"output_per_million":10.0},"batch":{"input_per_million":0.625,"output_per_million":5.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5","family":"gpt-5","provider":"openai","id":"gpt-5","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.25,"cached_input_per_million":0.125,"output_per_million":10.0},"batch":{"input_per_million":0.625,"output_per_million":5.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 mini","family":"gpt-5-mini","provider":"openai","id":"gpt-5-mini-2025-08-07","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.25,"cached_input_per_million":0.025,"output_per_million":2.0},"batch":{"input_per_million":0.125,"output_per_million":1.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 mini","family":"gpt-5-mini","provider":"openai","id":"gpt-5-mini","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.25,"cached_input_per_million":0.025,"output_per_million":2.0},"batch":{"input_per_million":0.125,"output_per_million":1.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 nano","family":"gpt-5-nano","provider":"openai","id":"gpt-5-nano-2025-08-07","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.05,"cached_input_per_million":0.005,"output_per_million":0.4},"batch":{"input_per_million":0.025,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 nano","family":"gpt-5-nano","provider":"openai","id":"gpt-5-nano","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.05,"cached_input_per_million":0.005,"output_per_million":0.4},"batch":{"input_per_million":0.025,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 pro","family":"gpt-5-pro","provider":"openai","id":"gpt-5-pro-2025-10-06","context_window":400000,"max_output_tokens":272000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":null,"output_per_million":120.0},"batch":{"input_per_million":7.5,"output_per_million":60.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 pro","family":"gpt-5-pro","provider":"openai","id":"gpt-5-pro","context_window":400000,"max_output_tokens":272000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":null,"output_per_million":120.0},"batch":{"input_per_million":7.5,"output_per_million":60.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.1","family":"gpt-4.1","provider":"openai","id":"gpt-4.1-2025-04-14","context_window":1047576,"max_output_tokens":32768,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.5,"output_per_million":8.0},"batch":{"input_per_million":1.0,"output_per_million":4.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.1","family":"gpt-4.1","provider":"openai","id":"gpt-4.1","context_window":1047576,"max_output_tokens":32768,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.5,"output_per_million":8.0},"batch":{"input_per_million":1.0,"output_per_million":4.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-oss-120b","family":"gpt-oss-120b","provider":"openai","id":"gpt-oss-120b","context_window":131072,"max_output_tokens":131072,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-oss-20b","family":"gpt-oss-20b","provider":"openai","id":"gpt-oss-20b","context_window":131072,"max_output_tokens":131072,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Sora 2","family":"sora-2","provider":"openai","id":"sora-2","context_window":null,"max_output_tokens":null,"modalities":{"input":["image","text"],"output":["audio","embeddings"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Sora 2 Pro","family":"sora-2-pro","provider":"openai","id":"sora-2-pro","context_window":null,"max_output_tokens":null,"modalities":{"input":["image","text"],"output":["audio","embeddings"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3-deep-research","family":"o3-deep-research","provider":"openai","id":"o3-deep-research-2025-06-26","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":10.0,"cached_input_per_million":2.5,"output_per_million":40.0},"batch":{"input_per_million":5.0,"output_per_million":20.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3-deep-research","family":"o3-deep-research","provider":"openai","id":"o3-deep-research","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":10.0,"cached_input_per_million":2.5,"output_per_million":40.0},"batch":{"input_per_million":5.0,"output_per_million":20.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o4-mini-deep-research","family":"o4-mini-deep-research","provider":"openai","id":"o4-mini-deep-research-2025-06-26","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.5,"output_per_million":8.0},"batch":{"input_per_million":1.0,"output_per_million":4.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o4-mini-deep-research","family":"o4-mini-deep-research","provider":"openai","id":"o4-mini-deep-research","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.5,"output_per_million":8.0},"batch":{"input_per_million":1.0,"output_per_million":4.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT Image 1","family":"gpt-image-1","provider":"openai","id":"gpt-image-1","context_window":null,"max_output_tokens":null,"modalities":{"input":["image","text"],"output":["embeddings","image"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":5.0,"cached_input_per_million":1.25,"output_per_million":40.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-image-1-mini","family":"gpt-image-1-mini","provider":"openai","id":"gpt-image-1-mini","context_window":null,"max_output_tokens":null,"modalities":{"input":["image","text"],"output":["embeddings","image"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.2,"output_per_million":8.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"DALL·E 3","family":"dall-e-3","provider":"openai","id":"dall-e-3","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["embeddings","image"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini TTS","family":"gpt-4o-mini-tts","provider":"openai","id":"gpt-4o-mini-tts","context_window":2000,"max_output_tokens":null,"modalities":{"input":["text"],"output":["audio","embeddings"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":null,"output_per_million":12.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o Transcribe","family":"gpt-4o-transcribe","provider":"openai","id":"gpt-4o-transcribe","context_window":16000,"max_output_tokens":2000,"modalities":{"input":["audio","text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Transcribe","family":"gpt-4o-mini-transcribe","provider":"openai","id":"gpt-4o-mini-transcribe","context_window":16000,"max_output_tokens":2000,"modalities":{"input":["audio","text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":1.25,"cached_input_per_million":null,"output_per_million":5.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-realtime","family":"gpt-realtime","provider":"openai","id":"gpt-realtime-2025-08-28","context_window":32000,"max_output_tokens":4096,"modalities":{"input":["audio","image","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":4.0,"cached_input_per_million":0.5,"output_per_million":16.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-realtime","family":"gpt-realtime","provider":"openai","id":"gpt-realtime","context_window":32000,"max_output_tokens":4096,"modalities":{"input":["audio","image","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":4.0,"cached_input_per_million":0.5,"output_per_million":16.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-audio","family":"gpt-audio","provider":"openai","id":"gpt-audio-2025-08-28","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-audio","family":"gpt-audio","provider":"openai","id":"gpt-audio","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-realtime-mini","family":"gpt-realtime-mini","provider":"openai","id":"gpt-realtime-mini-2025-10-06","context_window":32000,"max_output_tokens":4096,"modalities":{"input":["audio","image","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":0.06,"output_per_million":2.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-realtime-mini","family":"gpt-realtime-mini","provider":"openai","id":"gpt-realtime-mini","context_window":32000,"max_output_tokens":4096,"modalities":{"input":["audio","image","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":0.06,"output_per_million":2.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-audio-mini","family":"gpt-audio-mini","provider":"openai","id":"gpt-audio-mini-2025-10-06","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":null,"output_per_million":2.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-audio-mini","family":"gpt-audio-mini","provider":"openai","id":"gpt-audio-mini","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":null,"output_per_million":2.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5 Chat","family":"gpt-5-chat-latest","provider":"openai","id":"gpt-5-chat-latest","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.25,"cached_input_per_million":0.125,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"ChatGPT-4o","family":"chatgpt-4o-latest","provider":"openai","id":"chatgpt-4o-latest","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":5.0,"cached_input_per_million":null,"output_per_million":15.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-5-Codex","family":"gpt-5-codex","provider":"openai","id":"gpt-5-codex","context_window":400000,"max_output_tokens":128000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.25,"cached_input_per_million":0.125,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3-pro","family":"o3-pro","provider":"openai","id":"o3-pro-2025-06-10","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":20.0,"cached_input_per_million":null,"output_per_million":80.0},"batch":{"input_per_million":10.0,"output_per_million":40.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3-pro","family":"o3-pro","provider":"openai","id":"o3-pro","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":20.0,"cached_input_per_million":null,"output_per_million":80.0},"batch":{"input_per_million":10.0,"output_per_million":40.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3","family":"o3","provider":"openai","id":"o3-2025-04-16","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.5,"output_per_million":8.0},"batch":{"input_per_million":1.0,"output_per_million":4.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3","family":"o3","provider":"openai","id":"o3","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":0.5,"output_per_million":8.0},"batch":{"input_per_million":1.0,"output_per_million":4.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o4-mini","family":"o4-mini","provider":"openai","id":"o4-mini-2025-04-16","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.1,"cached_input_per_million":0.275,"output_per_million":4.4},"batch":{"input_per_million":0.55,"output_per_million":2.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o4-mini","family":"o4-mini","provider":"openai","id":"o4-mini","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.1,"cached_input_per_million":0.275,"output_per_million":4.4},"batch":{"input_per_million":0.55,"output_per_million":2.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.1 mini","family":"gpt-4.1-mini","provider":"openai","id":"gpt-4.1-mini-2025-04-14","context_window":1047576,"max_output_tokens":32768,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.4,"cached_input_per_million":0.1,"output_per_million":1.6},"batch":{"input_per_million":0.2,"output_per_million":0.8}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.1 mini","family":"gpt-4.1-mini","provider":"openai","id":"gpt-4.1-mini","context_window":1047576,"max_output_tokens":32768,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.4,"cached_input_per_million":0.1,"output_per_million":1.6},"batch":{"input_per_million":0.2,"output_per_million":0.8}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.1 nano","family":"gpt-4.1-nano","provider":"openai","id":"gpt-4.1-nano-2025-04-14","context_window":1047576,"max_output_tokens":32768,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.1 nano","family":"gpt-4.1-nano","provider":"openai","id":"gpt-4.1-nano","context_window":1047576,"max_output_tokens":32768,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":0.025,"output_per_million":0.4},"batch":{"input_per_million":0.05,"output_per_million":0.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1-pro","family":"o1-pro","provider":"openai","id":"o1-pro-2025-03-19","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":150.0,"cached_input_per_million":null,"output_per_million":600.0},"batch":{"input_per_million":75.0,"output_per_million":300.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1-pro","family":"o1-pro","provider":"openai","id":"o1-pro","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":150.0,"cached_input_per_million":null,"output_per_million":600.0},"batch":{"input_per_million":75.0,"output_per_million":300.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"computer-use-preview","family":"computer-use-preview","provider":"openai","id":"computer-use-preview-2025-03-11","context_window":8192,"max_output_tokens":1024,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":3.0,"cached_input_per_million":null,"output_per_million":12.0},"batch":{"input_per_million":1.5,"output_per_million":6.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"computer-use-preview","family":"computer-use-preview","provider":"openai","id":"computer-use-preview","context_window":8192,"max_output_tokens":1024,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":3.0,"cached_input_per_million":null,"output_per_million":12.0},"batch":{"input_per_million":1.5,"output_per_million":6.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Search Preview","family":"gpt-4o-mini-search-preview","provider":"openai","id":"gpt-4o-mini-search-preview-2025-03-11","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.15,"cached_input_per_million":null,"output_per_million":0.6},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Search Preview","family":"gpt-4o-mini-search-preview","provider":"openai","id":"gpt-4o-mini-search-preview","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.15,"cached_input_per_million":null,"output_per_million":0.6},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o Search Preview","family":"gpt-4o-search-preview","provider":"openai","id":"gpt-4o-search-preview-2025-03-11","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o Search Preview","family":"gpt-4o-search-preview","provider":"openai","id":"gpt-4o-search-preview","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.5 Preview (Deprecated)","family":"gpt-4.5-preview","provider":"openai","id":"gpt-4.5-preview-2025-02-27","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":75.0,"cached_input_per_million":37.5,"output_per_million":150.0},"batch":{"input_per_million":37.5,"output_per_million":75.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4.5 Preview (Deprecated)","family":"gpt-4.5-preview","provider":"openai","id":"gpt-4.5-preview","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":75.0,"cached_input_per_million":37.5,"output_per_million":150.0},"batch":{"input_per_million":37.5,"output_per_million":75.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3-mini","family":"o3-mini","provider":"openai","id":"o3-mini-2025-01-31","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.1,"cached_input_per_million":0.55,"output_per_million":4.4},"batch":{"input_per_million":0.55,"output_per_million":2.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o3-mini","family":"o3-mini","provider":"openai","id":"o3-mini","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.1,"cached_input_per_million":0.55,"output_per_million":4.4},"batch":{"input_per_million":0.55,"output_per_million":2.2}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Audio","family":"gpt-4o-mini-audio-preview","provider":"openai","id":"gpt-4o-mini-audio-preview-2024-12-17","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.15,"cached_input_per_million":null,"output_per_million":0.6},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Audio","family":"gpt-4o-mini-audio-preview","provider":"openai","id":"gpt-4o-mini-audio-preview","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.15,"cached_input_per_million":null,"output_per_million":0.6},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Realtime","family":"gpt-4o-mini-realtime-preview","provider":"openai","id":"gpt-4o-mini-realtime-preview-2024-12-17","context_window":16000,"max_output_tokens":4096,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":0.3,"output_per_million":2.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini Realtime","family":"gpt-4o-mini-realtime-preview","provider":"openai","id":"gpt-4o-mini-realtime-preview","context_window":16000,"max_output_tokens":4096,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.6,"cached_input_per_million":0.3,"output_per_million":2.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1","family":"o1","provider":"openai","id":"o1-2024-12-17","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":7.5,"output_per_million":60.0},"batch":{"input_per_million":7.5,"output_per_million":30.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1","family":"o1","provider":"openai","id":"o1","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":7.5,"output_per_million":60.0},"batch":{"input_per_million":7.5,"output_per_million":30.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"omni-moderation","family":"omni-moderation-latest","provider":"openai","id":"omni-moderation-latest","context_window":null,"max_output_tokens":null,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":0.0,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1-mini","family":"o1-mini","provider":"openai","id":"o1-mini-2024-09-12","context_window":128000,"max_output_tokens":65536,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":1.1,"cached_input_per_million":0.55,"output_per_million":4.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1-mini","family":"o1-mini","provider":"openai","id":"o1-mini","context_window":128000,"max_output_tokens":65536,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":1.1,"cached_input_per_million":0.55,"output_per_million":4.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1 Preview","family":"o1-preview","provider":"openai","id":"o1-preview-2024-09-12","context_window":128000,"max_output_tokens":32768,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":7.5,"output_per_million":60.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"o1 Preview","family":"o1-preview","provider":"openai","id":"o1-preview","context_window":128000,"max_output_tokens":32768,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":7.5,"output_per_million":60.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o","family":"gpt-4o","provider":"openai","id":"gpt-4o-2024-08-06","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":1.25,"output_per_million":10.0},"batch":{"input_per_million":1.25,"output_per_million":5.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o","family":"gpt-4o","provider":"openai","id":"gpt-4o","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":1.25,"output_per_million":10.0},"batch":{"input_per_million":1.25,"output_per_million":5.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o Audio","family":"gpt-4o-audio-preview","provider":"openai","id":"gpt-4o-audio-preview","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini","family":"gpt-4o-mini","provider":"openai","id":"gpt-4o-mini-2024-07-18","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.15,"cached_input_per_million":0.075,"output_per_million":0.6},"batch":{"input_per_million":0.075,"output_per_million":0.3}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o mini","family":"gpt-4o-mini","provider":"openai","id":"gpt-4o-mini","context_window":128000,"max_output_tokens":16384,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.15,"cached_input_per_million":0.075,"output_per_million":0.6},"batch":{"input_per_million":0.075,"output_per_million":0.3}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4o Realtime","family":"gpt-4o-realtime-preview","provider":"openai","id":"gpt-4o-realtime-preview","context_window":32000,"max_output_tokens":4096,"modalities":{"input":["audio","text"],"output":["audio","embeddings","text"]},"capabilities":["function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":5.0,"cached_input_per_million":2.5,"output_per_million":20.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4 Turbo","family":"gpt-4-turbo","provider":"openai","id":"gpt-4-turbo-2024-04-09","context_window":128000,"max_output_tokens":4096,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":10.0,"cached_input_per_million":null,"output_per_million":30.0},"batch":{"input_per_million":5.0,"output_per_million":15.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4 Turbo","family":"gpt-4-turbo","provider":"openai","id":"gpt-4-turbo","context_window":128000,"max_output_tokens":4096,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["batch","function_calling"],"pricing":{"text_tokens":{"standard":{"input_per_million":10.0,"cached_input_per_million":null,"output_per_million":30.0},"batch":{"input_per_million":5.0,"output_per_million":15.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"babbage-002","family":"babbage-002","provider":"openai","id":"babbage-002","context_window":null,"max_output_tokens":16384,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":0.4,"cached_input_per_million":null,"output_per_million":0.4},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"codex-mini-latest","family":"codex-mini-latest","provider":"openai","id":"codex-mini-latest","context_window":200000,"max_output_tokens":100000,"modalities":{"input":["image","text"],"output":["embeddings","text"]},"capabilities":["function_calling","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":1.5,"cached_input_per_million":0.375,"output_per_million":6.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"DALL·E 2","family":"dall-e-2","provider":"openai","id":"dall-e-2","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["embeddings","image"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"davinci-002","family":"davinci-002","provider":"openai","id":"davinci-002","context_window":null,"max_output_tokens":16384,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":2.0,"cached_input_per_million":null,"output_per_million":2.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-3.5 Turbo","family":"gpt-3.5-turbo","provider":"openai","id":"gpt-3.5-turbo","context_window":16385,"max_output_tokens":4096,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.5,"cached_input_per_million":null,"output_per_million":1.5},"batch":{"input_per_million":0.25,"output_per_million":0.75}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4","family":"gpt-4","provider":"openai","id":"gpt-4-0613","context_window":8192,"max_output_tokens":8192,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":30.0,"cached_input_per_million":null,"output_per_million":60.0},"batch":{"input_per_million":15.0,"output_per_million":30.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4","family":"gpt-4","provider":"openai","id":"gpt-4","context_window":8192,"max_output_tokens":8192,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":30.0,"cached_input_per_million":null,"output_per_million":60.0},"batch":{"input_per_million":15.0,"output_per_million":30.0}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"GPT-4 Turbo Preview","family":"gpt-4-turbo-preview","provider":"openai","id":"gpt-4-turbo-preview","context_window":128000,"max_output_tokens":4096,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":10.0,"cached_input_per_million":null,"output_per_million":30.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"gpt-4o-transcribe-diarize","family":"gpt-4o-transcribe-diarize","provider":"openai","id":"gpt-4o-transcribe-diarize","context_window":16000,"max_output_tokens":2000,"modalities":{"input":["audio","text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":2.5,"cached_input_per_million":null,"output_per_million":10.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"text-embedding-3-large","family":"text-embedding-3-large","provider":"openai","id":"text-embedding-3-large","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.13,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":0.065,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":0.13},"batch":{"input_per_million":0.065}}}},{"name":"text-embedding-3-small","family":"text-embedding-3-small","provider":"openai","id":"text-embedding-3-small","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch","structured_output"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.02,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":0.01,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":0.02},"batch":{"input_per_million":0.01}}}},{"name":"text-embedding-ada-002","family":"text-embedding-ada-002","provider":"openai","id":"text-embedding-ada-002","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":["batch"],"pricing":{"text_tokens":{"standard":{"input_per_million":0.1,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":0.05,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":0.1},"batch":{"input_per_million":0.05}}}},{"name":"text-moderation","family":"text-moderation-latest","provider":"openai","id":"text-moderation-latest","context_window":null,"max_output_tokens":32768,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":0.0,"cached_input_per_million":null,"output_per_million":0.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"text-moderation-stable","family":"text-moderation-stable","provider":"openai","id":"text-moderation-stable","context_window":null,"max_output_tokens":32768,"modalities":{"input":["text"],"output":["embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":0.0,"cached_input_per_million":null,"output_per_million":0.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"TTS-1","family":"tts-1","provider":"openai","id":"tts-1","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["audio","embeddings"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":15.0,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"TTS-1 HD","family":"tts-1-hd","provider":"openai","id":"tts-1-hd","context_window":null,"max_output_tokens":null,"modalities":{"input":["text"],"output":["audio","embeddings"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":null,"cached_input_per_million":null,"output_per_million":30.0},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}},{"name":"Whisper","family":"whisper-1","provider":"openai","id":"whisper-1","context_window":null,"max_output_tokens":null,"modalities":{"input":["audio"],"output":["audio","embeddings","text"]},"capabilities":[],"pricing":{"text_tokens":{"standard":{"input_per_million":0.006,"cached_input_per_million":null,"output_per_million":null},"batch":{"input_per_million":null,"output_per_million":null}},"embeddings":{"standard":{"input_per_million":null},"batch":{"input_per_million":null}}}}]