@stage-labs/metro 0.1.0-beta.308 → 0.1.0-beta.309
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/package.json +1 -1
- package/runtime/node_modules/@metro-labs/daemon/src/agent-user/view.ts +3 -9
- package/runtime/node_modules/@metro-labs/daemon/src/boot/boot.ts +11 -4
- package/runtime/node_modules/@metro-labs/daemon/src/claude/session.ts +7 -6
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/bedrock.ts +1 -6
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-logins.ts +53 -29
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/claude-store.ts +55 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex.ts +40 -62
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/delivered.ts +82 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/effective.ts +47 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/fallback.ts +18 -19
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gateway.ts +36 -64
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-api.ts +99 -213
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-config.ts +80 -283
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-import.ts +125 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-lists.ts +0 -17
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-v2.ts +79 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter.ts +0 -79
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/org-models.ts +231 -0
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/provider-models.ts +4 -44
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/text.ts +0 -2
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage-refresh.ts +37 -57
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/usage.ts +0 -13
- package/runtime/node_modules/@metro-labs/daemon/src/routes/local-mode.ts +3 -4
- package/runtime/runtime.json +1 -1
- package/runtime/sdk-runner/runner.json +1 -1
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-auth.ts +0 -219
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/codex-device.ts +0 -119
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-auth.ts +0 -160
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-client.ts +0 -46
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-setup.ts +0 -150
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-stream.ts +0 -139
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini-translate.ts +0 -236
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/gemini.ts +0 -208
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-signin.ts +0 -157
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/model-store.ts +0 -82
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter-login.ts +0 -192
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/openrouter-signin.ts +0 -64
- package/runtime/node_modules/@metro-labs/daemon/src/gateway/pkce.ts +0 -36
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
-
import { sendJson, sessionRoute } from '@metro-labs/http/api-http';
|
|
3
|
-
import { log } from '@metro-labs/core/log';
|
|
4
|
-
import { publicBaseUrl } from '../files/attach-serve.js';
|
|
5
|
-
import { askedConnection, type ModelApiDeps, type Store } from './model-store.js';
|
|
6
|
-
import { OPENROUTER_CALLBACK, OpenRouterLogins } from './openrouter-login.js';
|
|
7
|
-
|
|
8
|
-
const LOGIN = '/api/model/openrouter/login';
|
|
9
|
-
const ID_RE = /^[A-Za-z0-9_-]{32}$/;
|
|
10
|
-
const logins = new WeakMap<ModelApiDeps, OpenRouterLogins>();
|
|
11
|
-
const CALLBACK_HEADERS = {
|
|
12
|
-
'cache-control': 'no-store',
|
|
13
|
-
'referrer-policy': 'no-referrer',
|
|
14
|
-
'content-security-policy': "default-src 'none'; frame-ancestors 'none'; base-uri 'none'",
|
|
15
|
-
'x-content-type-options': 'nosniff',
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
function loginFor(deps: ModelApiDeps, store: Store): OpenRouterLogins {
|
|
19
|
-
let login = logins.get(deps);
|
|
20
|
-
if (login === undefined) {
|
|
21
|
-
login = new OpenRouterLogins({
|
|
22
|
-
store,
|
|
23
|
-
owner: () => deps.owner?.() ?? null,
|
|
24
|
-
publicBase: deps.openrouterPublicBase ?? publicBaseUrl,
|
|
25
|
-
fetchImpl: deps.fetchImpl,
|
|
26
|
-
now: deps.openrouterNow,
|
|
27
|
-
});
|
|
28
|
-
logins.set(deps, login);
|
|
29
|
-
}
|
|
30
|
-
return login;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function callback(req: IncomingMessage, res: ServerResponse, login: OpenRouterLogins): void {
|
|
34
|
-
if (req.method !== 'GET') {
|
|
35
|
-
sendJson(req, res, 405, { error: 'method not allowed' });
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const url = new URL(req.url ?? '', 'https://metro');
|
|
39
|
-
if (url.search === '') {
|
|
40
|
-
res.writeHead(200, { ...CALLBACK_HEADERS, 'content-type': 'text/html; charset=utf-8' });
|
|
41
|
-
res.end('<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>OpenRouter sign-in</title><h1>Return to Metro</h1><p>Check your connection in Metro. You can close this tab.</p><p>If you declined access, cancel the sign-in in Metro or use an API key.</p></html>');
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
const finish = (): void => { res.writeHead(303, { ...CALLBACK_HEADERS, location: OPENROUTER_CALLBACK }).end(); };
|
|
45
|
-
login.complete(url.searchParams).then(finish, finish).catch(() => {
|
|
46
|
-
log.warn('openrouter-signin: callback response closed');
|
|
47
|
-
if (!res.writableEnded) res.end();
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function handleOpenRouterSignIn(req: IncomingMessage, res: ServerResponse, deps: ModelApiDeps, store: Store): boolean {
|
|
52
|
-
const path = (req.url ?? '').split('?')[0] ?? '';
|
|
53
|
-
if (path === OPENROUTER_CALLBACK) {
|
|
54
|
-
callback(req, res, loginFor(deps, store));
|
|
55
|
-
return true;
|
|
56
|
-
}
|
|
57
|
-
const id = path.startsWith(`${LOGIN}/`) ? path.slice(LOGIN.length + 1) : '';
|
|
58
|
-
if (path !== LOGIN && !ID_RE.test(id)) return false;
|
|
59
|
-
return sessionRoute(req, res, { methods: { [path]: path === LOGIN ? ['POST'] : ['GET', 'DELETE'] }, admin: false, label: 'openrouter-signin' }, (session) => {
|
|
60
|
-
const login = loginFor(deps, store);
|
|
61
|
-
if (path === LOGIN) return Promise.resolve(login.begin(session.subject, askedConnection(req)));
|
|
62
|
-
return Promise.resolve(req.method === 'DELETE' ? login.cancel(session.subject, id) : login.status(session.subject, id));
|
|
63
|
-
});
|
|
64
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
-
|
|
3
|
-
const PENDING_TTL_MS = 10 * 60_000;
|
|
4
|
-
|
|
5
|
-
const b64url = (buf: Buffer): string => buf.toString('base64url');
|
|
6
|
-
|
|
7
|
-
export function newPkce(): { verifier: string; challenge: string } {
|
|
8
|
-
const verifier = b64url(randomBytes(32));
|
|
9
|
-
return { verifier, challenge: b64url(createHash('sha256').update(verifier).digest()) };
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export class PendingLogins {
|
|
13
|
-
private readonly pending = new Map<string, { verifier: string; at: number }>();
|
|
14
|
-
|
|
15
|
-
constructor(private readonly stateBytes: number) {}
|
|
16
|
-
|
|
17
|
-
private sweep(now: number): void {
|
|
18
|
-
for (const [state, entry] of this.pending) if (now - entry.at > PENDING_TTL_MS) this.pending.delete(state);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
begin(now: number): { state: string; challenge: string } {
|
|
22
|
-
this.sweep(now);
|
|
23
|
-
const { verifier, challenge } = newPkce();
|
|
24
|
-
const state = b64url(randomBytes(this.stateBytes));
|
|
25
|
-
this.pending.set(state, { verifier, at: now });
|
|
26
|
-
return { state, challenge };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
take(state: string, now: number): string | null {
|
|
30
|
-
this.sweep(now);
|
|
31
|
-
const entry = this.pending.get(state);
|
|
32
|
-
if (entry === undefined) return null;
|
|
33
|
-
this.pending.delete(state);
|
|
34
|
-
return entry.verifier;
|
|
35
|
-
}
|
|
36
|
-
}
|