zk-credits 0.2.0 → 0.2.2
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.
- package/README.md +74 -42
- package/dist/base-registered-trial.d.ts +33 -0
- package/dist/base-registered-trial.js +168 -0
- package/dist/base-sidecar.d.ts +14 -1
- package/dist/base-sidecar.js +82 -72
- package/dist/cli-runtime.d.ts +1 -0
- package/dist/cli-runtime.js +2 -1
- package/dist/cli.js +418 -16
- package/dist/node-sidecar-lifecycle.d.ts +2 -0
- package/dist/node-sidecar-lifecycle.js +29 -7
- package/dist/responses-bridge.d.ts +14 -0
- package/dist/responses-bridge.js +328 -0
- package/dist/setup-config.d.ts +36 -0
- package/dist/setup-config.js +320 -0
- package/dist/sidecar.js +52 -8
- package/dist/zk-credits.js +1409 -189
- package/package.json +2 -1
package/dist/sidecar.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createServer } from 'node:http';
|
|
2
2
|
import { codexModelsResponse } from './codex-profile.js';
|
|
3
|
+
import { responsesEventStream, translateResponsesRequest } from './responses-bridge.js';
|
|
3
4
|
import { PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, } from '@zk-credits/x402-zk-prepaid';
|
|
4
5
|
const MAX_REQUEST_BYTES = 2_000_000;
|
|
5
6
|
const PAYMENT_HEADERS = [PAYMENT_REQUIRED_HEADER, PAYMENT_RESPONSE_HEADER, 'cache-control'];
|
|
@@ -81,6 +82,32 @@ async function relayGatewayResponse(res, upstream) {
|
|
|
81
82
|
reader.releaseLock();
|
|
82
83
|
}
|
|
83
84
|
}
|
|
85
|
+
async function relayResponsesGatewayResponse(res, upstream, responseModel) {
|
|
86
|
+
if (upstream.status < 200 || upstream.status >= 300) {
|
|
87
|
+
await relayGatewayResponse(res, upstream);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const upstreamText = await upstream.text();
|
|
91
|
+
let completion;
|
|
92
|
+
try {
|
|
93
|
+
completion = JSON.parse(upstreamText);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
throw new Error('Gateway returned an invalid chat completion');
|
|
97
|
+
}
|
|
98
|
+
const eventStream = responsesEventStream(completion, responseModel);
|
|
99
|
+
const headers = {
|
|
100
|
+
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
101
|
+
'Cache-Control': 'no-cache',
|
|
102
|
+
};
|
|
103
|
+
for (const name of PAYMENT_HEADERS) {
|
|
104
|
+
const value = upstream.headers.get(name);
|
|
105
|
+
if (value)
|
|
106
|
+
headers[name] = value;
|
|
107
|
+
}
|
|
108
|
+
res.writeHead(upstream.status, headers);
|
|
109
|
+
res.end(eventStream);
|
|
110
|
+
}
|
|
84
111
|
/** Creates a loopback-only proxy whose sole spend path is x402 zk-prepaid. */
|
|
85
112
|
export function createSidecarServer(options) {
|
|
86
113
|
const gatewayBaseUrl = options.gatewayBaseUrl.replace(/\/$/u, '');
|
|
@@ -117,7 +144,7 @@ export function createSidecarServer(options) {
|
|
|
117
144
|
sendJson(res, 200, options.metrics());
|
|
118
145
|
return;
|
|
119
146
|
}
|
|
120
|
-
if (req.method !== 'POST' || pathname !== '/v1/chat/completions') {
|
|
147
|
+
if (req.method !== 'POST' || (pathname !== '/v1/chat/completions' && pathname !== '/v1/responses')) {
|
|
121
148
|
sendJson(res, 404, { error: 'unsupported_openai_path' });
|
|
122
149
|
return;
|
|
123
150
|
}
|
|
@@ -127,17 +154,34 @@ export function createSidecarServer(options) {
|
|
|
127
154
|
}
|
|
128
155
|
try {
|
|
129
156
|
const body = await readJsonBody(req);
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
157
|
+
const isResponses = pathname === '/v1/responses';
|
|
158
|
+
let outboundBody = body.raw;
|
|
159
|
+
let responseModel = '';
|
|
160
|
+
if (isResponses) {
|
|
161
|
+
const translation = translateResponsesRequest(body.parsed);
|
|
162
|
+
if (!translation.ok) {
|
|
163
|
+
sendJson(res, 400, { error: translation.error });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
outboundBody = JSON.stringify(translation.chatRequest);
|
|
167
|
+
responseModel = translation.responseModel;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
const rejection = completionRejection(body.parsed);
|
|
171
|
+
if (rejection) {
|
|
172
|
+
sendJson(res, 400, { error: rejection });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
134
175
|
}
|
|
135
|
-
const upstream = await options.prepaidClient.fetch(`${gatewayBaseUrl}
|
|
176
|
+
const upstream = await options.prepaidClient.fetch(`${gatewayBaseUrl}/v1/chat/completions`, {
|
|
136
177
|
method: 'POST',
|
|
137
178
|
headers: { 'Content-Type': 'application/json' },
|
|
138
|
-
body:
|
|
179
|
+
body: outboundBody,
|
|
139
180
|
});
|
|
140
|
-
|
|
181
|
+
if (isResponses)
|
|
182
|
+
await relayResponsesGatewayResponse(res, upstream, responseModel);
|
|
183
|
+
else
|
|
184
|
+
await relayGatewayResponse(res, upstream);
|
|
141
185
|
}
|
|
142
186
|
catch (error) {
|
|
143
187
|
if (!res.headersSent) {
|