unbound-claude-code 0.1.3
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/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/auth.d.ts +34 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +159 -0
- package/dist/auth.js.map +1 -0
- package/dist/cli.d.ts +24 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +303 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/interceptor-loader.js +52 -0
- package/dist/interceptor.d.ts +22 -0
- package/dist/interceptor.d.ts.map +1 -0
- package/dist/interceptor.js +319 -0
- package/dist/interceptor.js.map +1 -0
- package/dist/storage.d.ts +58 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +118 -0
- package/dist/storage.js.map +1 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unbound Code - Main Entry Point
|
|
3
|
+
*/
|
|
4
|
+
export { UnboundInterceptor, initializeUnboundInterceptor, getUnboundInterceptor, setUnboundApiKey } from './interceptor';
|
|
5
|
+
export { UnboundAuth } from './auth';
|
|
6
|
+
export { UnboundCli } from './cli';
|
|
7
|
+
export * from './types';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,kBAAkB,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC1H,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,cAAc,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unbound Code - Main Entry Point
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.UnboundCli = exports.UnboundAuth = exports.setUnboundApiKey = exports.getUnboundInterceptor = exports.initializeUnboundInterceptor = exports.UnboundInterceptor = void 0;
|
|
21
|
+
var interceptor_1 = require("./interceptor");
|
|
22
|
+
Object.defineProperty(exports, "UnboundInterceptor", { enumerable: true, get: function () { return interceptor_1.UnboundInterceptor; } });
|
|
23
|
+
Object.defineProperty(exports, "initializeUnboundInterceptor", { enumerable: true, get: function () { return interceptor_1.initializeUnboundInterceptor; } });
|
|
24
|
+
Object.defineProperty(exports, "getUnboundInterceptor", { enumerable: true, get: function () { return interceptor_1.getUnboundInterceptor; } });
|
|
25
|
+
Object.defineProperty(exports, "setUnboundApiKey", { enumerable: true, get: function () { return interceptor_1.setUnboundApiKey; } });
|
|
26
|
+
var auth_1 = require("./auth");
|
|
27
|
+
Object.defineProperty(exports, "UnboundAuth", { enumerable: true, get: function () { return auth_1.UnboundAuth; } });
|
|
28
|
+
var cli_1 = require("./cli");
|
|
29
|
+
Object.defineProperty(exports, "UnboundCli", { enumerable: true, get: function () { return cli_1.UnboundCli; } });
|
|
30
|
+
__exportStar(require("./types"), exports);
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;AAEH,6CAA0H;AAAjH,iHAAA,kBAAkB,OAAA;AAAE,2HAAA,4BAA4B,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AAAE,+GAAA,gBAAgB,OAAA;AAClG,+BAAqC;AAA5B,mGAAA,WAAW,OAAA;AACpB,6BAAmC;AAA1B,iGAAA,UAAU,OAAA;AACnB,0CAAwB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unbound Code Interceptor Loader
|
|
3
|
+
*
|
|
4
|
+
* This loader is injected into Claude Code to initialize the Unbound interceptor
|
|
5
|
+
* and redirect API calls to the Unbound API.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
// Determine the correct path to the interceptor based on how we're loaded
|
|
11
|
+
let interceptorPath;
|
|
12
|
+
if (__filename.includes('node_modules')) {
|
|
13
|
+
// Loaded from node_modules
|
|
14
|
+
interceptorPath = path.join(__dirname, 'interceptor.js');
|
|
15
|
+
} else {
|
|
16
|
+
// Loaded from development/build directory
|
|
17
|
+
interceptorPath = path.join(__dirname, 'interceptor.js');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// Load the interceptor
|
|
22
|
+
const { initializeUnboundInterceptor, setUnboundApiKey } = require(interceptorPath);
|
|
23
|
+
|
|
24
|
+
// Get API key from environment (it should be set by the CLI)
|
|
25
|
+
const apiKey = process.env.UNBOUND_API_KEY;
|
|
26
|
+
|
|
27
|
+
if (!apiKey) {
|
|
28
|
+
console.error('Error: UNBOUND_API_KEY not passed to interceptor.');
|
|
29
|
+
console.error('This should not happen if using the CLI properly.');
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Don't set ANTHROPIC_API_KEY - let Claude Code handle its own authentication
|
|
34
|
+
// The interceptor will extract the Claude API key from request headers
|
|
35
|
+
|
|
36
|
+
// Initialize the interceptor
|
|
37
|
+
const interceptor = initializeUnboundInterceptor({
|
|
38
|
+
logLevel: process.env.UNBOUND_LOG_LEVEL || 'info'
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Set the API key
|
|
42
|
+
setUnboundApiKey(apiKey);
|
|
43
|
+
|
|
44
|
+
// Only log success if not in production mode
|
|
45
|
+
if (process.env.UNBOUND_LOG_LEVEL === 'debug') {
|
|
46
|
+
console.log('✓ Unbound Code interceptor loaded successfully');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('Failed to load Unbound interceptor:', error.message);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unbound Code Interceptor
|
|
3
|
+
*
|
|
4
|
+
* This interceptor modifies Claude Code to work with the Unbound AI API
|
|
5
|
+
* by redirecting Anthropic API calls to api.getunbound.ai and handling
|
|
6
|
+
* OpenAI-compatible request/response formats.
|
|
7
|
+
*/
|
|
8
|
+
import { UnboundConfig } from "./types";
|
|
9
|
+
export declare class UnboundInterceptor {
|
|
10
|
+
private config;
|
|
11
|
+
private apiKey;
|
|
12
|
+
constructor(config?: UnboundConfig);
|
|
13
|
+
setApiKey(apiKey: string): void;
|
|
14
|
+
private isAnthropicAPI;
|
|
15
|
+
private convertAnthropicToOpenAI;
|
|
16
|
+
instrumentFetch(): void;
|
|
17
|
+
instrumentAll(): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function initializeUnboundInterceptor(config?: UnboundConfig): UnboundInterceptor;
|
|
20
|
+
export declare function getUnboundInterceptor(): UnboundInterceptor | null;
|
|
21
|
+
export declare function setUnboundApiKey(apiKey: string): void;
|
|
22
|
+
//# sourceMappingURL=interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interceptor.d.ts","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAExC,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,GAAE,aAAkB;IAQ/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,wBAAwB;IA6CzB,eAAe,IAAI,IAAI;IAuPvB,aAAa,IAAI,IAAI;CAG5B;AAKD,wBAAgB,4BAA4B,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,kBAAkB,CASvF;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CAEjE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAIrD"}
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unbound Code Interceptor
|
|
4
|
+
*
|
|
5
|
+
* This interceptor modifies Claude Code to work with the Unbound AI API
|
|
6
|
+
* by redirecting Anthropic API calls to api.getunbound.ai and handling
|
|
7
|
+
* OpenAI-compatible request/response formats.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.UnboundInterceptor = void 0;
|
|
11
|
+
exports.initializeUnboundInterceptor = initializeUnboundInterceptor;
|
|
12
|
+
exports.getUnboundInterceptor = getUnboundInterceptor;
|
|
13
|
+
exports.setUnboundApiKey = setUnboundApiKey;
|
|
14
|
+
class UnboundInterceptor {
|
|
15
|
+
constructor(config = {}) {
|
|
16
|
+
this.apiKey = null;
|
|
17
|
+
this.config = {
|
|
18
|
+
baseUrl: "https://api.getunbound.ai/v1",
|
|
19
|
+
logLevel: "debug",
|
|
20
|
+
...config,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
setApiKey(apiKey) {
|
|
24
|
+
this.apiKey = apiKey;
|
|
25
|
+
}
|
|
26
|
+
isAnthropicAPI(url) {
|
|
27
|
+
const urlString = typeof url === "string" ? url : url.toString();
|
|
28
|
+
return urlString.includes("api.anthropic.com") && urlString.includes("/v1/messages");
|
|
29
|
+
}
|
|
30
|
+
convertAnthropicToOpenAI(anthropicRequest) {
|
|
31
|
+
// Convert Anthropic request format to OpenAI format
|
|
32
|
+
const messages = [];
|
|
33
|
+
// Add system message if present
|
|
34
|
+
if (anthropicRequest.system) {
|
|
35
|
+
messages.push({
|
|
36
|
+
role: "system",
|
|
37
|
+
content: anthropicRequest.system,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
// Convert messages
|
|
41
|
+
if (anthropicRequest.messages) {
|
|
42
|
+
for (const msg of anthropicRequest.messages) {
|
|
43
|
+
if (msg.role === "user" || msg.role === "assistant") {
|
|
44
|
+
let content = "";
|
|
45
|
+
if (typeof msg.content === "string") {
|
|
46
|
+
content = msg.content;
|
|
47
|
+
}
|
|
48
|
+
else if (Array.isArray(msg.content)) {
|
|
49
|
+
content = msg.content
|
|
50
|
+
.filter((block) => block && block.type === "text" && block.text)
|
|
51
|
+
.map((block) => block.text)
|
|
52
|
+
.join("\n");
|
|
53
|
+
}
|
|
54
|
+
messages.push({
|
|
55
|
+
role: msg.role,
|
|
56
|
+
content: content,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
model: "claude-sonnet-4-20250514", // Use a fixed model for now
|
|
63
|
+
messages: messages,
|
|
64
|
+
max_tokens: anthropicRequest.max_tokens || 4096,
|
|
65
|
+
temperature: anthropicRequest.temperature || 0.7,
|
|
66
|
+
stream: anthropicRequest.stream || false,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
instrumentFetch() {
|
|
70
|
+
if (!global.fetch) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
// Check if already instrumented
|
|
74
|
+
if (global.fetch.__unboundIntercepted) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const originalFetch = global.fetch;
|
|
78
|
+
const interceptor = this;
|
|
79
|
+
global.fetch = async function (input, init = {}) {
|
|
80
|
+
const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
81
|
+
// Only intercept Anthropic API calls
|
|
82
|
+
if (!interceptor.isAnthropicAPI(url)) {
|
|
83
|
+
return originalFetch(input, init);
|
|
84
|
+
}
|
|
85
|
+
if (!interceptor.apiKey) {
|
|
86
|
+
throw new Error("Unbound API key not set. Please set your API key first.");
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
// Extract Claude API key from original request headers
|
|
90
|
+
let claudeApiKey = null;
|
|
91
|
+
if (init.headers) {
|
|
92
|
+
if (init.headers instanceof Headers) {
|
|
93
|
+
claudeApiKey = init.headers.get('authorization')?.replace('Bearer ', '') ||
|
|
94
|
+
null;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const headers = init.headers;
|
|
98
|
+
claudeApiKey = headers['authorization']?.replace('Bearer ', '') ||
|
|
99
|
+
null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (!claudeApiKey) {
|
|
103
|
+
throw new Error("Claude API key not found in request headers. Claude Code should have set this.");
|
|
104
|
+
}
|
|
105
|
+
// Parse original request body
|
|
106
|
+
let requestBody = {};
|
|
107
|
+
if (init.body) {
|
|
108
|
+
try {
|
|
109
|
+
requestBody = JSON.parse(init.body);
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
return originalFetch(input, init);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Convert Anthropic request to OpenAI format
|
|
116
|
+
const openAIRequest = interceptor.convertAnthropicToOpenAI(requestBody);
|
|
117
|
+
// Prepare new request to Unbound API
|
|
118
|
+
const unboundUrl = `${interceptor.config.baseUrl}/chat/completions`;
|
|
119
|
+
const newInit = {
|
|
120
|
+
...init,
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: {
|
|
123
|
+
"Content-Type": "application/json",
|
|
124
|
+
Authorization: `Bearer ${interceptor.apiKey}`,
|
|
125
|
+
"claude-code-key": claudeApiKey,
|
|
126
|
+
"User-Agent": "unbound-code/1.0.0",
|
|
127
|
+
},
|
|
128
|
+
body: JSON.stringify(openAIRequest),
|
|
129
|
+
};
|
|
130
|
+
// Make request to Unbound API
|
|
131
|
+
const response = await originalFetch(unboundUrl, newInit);
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
const errorText = await response.text();
|
|
134
|
+
throw new Error(`Unbound API error: ${response.status} ${response.statusText} - ${errorText}`);
|
|
135
|
+
}
|
|
136
|
+
// Handle streaming response
|
|
137
|
+
if (openAIRequest.stream) {
|
|
138
|
+
const reader = response.body?.getReader();
|
|
139
|
+
if (!reader) {
|
|
140
|
+
throw new Error("No readable stream in response");
|
|
141
|
+
}
|
|
142
|
+
// Create a new ReadableStream that converts OpenAI chunks to Anthropic format
|
|
143
|
+
const transformedStream = new ReadableStream({
|
|
144
|
+
async start(controller) {
|
|
145
|
+
const decoder = new TextDecoder();
|
|
146
|
+
const encoder = new TextEncoder();
|
|
147
|
+
let buffer = "";
|
|
148
|
+
let hasStartedContent = false;
|
|
149
|
+
let messageId = `msg_${Date.now()}`;
|
|
150
|
+
try {
|
|
151
|
+
// Send initial message_start event
|
|
152
|
+
const messageStart = {
|
|
153
|
+
type: "message_start",
|
|
154
|
+
message: {
|
|
155
|
+
id: messageId,
|
|
156
|
+
type: "message",
|
|
157
|
+
role: "assistant",
|
|
158
|
+
content: [],
|
|
159
|
+
model: "claude-sonnet-4-20250514",
|
|
160
|
+
stop_reason: null,
|
|
161
|
+
stop_sequence: null,
|
|
162
|
+
usage: { input_tokens: 0, output_tokens: 0 }
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(messageStart)}\n\n`));
|
|
166
|
+
while (true) {
|
|
167
|
+
const { done, value } = await reader.read();
|
|
168
|
+
if (done) {
|
|
169
|
+
// Send content_block_stop if we started content
|
|
170
|
+
if (hasStartedContent) {
|
|
171
|
+
const contentStop = {
|
|
172
|
+
type: "content_block_stop",
|
|
173
|
+
index: 0
|
|
174
|
+
};
|
|
175
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(contentStop)}\n\n`));
|
|
176
|
+
}
|
|
177
|
+
// Send message_delta with final usage
|
|
178
|
+
const messageDelta = {
|
|
179
|
+
type: "message_delta",
|
|
180
|
+
delta: {
|
|
181
|
+
stop_reason: "end_turn",
|
|
182
|
+
stop_sequence: null
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(messageDelta)}\n\n`));
|
|
186
|
+
// Send message_stop
|
|
187
|
+
const messageStop = {
|
|
188
|
+
type: "message_stop"
|
|
189
|
+
};
|
|
190
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(messageStop)}\n\n`));
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
buffer += decoder.decode(value, { stream: true });
|
|
194
|
+
const lines = buffer.split("\n");
|
|
195
|
+
buffer = lines.pop() || "";
|
|
196
|
+
for (const line of lines) {
|
|
197
|
+
if (line.trim().startsWith("data: ")) {
|
|
198
|
+
const jsonPart = line.substring(6).trim();
|
|
199
|
+
if (jsonPart === "[DONE]")
|
|
200
|
+
continue;
|
|
201
|
+
try {
|
|
202
|
+
const openAIChunk = JSON.parse(jsonPart);
|
|
203
|
+
// Convert OpenAI chunk to Anthropic format
|
|
204
|
+
if (openAIChunk.choices?.[0]?.delta?.content) {
|
|
205
|
+
// Send content_block_start if this is the first content
|
|
206
|
+
if (!hasStartedContent) {
|
|
207
|
+
const contentStart = {
|
|
208
|
+
type: "content_block_start",
|
|
209
|
+
index: 0,
|
|
210
|
+
content_block: {
|
|
211
|
+
type: "text",
|
|
212
|
+
text: ""
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(contentStart)}\n\n`));
|
|
216
|
+
hasStartedContent = true;
|
|
217
|
+
}
|
|
218
|
+
// Send content delta
|
|
219
|
+
const contentDelta = {
|
|
220
|
+
type: "content_block_delta",
|
|
221
|
+
index: 0,
|
|
222
|
+
delta: {
|
|
223
|
+
type: "text_delta",
|
|
224
|
+
text: openAIChunk.choices[0].delta.content
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(contentDelta)}\n\n`));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
console.error("Error processing chunk:", e);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
controller.error(error);
|
|
239
|
+
}
|
|
240
|
+
finally {
|
|
241
|
+
controller.close();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
return new Response(transformedStream, {
|
|
246
|
+
status: response.status,
|
|
247
|
+
statusText: response.statusText,
|
|
248
|
+
headers: {
|
|
249
|
+
...Object.fromEntries(response.headers.entries()),
|
|
250
|
+
"Content-Type": "text/event-stream",
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// Non-streaming response
|
|
256
|
+
const responseText = await response.text();
|
|
257
|
+
const openAIResponse = JSON.parse(responseText);
|
|
258
|
+
// Convert to Anthropic format
|
|
259
|
+
const anthropicResponse = {
|
|
260
|
+
id: openAIResponse.id,
|
|
261
|
+
type: "message",
|
|
262
|
+
role: "assistant",
|
|
263
|
+
content: [
|
|
264
|
+
{
|
|
265
|
+
type: "text",
|
|
266
|
+
text: openAIResponse.choices[0].message.content,
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
model: openAIResponse.model,
|
|
270
|
+
stop_reason: "end_turn",
|
|
271
|
+
stop_sequence: null,
|
|
272
|
+
usage: {
|
|
273
|
+
input_tokens: openAIResponse.usage?.prompt_tokens || 0,
|
|
274
|
+
output_tokens: openAIResponse.usage?.completion_tokens || 0,
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
// Return the response directly in JSON format
|
|
278
|
+
return new Response(JSON.stringify(anthropicResponse), {
|
|
279
|
+
status: response.status,
|
|
280
|
+
statusText: response.statusText,
|
|
281
|
+
headers: {
|
|
282
|
+
...Object.fromEntries(response.headers.entries()),
|
|
283
|
+
"Content-Type": "application/json",
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
console.error("Unbound interceptor error:", error);
|
|
290
|
+
throw error;
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
// Mark fetch as instrumented
|
|
294
|
+
global.fetch.__unboundIntercepted = true;
|
|
295
|
+
}
|
|
296
|
+
instrumentAll() {
|
|
297
|
+
this.instrumentFetch();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
exports.UnboundInterceptor = UnboundInterceptor;
|
|
301
|
+
// Global interceptor instance
|
|
302
|
+
let globalInterceptor = null;
|
|
303
|
+
function initializeUnboundInterceptor(config) {
|
|
304
|
+
if (globalInterceptor) {
|
|
305
|
+
return globalInterceptor;
|
|
306
|
+
}
|
|
307
|
+
globalInterceptor = new UnboundInterceptor(config);
|
|
308
|
+
globalInterceptor.instrumentAll();
|
|
309
|
+
return globalInterceptor;
|
|
310
|
+
}
|
|
311
|
+
function getUnboundInterceptor() {
|
|
312
|
+
return globalInterceptor;
|
|
313
|
+
}
|
|
314
|
+
function setUnboundApiKey(apiKey) {
|
|
315
|
+
if (globalInterceptor) {
|
|
316
|
+
globalInterceptor.setApiKey(apiKey);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=interceptor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interceptor.js","sourceRoot":"","sources":["../src/interceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unbound Code Storage - API Key and Config Management
|
|
3
|
+
*
|
|
4
|
+
* Stores API key and model configuration similar to how Claude Code stores its config
|
|
5
|
+
*/
|
|
6
|
+
export interface UnboundConfig {
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
model?: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
logLevel?: string;
|
|
11
|
+
lastUsed?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class UnboundStorage {
|
|
14
|
+
private configDir;
|
|
15
|
+
private configFile;
|
|
16
|
+
constructor();
|
|
17
|
+
/**
|
|
18
|
+
* Load configuration from file
|
|
19
|
+
*/
|
|
20
|
+
loadConfig(): UnboundConfig;
|
|
21
|
+
/**
|
|
22
|
+
* Save configuration to file
|
|
23
|
+
*/
|
|
24
|
+
saveConfig(config: UnboundConfig): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get stored API key
|
|
27
|
+
*/
|
|
28
|
+
getApiKey(): string | null;
|
|
29
|
+
/**
|
|
30
|
+
* Store API key
|
|
31
|
+
*/
|
|
32
|
+
setApiKey(apiKey: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Get stored model
|
|
35
|
+
*/
|
|
36
|
+
getModel(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Store model
|
|
39
|
+
*/
|
|
40
|
+
setModel(model: string): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get full configuration
|
|
43
|
+
*/
|
|
44
|
+
getFullConfig(): UnboundConfig;
|
|
45
|
+
/**
|
|
46
|
+
* Update configuration
|
|
47
|
+
*/
|
|
48
|
+
updateConfig(updates: Partial<UnboundConfig>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Clear all stored data
|
|
51
|
+
*/
|
|
52
|
+
clearConfig(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Check if API key is stored
|
|
55
|
+
*/
|
|
56
|
+
hasApiKey(): boolean;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;;IAa3B;;OAEG;IACH,UAAU,IAAI,aAAa;IAa3B;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IASvC;;OAEG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI;IAK1B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B;;OAEG;IACH,QAAQ,IAAI,MAAM;IAKlB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAO7B;;OAEG;IACH,aAAa,IAAI,aAAa;IAI9B;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAOnD;;OAEG;IACH,WAAW,IAAI,IAAI;IAUnB;;OAEG;IACH,SAAS,IAAI,OAAO;CAKrB"}
|
package/dist/storage.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unbound Code Storage - API Key and Config Management
|
|
4
|
+
*
|
|
5
|
+
* Stores API key and model configuration similar to how Claude Code stores its config
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.UnboundStorage = void 0;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const os_1 = require("os");
|
|
12
|
+
class UnboundStorage {
|
|
13
|
+
constructor() {
|
|
14
|
+
// Use similar path structure as Claude Code
|
|
15
|
+
this.configDir = (0, path_1.join)((0, os_1.homedir)(), '.unbound-code');
|
|
16
|
+
this.configFile = (0, path_1.join)(this.configDir, 'config.json');
|
|
17
|
+
// Ensure config directory exists
|
|
18
|
+
if (!(0, fs_1.existsSync)(this.configDir)) {
|
|
19
|
+
(0, fs_1.mkdirSync)(this.configDir, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Load configuration from file
|
|
24
|
+
*/
|
|
25
|
+
loadConfig() {
|
|
26
|
+
try {
|
|
27
|
+
if ((0, fs_1.existsSync)(this.configFile)) {
|
|
28
|
+
const configData = (0, fs_1.readFileSync)(this.configFile, 'utf8');
|
|
29
|
+
return JSON.parse(configData);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
console.warn('Failed to load config, using defaults');
|
|
34
|
+
}
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Save configuration to file
|
|
39
|
+
*/
|
|
40
|
+
saveConfig(config) {
|
|
41
|
+
try {
|
|
42
|
+
const configData = JSON.stringify(config, null, 2);
|
|
43
|
+
(0, fs_1.writeFileSync)(this.configFile, configData, 'utf8');
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.error('Failed to save config:', error);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get stored API key
|
|
51
|
+
*/
|
|
52
|
+
getApiKey() {
|
|
53
|
+
const config = this.loadConfig();
|
|
54
|
+
return config.apiKey || null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Store API key
|
|
58
|
+
*/
|
|
59
|
+
setApiKey(apiKey) {
|
|
60
|
+
const config = this.loadConfig();
|
|
61
|
+
config.apiKey = apiKey;
|
|
62
|
+
config.lastUsed = new Date().toISOString();
|
|
63
|
+
this.saveConfig(config);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get stored model
|
|
67
|
+
*/
|
|
68
|
+
getModel() {
|
|
69
|
+
const config = this.loadConfig();
|
|
70
|
+
return config.model || 'anthropic/claude-sonnet-4-20250514';
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Store model
|
|
74
|
+
*/
|
|
75
|
+
setModel(model) {
|
|
76
|
+
const config = this.loadConfig();
|
|
77
|
+
config.model = model;
|
|
78
|
+
config.lastUsed = new Date().toISOString();
|
|
79
|
+
this.saveConfig(config);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Get full configuration
|
|
83
|
+
*/
|
|
84
|
+
getFullConfig() {
|
|
85
|
+
return this.loadConfig();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Update configuration
|
|
89
|
+
*/
|
|
90
|
+
updateConfig(updates) {
|
|
91
|
+
const config = this.loadConfig();
|
|
92
|
+
Object.assign(config, updates);
|
|
93
|
+
config.lastUsed = new Date().toISOString();
|
|
94
|
+
this.saveConfig(config);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Clear all stored data
|
|
98
|
+
*/
|
|
99
|
+
clearConfig() {
|
|
100
|
+
try {
|
|
101
|
+
if ((0, fs_1.existsSync)(this.configFile)) {
|
|
102
|
+
(0, fs_1.writeFileSync)(this.configFile, '{}', 'utf8');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error('Failed to clear config:', error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if API key is stored
|
|
111
|
+
*/
|
|
112
|
+
hasApiKey() {
|
|
113
|
+
const apiKey = this.getApiKey();
|
|
114
|
+
return apiKey !== null && apiKey.trim().length > 0;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.UnboundStorage = UnboundStorage;
|
|
118
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|