multiwoven-integrations 0.41.10 → 0.41.11

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 (31) hide show
  1. checksums.yaml +4 -4
  2. data/lib/multiwoven/integrations/core/base_connector.rb +36 -5
  3. data/lib/multiwoven/integrations/core/constants.rb +1 -0
  4. data/lib/multiwoven/integrations/core/open_router_catalog.rb +16 -3
  5. data/lib/multiwoven/integrations/rollout.rb +5 -1
  6. data/lib/multiwoven/integrations/source/azure_open_ai/client.rb +25 -0
  7. data/lib/multiwoven/integrations/source/azure_open_ai/config/catalog.json +6 -0
  8. data/lib/multiwoven/integrations/source/azure_open_ai/config/meta.json +22 -0
  9. data/lib/multiwoven/integrations/source/azure_open_ai/config/spec.json +71 -0
  10. data/lib/multiwoven/integrations/source/azure_open_ai/icon.svg +9 -0
  11. data/lib/multiwoven/integrations/source/generic_open_ai/client.rb +2 -0
  12. data/lib/multiwoven/integrations/source/groq/client.rb +21 -0
  13. data/lib/multiwoven/integrations/source/groq/config/catalog.json +6 -0
  14. data/lib/multiwoven/integrations/source/groq/config/meta.json +22 -0
  15. data/lib/multiwoven/integrations/source/groq/config/models.json +126 -0
  16. data/lib/multiwoven/integrations/source/groq/config/spec.json +71 -0
  17. data/lib/multiwoven/integrations/source/groq/icon.svg +4 -0
  18. data/lib/multiwoven/integrations/source/open_router/client.rb +16 -0
  19. data/lib/multiwoven/integrations/source/open_router/config/catalog.json +6 -0
  20. data/lib/multiwoven/integrations/source/open_router/config/meta.json +23 -0
  21. data/lib/multiwoven/integrations/source/open_router/config/models.json +4 -0
  22. data/lib/multiwoven/integrations/source/open_router/config/spec.json +71 -0
  23. data/lib/multiwoven/integrations/source/open_router/icon.svg +4 -0
  24. data/lib/multiwoven/integrations/source/xai/client.rb +18 -0
  25. data/lib/multiwoven/integrations/source/xai/config/catalog.json +6 -0
  26. data/lib/multiwoven/integrations/source/xai/config/meta.json +23 -0
  27. data/lib/multiwoven/integrations/source/xai/config/models.json +4 -0
  28. data/lib/multiwoven/integrations/source/xai/config/spec.json +71 -0
  29. data/lib/multiwoven/integrations/source/xai/icon.svg +7 -0
  30. data/lib/multiwoven/integrations.rb +5 -1
  31. metadata +25 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bca80f558a046bf547203d290844fd167499851db1282cb0f939787aa39c6c3c
4
- data.tar.gz: 59e9a9e02fc05b8ca2fcfc2efd1e0f2a7b2c032165137c41846451c27c89a679
3
+ metadata.gz: e78743031c41b84a06b73d14d7ed2cd6e1dd99b447287f41ab568c7a5b469efe
4
+ data.tar.gz: c9e9abf49955adf2697f15c7365efbb4599c41da74cd890383731c73851f74e3
5
5
  SHA512:
6
- metadata.gz: 2b3207fb708fc988fd090a1e6f040cbb427b170208f9fb5537bf9216733e5c14a75a3acb9e27e815059d56508a22c6fd4347d8b88b5bce2a7484a356960992ef
7
- data.tar.gz: 59bdabef23a0379bebd7905c57b50199b79dfc8e74bcf9e24ea5beb180f2492c02a5c901895a83d3ba871dc05769a5230749f20643383b2b6413697ac5d103bb
6
+ metadata.gz: 5a1ae308ad0319221b49a05fad29b16a44c1b2f87d5dc55ff0ddbb2ff39db101ca022b565d9c9025b7dc2262838fff4bb2733f8fd92bf21ee0381ca6b8c9546f
7
+ data.tar.gz: eff59ef28784b9c5c52bd3a7887cf966d887b9e55c187eb4250d6347176788104c734f6e435fdfdc776758812b5aecbbda29256380d59980b8fe851dc9f87d9b
@@ -102,14 +102,45 @@ module Multiwoven
102
102
 
103
103
  def excluded_model?(model)
104
104
  openrouter_id = (model&.dig(:openrouter_id) || model&.dig("openrouter_id")).to_s
105
- model_id = (model&.dig(:id) || model&.dig("id")).to_s
106
105
  return false if openrouter_id.empty?
107
106
 
