opencode-pollinations-plugin 6.1.0-beta.6 → 6.1.0-beta.8

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.
@@ -124,7 +124,9 @@ function sanitizeForBedrock(body) {
124
124
  if (!body)
125
125
  return body;
126
126
  const sanitized = JSON.parse(JSON.stringify(body)); // Deep clone
127
- // 1. Sanitize toolUseId in all messages
127
+ // 1. Sanitize toolUseId in all messages AND detect tool history
128
+ let hasToolHistory = false;
129
+ const toolNamesFromHistory = [];
128
130
  if (sanitized.messages && Array.isArray(sanitized.messages)) {
129
131
  for (const msg of sanitized.messages) {
130
132
  if (msg.content && Array.isArray(msg.content)) {
@@ -132,31 +134,44 @@ function sanitizeForBedrock(body) {
132
134
  // Handle toolUse blocks
133
135
  if (block.toolUse && block.toolUse.toolUseId) {
134
136
  block.toolUse.toolUseId = sanitizeToolUseId(block.toolUse.toolUseId);
137
+ hasToolHistory = true;
138
+ if (block.toolUse.name)
139
+ toolNamesFromHistory.push(block.toolUse.name);
135
140
  }
136
141
  // Handle toolResult blocks
137
142
  if (block.toolResult && block.toolResult.toolUseId) {
138
143
  block.toolResult.toolUseId = sanitizeToolUseId(block.toolResult.toolUseId);
144
+ hasToolHistory = true;
139
145
  }
140
- // Handle OpenAI-style tool_calls
146
+ // Handle OpenAI-style tool_use in content array
141
147
  if (block.type === 'tool_use' && block.id) {
142
148
  block.id = sanitizeToolUseId(block.id);
149
+ hasToolHistory = true;
150
+ if (block.name)
151
+ toolNamesFromHistory.push(block.name);
143
152
  }
144
153
  }
145
154
  }
146
155
  // Handle assistant tool_calls array (OpenAI format)
147
156
  if (msg.tool_calls && Array.isArray(msg.tool_calls)) {
157
+ hasToolHistory = true;
148
158
  for (const tc of msg.tool_calls) {
149
159
  if (tc.id)
150
160
  tc.id = sanitizeToolUseId(tc.id);
161
+ if (tc.function?.name)
162
+ toolNamesFromHistory.push(tc.function.name);
151
163
  }
152
164
  }
153
165
  // Handle tool role message (OpenAI format)
154
- if (msg.role === 'tool' && msg.tool_call_id) {
155
- msg.tool_call_id = sanitizeToolUseId(msg.tool_call_id);
166
+ if (msg.role === 'tool') {
167
+ hasToolHistory = true;
168
+ if (msg.tool_call_id) {
169
+ msg.tool_call_id = sanitizeToolUseId(msg.tool_call_id);
170
+ }
156
171
  }
157
172
  }
158
173
  }
159
- // 2. Add toolConfig if tools present but toolConfig missing
174
+ // 2. Add toolConfig if tools present
160
175
  if (sanitized.tools && Array.isArray(sanitized.tools) && sanitized.tools.length > 0) {
161
176
  if (!sanitized.tool_config && !sanitized.toolConfig) {
162
177
  // Build toolConfig from tools array (Bedrock Converse format)
@@ -179,6 +194,30 @@ function sanitizeForBedrock(body) {
179
194
  };
180
195
  }
181
196
  }
197
+ // 3. CRITICAL: If no tools BUT history has tool calls, inject shim toolConfig
198
+ else if (hasToolHistory && !sanitized.tool_config && !sanitized.toolConfig) {
199
+ // Bedrock requires toolConfig when history contains toolUse/toolResult
200
+ // Create shim tools from the tool names we found in history
201
+ const uniqueToolNames = [...new Set(toolNamesFromHistory)];
202
+ sanitized.tool_config = {
203
+ tools: uniqueToolNames.length > 0
204
+ ? uniqueToolNames.map(name => ({
205
+ toolSpec: {
206
+ name: name,
207
+ description: 'Tool inferred from conversation history (Bedrock compatibility shim)',
208
+ inputSchema: { json: { type: 'object', properties: {} } }
209
+ }
210
+ }))
211
+ : [{
212
+ toolSpec: {
213
+ name: '_bedrock_shim_tool',
214
+ description: 'Internal shim to satisfy Bedrock toolConfig requirement',
215
+ inputSchema: { json: { type: 'object', properties: {} } }
216
+ }
217
+ }]
218
+ };
219
+ log(`[Bedrock Shim] Injected toolConfig with ${uniqueToolNames.length || 1} shim tool(s) for history compatibility`);
220
+ }
182
221
  return sanitized;
183
222
  }
184
223
  const MAX_RETRIES = 3;
@@ -656,10 +695,18 @@ export async function handleChatCompletion(req, res, bodyRaw) {
656
695
  if (authHeader)
657
696
  headers['Authorization'] = authHeader;
658
697
  // 5. Forward (Global Fetch with Retry)
698
+ // BEDROCK COMPATIBILITY: Apply transformation BEFORE first request
699
+ const isBedrockModel = actualModel.includes('nova') ||
700
+ actualModel.includes('amazon') ||
701
+ actualModel.includes('chickytutor');
702
+ const finalProxyBody = isBedrockModel ? sanitizeForBedrock(proxyBody) : proxyBody;
703
+ if (isBedrockModel) {
704
+ log(`[Proxy] Applied Bedrock shim for ${actualModel} (Initial Request)`);
705
+ }
659
706
  const fetchRes = await fetchWithRetry(targetUrl, {
660
707
  method: 'POST',
661
708
  headers: headers,
662
- body: JSON.stringify(proxyBody)
709
+ body: JSON.stringify(finalProxyBody)
663
710
  });
664
711
  res.statusCode = fetchRes.status;
665
712
  fetchRes.headers.forEach((val, key) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opencode-pollinations-plugin",
3
3
  "displayName": "Pollinations AI (V5.6)",
4
- "version": "6.1.0-beta.6",
4
+ "version": "6.1.0-beta.8",
5
5
  "description": "Native Pollinations.ai Provider Plugin for OpenCode",
6
6
  "publisher": "pollinations",
7
7
  "repository": {