@serii84/vertex-partner-provider 1.0.7 → 1.0.10

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 +96 -9
  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
+ * v1.0.10 - Skip reasoning_content, only pass actual content
4
4
  */
5
5
 
6
6
  const { createOpenAICompatible } = require('@ai-sdk/openai-compatible');
@@ -20,6 +20,91 @@ async function getAuthToken(googleAuthOptions) {
20
20
  return token.token;
21
21
  }
22
22
 
23
+ function transformStream(response) {
24
+ const reader = response.body.getReader();
25
+ const decoder = new TextDecoder();
26
+ const encoder = new TextEncoder();
27
+
28
+ let buffer = '';
29
+
30
+ const transformedStream = new ReadableStream({
31
+ async pull(controller) {
32
+ try {
33
+ const { done, value } = await reader.read();
34
+
35
+ if (done) {
36
+ controller.close();
37
+ return;
38
+ }
39
+
40
+ buffer += decoder.decode(value, { stream: true });
41
+ const lines = buffer.split('\n');
42
+ buffer = lines.pop() || '';
43
+
44
+ for (const line of lines) {
45
+ if (!line.trim()) continue;
46
+
47
+ if (line.startsWith('data: ')) {
48
+ const data = line.slice(6).trim();
49
+
50
+ if (data === '[DONE]') {
51
+ controller.enqueue(encoder.encode('data: [DONE]\n\n'));
52
+ continue;
53
+ }
54
+
55
+ try {
56
+ const parsed = JSON.parse(data);
57
+
58
+ // Skip empty choices
59
+ if (!parsed.choices || parsed.choices.length === 0) {
60
+ continue;
61
+ }
62
+
63
+ let hasContent = false;
64
+
65
+ for (const choice of parsed.choices) {
66
+ if (choice.delta) {
67
+ // Only keep chunks that have actual content (not reasoning)
68
+ if (choice.delta.content && choice.delta.content !== null) {
69
+ hasContent = true;
70
+ }
71
+ // Remove reasoning_content entirely
72
+ delete choice.delta.reasoning_content;
73
+
74
+ // If only reasoning was present, set empty content
75
+ if (!choice.delta.content) {
76
+ choice.delta.content = '';
77
+ }
78
+ }
79
+
80
+ // Pass through finish_reason chunks
81
+ if (choice.finish_reason) {
82
+ hasContent = true;
83
+ }
84
+ }
85
+
86
+ // Only emit if there's actual content or it's a finish chunk
87
+ if (hasContent || parsed.choices.some(c => c.finish_reason)) {
88
+ controller.enqueue(encoder.encode('data: ' + JSON.stringify(parsed) + '\n\n'));
89
+ }
90
+ } catch (e) {
91
+ controller.enqueue(encoder.encode(line + '\n'));
92
+ }
93
+ }
94
+ }
95
+ } catch (err) {
96
+ controller.error(err);
97
+ }
98
+ }
99
+ });
100
+
101
+ return new Response(transformedStream, {
102
+ headers: response.headers,
103
+ status: response.status,
104
+ statusText: response.statusText,
105
+ });
106
+ }
107
+
23
108
  function createVertexPartner(options = {}) {
24
109
  const {
25
110
  project = process.env.GOOGLE_VERTEX_PROJECT,
@@ -42,19 +127,21 @@ function createVertexPartner(options = {}) {
42
127
  const headers = new Headers(init?.headers);
43
128
  headers.set('Authorization', `Bearer ${token}`);
44
129
 
45
- // Force non-streaming by modifying the request body
46
- let modifiedInit = { ...init, headers };
130
+ let isStreaming = false;
47
131
  if (init?.body) {
48
132
  try {
49
133
  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
- }
134
+ isStreaming = body.stream === true;
135
+ } catch (e) {}
136
+ }
137
+
138
+ const response = await fetch(url, { ...init, headers });
139
+
140
+ if (isStreaming && response.ok) {
141
+ return transformStream(response);
55
142
  }
56
143
 
57
- return fetch(url, modifiedInit);
144
+ return response;
58
145
  };
59
146
 
60
147
  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.10",
4
4
  "description": "Vertex AI partner models (GLM, Kimi, DeepSeek) for OpenCode",
5
5
  "main": "index.js",
6
6
  "scripts": {