108
- return excluded_openai_model?(model_id) if openrouter_id.start_with?("openai/")
109
- return excluded_anthropic_model?(model_id) if openrouter_id.start_with?("anthropic/")
110
- return excluded_google_gemini_model?(model_id) if openrouter_id.start_with?("google/")
107
+ # Provider routing uses openrouter_id; list/version checks use the catalog
108
+ # id we show/send (after model_id_overrides), not the openrouter_id segment.
109
+ normalized_id = openrouter_id.delete_prefix("~")
110
+ model_id = (model&.dig(:id) || model&.dig("id")).to_s
111
+
112
+ # Gateway catalogs only honor OPEN_ROUTER_EXCLUDE_PROVIDERS. First-party
113
+ # lists (OPENAI_EXCLUDE_MODELS, etc.) mean "unsupported on that API", not
114
+ # "hide from OpenRouter which can still serve it".
115
+ if open_router_gateway?
116
+ excluded_openrouter_provider?(normalized_id)
117
+ else
118
+ excluded_model_for_provider?(normalized_id, model_id)
119
+ end
120
+ end
121
+
122
+ # OPEN_ROUTER_EXCLUDE_PROVIDERS only applies to the OpenRouter gateway catalog
123
+ # (openrouter_slug: "*"). First-party connectors reuse openrouter_id prefixes
124
+ # like "openai/..." and must not be emptied by that env var.
125
+ def open_router_gateway?
126
+ meta_data.dig(:data, :openrouter_slug).to_s == "*"
127
+ end
128
+
129
+ def excluded_model_for_provider?(openrouter_id, model_id)
130
+ case openrouter_id
131
+ when %r{\Aopenai/} then excluded_openai_model?(model_id)
132
+ when %r{\Aanthropic/} then excluded_anthropic_model?(model_id)
133
+ when %r{\Agoogle/} then excluded_google_gemini_model?(model_id)
134
+ else false
135
+ end
136
+ end
111
137
 
112
- false
138
+ def excluded_openrouter_provider?(openrouter_id)
139
+ provider = openrouter_id.to_s.split("/", 2).first
140
+ @open_router_exclude_providers ||= OPEN_ROUTER_EXCLUDE_PROVIDERS.split(",").map do |entry|
141
+ entry.strip.downcase
142
+ end.reject(&:empty?)
143
+ @open_router_exclude_providers.include?(provider.downcase)
113
144
  end
114
145
 
115
146
  def excluded_openai_model?(model_id)
@@ -19,6 +19,7 @@ module Multiwoven
19
19
  OPENAI_EXCLUDE_MODELS = ENV["OPENAI_EXCLUDE_MODELS"] || ""
20
20
  ANTHROPIC_EXCLUDE_MODELS = ENV["ANTHROPIC_EXCLUDE_MODELS"] || ""
21
21
  GOOGLE_GEMINI_EXCLUDE_MODELS = ENV["GOOGLE_GEMINI_EXCLUDE_MODELS"] || ""
22
+ OPEN_ROUTER_EXCLUDE_PROVIDERS = ENV["OPEN_ROUTER_EXCLUDE_PROVIDERS"] || ""
22
23
 
23
24
  # CONNECTORS
24
25
  INSTALL_HTTPFS_QUERY = ENV["INSTALL_HTTPFS_QUERY"] || "INSTALL HTTPFS; LOAD HTTPFS;"
@@ -3,8 +3,10 @@
3
3
  module Multiwoven
4
4
  module Integrations::Core
5
5
  # Live model metadata from OpenRouter's public /models endpoint, so a connector
6
- # need not ship prices that go stale. Providers opt in with an openrouter_slug;
7
- # embeddings and partner-hosted models stay curated in models.json.
6
+ # need not ship prices that go stale. Providers opt in via meta.json:
7
+ # - openrouter_slug: "<author>" → BaseConnector#live_models for that author
8
+ # - openrouter_slug: "*" → full catalog with provider/model ids (gateways)
9
+ # Embeddings and partner-hosted models stay curated in models.json.
8
10
  class OpenRouterCatalog
9
11
  MODELS_URL = "https://openrouter.ai/api/v1/models"
10
12
  CACHE_KEY = "multiwoven_open_router_catalog_v1"
@@ -13,10 +15,21 @@ module Multiwoven
13
15
  PER_MILLION = 1_000_000
14
16
 
15
17
  Result = Struct.new(:models_by_slug, :fetched_at, :source, keyword_init: true) do
18
+ # "*" returns every provider's models with full OpenRouter ids
19
+ # (provider/model) for gateways like OpenRouter, LiteLLM, Portkey.
16
20
  def models_for(slug)
17
21
  return [] if slug.blank?
18
22
 
19
- models_by_slug.fetch(slug.to_s.downcase, [])
23
+ key = slug.to_s.downcase
24
+ return all_models_with_openrouter_ids if key == "*"
25
+
26
+ models_by_slug.fetch(key, [])
27
+ end
28
+
29
+ def all_models_with_openrouter_ids
30
+ models_by_slug.values.flatten.map do |model|
31
+ model.merge(id: model[:openrouter_id].presence || model[:id])
32
+ end
20
33
  end
21
34
  end
22
35
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Multiwoven
4
4
  module Integrations
5
- VERSION = "0.41.10"
5
+ VERSION = "0.41.11"
6
6
 
