@calliopelabs/cli 3.6.0 → 3.8.0
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 +13 -0
- package/dist/acp/controls.d.ts +10 -0
- package/dist/acp/controls.d.ts.map +1 -0
- package/dist/acp/controls.js +81 -0
- package/dist/acp/controls.js.map +1 -0
- package/dist/acp.d.ts +11 -4
- package/dist/acp.d.ts.map +1 -1
- package/dist/acp.js +114 -18
- package/dist/acp.js.map +1 -1
- package/dist/approvals/request.d.ts.map +1 -1
- package/dist/approvals/request.js +10 -0
- package/dist/approvals/request.js.map +1 -1
- package/dist/auth/chatgpt/fallback.d.ts +31 -0
- package/dist/auth/chatgpt/fallback.d.ts.map +1 -0
- package/dist/auth/chatgpt/fallback.js +111 -0
- package/dist/auth/chatgpt/fallback.js.map +1 -0
- package/dist/auth/chatgpt/index.d.ts +6 -0
- package/dist/auth/chatgpt/index.d.ts.map +1 -0
- package/dist/auth/chatgpt/index.js +6 -0
- package/dist/auth/chatgpt/index.js.map +1 -0
- package/dist/auth/chatgpt/login.d.ts +4 -0
- package/dist/auth/chatgpt/login.d.ts.map +1 -0
- package/dist/auth/chatgpt/login.js +82 -0
- package/dist/auth/chatgpt/login.js.map +1 -0
- package/dist/auth/chatgpt/protocol.d.ts +24 -0
- package/dist/auth/chatgpt/protocol.d.ts.map +1 -0
- package/dist/auth/chatgpt/protocol.js +71 -0
- package/dist/auth/chatgpt/protocol.js.map +1 -0
- package/dist/auth/chatgpt/session.d.ts +24 -0
- package/dist/auth/chatgpt/session.d.ts.map +1 -0
- package/dist/auth/chatgpt/session.js +101 -0
- package/dist/auth/chatgpt/session.js.map +1 -0
- package/dist/auth/chatgpt/store.d.ts +28 -0
- package/dist/auth/chatgpt/store.d.ts.map +1 -0
- package/dist/auth/chatgpt/store.js +75 -0
- package/dist/auth/chatgpt/store.js.map +1 -0
- package/dist/auth/cli.d.ts +2 -0
- package/dist/auth/cli.d.ts.map +1 -0
- package/dist/auth/cli.js +38 -0
- package/dist/auth/cli.js.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +25 -0
- package/dist/bin.js.map +1 -1
- package/dist/brain/exchange.d.ts.map +1 -1
- package/dist/brain/exchange.js +3 -1
- package/dist/brain/exchange.js.map +1 -1
- package/dist/brain/kg-export.d.ts +1 -1
- package/dist/brain/kg.d.ts +1 -1
- package/dist/brain/kg.d.ts.map +1 -1
- package/dist/brain/kg.js +3 -1
- package/dist/brain/kg.js.map +1 -1
- package/dist/build-identity.d.ts +27 -0
- package/dist/build-identity.d.ts.map +1 -0
- package/dist/build-identity.js +32 -0
- package/dist/build-identity.js.map +1 -0
- package/dist/build-metadata.json +1 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -2
- package/dist/config.js.map +1 -1
- package/dist/delegation/claude.d.ts +28 -0
- package/dist/delegation/claude.d.ts.map +1 -0
- package/dist/delegation/claude.js +107 -0
- package/dist/delegation/claude.js.map +1 -0
- package/dist/delegation/index.d.ts +2 -0
- package/dist/delegation/index.d.ts.map +1 -0
- package/dist/delegation/index.js +2 -0
- package/dist/delegation/index.js.map +1 -0
- package/dist/execution/attribution.d.ts +3 -0
- package/dist/execution/attribution.d.ts.map +1 -1
- package/dist/execution/attribution.js.map +1 -1
- package/dist/execution/delegated.d.ts.map +1 -1
- package/dist/execution/delegated.js +5 -2
- package/dist/execution/delegated.js.map +1 -1
- package/dist/execution/ledger-cli.d.ts.map +1 -1
- package/dist/execution/ledger-cli.js +9 -7
- package/dist/execution/ledger-cli.js.map +1 -1
- package/dist/execution/ledger-server.d.ts +6 -0
- package/dist/execution/ledger-server.d.ts.map +1 -1
- package/dist/execution/ledger-server.js +39 -4
- package/dist/execution/ledger-server.js.map +1 -1
- package/dist/execution/quote.d.ts +1 -1
- package/dist/execution/quote.d.ts.map +1 -1
- package/dist/execution/quote.js +4 -2
- package/dist/execution/quote.js.map +1 -1
- package/dist/execution/remote-ledger.d.ts +7 -0
- package/dist/execution/remote-ledger.d.ts.map +1 -1
- package/dist/execution/remote-ledger.js +22 -5
- package/dist/execution/remote-ledger.js.map +1 -1
- package/dist/health/target.d.ts.map +1 -1
- package/dist/health/target.js +8 -1
- package/dist/health/target.js.map +1 -1
- package/dist/improvement/cli.d.ts +1 -1
- package/dist/improvement/cli.d.ts.map +1 -1
- package/dist/improvement/cli.js +18 -4
- package/dist/improvement/cli.js.map +1 -1
- package/dist/improvement/host-capabilities.d.ts +252 -0
- package/dist/improvement/host-capabilities.d.ts.map +1 -0
- package/dist/improvement/host-capabilities.js +25 -0
- package/dist/improvement/host-capabilities.js.map +1 -0
- package/dist/improvement/index.d.ts +3 -0
- package/dist/improvement/index.d.ts.map +1 -1
- package/dist/improvement/index.js +3 -0
- package/dist/improvement/index.js.map +1 -1
- package/dist/improvement/task-feedback-contract.d.ts +41 -0
- package/dist/improvement/task-feedback-contract.d.ts.map +1 -0
- package/dist/improvement/task-feedback-contract.js +83 -0
- package/dist/improvement/task-feedback-contract.js.map +1 -0
- package/dist/improvement/task-feedback.d.ts +149 -0
- package/dist/improvement/task-feedback.d.ts.map +1 -0
- package/dist/improvement/task-feedback.js +117 -0
- package/dist/improvement/task-feedback.js.map +1 -0
- package/dist/improvement/task-outcomes.d.ts +2 -2
- package/dist/improvement/task-outcomes.d.ts.map +1 -1
- package/dist/improvement/task-outcomes.js +2 -3
- package/dist/improvement/task-outcomes.js.map +1 -1
- package/dist/model-detection.d.ts +0 -5
- package/dist/model-detection.d.ts.map +1 -1
- package/dist/model-detection.js +5 -5
- package/dist/model-detection.js.map +1 -1
- package/dist/orchestration/coordinator-types.d.ts +4 -1
- package/dist/orchestration/coordinator-types.d.ts.map +1 -1
- package/dist/orchestration/execution-journal.d.ts.map +1 -1
- package/dist/orchestration/execution-journal.js +10 -3
- package/dist/orchestration/execution-journal.js.map +1 -1
- package/dist/orchestration/execution.d.ts +3 -1
- package/dist/orchestration/execution.d.ts.map +1 -1
- package/dist/orchestration/execution.js +1 -1
- package/dist/orchestration/execution.js.map +1 -1
- package/dist/orchestration/reviewed-ledger.d.ts +42 -0
- package/dist/orchestration/reviewed-ledger.d.ts.map +1 -1
- package/dist/orchestration/reviewed-ledger.js +59 -9
- package/dist/orchestration/reviewed-ledger.js.map +1 -1
- package/dist/orchestration/routing.d.ts +5 -0
- package/dist/orchestration/routing.d.ts.map +1 -1
- package/dist/orchestration/routing.js +15 -2
- package/dist/orchestration/routing.js.map +1 -1
- package/dist/orchestration/task-configuration.d.ts +8 -0
- package/dist/orchestration/task-configuration.d.ts.map +1 -0
- package/dist/orchestration/task-configuration.js +23 -0
- package/dist/orchestration/task-configuration.js.map +1 -0
- package/dist/providers/chatgpt.d.ts +11 -0
- package/dist/providers/chatgpt.d.ts.map +1 -0
- package/dist/providers/chatgpt.js +156 -0
- package/dist/providers/chatgpt.js.map +1 -0
- package/dist/providers/index.d.ts +0 -5
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +10 -2
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/types.d.ts +5 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/runlog.d.ts +1 -1
- package/dist/runlog.d.ts.map +1 -1
- package/dist/runtime/permissions.d.ts.map +1 -1
- package/dist/runtime/permissions.js +1 -0
- package/dist/runtime/permissions.js.map +1 -1
- package/dist/runtime/turn.d.ts.map +1 -1
- package/dist/runtime/turn.js +79 -12
- package/dist/runtime/turn.js.map +1 -1
- package/dist/sessions/execution-binding.d.ts +8 -3
- package/dist/sessions/execution-binding.d.ts.map +1 -1
- package/dist/sessions/execution-binding.js +13 -3
- package/dist/sessions/execution-binding.js.map +1 -1
- package/dist/storage.d.ts +2 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +5 -1
- package/dist/storage.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/components.d.ts.map +1 -1
- package/dist/ui/components.js +3 -5
- package/dist/ui/components.js.map +1 -1
- package/dist/ui/frame.js +3 -3
- package/dist/ui/frame.js.map +1 -1
- package/dist/ui/modals/tool-output.d.ts.map +1 -1
- package/dist/ui/modals/tool-output.js +5 -6
- package/dist/ui/modals/tool-output.js.map +1 -1
- package/dist/ui/state/use-terminal-width.d.ts.map +1 -1
- package/dist/ui/state/use-terminal-width.js +2 -13
- package/dist/ui/state/use-terminal-width.js.map +1 -1
- package/docs/acp.md +228 -0
- package/docs/chatgpt-plan.md +109 -0
- package/docs/claude-plan.md +58 -0
- package/docs/delegation-ledger.md +56 -3
- package/docs/improvement-cycles.md +309 -0
- package/docs/releases/3.7.0.md +53 -0
- package/docs/releases/3.8.0.md +65 -0
- package/docs/reviewed-provider-metadata.md +84 -0
- package/docs/task-feedback.md +77 -0
- package/package.json +21 -12
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { StreamProtocolError } from '../../errors.js';
|
|
2
|
+
import type { Message } from '../../types.js';
|
|
3
|
+
import { ChatGPTStore } from './store.js';
|
|
4
|
+
export declare const apiKeyAccessActive: () => boolean;
|
|
5
|
+
export declare const withAPIKeyAccess: <T>(action: () => T) => T;
|
|
6
|
+
export interface ChatGPTFallbackPolicy {
|
|
7
|
+
model: string;
|
|
8
|
+
maxProjectCostUsd: number;
|
|
9
|
+
maxOutputTokens: number;
|
|
10
|
+
cooldownSeconds: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class ChatGPTQuotaError extends StreamProtocolError {
|
|
13
|
+
readonly reason: 'quota' | 'rate-limit';
|
|
14
|
+
readonly partial: boolean;
|
|
15
|
+
constructor(reason: 'quota' | 'rate-limit', partial?: boolean);
|
|
16
|
+
}
|
|
17
|
+
export declare function fallbackPolicy(): ChatGPTFallbackPolicy | undefined;
|
|
18
|
+
export declare function validateFallbackPolicy(p: ChatGPTFallbackPolicy): ChatGPTFallbackPolicy;
|
|
19
|
+
export declare function quotaCircuit(store?: ChatGPTStore, now?: number): {
|
|
20
|
+
reason: 'quota' | 'rate-limit';
|
|
21
|
+
until: number;
|
|
22
|
+
} | undefined;
|
|
23
|
+
export declare function openQuotaCircuit(clientId: string, reason: 'quota' | 'rate-limit', store?: ChatGPTStore): Promise<void>;
|
|
24
|
+
export declare function fallbackHistory(messages: Message[]): {
|
|
25
|
+
clientId: string;
|
|
26
|
+
model: string;
|
|
27
|
+
} | undefined;
|
|
28
|
+
/** Preserve visible conversation and completed tool pairs; never send encrypted plan state to an API key. */
|
|
29
|
+
export declare function publicFallbackHistory(messages: Message[], clientId: string, model: string): Message[];
|
|
30
|
+
export declare function runFallbackCommand(args: string[], signal?: AbortSignal): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/fallback.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,eAAO,MAAM,kBAAkB,eAAsC,CAAC;AACtE,eAAO,MAAM,gBAAgB,GAAI,CAAC,UAAU,MAAM,CAAC,KAAG,CAAgC,CAAC;AACvF,MAAM,WAAW,qBAAqB;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE;AACrI,qBAAa,iBAAkB,SAAQ,mBAAmB;IAC5C,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY;IAAE,QAAQ,CAAC,OAAO;IAArE,YAAqB,MAAM,EAAE,OAAO,GAAG,YAAY,EAAW,OAAO,UAAQ,EAG5E;CACF;AACD,wBAAgB,cAAc,IAAI,qBAAqB,GAAG,SAAS,CAGlE;AACD,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,qBAAqB,GAAG,qBAAqB,CAQtF;AACD,wBAAgB,YAAY,CAAC,KAAK,eAAqB,EAAE,GAAG,SAAa;;;cAGxE;AACD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,YAAY,EAAE,KAAK,eAAqB,iBAOlH;AACD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAWpG;AACD,6GAA6G;AAC7G,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAiBrG;AACD,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB5F"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import * as config from '../../config.js';
|
|
3
|
+
import { StreamProtocolError } from '../../errors.js';
|
|
4
|
+
import { ChatGPTStore } from './store.js';
|
|
5
|
+
import { ChatGPTAuthError } from './protocol.js';
|
|
6
|
+
const apiAccess = new AsyncLocalStorage();
|
|
7
|
+
export const apiKeyAccessActive = () => apiAccess.getStore() === true;
|
|
8
|
+
export const withAPIKeyAccess = (action) => apiAccess.run(true, action);
|
|
9
|
+
export class ChatGPTQuotaError extends StreamProtocolError {
|
|
10
|
+
reason;
|
|
11
|
+
partial;
|
|
12
|
+
constructor(reason, partial = false) {
|
|
13
|
+
super(reason === 'quota' ? 'ChatGPT plan usage limit reached. Subscription inference is paused; configure API-key fallback or wait for the cooldown.' : 'ChatGPT rate limit reached. Subscription inference is paused until the cooldown.');
|
|
14
|
+
this.reason = reason;
|
|
15
|
+
this.partial = partial;
|
|
16
|
+
this.name = 'ChatGPTQuotaError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export function fallbackPolicy() {
|
|
20
|
+
const p = config.get('chatgptFallback');
|
|
21
|
+
return p == null ? undefined : validateFallbackPolicy(p);
|
|
22
|
+
}
|
|
23
|
+
export function validateFallbackPolicy(p) {
|
|
24
|
+
if (!p || typeof p.model !== 'string' || !p.model.trim() || p.model.length > 512 || /[\x00-\x20\x7f]/.test(p.model) ||
|
|
25
|
+
!Number.isFinite(p.maxProjectCostUsd) || p.maxProjectCostUsd <= 0 || p.maxProjectCostUsd > 1000000 ||
|
|
26
|
+
!Number.isSafeInteger(p.maxOutputTokens) || p.maxOutputTokens < 1 || p.maxOutputTokens > 100000000 ||
|
|
27
|
+
!Number.isSafeInteger(p.cooldownSeconds) || p.cooldownSeconds < 1 || p.cooldownSeconds > 86400 ||
|
|
28
|
+
Object.keys(p).some(k => !['model', 'maxProjectCostUsd', 'maxOutputTokens', 'cooldownSeconds'].includes(k)))
|
|
29
|
+
throw new ChatGPTAuthError('Invalid ChatGPT fallback configuration. Configure it again before using paid fallback.');
|
|
30
|
+
return { ...p };
|
|
31
|
+
}
|
|
32
|
+
export function quotaCircuit(store = new ChatGPTStore(), now = Date.now()) {
|
|
33
|
+
const breaker = store.active()?.quotaCircuit;
|
|
34
|
+
return breaker && breaker.until > now ? { ...breaker } : undefined;
|
|
35
|
+
}
|
|
36
|
+
export async function openQuotaCircuit(clientId, reason, store = new ChatGPTStore()) {
|
|
37
|
+
const configured = config.get('chatgptFallback')?.cooldownSeconds;
|
|
38
|
+
const seconds = reason === 'rate-limit' ? 60 : Number.isSafeInteger(configured) && configured >= 1 && configured <= 86400 ? configured : 3600;
|
|
39
|
+
await store.update(state => {
|
|
40
|
+
const a = state.accounts[clientId];
|
|
41
|
+
if (a)
|
|
42
|
+
a.quotaCircuit = { reason, until: Date.now() + seconds * 1000 };
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export function fallbackHistory(messages) {
|
|
46
|
+
let found;
|
|
47
|
+
for (const m of messages) {
|
|
48
|
+
const marker = m.providerMetadata?.openai?.chatgptFallback;
|
|
49
|
+
if (!marker)
|
|
50
|
+
continue;
|
|
51
|
+
if (!/^oaiapp_[\w-]+$/.test(marker.clientId) || typeof marker.model !== 'string' || !marker.model ||
|
|
52
|
+
found && (found.clientId !== marker.clientId || found.model !== marker.model))
|
|
53
|
+
throw new ChatGPTAuthError('Inconsistent API-key fallback history. Start a new session.');
|
|
54
|
+
found = { clientId: marker.clientId, model: marker.model };
|
|
55
|
+
}
|
|
56
|
+
return found;
|
|
57
|
+
}
|
|
58
|
+
/** Preserve visible conversation and completed tool pairs; never send encrypted plan state to an API key. */
|
|
59
|
+
export function publicFallbackHistory(messages, clientId, model) {
|
|
60
|
+
const existing = fallbackHistory(messages);
|
|
61
|
+
if (existing && (existing.clientId !== clientId || existing.model !== model))
|
|
62
|
+
throw new ChatGPTAuthError('Fallback account or model changed. Start a new session.');
|
|
63
|
+
const result = messages.map(m => {
|
|
64
|
+
const metadata = m.providerMetadata;
|
|
65
|
+
if (metadata && Object.keys(metadata).some(k => k !== 'openai' && k !== 'calliopeRouting'))
|
|
66
|
+
throw new ChatGPTAuthError('Other provider state cannot be converted to API-key fallback. Start a new session.');
|
|
67
|
+
if (metadata?.openai && Object.keys(metadata.openai).some(k => k !== 'chatgpt' && k !== 'chatgptFallback'))
|
|
68
|
+
throw new ChatGPTAuthError('Unknown OpenAI state cannot be converted to API-key fallback. Start a new session.');
|
|
69
|
+
const saved = metadata?.openai?.chatgpt;
|
|
70
|
+
if (saved && saved.clientId !== clientId)
|
|
71
|
+
throw new ChatGPTAuthError('ChatGPT history belongs to a different account. Start a new session.');
|
|
72
|
+
const { providerMetadata: _opaque, ...publicMessage } = m;
|
|
73
|
+
return structuredClone(publicMessage);
|
|
74
|
+
});
|
|
75
|
+
const last = result.at(-1);
|
|
76
|
+
if (last)
|
|
77
|
+
last.providerMetadata = { openai: { chatgptFallback: { clientId, model } }, calliopeRouting: { provider: 'openai', model } };
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
export async function runFallbackCommand(args, signal) {
|
|
81
|
+
const store = new ChatGPTStore();
|
|
82
|
+
if (args.length === 1 && args[0] === 'models') {
|
|
83
|
+
if (!config.getApiKey('openai'))
|
|
84
|
+
throw new ChatGPTAuthError('Configure an OpenAI API key before listing paid fallback models.');
|
|
85
|
+
const { getAvailableModels } = await import('../../model-detection.js');
|
|
86
|
+
const { providerTarget } = await import('../../health/index.js');
|
|
87
|
+
const result = await withAPIKeyAccess(async () => ({ target: providerTarget('openai').key, models: await getAvailableModels('openai', { signal, quiet: true, throwOnError: true }) }));
|
|
88
|
+
console.log(JSON.stringify(result, null, 2));
|
|
89
|
+
}
|
|
90
|
+
else if (args[0] === 'enable' && (args.length === 3 || args.length === 4)) {
|
|
91
|
+
if (!config.getApiKey('openai'))
|
|
92
|
+
throw new ChatGPTAuthError('Configure an OpenAI API key before enabling paid fallback.');
|
|
93
|
+
config.set('chatgptFallback', validateFallbackPolicy({ model: args[1], maxProjectCostUsd: Number(args[2]), maxOutputTokens: Number(args[3] ?? 4096), cooldownSeconds: 3600 }));
|
|
94
|
+
console.log('Paid OpenAI API-key fallback enabled. Each request requires live model discovery, verified billing bounds and a shared project-budget reservation. Existing project spend counts toward this cap.');
|
|
95
|
+
}
|
|
96
|
+
else if (args.length === 1 && args[0] === 'disable') {
|
|
97
|
+
config.set('chatgptFallback', null);
|
|
98
|
+
console.log('Automatic paid fallback disabled.');
|
|
99
|
+
}
|
|
100
|
+
else if (args.length === 1 && args[0] === 'reset') {
|
|
101
|
+
await store.update(s => { if (s.active)
|
|
102
|
+
delete s.accounts[s.active].quotaCircuit; });
|
|
103
|
+
console.log('Subscription quota circuit reset. Existing API-key fallback sessions stay on the paid route; start a new session to try the plan again.');
|
|
104
|
+
}
|
|
105
|
+
else if (args.length === 1 && args[0] === 'status') {
|
|
106
|
+
console.log(JSON.stringify({ enabled: !!fallbackPolicy(), policy: fallbackPolicy() ?? null, circuit: quotaCircuit(store) ?? null }, null, 2));
|
|
107
|
+
}
|
|
108
|
+
else
|
|
109
|
+
throw new ChatGPTAuthError('Usage: calliope auth chatgpt fallback enable <api-model> <max-project-cost-usd> [max-output-tokens] | models | disable | status | reset');
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=fallback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/fallback.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ChatGPTStore } from './store.js';
|
|
2
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
3
|
+
export declare function login(store?: ChatGPTStore, clientId?: string, signal?: AbortSignal, launch?: typeof openBrowser): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/login.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI1C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAStD;AACD,wBAAsB,KAAK,CAAC,KAAK,eAAqB,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,MAAM,qBAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CA4CpI"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { ChatGPTStore } from './store.js';
|
|
4
|
+
import { prepareAuthorization, ChatGPTAuthError } from './protocol.js';
|
|
5
|
+
import { tokenRequest, validateIdentity, applyTokens } from './session.js';
|
|
6
|
+
export function openBrowser(url) {
|
|
7
|
+
// argv only; no shell and no user-controlled executable.
|
|
8
|
+
const command = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'rundll32.exe' : 'xdg-open';
|
|
9
|
+
const args = process.platform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const child = spawn(command, args, { stdio: 'ignore', shell: false });
|
|
12
|
+
child.once('error', () => reject(new ChatGPTAuthError('Could not open the browser.')));
|
|
13
|
+
child.once('exit', code => code === 0 ? resolve() : reject(new ChatGPTAuthError('Could not open the browser.')));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export async function login(store = new ChatGPTStore(), clientId, signal, launch = openBrowser) {
|
|
17
|
+
// Persist host identity before opening a browser; failed attempts retain it.
|
|
18
|
+
await store.update(() => { });
|
|
19
|
+
const state = store.read();
|
|
20
|
+
const previous = clientId ? state.accounts[clientId] : undefined;
|
|
21
|
+
if (clientId && !previous)
|
|
22
|
+
throw new ChatGPTAuthError('Unknown ChatGPT registration. Use auth chatgpt status.');
|
|
23
|
+
const server = createServer();
|
|
24
|
+
await new Promise((resolve, reject) => { server.once('error', reject); server.listen(0, '127.0.0.1', resolve); });
|
|
25
|
+
const address = server.address();
|
|
26
|
+
if (!address || typeof address === 'string')
|
|
27
|
+
throw new ChatGPTAuthError('Could not start ChatGPT callback listener.');
|
|
28
|
+
const redirect = `http://127.0.0.1:${address.port}/auth/callback`;
|
|
29
|
+
const attempt = prepareAuthorization(state.hostId, redirect, previous);
|
|
30
|
+
let timer;
|
|
31
|
+
let abort;
|
|
32
|
+
try {
|
|
33
|
+
const callback = new Promise((resolve, reject) => {
|
|
34
|
+
timer = setTimeout(() => reject(new ChatGPTAuthError('ChatGPT sign-in timed out.')), 300000);
|
|
35
|
+
abort = () => reject(new ChatGPTAuthError('ChatGPT sign-in cancelled.'));
|
|
36
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
37
|
+
if (signal?.aborted) {
|
|
38
|
+
abort();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
server.on('request', (req, res) => {
|
|
42
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
43
|
+
res.setHeader('Content-Type', 'text/plain');
|
|
44
|
+
if (req.method !== 'GET' || req.headers.host !== `127.0.0.1:${address.port}` || !req.url?.startsWith('/auth/callback?')) {
|
|
45
|
+
res.writeHead(404).end('Not found');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const result = attempt.consume(new URL(req.url, redirect).href);
|
|
50
|
+
res.end('Authorization received. Return to your terminal to finish verification.');
|
|
51
|
+
resolve(result);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
res.writeHead(400).end('Sign-in rejected. Return to your terminal.');
|
|
55
|
+
reject(e);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
// Attach a rejection handler before browser launch so an immediate abort is handled.
|
|
60
|
+
const [result] = await Promise.all([callback, launch(attempt.url)]);
|
|
61
|
+
const tokens = await tokenRequest(result.form, signal);
|
|
62
|
+
if (!tokens.id_token)
|
|
63
|
+
throw new ChatGPTAuthError('ChatGPT did not return an identity token.');
|
|
64
|
+
const identity = await validateIdentity(tokens.id_token, result.clientId, attempt.nonce, previous ?? state.accounts[result.clientId]);
|
|
65
|
+
signal?.throwIfAborted();
|
|
66
|
+
await store.update(current => {
|
|
67
|
+
if (JSON.stringify(current.accounts[result.clientId]) !== JSON.stringify(state.accounts[result.clientId]))
|
|
68
|
+
throw new ChatGPTAuthError('ChatGPT registration changed during sign-in. Retry.');
|
|
69
|
+
current.accounts[result.clientId] = applyTokens({ clientId: result.clientId, ...identity, scopes: [] }, tokens);
|
|
70
|
+
current.active = result.clientId;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
attempt.cancel();
|
|
75
|
+
clearTimeout(timer);
|
|
76
|
+
if (abort)
|
|
77
|
+
signal?.removeEventListener('abort', abort);
|
|
78
|
+
server.closeAllConnections();
|
|
79
|
+
await new Promise(resolve => server.close(() => resolve()));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const ISSUER = "https://auth.openai.com";
|
|
2
|
+
export declare const RESOURCE = "https://api.openai.com/v1";
|
|
3
|
+
export declare const TOKEN_URL = "https://auth.openai.com/api/accounts/oauth/token";
|
|
4
|
+
export declare const SCOPES = "openid profile email offline_access resource.invoke chatgpt.tokens.use.direct";
|
|
5
|
+
export declare class ChatGPTAuthError extends Error {
|
|
6
|
+
readonly code?: 'reauthenticate' | undefined;
|
|
7
|
+
constructor(message: string, code?: 'reauthenticate' | undefined);
|
|
8
|
+
}
|
|
9
|
+
export interface Registration {
|
|
10
|
+
clientId: string;
|
|
11
|
+
subject: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
idToken?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function prepareAuthorization(hostId: string, redirectUri: string, registration?: Registration, now?: number): {
|
|
16
|
+
url: string;
|
|
17
|
+
nonce: string;
|
|
18
|
+
cancel(): void;
|
|
19
|
+
consume(callback: string, at?: number): {
|
|
20
|
+
clientId: string;
|
|
21
|
+
form: import("node:url").URLSearchParams;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/protocol.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,MAAM,4BAA4B,CAAC;AAChD,eAAO,MAAM,QAAQ,8BAA8B,CAAC;AACpD,eAAO,MAAM,SAAS,qDAAuC,CAAC;AAC9D,eAAO,MAAM,MAAM,kFAAkF,CAAC;AACtG,qBAAa,gBAAiB,SAAQ,KAAK;IAAgC,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB;IAA7D,YAAY,OAAO,EAAE,MAAM,EAAW,IAAI,CAAC,EAAE,gBAAgB,YAAA,EAAqD;CAAE;AAElK,MAAM,WAAW,YAAY;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE;AACrG,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,EAAE,GAAG,SAAa;;;;sBAejG,MAAM;;;;EAiB3B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
export const ISSUER = 'https://auth.openai.com';
|
|
3
|
+
export const RESOURCE = 'https://api.openai.com/v1';
|
|
4
|
+
export const TOKEN_URL = `${ISSUER}/api/accounts/oauth/token`;
|
|
5
|
+
export const SCOPES = 'openid profile email offline_access resource.invoke chatgpt.tokens.use.direct';
|
|
6
|
+
export class ChatGPTAuthError extends Error {
|
|
7
|
+
code;
|
|
8
|
+
constructor(message, code) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.name = 'ChatGPTAuthError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
const fail = () => new ChatGPTAuthError('ChatGPT callback rejected. Start a new sign-in.');
|
|
15
|
+
export function prepareAuthorization(hostId, redirectUri, registration, now = Date.now()) {
|
|
16
|
+
const uri = new URL(redirectUri);
|
|
17
|
+
if (uri.protocol !== 'http:' || uri.hostname !== '127.0.0.1' || uri.pathname !== '/auth/callback' || !uri.port || uri.search || uri.hash || uri.username || uri.password)
|
|
18
|
+
throw fail();
|
|
19
|
+
if (!/^urn:uuid:[0-9a-f-]{36}$/i.test(hostId))
|
|
20
|
+
throw new ChatGPTAuthError('Invalid ChatGPT host identity.');
|
|
21
|
+
if (registration && !/^oaiapp_[A-Za-z0-9_-]+$/.test(registration.clientId))
|
|
22
|
+
throw fail();
|
|
23
|
+
const state = randomBytes(32).toString('base64url'), nonce = randomBytes(32).toString('base64url'), verifier = randomBytes(32).toString('base64url');
|
|
24
|
+
const params = new URLSearchParams({ client_id: registration?.clientId ?? 'dynamic_agent_client', ext_agent_host_id: hostId,
|
|
25
|
+
response_type: 'code', redirect_uri: redirectUri, scope: SCOPES, resource: RESOURCE, state, nonce,
|
|
26
|
+
code_challenge_method: 'S256', code_challenge: createHash('sha256').update(verifier).digest('base64url') });
|
|
27
|
+
if (!registration)
|
|
28
|
+
params.set('agent_name_hint', 'Calliope AI CLI');
|
|
29
|
+
else {
|
|
30
|
+
if (registration.idToken)
|
|
31
|
+
params.set('id_token_hint', registration.idToken);
|
|
32
|
+
if (registration.email)
|
|
33
|
+
params.set('login_hint', registration.email);
|
|
34
|
+
}
|
|
35
|
+
let consumed = false;
|
|
36
|
+
return {
|
|
37
|
+
url: `${ISSUER}/api/accounts/authorize?${params}`, nonce,
|
|
38
|
+
cancel() { consumed = true; },
|
|
39
|
+
consume(callback, at = Date.now()) {
|
|
40
|
+
if (consumed)
|
|
41
|
+
throw fail();
|
|
42
|
+
consumed = true;
|
|
43
|
+
if (at < now || at - now > 300000)
|
|
44
|
+
throw fail();
|
|
45
|
+
let url;
|
|
46
|
+
try {
|
|
47
|
+
url = new URL(callback);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
throw fail();
|
|
51
|
+
}
|
|
52
|
+
if (url.origin !== uri.origin || url.pathname !== uri.pathname || url.hash || url.username || url.password)
|
|
53
|
+
throw fail();
|
|
54
|
+
for (const key of url.searchParams.keys())
|
|
55
|
+
if (url.searchParams.getAll(key).length !== 1)
|
|
56
|
+
throw fail();
|
|
57
|
+
const received = Buffer.from(url.searchParams.get('state') ?? '');
|
|
58
|
+
if (received.length !== state.length || !timingSafeEqual(received, Buffer.from(state)))
|
|
59
|
+
throw fail();
|
|
60
|
+
if (url.searchParams.has('error'))
|
|
61
|
+
throw new ChatGPTAuthError('ChatGPT sign-in was denied or failed.');
|
|
62
|
+
const clientId = url.searchParams.get('client_id') ?? registration?.clientId;
|
|
63
|
+
const code = url.searchParams.get('code');
|
|
64
|
+
if (!code || !clientId || !/^oaiapp_[A-Za-z0-9_-]+$/.test(clientId) || registration && clientId !== registration.clientId)
|
|
65
|
+
throw fail();
|
|
66
|
+
return { clientId, form: new URLSearchParams({ grant_type: 'authorization_code', client_id: clientId, code,
|
|
67
|
+
code_verifier: verifier, redirect_uri: redirectUri, resource: RESOURCE }) };
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type JWTVerifyGetKey } from 'jose';
|
|
2
|
+
import { ChatGPTStore, type Account } from './store.js';
|
|
3
|
+
import { type Registration } from './protocol.js';
|
|
4
|
+
export interface Tokens {
|
|
5
|
+
access_token: string;
|
|
6
|
+
refresh_token: string;
|
|
7
|
+
id_token?: string;
|
|
8
|
+
token_type: string;
|
|
9
|
+
expires_in: number;
|
|
10
|
+
scope: string;
|
|
11
|
+
earliest_refresh_at?: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function tokenRequest(form: URLSearchParams, signal?: AbortSignal): Promise<Tokens>;
|
|
14
|
+
export declare function validateIdentity(token: string, clientId: string, nonce?: string, previous?: Registration, key?: JWTVerifyGetKey): Promise<{
|
|
15
|
+
subject: string;
|
|
16
|
+
email?: string | undefined;
|
|
17
|
+
}>;
|
|
18
|
+
export declare function applyTokens(account: Account, tokens: Tokens): Account;
|
|
19
|
+
export declare function accessToken(store?: ChatGPTStore, signal?: AbortSignal): Promise<{
|
|
20
|
+
token: string;
|
|
21
|
+
clientId: string;
|
|
22
|
+
}>;
|
|
23
|
+
export declare function logout(store?: ChatGPTStore): Promise<boolean>;
|
|
24
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,eAAe,EAAE,MAAM,MAAM,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAiD,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAEjG,MAAM,WAAW,MAAM;IAAG,YAAY,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE;AAC/K,wBAAsB,YAAY,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAW/F;AACD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,GAAG,GAAE,eAAsB;;;GAM3I;AACD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAIrE;AACD,wBAAsB,WAAW,CAAC,KAAK,eAAqB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAuBhI;AACD,wBAAsB,MAAM,CAAC,KAAK,eAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBzE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
2
|
+
import { ChatGPTStore } from './store.js';
|
|
3
|
+
import { ChatGPTAuthError, ISSUER, TOKEN_URL, RESOURCE } from './protocol.js';
|
|
4
|
+
const jwks = createRemoteJWKSet(new URL(`${ISSUER}/.well-known/jwks.json`));
|
|
5
|
+
export async function tokenRequest(form, signal) {
|
|
6
|
+
let response;
|
|
7
|
+
try {
|
|
8
|
+
response = await fetch(TOKEN_URL, { method: 'POST', redirect: 'error', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: form, signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(30000)]) : AbortSignal.timeout(30000) });
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
throw new ChatGPTAuthError('ChatGPT token request failed. Retry sign-in or check your connection.');
|
|
12
|
+
}
|
|
13
|
+
let body;
|
|
14
|
+
try {
|
|
15
|
+
body = await response.json();
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
throw new ChatGPTAuthError('Invalid ChatGPT token response.');
|
|
19
|
+
}
|
|
20
|
+
if (!response.ok) {
|
|
21
|
+
const terminal = ['invalid_grant', 'invalid_refresh_token', 'token_expired', 'refresh_token_expired', 'refresh_token_invalidated', 'refresh_token_reused'].includes(String(body.error));
|
|
22
|
+
throw new ChatGPTAuthError(terminal ? 'ChatGPT session expired or revoked. Sign in again.' : `ChatGPT token request failed (HTTP ${response.status}).`, terminal ? 'reauthenticate' : undefined);
|
|
23
|
+
}
|
|
24
|
+
if (typeof body.access_token !== 'string' || !body.access_token || typeof body.refresh_token !== 'string' || !body.refresh_token || body.token_type !== 'Bearer' || typeof body.expires_in !== 'number' || !Number.isFinite(body.expires_in) || body.expires_in <= 0 || typeof body.scope !== 'string')
|
|
25
|
+
throw new ChatGPTAuthError('Invalid ChatGPT token response.');
|
|
26
|
+
return body;
|
|
27
|
+
}
|
|
28
|
+
export async function validateIdentity(token, clientId, nonce, previous, key = jwks) {
|
|
29
|
+
try {
|
|
30
|
+
const { payload } = await jwtVerify(token, key, { issuer: ISSUER, audience: clientId, algorithms: ['RS256'], requiredClaims: ['exp', 'iat', 'sub'] });
|
|
31
|
+
if (!payload.sub || nonce !== undefined && payload.nonce !== nonce || previous && payload.sub !== previous.subject)
|
|
32
|
+
throw Error();
|
|
33
|
+
return { subject: payload.sub, ...(typeof payload.email === 'string' ? { email: payload.email } : {}) };
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
throw new ChatGPTAuthError('ChatGPT identity verification failed. Sign in again.');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function applyTokens(account, tokens) {
|
|
40
|
+
return { ...account, accessToken: tokens.access_token, refreshToken: tokens.refresh_token,
|
|
41
|
+
...(tokens.id_token ? { idToken: tokens.id_token } : {}), scopes: tokens.scope.split(/\s+/).filter(Boolean),
|
|
42
|
+
expiresAt: Date.now() + tokens.expires_in * 1000, earliestRefreshAt: tokens.earliest_refresh_at ? tokens.earliest_refresh_at * 1000 : undefined };
|
|
43
|
+
}
|
|
44
|
+
export async function accessToken(store = new ChatGPTStore(), signal) {
|
|
45
|
+
const selected = store.active();
|
|
46
|
+
if (!selected?.accessToken || !selected.refreshToken || !selected.scopes.includes('chatgpt.tokens.use.direct'))
|
|
47
|
+
throw new ChatGPTAuthError('ChatGPT plan access is unavailable. Run calliope auth chatgpt login.');
|
|
48
|
+
if ((selected.expiresAt ?? 0) > Date.now() + 60000)
|
|
49
|
+
return { token: selected.accessToken, clientId: selected.clientId };
|
|
50
|
+
const result = await store.update(async (state) => {
|
|
51
|
+
if (state.active !== selected.clientId)
|
|
52
|
+
throw new ChatGPTAuthError('ChatGPT account changed. Retry the request.');
|
|
53
|
+
const a = state.accounts[selected.clientId];
|
|
54
|
+
if ((a.expiresAt ?? 0) > Date.now() + 60000)
|
|
55
|
+
return { token: a.accessToken, clientId: a.clientId };
|
|
56
|
+
if (a.earliestRefreshAt && a.earliestRefreshAt > Date.now())
|
|
57
|
+
throw new ChatGPTAuthError('ChatGPT token cannot refresh yet. Retry later.');
|
|
58
|
+
let tokens;
|
|
59
|
+
try {
|
|
60
|
+
tokens = await tokenRequest(new URLSearchParams({ grant_type: 'refresh_token', client_id: a.clientId, refresh_token: a.refreshToken, resource: RESOURCE }), signal);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (!(error instanceof ChatGPTAuthError) || error.code !== 'reauthenticate')
|
|
64
|
+
throw error;
|
|
65
|
+
state.accounts[a.clientId] = { clientId: a.clientId, subject: a.subject, email: a.email, scopes: [] };
|
|
66
|
+
return { error };
|
|
67
|
+
}
|
|
68
|
+
if (tokens.id_token)
|
|
69
|
+
await validateIdentity(tokens.id_token, a.clientId, undefined, a);
|
|
70
|
+
state.accounts[a.clientId] = applyTokens(a, tokens);
|
|
71
|
+
if (!state.accounts[a.clientId].scopes.includes('chatgpt.tokens.use.direct'))
|
|
72
|
+
return { error: new ChatGPTAuthError('ChatGPT plan permission was removed. Sign in again.') };
|
|
73
|
+
return { token: tokens.access_token, clientId: a.clientId };
|
|
74
|
+
});
|
|
75
|
+
if ('error' in result)
|
|
76
|
+
throw result.error;
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
export async function logout(store = new ChatGPTStore()) {
|
|
80
|
+
return store.update(async (state) => {
|
|
81
|
+
const a = state.active ? state.accounts[state.active] : undefined;
|
|
82
|
+
if (!a)
|
|
83
|
+
return true;
|
|
84
|
+
let revoked = !a.refreshToken;
|
|
85
|
+
if (a.refreshToken) {
|
|
86
|
+
try {
|
|
87
|
+
const discovery = await fetch(`${ISSUER}/.well-known/openid-configuration`, { redirect: 'error', signal: AbortSignal.timeout(10000) });
|
|
88
|
+
const metadata = await discovery.json();
|
|
89
|
+
const endpoint = new URL(metadata.revocation_endpoint);
|
|
90
|
+
if (!discovery.ok || metadata.issuer !== ISSUER || endpoint.origin !== ISSUER || endpoint.username || endpoint.password)
|
|
91
|
+
throw Error();
|
|
92
|
+
const response = await fetch(endpoint, { method: 'POST', redirect: 'error', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: new URLSearchParams({ token: a.refreshToken, token_type_hint: 'refresh_token', client_id: a.clientId }), signal: AbortSignal.timeout(10000) });
|
|
93
|
+
revoked = response.ok;
|
|
94
|
+
}
|
|
95
|
+
catch { /* Local sign-out still removes every token. */ }
|
|
96
|
+
}
|
|
97
|
+
state.accounts[a.clientId] = { clientId: a.clientId, subject: a.subject, email: a.email, scopes: [] };
|
|
98
|
+
return revoked;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/auth/chatgpt/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type Registration } from './protocol.js';
|
|
2
|
+
export interface Account extends Registration {
|
|
3
|
+
quotaCircuit?: {
|
|
4
|
+
reason: 'quota' | 'rate-limit';
|
|
5
|
+
until: number;
|
|
6
|
+
};
|
|
7
|
+
accessToken?: string;
|
|
8
|
+
refreshToken?: string;
|
|
9
|
+
expiresAt?: number;
|
|
10
|
+
earliestRefreshAt?: number;
|
|
11
|
+
scopes: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface AuthState {
|
|
14
|
+
version: 1;
|
|
15
|
+
hostId: string;
|
|
16
|
+
active?: string;
|
|
17
|
+
accounts: Record<string, Account>;
|
|
18
|
+
}
|
|
19
|
+
export declare class ChatGPTStore {
|
|
20
|
+
readonly directory: string;
|
|
21
|
+
constructor(directory?: string);
|
|
22
|
+
private file;
|
|
23
|
+
private check;
|
|
24
|
+
read(): AuthState | undefined;
|
|
25
|
+
update<T>(action: (state: AuthState) => T | Promise<T>): Promise<T>;
|
|
26
|
+
active(): Account | undefined;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/auth/chatgpt/store.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AACpE,MAAM,WAAW,OAAQ,SAAQ,YAAY;IAAG,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE;AACjO,MAAM,WAAW,SAAS;IAAG,OAAO,EAAE,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AAC7G,qBAAa,YAAY;IACX,QAAQ,CAAC,SAAS;IAA9B,YAAqB,SAAS,SAA2D,EAAI;IAC7F,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,KAAK;IAKb,IAAI,IAAI,SAAS,GAAG,SAAS,CAkB5B;IACK,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAcxE;IACD,MAAM,IAAI,OAAO,GAAG,SAAS,CAAgG;CAC9H"}
|