@crouton-kit/crouter 0.3.34 → 0.3.35
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/dist/builtin-pi-packages/pi-mode-switch/extensions/index.ts +10 -5
- package/dist/clients/attach/attach-cmd.js +732 -704
- package/dist/core/__tests__/fixtures/fake-engine.js +18 -8
- package/dist/core/__tests__/flagship-lifecycle.test.js +4 -1
- package/dist/core/__tests__/full/broker-navigate-tree-rewelcome.test.js +1 -1
- package/dist/core/__tests__/full/detach-focus.test.js +15 -1
- package/dist/core/__tests__/live-mutation-verbs.test.js +8 -2
- package/dist/core/__tests__/live-mutation.test.js +7 -2
- package/dist/core/hearth/config.js +3 -6
- package/dist/core/hearth/index.d.ts +0 -1
- package/dist/core/hearth/index.js +0 -1
- package/dist/core/hearth/model-auth-guest.js +9 -14
- package/dist/core/hearth/providers/blaxel.js +3 -3
- package/dist/core/hearth/types.d.ts +0 -1
- package/dist/web-client/assets/index-DUThOUzU.css +2 -0
- package/dist/web-client/assets/index-IAJVtuVe.js +80 -0
- package/dist/web-client/index.html +2 -2
- package/package.json +2 -3
- package/dist/core/hearth/registry.d.ts +0 -15
- package/dist/core/hearth/registry.js +0 -180
- package/dist/hearth/wake-proxy/__tests__/anthropic-oauth.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/anthropic-oauth.test.js +0 -289
- package/dist/hearth/wake-proxy/__tests__/config-timeout.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/config-timeout.test.js +0 -34
- package/dist/hearth/wake-proxy/__tests__/guest-source.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/guest-source.test.js +0 -203
- package/dist/hearth/wake-proxy/__tests__/hardening.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/hardening.test.js +0 -59
- package/dist/hearth/wake-proxy/__tests__/hearth-status-route.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/hearth-status-route.test.js +0 -372
- package/dist/hearth/wake-proxy/__tests__/http-running-route-fast-path.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/http-running-route-fast-path.test.js +0 -258
- package/dist/hearth/wake-proxy/__tests__/model-auth-routes.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/model-auth-routes.test.js +0 -437
- package/dist/hearth/wake-proxy/__tests__/static-asset-allowlist.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/static-asset-allowlist.test.js +0 -15
- package/dist/hearth/wake-proxy/__tests__/warm-path-concurrency.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/warm-path-concurrency.test.js +0 -141
- package/dist/hearth/wake-proxy/__tests__/ws-teardown-accounting.test.d.ts +0 -1
- package/dist/hearth/wake-proxy/__tests__/ws-teardown-accounting.test.js +0 -143
- package/dist/hearth/wake-proxy/anthropic-oauth.d.ts +0 -58
- package/dist/hearth/wake-proxy/anthropic-oauth.js +0 -189
- package/dist/hearth/wake-proxy/auth.d.ts +0 -22
- package/dist/hearth/wake-proxy/auth.js +0 -128
- package/dist/hearth/wake-proxy/config.d.ts +0 -2
- package/dist/hearth/wake-proxy/config.js +0 -151
- package/dist/hearth/wake-proxy/guest-source.d.ts +0 -14
- package/dist/hearth/wake-proxy/guest-source.js +0 -130
- package/dist/hearth/wake-proxy/hearth-status.d.ts +0 -44
- package/dist/hearth/wake-proxy/hearth-status.js +0 -267
- package/dist/hearth/wake-proxy/home.d.ts +0 -61
- package/dist/hearth/wake-proxy/home.js +0 -333
- package/dist/hearth/wake-proxy/main.d.ts +0 -1
- package/dist/hearth/wake-proxy/main.js +0 -134
- package/dist/hearth/wake-proxy/model-auth.d.ts +0 -13
- package/dist/hearth/wake-proxy/model-auth.js +0 -345
- package/dist/hearth/wake-proxy/proxy.d.ts +0 -35
- package/dist/hearth/wake-proxy/proxy.js +0 -716
- package/dist/hearth/wake-proxy/public-source-gate.d.ts +0 -9
- package/dist/hearth/wake-proxy/public-source-gate.js +0 -409
- package/dist/hearth/wake-proxy/redact.d.ts +0 -1
- package/dist/hearth/wake-proxy/redact.js +0 -17
- package/dist/hearth/wake-proxy/server.d.ts +0 -11
- package/dist/hearth/wake-proxy/server.js +0 -142
- package/dist/hearth/wake-proxy/state.d.ts +0 -18
- package/dist/hearth/wake-proxy/state.js +0 -342
- package/dist/hearth/wake-proxy/types.d.ts +0 -76
- package/dist/hearth/wake-proxy/types.js +0 -1
- package/dist/web-client/assets/index-BRKxe-hy.js +0 -80
- package/dist/web-client/assets/index-BZUxTkv5.css +0 -2
|
@@ -1,345 +0,0 @@
|
|
|
1
|
-
import { general } from '../../core/errors.js';
|
|
2
|
-
import { currentProxyState, resolveOwnerAuth, resolveOwnerWriteAuth } from './auth.js';
|
|
3
|
-
import { finishAnthropicOAuthSession, startAnthropicOAuthSession } from './anthropic-oauth.js';
|
|
4
|
-
import { redactWakeProxyMessage } from './redact.js';
|
|
5
|
-
import { requireSuccessfulExec, runGuestSource } from './guest-source.js';
|
|
6
|
-
const MODEL_AUTH_PREFIX = '/__hearth/model-auth/anthropic/';
|
|
7
|
-
const BODY_LIMIT_BYTES = 16 * 1024;
|
|
8
|
-
export const AUTH_STORAGE_STATUS_SCRIPT = `import { AuthStorage } from '@earendil-works/pi-coding-agent';
|
|
9
|
-
|
|
10
|
-
const storage = AuthStorage.create();
|
|
11
|
-
const credential = storage.get('anthropic');
|
|
12
|
-
const firstErrors = storage.drainErrors();
|
|
13
|
-
if (firstErrors.length > 0) {
|
|
14
|
-
throw new Error(firstErrors.map((error) => error.message).join('; '));
|
|
15
|
-
}
|
|
16
|
-
const adapterConfigured = storage.getOAuthProviders().some((provider) => provider.id === 'anthropic');
|
|
17
|
-
const storedOauth = credential?.type === 'oauth';
|
|
18
|
-
const expiresAt = storedOauth ? credential.expires : null;
|
|
19
|
-
console.log(JSON.stringify({ storedOauth, expiresAt, adapterConfigured }));
|
|
20
|
-
`;
|
|
21
|
-
export const AUTH_STORAGE_WRITE_SCRIPT = `import { AuthStorage } from '@earendil-works/pi-coding-agent';
|
|
22
|
-
|
|
23
|
-
const input = JSON.parse(await new Promise((resolve, reject) => {
|
|
24
|
-
let value = '';
|
|
25
|
-
process.stdin.setEncoding('utf8');
|
|
26
|
-
process.stdin.on('data', (chunk) => { value += chunk; });
|
|
27
|
-
process.stdin.on('end', () => resolve(value));
|
|
28
|
-
process.stdin.on('error', reject);
|
|
29
|
-
}));
|
|
30
|
-
if (!input || typeof input !== 'object') throw new Error('expected stdin JSON object');
|
|
31
|
-
if (input.provider !== 'anthropic') throw new Error('expected anthropic provider');
|
|
32
|
-
const credential = input.credential;
|
|
33
|
-
if (!credential || typeof credential !== 'object' || credential.type !== 'oauth') throw new Error('expected oauth credential');
|
|
34
|
-
if (typeof credential.refresh !== 'string' || typeof credential.access !== 'string' || typeof credential.expires !== 'number') throw new Error('expected oauth credential fields');
|
|
35
|
-
const storage = AuthStorage.create();
|
|
36
|
-
storage.set('anthropic', credential);
|
|
37
|
-
const firstErrors = storage.drainErrors();
|
|
38
|
-
if (firstErrors.length > 0) {
|
|
39
|
-
throw new Error(firstErrors.map((error) => error.message).join('; '));
|
|
40
|
-
}
|
|
41
|
-
const reread = AuthStorage.create();
|
|
42
|
-
const stored = reread.get('anthropic');
|
|
43
|
-
const rereadErrors = reread.drainErrors();
|
|
44
|
-
if (rereadErrors.length > 0) {
|
|
45
|
-
throw new Error(rereadErrors.map((error) => error.message).join('; '));
|
|
46
|
-
}
|
|
47
|
-
if (!stored || stored.type !== 'oauth' || stored.refresh !== credential.refresh || stored.access !== credential.access || stored.expires !== credential.expires) {
|
|
48
|
-
throw new Error('stored anthropic oauth credential did not round-trip');
|
|
49
|
-
}
|
|
50
|
-
console.log(JSON.stringify({ ok: true, provider: 'anthropic', storedOauth: true, expiresAt: stored.expires }));
|
|
51
|
-
`;
|
|
52
|
-
function requestPathname(req) {
|
|
53
|
-
return new URL(req.url ?? '/', 'http://127.0.0.1').pathname;
|
|
54
|
-
}
|
|
55
|
-
function respondJson(res, statusCode, value) {
|
|
56
|
-
const body = `${JSON.stringify(value, null, 2)}\n`;
|
|
57
|
-
res.writeHead(statusCode, {
|
|
58
|
-
'content-type': 'application/json; charset=utf-8',
|
|
59
|
-
'content-length': Buffer.byteLength(body),
|
|
60
|
-
'cache-control': 'no-store',
|
|
61
|
-
});
|
|
62
|
-
res.end(body);
|
|
63
|
-
}
|
|
64
|
-
function respondText(res, statusCode, message) {
|
|
65
|
-
const body = `${redactWakeProxyMessage(message)}\n`;
|
|
66
|
-
res.writeHead(statusCode, {
|
|
67
|
-
'content-type': 'text/plain; charset=utf-8',
|
|
68
|
-
'content-length': Buffer.byteLength(body),
|
|
69
|
-
'cache-control': 'no-store',
|
|
70
|
-
});
|
|
71
|
-
res.end(body);
|
|
72
|
-
}
|
|
73
|
-
async function readJsonBody(req, limitBytes) {
|
|
74
|
-
return await new Promise((resolve, reject) => {
|
|
75
|
-
const chunks = [];
|
|
76
|
-
let bytes = 0;
|
|
77
|
-
const cleanup = () => {
|
|
78
|
-
req.off('data', onData);
|
|
79
|
-
req.off('end', onEnd);
|
|
80
|
-
req.off('error', onError);
|
|
81
|
-
req.off('aborted', onAbort);
|
|
82
|
-
};
|
|
83
|
-
const onData = (chunk) => {
|
|
84
|
-
bytes += chunk.byteLength;
|
|
85
|
-
if (bytes > limitBytes) {
|
|
86
|
-
cleanup();
|
|
87
|
-
req.destroy();
|
|
88
|
-
reject(general('request body too large', { limitBytes }));
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
chunks.push(chunk);
|
|
92
|
-
};
|
|
93
|
-
const onEnd = () => {
|
|
94
|
-
cleanup();
|
|
95
|
-
try {
|
|
96
|
-
const text = Buffer.concat(chunks).toString('utf8');
|
|
97
|
-
resolve(text === '' ? {} : JSON.parse(text));
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
reject(error);
|
|
101
|
-
}
|
|
102
|
-
};
|
|
103
|
-
const onError = (error) => {
|
|
104
|
-
cleanup();
|
|
105
|
-
reject(error instanceof Error ? error : new Error(String(error)));
|
|
106
|
-
};
|
|
107
|
-
const onAbort = () => {
|
|
108
|
-
cleanup();
|
|
109
|
-
reject(general('request aborted while reading body'));
|
|
110
|
-
};
|
|
111
|
-
req.on('data', onData);
|
|
112
|
-
req.once('end', onEnd);
|
|
113
|
-
req.once('error', onError);
|
|
114
|
-
req.once('aborted', onAbort);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
function isPlainObject(value) {
|
|
118
|
-
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
119
|
-
}
|
|
120
|
-
function isAnthropicModelAuthPath(pathname) {
|
|
121
|
-
return pathname === '/__hearth/model-auth/anthropic/status'
|
|
122
|
-
|| pathname === '/__hearth/model-auth/anthropic/start'
|
|
123
|
-
|| pathname === '/__hearth/model-auth/anthropic/finish'
|
|
124
|
-
|| pathname.startsWith(MODEL_AUTH_PREFIX);
|
|
125
|
-
}
|
|
126
|
-
function parseFinishBody(body) {
|
|
127
|
-
if (body === null || typeof body !== 'object' || Array.isArray(body))
|
|
128
|
-
return null;
|
|
129
|
-
const value = body;
|
|
130
|
-
if (Object.keys(value).length !== 2)
|
|
131
|
-
return null;
|
|
132
|
-
const sessionId = typeof value.sessionId === 'string' ? value.sessionId.trim() : '';
|
|
133
|
-
const redirectUrl = typeof value.redirectUrl === 'string' ? value.redirectUrl.trim() : '';
|
|
134
|
-
if (sessionId === '' || redirectUrl === '')
|
|
135
|
-
return null;
|
|
136
|
-
return { sessionId, redirectUrl };
|
|
137
|
-
}
|
|
138
|
-
function sendAnthropicStatusError(res, status, error) {
|
|
139
|
-
respondText(res, status, error);
|
|
140
|
-
}
|
|
141
|
-
function resolveModelAuth(req, runtime, write) {
|
|
142
|
-
try {
|
|
143
|
-
const state = currentProxyState(runtime);
|
|
144
|
-
const auth = write ? resolveOwnerWriteAuth(req, runtime.proxy, state) : resolveOwnerAuth(req, runtime.proxy, state);
|
|
145
|
-
if (auth === null)
|
|
146
|
-
return null;
|
|
147
|
-
return { ownerUserId: auth.ownerUserId, tenantId: auth.tenantId };
|
|
148
|
-
}
|
|
149
|
-
catch (error) {
|
|
150
|
-
throw error instanceof Error ? error : new Error(String(error));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
function parseAnthropicOAuthStatus(stdout) {
|
|
154
|
-
try {
|
|
155
|
-
const parsed = JSON.parse(stdout);
|
|
156
|
-
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
157
|
-
return null;
|
|
158
|
-
const value = parsed;
|
|
159
|
-
if (typeof value.storedOauth !== 'boolean' || typeof value.adapterConfigured !== 'boolean')
|
|
160
|
-
return null;
|
|
161
|
-
if (value.expiresAt !== null && typeof value.expiresAt !== 'number')
|
|
162
|
-
return null;
|
|
163
|
-
return {
|
|
164
|
-
storedOauth: value.storedOauth,
|
|
165
|
-
expiresAt: value.expiresAt === null ? null : value.expiresAt,
|
|
166
|
-
adapterConfigured: value.adapterConfigured,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
function parseAnthropicOAuthFinishStatus(stdout) {
|
|
174
|
-
try {
|
|
175
|
-
const parsed = JSON.parse(stdout);
|
|
176
|
-
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
177
|
-
return null;
|
|
178
|
-
const value = parsed;
|
|
179
|
-
if (value.ok !== true || value.provider !== 'anthropic' || value.storedOauth !== true || typeof value.expiresAt !== 'number')
|
|
180
|
-
return null;
|
|
181
|
-
return { ok: true, provider: 'anthropic', storedOauth: true, expiresAt: value.expiresAt };
|
|
182
|
-
}
|
|
183
|
-
catch {
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
async function handleAnthropicStatus(req, res, runtime, deps) {
|
|
188
|
-
let auth;
|
|
189
|
-
try {
|
|
190
|
-
auth = resolveModelAuth(req, runtime, false);
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
sendAnthropicStatusError(res, 403, 'forbidden');
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
if (auth === null) {
|
|
197
|
-
sendAnthropicStatusError(res, 401, 'owner token required');
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
try {
|
|
201
|
-
const raw = await (deps.guestSource ?? runGuestSource)(auth.tenantId, {
|
|
202
|
-
kind: 'exec',
|
|
203
|
-
bin: 'node',
|
|
204
|
-
args: ['--input-type=module', '-e', AUTH_STORAGE_STATUS_SCRIPT],
|
|
205
|
-
cwd: runtime.m0.guestCodePath,
|
|
206
|
-
}, {
|
|
207
|
-
now: deps.now,
|
|
208
|
-
wakeTimeoutMs: runtime.proxy.wakeTimeoutMs,
|
|
209
|
-
bridgeTimeoutMs: runtime.proxy.wakeTimeoutMs,
|
|
210
|
-
});
|
|
211
|
-
const successful = requireSuccessfulExec(raw, 'read anthropic auth');
|
|
212
|
-
const parsed = parseAnthropicOAuthStatus(successful.stdout);
|
|
213
|
-
if (parsed === null) {
|
|
214
|
-
throw general('anthropic auth status returned invalid data');
|
|
215
|
-
}
|
|
216
|
-
respondJson(res, 200, parsed);
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
respondJson(res, 502, { error: redactWakeProxyMessage(error instanceof Error ? error.message : String(error)) });
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
async function handleAnthropicStart(req, res, runtime, deps) {
|
|
223
|
-
let auth;
|
|
224
|
-
try {
|
|
225
|
-
auth = resolveModelAuth(req, runtime, true);
|
|
226
|
-
}
|
|
227
|
-
catch {
|
|
228
|
-
sendAnthropicStatusError(res, 403, 'forbidden');
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
if (auth === null) {
|
|
232
|
-
sendAnthropicStatusError(res, 401, 'owner token required');
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
let body;
|
|
236
|
-
try {
|
|
237
|
-
body = await readJsonBody(req, BODY_LIMIT_BYTES);
|
|
238
|
-
}
|
|
239
|
-
catch (error) {
|
|
240
|
-
respondJson(res, 400, { error: redactWakeProxyMessage(error instanceof Error ? error.message : String(error)) });
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
if (!isPlainObject(body)) {
|
|
244
|
-
respondJson(res, 400, { error: 'start request must be empty or a JSON object' });
|
|
245
|
-
return;
|
|
246
|
-
}
|
|
247
|
-
const started = (deps.startSession ?? startAnthropicOAuthSession)(auth.tenantId, deps.now ?? Date.now);
|
|
248
|
-
respondJson(res, 200, {
|
|
249
|
-
provider: 'anthropic',
|
|
250
|
-
sessionId: started.sessionId,
|
|
251
|
-
authUrl: started.authUrl,
|
|
252
|
-
expiresAt: started.expiresAt,
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
async function handleAnthropicFinish(req, res, runtime, deps) {
|
|
256
|
-
let auth;
|
|
257
|
-
try {
|
|
258
|
-
auth = resolveModelAuth(req, runtime, true);
|
|
259
|
-
}
|
|
260
|
-
catch {
|
|
261
|
-
sendAnthropicStatusError(res, 403, 'forbidden');
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
if (auth === null) {
|
|
265
|
-
sendAnthropicStatusError(res, 401, 'owner token required');
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
let body;
|
|
269
|
-
try {
|
|
270
|
-
body = await readJsonBody(req, BODY_LIMIT_BYTES);
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
respondJson(res, 400, { error: redactWakeProxyMessage(error instanceof Error ? error.message : String(error)) });
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
const parsed = parseFinishBody(body);
|
|
277
|
-
if (parsed === null) {
|
|
278
|
-
respondJson(res, 400, { error: 'finish request must be { sessionId, redirectUrl }' });
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
try {
|
|
282
|
-
const finished = await (deps.finishSession ?? finishAnthropicOAuthSession)({ tenantId: auth.tenantId, sessionId: parsed.sessionId, redirectUrl: parsed.redirectUrl });
|
|
283
|
-
if (!finished.ok) {
|
|
284
|
-
respondJson(res, finished.status, { error: finished.error });
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
const raw = await (deps.guestSource ?? runGuestSource)(auth.tenantId, {
|
|
288
|
-
kind: 'exec',
|
|
289
|
-
bin: 'node',
|
|
290
|
-
args: ['--input-type=module', '-e', AUTH_STORAGE_WRITE_SCRIPT],
|
|
291
|
-
stdin: JSON.stringify({ provider: 'anthropic', credential: finished.credential }),
|
|
292
|
-
cwd: runtime.m0.guestCodePath,
|
|
293
|
-
}, {
|
|
294
|
-
now: deps.now,
|
|
295
|
-
wakeTimeoutMs: runtime.proxy.wakeTimeoutMs,
|
|
296
|
-
bridgeTimeoutMs: runtime.proxy.wakeTimeoutMs,
|
|
297
|
-
});
|
|
298
|
-
const successful = requireSuccessfulExec(raw, 'write anthropic auth');
|
|
299
|
-
const parsedStatus = parseAnthropicOAuthFinishStatus(successful.stdout);
|
|
300
|
-
if (parsedStatus === null) {
|
|
301
|
-
throw general('anthropic auth write returned invalid data');
|
|
302
|
-
}
|
|
303
|
-
respondJson(res, 200, {
|
|
304
|
-
ok: true,
|
|
305
|
-
provider: parsedStatus.provider,
|
|
306
|
-
sessionId: finished.sessionId,
|
|
307
|
-
storedOauth: parsedStatus.storedOauth,
|
|
308
|
-
expiresAt: parsedStatus.expiresAt,
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
catch (error) {
|
|
312
|
-
respondJson(res, 502, { error: redactWakeProxyMessage(error instanceof Error ? error.message : String(error)) });
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
export async function handleModelAuthRequest(req, res, runtime, deps = {}) {
|
|
316
|
-
const pathname = requestPathname(req);
|
|
317
|
-
if (!isAnthropicModelAuthPath(pathname))
|
|
318
|
-
return false;
|
|
319
|
-
if (pathname === '/__hearth/model-auth/anthropic/status') {
|
|
320
|
-
if (req.method !== 'GET') {
|
|
321
|
-
respondText(res, 405, 'method not allowed');
|
|
322
|
-
return true;
|
|
323
|
-
}
|
|
324
|
-
await handleAnthropicStatus(req, res, runtime, deps);
|
|
325
|
-
return true;
|
|
326
|
-
}
|
|
327
|
-
if (pathname === '/__hearth/model-auth/anthropic/start') {
|
|
328
|
-
if (req.method !== 'POST') {
|
|
329
|
-
respondText(res, 405, 'method not allowed');
|
|
330
|
-
return true;
|
|
331
|
-
}
|
|
332
|
-
await handleAnthropicStart(req, res, runtime, deps);
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
|
-
if (pathname === '/__hearth/model-auth/anthropic/finish') {
|
|
336
|
-
if (req.method !== 'POST') {
|
|
337
|
-
respondText(res, 405, 'method not allowed');
|
|
338
|
-
return true;
|
|
339
|
-
}
|
|
340
|
-
await handleAnthropicFinish(req, res, runtime, deps);
|
|
341
|
-
return true;
|
|
342
|
-
}
|
|
343
|
-
respondText(res, 404, 'not found');
|
|
344
|
-
return true;
|
|
345
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import type { Socket } from 'node:net';
|
|
3
|
-
import { WebSocket } from 'ws';
|
|
4
|
-
import type { HearthWakeProxyRuntime } from './types.js';
|
|
5
|
-
export declare function serializeWakeProxyError(error: unknown): Record<string, unknown>;
|
|
6
|
-
export declare function isPublicStaticAssetPath(pathname: string): boolean;
|
|
7
|
-
export declare function buildUpstreamHttpUrl(routeUrl: string, rawRequestUrl: string | undefined): URL;
|
|
8
|
-
declare function withWakeTimeout<T>(work: Promise<T>, timeoutMs: number, label: string): Promise<T>;
|
|
9
|
-
export declare const proxyInternals: {
|
|
10
|
-
withWakeTimeout: typeof withWakeTimeout;
|
|
11
|
-
attachWsKeepalive: typeof attachWsKeepalive;
|
|
12
|
-
proxyWebSocketBrowser: typeof proxyWebSocketBrowser;
|
|
13
|
-
};
|
|
14
|
-
export declare function proxyHttpRequest(req: IncomingMessage, res: ServerResponse, runtime: HearthWakeProxyRuntime): Promise<void>;
|
|
15
|
-
type WsLeg = 'browser' | 'upstream';
|
|
16
|
-
type WsKeepaliveContext = {
|
|
17
|
-
nodeId: string;
|
|
18
|
-
tenantId: string;
|
|
19
|
-
leg: WsLeg;
|
|
20
|
-
};
|
|
21
|
-
type AttachWsKeepaliveOptions = {
|
|
22
|
-
intervalMs?: number;
|
|
23
|
-
onStale?: () => void;
|
|
24
|
-
};
|
|
25
|
-
declare function attachWsKeepalive(socket: WebSocket, context: WsKeepaliveContext, options?: AttachWsKeepaliveOptions): () => void;
|
|
26
|
-
export interface ProxyWebSocketDeps {
|
|
27
|
-
ensureAwake?: (tenantId: string) => Promise<{
|
|
28
|
-
routeUrl: string;
|
|
29
|
-
relayToken: string;
|
|
30
|
-
}>;
|
|
31
|
-
createUpstream?: (url: string, relayToken: string) => WebSocket;
|
|
32
|
-
}
|
|
33
|
-
declare function proxyWebSocketBrowser(browserWs: WebSocket, nodeId: string, tenantId: string, runtime: HearthWakeProxyRuntime, deps?: ProxyWebSocketDeps): Promise<void>;
|
|
34
|
-
export declare function proxyUpgrade(req: IncomingMessage, socket: Socket, head: Buffer, runtime: HearthWakeProxyRuntime): void;
|
|
35
|
-
export {};
|