7
7
  ENABLED_SOURCES = %w[
8
8
  Snowflake
@@ -29,6 +29,10 @@ module Multiwoven
29
29
  GenericOpenAI
30
30
  GoogleGemini
31
31
  JohnSnowLabs
32
+ AzureOpenAI
33
+ Xai
34
+ Groq
35
+ OpenRouter
32
36
  IntuitQuickBooks
33
37
  PineconeDB
34
38
  Qdrant
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven::Integrations::Source
4
+ module AzureOpenAI
5
+ include Multiwoven::Integrations::Core
6
+ # Azure OpenAI exposes an OpenAI-compatible chat completions API, so request,
7
+ # streaming and response handling reuse GenericOpenAI. Auth uses Azure's
8
+ # api-key header rather than Bearer.
9
+ class Client < GenericOpenAI::Client
10
+ private
11
+
12
+ def log_context
13
+ "AZURE OPEN AI"
14
+ end
15
+
16
+ def auth_headers(access_token)
17
+ {
18
+ "Accept" => "application/json",
19
+ "api-key" => access_token.to_s,
20
+ "Content-Type" => "application/json"
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,6 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "streams": []
6
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "data": {
3
+ "name": "AzureOpenAI",
4
+ "title": "Azure OpenAI",
5
+ "connector_type": "source",
6
+ "category": "AI Model",
7
+ "sub_category": "LLM",
8
+ "provider_type": "cloud_provider",
9
+ "display_order": 130,
10
+ "description": "Azure-hosted OpenAI models via your resource deployment endpoint. Use your Azure OpenAI API key and deployment-specific chat completions URL.",
11
+ "documentation_url": "https://learn.microsoft.com/en-us/azure/ai-foundry/openai/reference",
12
+ "github_issue_label": "source-azure-open-ai",
13
+ "icon": "https://res.cloudinary.com/dspflukeu/image/upload/v1789523456/Multiwoven/connectors/azure_open_ai/icon.svg",
14
+ "license": "MIT",
15
+ "release_stage": "alpha",
16
+ "support_level": "community",
17
+ "tags": [
18
+ "language:ruby",
19
+ "multiwoven"
20
+ ]
21
+ }
22
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "documentation_url": "https://learn.microsoft.com/en-us/azure/ai-foundry/openai/reference",
3
+ "stream_type": "user_defined",
4
+ "connector_query_type": "ai_ml",
5
+ "connection_specification": {
6
+ "$schema": "http://json-schema.org/draft-07/schema#",
7
+ "title": "Azure OpenAI",
8
+ "type": "object",
9
+ "x-dynamic-input-path": "messages.0.content",
10
+ "x-output-path": "choices.0.message.content",
11
+ "required": [
12
+ "url",
13
+ "api_key",
14
+ "request_format",
15
+ "response_format"
16
+ ],
17
+ "properties": {
18
+ "url": {
19
+ "type": "string",
20
+ "title": "Endpoint URL",
21
+ "description": "Your Azure OpenAI deployment chat completions URL, including api-version. Example: https://{resource}.openai.azure.com/openai/deployments/{deployment}/chat/completions?api-version=2024-10-21",
22
+ "default": "https://{resource}.openai.azure.com/openai/deployments/{deployment}/chat/completions?api-version=2024-10-21",
23
+ "order": 0
24
+ },
25
+ "api_key": {
26
+ "type": "string",
27
+ "multiwoven_secret": true,
28
+ "title": "API Key",
29
+ "description": "Your Azure OpenAI resource API key.",
30
+ "order": 1
31
+ },
32
+ "is_stream": {
33
+ "type": "boolean",
34
+ "title": "Enable streaming",
35
+ "description": "Enables data streaming when supported by the model. When true, responses are processed in chunks for immediate delivery. Default is false.",
36
+ "default": false,
37
+ "order": 2
38
+ },
39
+ "config": {
40
+ "title": "",
41
+ "type": "object",
42
+ "properties": {
43
+ "timeout": {
44
+ "type": "string",
45
+ "default": "30",
46
+ "title": "HTTP Timeout",
47
+ "description": "The maximum time, in seconds, to wait for a response from the server before the request is canceled.",
48
+ "order": 0
49
+ }
50
+ },
51
+ "order": 3
52
+ },
53
+ "request_format": {
54
+ "title": "Request Format",
55
+ "description": "Sample Request Format. For Azure OpenAI the model is implied by the deployment in the URL.",
56
+ "type": "string",
57
+ "default": "{\"messages\":[{\"role\": \"user\", \"content\": \"Hi.\"}], \"stream\": false}",
58
+ "x-request-format": true,
59
+ "order": 4
60
+ },
61
+ "response_format": {
62
+ "title": "Response Format",
63
+ "description": "Sample Response Format",
64
+ "type": "string",
65
+ "default": "{\"choices\":[{\"index\": 0, \"message\":{\"role\": \"assistant\", \"content\": \"Hello!\"}, \"finish_reason\": \"stop\"}]}",
66
+ "x-response-format": true,
67
+ "order": 5
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,9 @@
1
+ <svg width="40" height="40" viewBox="0 0 18 18" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <radialGradient id="azure-open-ai-gradient" cx="-67.981" cy="793.199" r=".45" gradientTransform="translate(-17939.03 20368.029) rotate(45) scale(25.091 -34.149)" gradientUnits="userSpaceOnUse">
4
+ <stop offset="0" stop-color="#83B9F9"/>
5
+ <stop offset="1" stop-color="#0078D4"/>
6
+ </radialGradient>
7
+ </defs>
8
+ <path d="M0 2.7V15.3C0 16.791 1.209 18 2.7 18H15.3C16.791 18 18 16.791 18 15.3V2.7C18 1.209 16.791 0 15.3 0H2.7C1.209 0 0 1.209 0 2.7ZM10.8 0V3.6C10.8 7.576 14.024 10.8 18 10.8H14.4C10.424 10.8 7.201 14.022 7.2 17.998V14.4C7.2 10.424 3.976 7.2 0 7.2H3.6C7.576 7.2 10.8 3.976 10.8 0Z" fill="url(#azure-open-ai-gradient)"/>
9
+ </svg>
@@ -34,6 +34,7 @@ module Multiwoven::Integrations::Source
34
34
  # If it's "ai_ml," the server calculates the payload and passes it as a query in the sync config model protocol.
35
35
  # This query is then sent to the AI/ML model.
36
36
  payload = parse_json(sync_config.model.query)
37
+ payload["stream"] = stream
37
38
 
38
39
  if stream
39
40
  run_model_stream(connection_config, payload) { |message| yield message if block_given? }
@@ -55,6 +56,7 @@ module Multiwoven::Integrations::Source
55
56
 
56
57
  def prepare_config(config)
57
58
  config.with_indifferent_access.tap do |conf|
59
+ conf[:config] ||= {}
58
60
  conf[:config][:timeout] ||= 30
59
61
  end
60
62
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven::Integrations::Source
4
+ module Groq
5
+ include Multiwoven::Integrations::Core
6
+ # Groq exposes an OpenAI-compatible chat completions API, so the request,
7
+ # streaming and response handling is identical to GenericOpenAI. Only the
8
+ # config/ directory differs, and BaseConnector#read_json resolves that from
9
+ # this class's own source location.
10
+ #
11
+ # Model Hub stays curated in config/models.json: OpenRouter has no groq/*
12
+ # author, and its meta-llama/* ids are not GroqCloud API ids.
13
+ class Client < GenericOpenAI::Client
14
+ private
15
+
16
+ def log_context
17
+ "GROQ"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "streams": []
6
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "data": {
3
+ "name": "Groq",
4
+ "title": "Groq",
5
+ "connector_type": "source",
6
+ "category": "AI Model",
7
+ "sub_category": "LLM",
8
+ "provider_type": "third_party",
9
+ "display_order": 140,
10
+ "description": "Fast inference for open models on GroqCloud. OpenAI-compatible chat completions endpoint optimized for low latency.",
11
+ "documentation_url": "https://console.groq.com/docs/openai",
12
+ "github_issue_label": "source-groq",
13
+ "icon": "https://res.cloudinary.com/dspflukeu/image/upload/v1789523436/Multiwoven/connectors/groq/icon.svg",
14
+ "license": "MIT",
15
+ "release_stage": "alpha",
16
+ "support_level": "community",
17
+ "tags": [
18
+ "language:ruby",
19
+ "multiwoven"
20
+ ]
21
+ }
22
+ }
@@ -0,0 +1,126 @@
1
+ {
2
+ "//models": "Curated for GroqCloud API ids (https://console.groq.com/docs/models). OpenRouter has no groq/* author slug, and its meta-llama/* / openai/* ids do not match Groq's (e.g. llama-3.3-70b-versatile vs llama-3.3-70b-instruct). Do not set openrouter_slug.",
3
+ "models": [
4
+ {
5
+ "id": "llama-3.1-8b-instant",
6
+ "name": "Llama 3.1 8B Instant",
7
+ "model_type": "llm",
8
+ "type": "completion",
9
+ "tasks": [
10
+ "Text Generation"
11
+ ],
12
+ "context_window": 131072,
13
+ "max_output": 131072,
14
+ "capabilities": [
15
+ "Tool Use",
16
+ "JSON Object Mode"
17
+ ]
18
+ },
19
+ {
20
+ "id": "llama-3.3-70b-versatile",
21
+ "name": "Llama 3.3 70B Versatile",
22
+ "model_type": "llm",
23
+ "type": "completion",
24
+ "tasks": [
25
+ "Text Generation",
26
+ "Reasoning"
27
+ ],
28
+ "context_window": 131072,
29
+ "max_output": 32768,
30
+ "capabilities": [
31
+ "Tool Use",
32
+ "JSON Object Mode"
33
+ ]
34
+ },
35
+ {
36
+ "id": "openai/gpt-oss-120b",
37
+ "name": "GPT OSS 120B",
38
+ "model_type": "llm",
39
+ "type": "completion",
40
+ "tasks": [
41
+ "Text Generation",
42
+ "Reasoning"
43
+ ],
44
+ "context_window": 131072,
45
+ "max_output": 65536,
46
+ "pricing": {
47
+ "input": 0.15,
48
+ "output": 0.60,
49
+ "cached_read": 0.075,
50
+ "unit": "per_1m_tokens"
51
+ },
52
+ "capabilities": [
53
+ "Tool Use",
54
+ "Browser Search",
55
+ "Code Execution",
56
+ "JSON Object Mode",
57
+ "JSON Schema Mode",
58
+ "Reasoning"
59
+ ]
60
+ },
61
+ {
62
+ "id": "openai/gpt-oss-20b",
63
+ "name": "GPT OSS 20B",
64
+ "model_type": "llm",
65
+ "type": "completion",
66
+ "tasks": [
67
+ "Text Generation",
68
+ "Reasoning"
69
+ ],
70
+ "context_window": 131072,
71
+ "max_output": 65536,
72
+ "pricing": {
73
+ "input": 0.075,
74
+ "output": 0.30,
75
+ "cached_read": 0.0375,
76
+ "unit": "per_1m_tokens"
77
+ },
78
+ "capabilities": [
79
+ "Tool Use",
80
+ "Browser Search",
81
+ "Code Execution",
82
+ "JSON Object Mode",
83
+ "JSON Schema Mode",
84
+ "Reasoning"
85
+ ]
86
+ },
87
+ {
88
+ "id": "groq/compound",
89
+ "name": "Compound",
90
+ "model_type": "llm",
91
+ "type": "completion",
92
+ "tasks": [
93
+ "Text Generation",
94
+ "Reasoning"
95
+ ],
96
+ "context_window": 131072,
97
+ "max_output": 8192,
98
+ "capabilities": [
99
+ "Web Search",
100
+ "Code Execution",
101
+ "Visit Websites",
102
+ "Wolfram Alpha",
103
+ "JSON Object Mode"
104
+ ]
105
+ },
106
+ {
107
+ "id": "groq/compound-mini",
108
+ "name": "Compound Mini",
109
+ "model_type": "llm",
110
+ "type": "completion",
111
+ "tasks": [
112
+ "Text Generation",
113
+ "Reasoning"
114
+ ],
115
+ "context_window": 131072,
116
+ "max_output": 8192,
117
+ "capabilities": [
118
+ "Web Search",
119
+ "Code Execution",
120
+ "Visit Websites",
121
+ "Wolfram Alpha",
122
+ "JSON Object Mode"
123
+ ]
124
+ }
125
+ ]
126
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "documentation_url": "https://console.groq.com/docs/openai",
3
+ "stream_type": "user_defined",
4
+ "connector_query_type": "ai_ml",
5
+ "connection_specification": {
6
+ "$schema": "http://json-schema.org/draft-07/schema#",
7
+ "title": "Groq",
8
+ "type": "object",
9
+ "x-dynamic-input-path": "messages.0.content",
10
+ "x-output-path": "choices.0.message.content",
11
+ "required": [
12
+ "url",
13
+ "api_key",
14
+ "request_format",
15
+ "response_format"
16
+ ],
17
+ "properties": {
18
+ "url": {
19
+ "type": "string",
20
+ "title": "Endpoint URL",
21
+ "description": "The Groq OpenAI-compatible chat completions endpoint.",
22
+ "default": "https://api.groq.com/openai/v1/chat/completions",
23
+ "order": 0
24
+ },
25
+ "api_key": {
26
+ "type": "string",
27
+ "multiwoven_secret": true,
28
+ "title": "API Key",
29
+ "description": "Your GroqCloud API key.",
30
+ "order": 1
31
+ },
32
+ "is_stream": {
33
+ "type": "boolean",
34
+ "title": "Enable streaming",
35
+ "description": "Enables data streaming when supported by the model. When true, responses are processed in chunks for immediate delivery. Default is false.",
36
+ "default": false,
37
+ "order": 2
38
+ },
39
+ "config": {
40
+ "title": "",
41
+ "type": "object",
42
+ "properties": {
43
+ "timeout": {
44
+ "type": "string",
45
+ "default": "30",
46
+ "title": "HTTP Timeout",
47
+ "description": "The maximum time, in seconds, to wait for a response from the server before the request is canceled.",
48
+ "order": 0
49
+ }
50
+ },
51
+ "order": 3
52
+ },
53
+ "request_format": {
54
+ "title": "Request Format",
55
+ "description": "Sample Request Format",
56
+ "type": "string",
57
+ "default": "{\"model\":\"groq/compound\", \"messages\":[{\"role\": \"user\", \"content\": \"Hi.\"}], \"stream\": false}",
58
+ "x-request-format": true,
59
+ "order": 4
60
+ },
61
+ "response_format": {
62
+ "title": "Response Format",
63
+ "description": "Sample Response Format",
64
+ "type": "string",
65
+ "default": "{\"choices\":[{\"index\": 0, \"message\":{\"role\": \"assistant\", \"content\": \"Hello!\"}, \"finish_reason\": \"stop\"}]}",
66
+ "x-response-format": true,
67
+ "order": 5
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,4 @@
1
+ <svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <title>Groq</title>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M12.036 2C8.183 1.965 5.036 5 5 8.781C4.965 12.563 8.055 15.653 11.908 15.688H14.328V13.122H12.036C9.629 13.15 7.656 11.256 7.628 8.892C7.599 6.53 9.529 4.594 11.936 4.566H12.036C14.443 4.566 16.394 6.481 16.401 8.844V15.149C16.401 17.491 14.457 19.399 12.078 19.428C10.941 19.416 9.853 18.967 9.045 18.176L7.194 19.994C8.482 21.286 10.224 22.006 12.029 22H12.121C15.924 21.944 18.979 18.917 19 15.184V8.684C18.907 4.963 15.817 2 12.036 2Z" fill="#000000"/>
4
+ </svg>
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven::Integrations::Source
4
+ module OpenRouter
5
+ include Multiwoven::Integrations::Core
6
+ # OpenAI-compatible gateway. Model Hub loads the full OpenRouter catalog via
7
+ # openrouter_slug: "*" in meta.json (provider/model ids).
8
+ class Client < GenericOpenAI::Client
9
+ private
10
+
11
+ def log_context
12
+ "OPEN ROUTER"
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,6 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "streams": []
6
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "data": {
3
+ "name": "OpenRouter",
4
+ "title": "OpenRouter",
5
+ "connector_type": "source",
6
+ "category": "AI Model",
7
+ "sub_category": "LLM",
8
+ "provider_type": "third_party",
9
+ "display_order": 150,
10
+ "openrouter_slug": "*",
11
+ "description": "Unified OpenAI-compatible gateway to many LLM providers. Use one API key and select models by their OpenRouter id (provider/model).",
12
+ "documentation_url": "https://openrouter.ai/docs/api-reference/overview",
13
+ "github_issue_label": "source-open-router",
14
+ "icon": "https://res.cloudinary.com/dspflukeu/image/upload/v1789523591/Multiwoven/connectors/open_router/icon.svg",
15
+ "license": "MIT",
16
+ "release_stage": "alpha",
17
+ "support_level": "community",
18
+ "tags": [
19
+ "language:ruby",
20
+ "multiwoven"
21
+ ]
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "//models": "Sourced live from OpenRouterCatalog via openrouter_slug: \"*\". Do not hand-curate; add entries here only for models the live catalog does not list.",
3
+ "models": []
4
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "documentation_url": "https://openrouter.ai/docs/api-reference/overview",
3
+ "stream_type": "user_defined",
4
+ "connector_query_type": "ai_ml",
5
+ "connection_specification": {
6
+ "$schema": "http://json-schema.org/draft-07/schema#",
7
+ "title": "OpenRouter",
8
+ "type": "object",
9
+ "x-dynamic-input-path": "messages.0.content",
10
+ "x-output-path": "choices.0.message.content",
11
+ "required": [
12
+ "url",
13
+ "api_key",
14
+ "request_format",
15
+ "response_format"
16
+ ],
17
+ "properties": {
18
+ "url": {
19
+ "type": "string",
20
+ "title": "Endpoint URL",
21
+ "description": "The OpenRouter OpenAI-compatible chat completions endpoint.",
22
+ "default": "https://openrouter.ai/api/v1/chat/completions",
23
+ "order": 0
24
+ },
25
+ "api_key": {
26
+ "type": "string",
27
+ "multiwoven_secret": true,
28
+ "title": "API Key",
29
+ "description": "Your OpenRouter API key.",
30
+ "order": 1
31
+ },
32
+ "is_stream": {
33
+ "type": "boolean",
34
+ "title": "Enable streaming",
35
+ "description": "Enables data streaming when supported by the model. When true, responses are processed in chunks for immediate delivery. Default is false.",
36
+ "default": false,
37
+ "order": 2
38
+ },
39
+ "config": {
40
+ "title": "",
41
+ "type": "object",
42
+ "properties": {
43
+ "timeout": {
44
+ "type": "string",
45
+ "default": "30",
46
+ "title": "HTTP Timeout",
47
+ "description": "The maximum time, in seconds, to wait for a response from the server before the request is canceled.",
48
+ "order": 0
49
+ }
50
+ },
51
+ "order": 3
52
+ },
53
+ "request_format": {
54
+ "title": "Request Format",
55
+ "description": "Sample Request Format. Use the full OpenRouter model id (provider/model).",
56
+ "type": "string",
57
+ "default": "{\"model\":\"openai/gpt-4o-mini\", \"messages\":[{\"role\": \"user\", \"content\": \"Hi.\"}], \"stream\": false}",
58
+ "x-request-format": true,
59
+ "order": 4
60
+ },
61
+ "response_format": {
62
+ "title": "Response Format",
63
+ "description": "Sample Response Format",
64
+ "type": "string",
65
+ "default": "{\"choices\":[{\"index\": 0, \"message\":{\"role\": \"assistant\", \"content\": \"Hello!\"}, \"finish_reason\": \"stop\"}]}",
66
+ "x-response-format": true,
67
+ "order": 5
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,4 @@
1
+ <svg width="40" height="40" viewBox="0 0 1024 730" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <title>OpenRouter</title>
3
+ <path d="M795.893 0C915.776 0 1012.95 97.9963 1012.95 218.88C1012.95 339.764 915.776 437.76 795.893 437.76L1011.2 654.869C1038.55 682.447 1019.18 729.6 980.504 729.6H361.77C161.97 729.6 0 566.273 0 364.8C0 163.327 161.97 0 361.77 0H795.893ZM361.77 145.92C241.89 145.92 144.708 243.916 144.708 364.8C144.708 485.684 241.89 583.68 361.77 583.68C481.649 583.68 578.831 485.684 578.831 364.8C578.831 243.916 481.649 145.92 361.77 145.92Z" fill="#7624F4"/>
4
+ </svg>
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Multiwoven::Integrations::Source
4
+ module Xai
5
+ include Multiwoven::Integrations::Core
6
+ # xAI exposes an OpenAI-compatible chat completions API, so the request,
7
+ # streaming and response handling is identical to GenericOpenAI. Only the
8
+ # config/ directory differs, and BaseConnector#read_json resolves that from
9
+ # this class's own source location.
10
+ class Client < GenericOpenAI::Client
11
+ private
12
+
13
+ def log_context
14
+ "XAI"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ {
2
+ "request_rate_limit": 600,
3
+ "request_rate_limit_unit": "minute",
4
+ "request_rate_concurrency": 10,
5
+ "streams": []
6
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "data": {
3
+ "name": "Xai",
4
+ "title": "xAI",
5
+ "connector_type": "source",
6
+ "category": "AI Model",
7
+ "sub_category": "LLM",
8
+ "provider_type": "third_party",
9
+ "display_order": 160,
10
+ "openrouter_slug": "x-ai",
11
+ "description": "Grok model family from xAI. OpenAI-compatible chat completions endpoint for reasoning and general-purpose generation.",
12
+ "documentation_url": "https://docs.x.ai/docs/guides/chat-completions",
13
+ "github_issue_label": "source-xai",
14
+ "icon": "https://res.cloudinary.com/dspflukeu/image/upload/v1789523733/Multiwoven/connectors/xai/icon.svg",
15
+ "license": "MIT",
16
+ "release_stage": "alpha",
17
+ "support_level": "community",
18
+ "tags": [
19
+ "language:ruby",
20
+ "multiwoven"
21
+ ]
22
+ }
23
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "//models": "Sourced live from OpenRouter via the openrouter_slug in meta.json. Do not hand-curate; add entries here only for models OpenRouter does not list.",
3
+ "models": []
4
+ }
@@ -0,0 +1,71 @@
1
+ {
2
+ "documentation_url": "https://docs.x.ai/docs/guides/chat-completions",
3
+ "stream_type": "user_defined",
4
+ "connector_query_type": "ai_ml",
5
+ "connection_specification": {
6
+ "$schema": "http://json-schema.org/draft-07/schema#",
7
+ "title": "xAI",
8
+ "type": "object",
9
+ "x-dynamic-input-path": "messages.0.content",
10
+ "x-output-path": "choices.0.message.content",
11
+ "required": [
12
+ "url",
13
+ "api_key",
14
+ "request_format",
15
+ "response_format"
16
+ ],
17
+ "properties": {
18
+ "url": {
19
+ "type": "string",
20
+ "title": "Endpoint URL",
21
+ "description": "The xAI OpenAI-compatible chat completions endpoint.",
22
+ "default": "https://api.x.ai/v1/chat/completions",
23
+ "order": 0
24
+ },
25
+ "api_key": {
26
+ "type": "string",
27
+ "multiwoven_secret": true,
28
+ "title": "API Key",
29
+ "description": "Your xAI API key.",
30
+ "order": 1
31
+ },
32
+ "is_stream": {
33
+ "type": "boolean",
34
+ "title": "Enable streaming",
35
+ "description": "Enables data streaming when supported by the model. When true, responses are processed in chunks for immediate delivery. Default is false.",
36
+ "default": false,
37
+ "order": 2
38
+ },
39
+ "config": {
40
+ "title": "",
41
+ "type": "object",
42
+ "properties": {
43
+ "timeout": {
44
+ "type": "string",
45
+ "default": "30",
46
+ "title": "HTTP Timeout",
47
+ "description": "The maximum time, in seconds, to wait for a response from the server before the request is canceled.",
48
+ "order": 0
49
+ }
50
+ },
51
+ "order": 3
52
+ },
53
+ "request_format": {
54
+ "title": "Request Format",
55
+ "description": "Sample Request Format",
56
+ "type": "string",
57
+ "default": "{\"model\":\"grok-3\", \"messages\":[{\"role\": \"user\", \"content\": \"Hi.\"}], \"stream\": false}",
58
+ "x-request-format": true,
59
+ "order": 4
60
+ },
61
+ "response_format": {
62
+ "title": "Response Format",
63
+ "description": "Sample Response Format",
64
+ "type": "string",
65
+ "default": "{\"choices\":[{\"index\": 0, \"message\":{\"role\": \"assistant\", \"content\": \"Hello!\"}, \"finish_reason\": \"stop\"}]}",
66
+ "x-response-format": true,
67
+ "order": 5
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,7 @@
1
+ <svg width="40" height="40" viewBox="0 0 466.04 516.93" xmlns="http://www.w3.org/2000/svg">
2
+ <title>xAI</title>
3
+ <polygon points="0.12 182.71 234.14 516.92 338.15 516.92 104.13 182.71 0.12 182.71"/>
4
+ <polygon points="0 516.92 104.08 516.92 156.08 442.67 104.04 368.34 0 516.92"/>
5
+ <polygon points="466.04 0 361.96 0 182.1 256.86 234.15 331.18 466.04 0"/>
6
+ <polygon points="380.78 516.92 466.04 516.92 466.04 37.16 380.78 158.92 380.78 516.92"/>
7
+ </svg>
@@ -94,9 +94,13 @@ require_relative "integrations/source/watsonx_data/client"
94
94
  require_relative "integrations/source/anthropic/client"
95
95
  require_relative "integrations/source/aws_bedrock_model/client"
96
96
  require_relative "integrations/source/generic_open_ai/client"
97
- # Both subclass GenericOpenAI::Client, so they must load after it.
97
+ # All other sources that subclass GenericOpenAI::Client must load after it.
98
98
  require_relative "integrations/source/google_gemini/client"
99
99
  require_relative "integrations/source/john_snow_labs/client"
100
+ require_relative "integrations/source/azure_open_ai/client"
101
+ require_relative "integrations/source/xai/client"
102
+ require_relative "integrations/source/groq/client"
103
+ require_relative "integrations/source/open_router/client"
100
104
  require_relative "integrations/source/intuit_quick_books/client"
101
105
  require_relative "integrations/source/pinecone_db/client"
102
106
  require_relative "integrations/source/qdrant/client"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multiwoven-integrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.41.10
4
+ version: 0.41.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Subin T P
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-15 00:00:00.000000000 Z
11
+ date: 2026-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -765,6 +765,11 @@ files:
765
765
  - lib/multiwoven/integrations/source/aws_sagemaker_model/config/meta.json
766
766
  - lib/multiwoven/integrations/source/aws_sagemaker_model/config/spec.json
767
767
  - lib/multiwoven/integrations/source/aws_sagemaker_model/icon.svg
768
+ - lib/multiwoven/integrations/source/azure_open_ai/client.rb
769
+ - lib/multiwoven/integrations/source/azure_open_ai/config/catalog.json
770
+ - lib/multiwoven/integrations/source/azure_open_ai/config/meta.json
771
+ - lib/multiwoven/integrations/source/azure_open_ai/config/spec.json
772
+ - lib/multiwoven/integrations/source/azure_open_ai/icon.svg
768
773
  - lib/multiwoven/integrations/source/bigquery/client.rb
769
774
  - lib/multiwoven/integrations/source/bigquery/config/meta.json
770
775
  - lib/multiwoven/integrations/source/bigquery/config/spec.json
@@ -812,6 +817,12 @@ files:
812
817
  - lib/multiwoven/integrations/source/google_vertex_model/config/meta.json
813
818
  - lib/multiwoven/integrations/source/google_vertex_model/config/spec.json
814
819
  - lib/multiwoven/integrations/source/google_vertex_model/icon.svg
820
+ - lib/multiwoven/integrations/source/groq/client.rb
821
+ - lib/multiwoven/integrations/source/groq/config/catalog.json
822
+ - lib/multiwoven/integrations/source/groq/config/meta.json
823
+ - lib/multiwoven/integrations/source/groq/config/models.json
824
+ - lib/multiwoven/integrations/source/groq/config/spec.json
825
+ - lib/multiwoven/integrations/source/groq/icon.svg
815
826
  - lib/multiwoven/integrations/source/http/client.rb
816
827
  - lib/multiwoven/integrations/source/http/config/meta.json
817
828
  - lib/multiwoven/integrations/source/http/config/spec.json
@@ -854,6 +865,12 @@ files:
854
865
  - lib/multiwoven/integrations/source/open_ai/config/models.json
855
866
  - lib/multiwoven/integrations/source/open_ai/config/spec.json
856
867
  - lib/multiwoven/integrations/source/open_ai/icon.svg
868
+ - lib/multiwoven/integrations/source/open_router/client.rb
869
+ - lib/multiwoven/integrations/source/open_router/config/catalog.json
870
+ - lib/multiwoven/integrations/source/open_router/config/meta.json
871
+ - lib/multiwoven/integrations/source/open_router/config/models.json
872
+ - lib/multiwoven/integrations/source/open_router/config/spec.json
873
+ - lib/multiwoven/integrations/source/open_router/icon.svg
857
874
  - lib/multiwoven/integrations/source/oracle_db/client.rb
858
875
  - lib/multiwoven/integrations/source/oracle_db/config/meta.json
859
876
  - lib/multiwoven/integrations/source/oracle_db/config/spec.json
@@ -900,6 +917,12 @@ files:
900
917
  - lib/multiwoven/integrations/source/watsonx_data/config/meta.json
901
918
  - lib/multiwoven/integrations/source/watsonx_data/config/spec.json
902
919
  - lib/multiwoven/integrations/source/watsonx_data/icon.svg
920
+ - lib/multiwoven/integrations/source/xai/client.rb
921
+ - lib/multiwoven/integrations/source/xai/config/catalog.json
922
+ - lib/multiwoven/integrations/source/xai/config/meta.json
923
+ - lib/multiwoven/integrations/source/xai/config/models.json
924
+ - lib/multiwoven/integrations/source/xai/config/spec.json
925
+ - lib/multiwoven/integrations/source/xai/icon.svg
903
926
  - multiwoven-integrations.gemspec
904
927
  - sig/multiwoven/integrations.rbs
905
928
  homepage: https://www.multiwoven.com/