multiwoven-integrations 0.41.7 → 0.41.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/multiwoven/integrations/core/base_connector.rb +46 -2
- data/lib/multiwoven/integrations/core/constants.rb +3 -0
- data/lib/multiwoven/integrations/destination/sftp/client.rb +1 -1
- data/lib/multiwoven/integrations/rollout.rb +1 -1
- data/lib/multiwoven/integrations/source/open_ai/client.rb +12 -2
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1b2f25b2f211e2af49f7a5e5ebb7231d6e6a697479a3aea8c9194c2e951f0b34
|
|
4
|
+
data.tar.gz: d7adf1c8bfd2f93a1c953ab2233feabe6c3222a3dc281e9ce651f32a74f6d5d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e9b7989c7cc64fbb6080b4dbcae05d4f0fe427429d962aa8d40a6f9ca8d2ae0de0dc9cc610e2680a4b8d76e614cced6c4215fb5fb5c5ae03e3e598ee038b4614
|
|
7
|
+
data.tar.gz: 5295ae2e994ca6858774d2ec5f7f4b22c087c6aba64ebfb61d783263aafb44b05038e681763b32132388a6a5b95866607d2354135a2bb4da2312a0e62f2c3f5f
|
|
@@ -8,6 +8,14 @@ module Multiwoven
|
|
|
8
8
|
include Constants
|
|
9
9
|
|
|
10
10
|
MAX_ERROR_MESSAGE_LENGTH = 500
|
|
11
|
+
ANTHROPIC_DATE_SUFFIX = /-\d{8}\z/.freeze
|
|
12
|
+
ANTHROPIC_VERSION_PATTERN = /
|
|
13
|
+
\A(?:
|
|
14
|
+
claude-(?:opus|sonnet|haiku)-(\d+)(?:[.-](\d+))?
|
|
15
|
+
|
|
|
16
|
+
claude-(\d+)(?:[.-](\d+))?-(?:opus|sonnet|haiku)
|
|
17
|
+
)\z
|
|
18
|
+
/x.freeze
|
|
11
19
|
|
|
12
20
|
def connector_spec
|
|
13
21
|
@connector_spec ||= ConnectorSpecification.from_json(keys_to_symbols(read_json(CONNECTOR_SPEC_PATH)).to_json)
|
|
@@ -78,9 +86,9 @@ module Multiwoven
|
|
|
78
86
|
private
|
|
79
87
|
|
|
80
88
|
# Only list what the connector can actually serve. No connector has an
|
|
81
|
-
# image-generation payload path
|
|
89
|
+
# image-generation payload path and deprecated models are dropped everywhere.
|
|
82
90
|
def include_model?(model)
|
|
83
|
-
!image_output_model?(model)
|
|
91
|
+
!image_output_model?(model) && !excluded_model?(model)
|
|
84
92
|
end
|
|
85
93
|
|
|
86
94
|
def image_output_model?(model)
|
|
@@ -92,6 +100,42 @@ module Multiwoven
|
|
|
92
100
|
.any? { |value| value.to_s == "embedding" }
|
|
93
101
|
end
|
|
94
102
|
|
|
103
|
+
def excluded_model?(model)
|
|
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
|
+
return false if openrouter_id.empty?
|
|
107
|
+
|
|
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
|
+
|
|
111
|
+
false
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def excluded_openai_model?(model_id)
|
|
115
|
+
@openai_exclude_models ||= OPENAI_EXCLUDE_MODELS.split(",").map(&:strip).reject(&:empty?)
|
|
116
|
+
@openai_exclude_models.include?(model_id)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def excluded_anthropic_model?(model_id)
|
|
120
|
+
threshold = ANTHROPIC_EXCLUDE_MODELS.to_s.strip
|
|
121
|
+
return false if threshold.empty? || !Gem::Version.correct?(threshold)
|
|
122
|
+
|
|
123
|
+
version = anthropic_model_version(model_id)
|
|
124
|
+
return false if version.nil? || !Gem::Version.correct?(version)
|
|
125
|
+
|
|
126
|
+
Gem::Version.new(version) < Gem::Version.new(threshold)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def anthropic_model_version(model_id)
|
|
130
|
+
base = model_id.to_s.sub(ANTHROPIC_DATE_SUFFIX, "")
|
|
131
|
+
match = ANTHROPIC_VERSION_PATTERN.match(base)
|
|
132
|
+
return unless match
|
|
133
|
+
|
|
134
|
+
major = match[1] || match[3]
|
|
135
|
+
minor = match[2] || match[4]
|
|
136
|
+
minor ? "#{major}.#{minor}" : major
|
|
137
|
+
end
|
|
138
|
+
|
|
95
139
|
def read_json(file_path)
|
|
96
140
|
path = Object.const_source_location(self.class.to_s)[0]
|
|
97
141
|
connector_folder = File.dirname(path)
|
|
@@ -16,6 +16,9 @@ module Multiwoven
|
|
|
16
16
|
|
|
17
17
|
JSON_SCHEMA_URL = "https://json-schema.org/draft-07/schema#"
|
|
18
18
|
|
|
19
|
+
OPENAI_EXCLUDE_MODELS = ENV["OPENAI_EXCLUDE_MODELS"] || ""
|
|
20
|
+
ANTHROPIC_EXCLUDE_MODELS = ENV["ANTHROPIC_EXCLUDE_MODELS"] || ""
|
|
21
|
+
|
|
19
22
|
# CONNECTORS
|
|
20
23
|
INSTALL_HTTPFS_QUERY = ENV["INSTALL_HTTPFS_QUERY"] || "INSTALL HTTPFS; LOAD HTTPFS;"
|
|
21
24
|
|
|
@@ -67,7 +67,7 @@ module Multiwoven::Integrations::Destination
|
|
|
67
67
|
def write_compressed_data(connection_config, file_path, local_file_name, csv_content, records_size)
|
|
68
68
|
write_success = 0
|
|
69
69
|
Tempfile.create([local_file_name, ".zip"]) do |tempfile|
|
|
70
|
-
Zip::File.open(tempfile.path,
|
|
70
|
+
Zip::File.open(tempfile.path, create: true) do |zipfile|
|
|
71
71
|
zipfile.get_output_stream("#{local_file_name}.csv") { |f| f.write(csv_content) }
|
|
72
72
|
end
|
|
73
73
|
with_sftp_client(connection_config) do |sftp|
|
|
@@ -72,8 +72,10 @@ module Multiwoven::Integrations::Source
|
|
|
72
72
|
end
|
|
73
73
|
|
|
74
74
|
# Some OpenAI models reject /v1/chat/completions and require /v1/completions or /v1/responses.
|
|
75
|
-
|
|
75
|
+
# Models whose id ends with "-pro" (e.g. gpt-5-pro) only work on /v1/responses.
|
|
76
|
+
def request_with_endpoint_fallback(connection_config, payload, url: nil)
|
|
76
77
|
normalized = normalize_payload(payload)
|
|
78
|
+
url ||= resolve_endpoint_url(normalized)
|
|
77
79
|
response = post_openai(connection_config, adapt_payload_for_url(normalized, url), url)
|
|
78
80
|
return response if success?(response)
|
|
79
81
|
|
|
@@ -83,8 +85,9 @@ module Multiwoven::Integrations::Source
|
|
|
83
85
|
post_openai(connection_config, adapt_payload_for_url(normalized, fallback_url), fallback_url)
|
|
84
86
|
end
|
|
85
87
|
|
|
86
|
-
def stream_with_endpoint_fallback(connection_config, payload, url:
|
|
88
|
+
def stream_with_endpoint_fallback(connection_config, payload, url: nil)
|
|
87
89
|
normalized = normalize_payload(payload)
|
|
90
|
+
url ||= resolve_endpoint_url(normalized)
|
|
88
91
|
emitted = false
|
|
89
92
|
|
|
90
93
|
begin
|
|
@@ -103,6 +106,13 @@ module Multiwoven::Integrations::Source
|
|
|
103
106
|
end
|
|
104
107
|
end
|
|
105
108
|
|
|
109
|
+
def resolve_endpoint_url(payload)
|
|
110
|
+
model = payload["model"] || payload[:model]
|
|
111
|
+
return OPEN_AI_RESPONSES_URL if model.to_s.end_with?("-pro")
|
|
112
|
+
|
|
113
|
+
OPEN_AI_URL
|
|
114
|
+
end
|
|
115
|
+
|
|
106
116
|
def post_openai(connection_config, payload, url)
|
|
107
117
|
send_request(
|
|
108
118
|
url: url,
|
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.
|
|
4
|
+
version: 0.41.9
|
|
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-
|
|
11
|
+
date: 2026-09-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|