@serii84/vertex-partner-provider 1.0.7 → 1.0.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.
Files changed (2) hide show
  1. package/index.js +76 -12
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Vertex Partner Provider for OpenCode
3
- * Forces non-streaming to avoid parsing issues
3
+ * Transforms streaming responses to handle reasoning_content
4
4
  */
5
5
 
6
6
  const { createOpenAICompatible } = require('@ai-sdk/openai-compatible');
@@ -20,6 +20,74 @@ async function getAuthToken(googleAuthOptions) {
20
20
  return token.token;
21
21
  }
22
22
 
23
+ /**
24
+ * Transform SSE stream to handle reasoning_content
25
+ * Converts reasoning_content to content so SDK can parse it
26
+ */
27
+ function transformStream(response) {
28
+ const reader = response.body.getReader();
29
+ const decoder = new TextDecoder();
30
+ const encoder = new TextEncoder();
31
+
32
+ let buffer = '';
33
+
34
+ const transformedStream = new ReadableStream({
35
+ async pull(controller) {
36
+ const { done, value } = await reader.read();
37
+
38
+ if (done) {
39
+ controller.close();
40
+ return;
41
+ }
42
+
43
+ buffer += decoder.decode(value, { stream: true });
44
+ const lines = buffer.split('\n');
45
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
46
+
47
+ for (const line of lines) {
48
+ if (line.startsWith('data: ')) {
49
+ const data = line.slice(6);
50
+ if (data === '[DONE]') {
51
+ controller.enqueue(encoder.encode(line + '\n'));
52
+ continue;
53
+ }
54
+
55
+ try {
56
+ const parsed = JSON.parse(data);
57
+
58
+ // Transform: move reasoning_content to content if content is null
59
+ if (parsed.choices) {
60
+ for (const choice of parsed.choices) {
61
+ if (choice.delta) {
62
+ // If content is null but reasoning_content exists, use reasoning_content
63
+ if (choice.delta.content === null && choice.delta.reasoning_content) {
64
+ choice.delta.content = choice.delta.reasoning_content;
65
+ }
66
+ // Remove reasoning_content to avoid confusion
67
+ delete choice.delta.reasoning_content;
68
+ }
69
+ }
70
+ }
71
+
72
+ controller.enqueue(encoder.encode('data: ' + JSON.stringify(parsed) + '\n'));
73
+ } catch (e) {
74
+ // If JSON parse fails, pass through unchanged
75
+ controller.enqueue(encoder.encode(line + '\n'));
76
+ }
77
+ } else if (line.trim()) {
78
+ controller.enqueue(encoder.encode(line + '\n'));
79
+ }
80
+ }
81
+ }
82
+ });
83
+
84
+ return new Response(transformedStream, {
85
+ headers: response.headers,
86
+ status: response.status,
87
+ statusText: response.statusText,
88
+ });
89
+ }
90
+
23
91
  function createVertexPartner(options = {}) {
24
92
  const {
25
93
  project = process.env.GOOGLE_VERTEX_PROJECT,
@@ -42,19 +110,15 @@ function createVertexPartner(options = {}) {
42
110
  const headers = new Headers(init?.headers);
43
111
  headers.set('Authorization', `Bearer ${token}`);
44
112
 
45
- // Force non-streaming by modifying the request body
46
- let modifiedInit = { ...init, headers };
47
- if (init?.body) {
48
- try {
49
- const body = JSON.parse(init.body);
50
- body.stream = false; // Force non-streaming
51
- modifiedInit.body = JSON.stringify(body);
52
- } catch (e) {
53
- // If body isn't JSON, leave it as is
54
- }
113
+ const response = await fetch(url, { ...init, headers });
114
+
115
+ // Check if this is a streaming request
116
+ const contentType = response.headers.get('content-type') || '';
117
+ if (contentType.includes('text/event-stream')) {
118
+ return transformStream(response);
55
119
  }
56
120
 
57
- return fetch(url, modifiedInit);
121
+ return response;
58
122
  };
59
123
 
60
124
  const provider = createOpenAICompatible({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@serii84/vertex-partner-provider",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Vertex AI partner models (GLM, Kimi, DeepSeek) for OpenCode",
5
5
  "main": "index.js",
6
6
  "scripts": {