@sentropic/llm-mesh 0.12.0 → 0.13.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/dist/auth.d.ts +8 -2
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +14 -0
- package/dist/auth.js.map +1 -1
- package/dist/enrollment/claude-code.d.ts +9 -0
- package/dist/enrollment/claude-code.d.ts.map +1 -0
- package/dist/enrollment/claude-code.js +18 -0
- package/dist/enrollment/claude-code.js.map +1 -0
- package/dist/enrollment/cloud-code.d.ts +32 -0
- package/dist/enrollment/cloud-code.d.ts.map +1 -0
- package/dist/enrollment/cloud-code.js +232 -0
- package/dist/enrollment/cloud-code.js.map +1 -0
- package/dist/enrollment/codex.d.ts +33 -0
- package/dist/enrollment/codex.d.ts.map +1 -0
- package/dist/enrollment/codex.js +222 -0
- package/dist/enrollment/codex.js.map +1 -0
- package/dist/enrollment/contracts.d.ts +77 -0
- package/dist/enrollment/contracts.d.ts.map +1 -0
- package/dist/enrollment/contracts.js +3 -0
- package/dist/enrollment/contracts.js.map +1 -0
- package/dist/enrollment/index.d.ts +2 -0
- package/dist/enrollment/index.d.ts.map +1 -0
- package/dist/enrollment/index.js +3 -0
- package/dist/enrollment/index.js.map +1 -0
- package/dist/enrollment/pkce.d.ts +18 -0
- package/dist/enrollment/pkce.d.ts.map +1 -0
- package/dist/enrollment/pkce.js +104 -0
- package/dist/enrollment/pkce.js.map +1 -0
- package/dist/node/index.d.ts +6 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +5 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/keyring/env-keyring.d.ts +11 -0
- package/dist/node/keyring/env-keyring.d.ts.map +1 -0
- package/dist/node/keyring/env-keyring.js +26 -0
- package/dist/node/keyring/env-keyring.js.map +1 -0
- package/dist/node/keyring/in-memory-keyring.d.ts +8 -0
- package/dist/node/keyring/in-memory-keyring.d.ts.map +1 -0
- package/dist/node/keyring/in-memory-keyring.js +13 -0
- package/dist/node/keyring/in-memory-keyring.js.map +1 -0
- package/dist/node/keyring/linux-secretstore-keyring.d.ts +10 -0
- package/dist/node/keyring/linux-secretstore-keyring.d.ts.map +1 -0
- package/dist/node/keyring/linux-secretstore-keyring.js +17 -0
- package/dist/node/keyring/linux-secretstore-keyring.js.map +1 -0
- package/dist/node/keyring/macos-keychain-keyring.d.ts +10 -0
- package/dist/node/keyring/macos-keychain-keyring.d.ts.map +1 -0
- package/dist/node/keyring/macos-keychain-keyring.js +17 -0
- package/dist/node/keyring/macos-keychain-keyring.js.map +1 -0
- package/dist/service/facade.d.ts +52 -0
- package/dist/service/facade.d.ts.map +1 -0
- package/dist/service/facade.js +51 -0
- package/dist/service/facade.js.map +1 -0
- package/dist/service/local-account-transport-service.d.ts +31 -0
- package/dist/service/local-account-transport-service.d.ts.map +1 -0
- package/dist/service/local-account-transport-service.js +181 -0
- package/dist/service/local-account-transport-service.js.map +1 -0
- package/dist/transport/cloud-code-transport.d.ts +26 -0
- package/dist/transport/cloud-code-transport.d.ts.map +1 -0
- package/dist/transport/cloud-code-transport.js +213 -0
- package/dist/transport/cloud-code-transport.js.map +1 -0
- package/package.json +18 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export class MacOSKeychainKeyring {
|
|
2
|
+
memoryStore = new Map();
|
|
3
|
+
serviceName;
|
|
4
|
+
constructor(serviceName = 'sentropic-llm-mesh') {
|
|
5
|
+
this.serviceName = serviceName;
|
|
6
|
+
}
|
|
7
|
+
async getSecret(key) {
|
|
8
|
+
return this.memoryStore.get(`${this.serviceName}:${key}`) ?? null;
|
|
9
|
+
}
|
|
10
|
+
async setSecret(key, secret) {
|
|
11
|
+
this.memoryStore.set(`${this.serviceName}:${key}`, secret);
|
|
12
|
+
}
|
|
13
|
+
async deleteSecret(key) {
|
|
14
|
+
this.memoryStore.delete(`${this.serviceName}:${key}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=macos-keychain-keyring.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"macos-keychain-keyring.js","sourceRoot":"","sources":["../../../src/node/keyring/macos-keychain-keyring.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,oBAAoB;IACd,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,WAAW,CAAS;IAErC,YAAY,WAAW,GAAG,oBAAoB;QAC5C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW;QACzB,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,CAAC,IAAI,IAAI,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAW,EAAE,MAAc;QACzC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,GAAW;QAC5B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;CACF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { AccountTransportAcquireInput, AccountTransportAcquisition } from '../account-transports.js';
|
|
2
|
+
import type { AccountTransportProviderId } from '../auth.js';
|
|
3
|
+
import type { EnrollmentSession, StartEnrollmentInput } from '../enrollment/contracts.js';
|
|
4
|
+
export interface ProviderRequest {
|
|
5
|
+
modelId: string;
|
|
6
|
+
contents: unknown[];
|
|
7
|
+
generationConfig?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export type ProviderEvent = {
|
|
10
|
+
kind: 'content';
|
|
11
|
+
delta: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'done';
|
|
14
|
+
usage: unknown;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'error';
|
|
17
|
+
code: string;
|
|
18
|
+
message: string;
|
|
19
|
+
};
|
|
20
|
+
export interface ProviderAdapter {
|
|
21
|
+
execute(acquisition: AccountTransportAcquisition, request: ProviderRequest, signal: AbortSignal): AsyncIterable<ProviderEvent>;
|
|
22
|
+
}
|
|
23
|
+
export interface KeyringAdapter {
|
|
24
|
+
getSecret(key: string): Promise<string | null>;
|
|
25
|
+
setSecret(key: string, secret: string): Promise<void>;
|
|
26
|
+
deleteSecret(key: string): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export interface ConfigResolver {
|
|
29
|
+
resolveConfig(configRef: string): Promise<Record<string, unknown>>;
|
|
30
|
+
}
|
|
31
|
+
export interface FacadeOptions {
|
|
32
|
+
configResolver: ConfigResolver;
|
|
33
|
+
keyring?: KeyringAdapter;
|
|
34
|
+
mode: 'cli' | 'portal';
|
|
35
|
+
}
|
|
36
|
+
export interface LlmMeshFacade {
|
|
37
|
+
enroll(providerId: AccountTransportProviderId, input: StartEnrollmentInput): Promise<EnrollmentSession>;
|
|
38
|
+
waitForCallback(enrollmentId: string): Promise<{
|
|
39
|
+
accountId: string;
|
|
40
|
+
label: string;
|
|
41
|
+
}>;
|
|
42
|
+
pollForCompletion(enrollmentId: string): Promise<{
|
|
43
|
+
accountId: string;
|
|
44
|
+
label: string;
|
|
45
|
+
}>;
|
|
46
|
+
cancel(enrollmentId: string): Promise<void>;
|
|
47
|
+
acquire(input: AccountTransportAcquireInput): Promise<AccountTransportAcquisition>;
|
|
48
|
+
release(acquisition: AccountTransportAcquisition): Promise<void>;
|
|
49
|
+
getAdapter(providerId: AccountTransportProviderId): ProviderAdapter;
|
|
50
|
+
}
|
|
51
|
+
export declare function createLlmMeshFacade(options: FacadeOptions): LlmMeshFacade;
|
|
52
|
+
//# sourceMappingURL=facade.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../../src/service/facade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,4BAA4B,EAC5B,2BAA2B,EAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,KAAK,EAEV,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAQpC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,OAAO,CACL,WAAW,EAAE,2BAA2B,EACxC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,aAAa,CAAC,aAAa,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAE5B,MAAM,CACJ,UAAU,EAAE,0BAA0B,EACtC,KAAK,EAAE,oBAAoB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9B,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrF,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvF,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG5C,OAAO,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IACnF,OAAO,CAAC,WAAW,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGjE,UAAU,CAAC,UAAU,EAAE,0BAA0B,GAAG,eAAe,CAAC;CACrE;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CA+CzE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { ClaudeCodeEnrollmentProvider } from '../enrollment/claude-code.js';
|
|
2
|
+
import { CloudCodeEnrollmentProvider } from '../enrollment/cloud-code.js';
|
|
3
|
+
import { CodexEnrollmentProvider } from '../enrollment/codex.js';
|
|
4
|
+
import { InMemoryKeyring } from '../node/keyring/in-memory-keyring.js';
|
|
5
|
+
import { CloudCodeProviderAdapter } from '../transport/cloud-code-transport.js';
|
|
6
|
+
import { LocalAccountTransportService } from './local-account-transport-service.js';
|
|
7
|
+
export function createLlmMeshFacade(options) {
|
|
8
|
+
if (!options) {
|
|
9
|
+
throw new Error('LlmMeshFacade: options is required');
|
|
10
|
+
}
|
|
11
|
+
if (!options.configResolver) {
|
|
12
|
+
throw new Error('configResolver is required');
|
|
13
|
+
}
|
|
14
|
+
const keyring = options.keyring ?? new InMemoryKeyring();
|
|
15
|
+
const providers = new Map([
|
|
16
|
+
[
|
|
17
|
+
'cloud-code',
|
|
18
|
+
new CloudCodeEnrollmentProvider({ configResolver: options.configResolver }),
|
|
19
|
+
],
|
|
20
|
+
['codex', new CodexEnrollmentProvider({ configResolver: options.configResolver })],
|
|
21
|
+
['claude-code', new ClaudeCodeEnrollmentProvider()],
|
|
22
|
+
]);
|
|
23
|
+
const service = new LocalAccountTransportService(keyring, providers, options.configResolver);
|
|
24
|
+
return {
|
|
25
|
+
async enroll(providerId, input) {
|
|
26
|
+
return service.enroll(providerId, input);
|
|
27
|
+
},
|
|
28
|
+
async waitForCallback(enrollmentId) {
|
|
29
|
+
return service.waitForCallback(enrollmentId);
|
|
30
|
+
},
|
|
31
|
+
async pollForCompletion(enrollmentId) {
|
|
32
|
+
return service.pollForCompletion(enrollmentId);
|
|
33
|
+
},
|
|
34
|
+
async cancel(enrollmentId) {
|
|
35
|
+
return service.cancel(enrollmentId);
|
|
36
|
+
},
|
|
37
|
+
async acquire(input) {
|
|
38
|
+
return service.acquire(input);
|
|
39
|
+
},
|
|
40
|
+
async release(acquisition) {
|
|
41
|
+
return service.release(acquisition);
|
|
42
|
+
},
|
|
43
|
+
getAdapter(providerId) {
|
|
44
|
+
if (providerId === 'cloud-code') {
|
|
45
|
+
return new CloudCodeProviderAdapter();
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`Adapter for ${providerId} not available locally`);
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=facade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facade.js","sourceRoot":"","sources":["../../src/service/facade.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,4BAA4B,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AAuDpF,MAAM,UAAU,mBAAmB,CAAC,OAAsB;IACxD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,eAAe,EAAE,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,GAAG,CAA6B;QACpD;YACE,YAAY;YACZ,IAAI,2BAA2B,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;SAC5E;QACD,CAAC,OAAO,EAAE,IAAI,uBAAuB,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;QAClF,CAAC,aAAa,EAAE,IAAI,4BAA4B,EAAE,CAAC;KACpD,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,4BAA4B,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAE7F,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK;YAC5B,OAAO,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,CAAC,eAAe,CAAC,YAAY;YAChC,OAAO,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,CAAC,iBAAiB,CAAC,YAAY;YAClC,OAAO,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QACjD,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,YAAY;YACvB,OAAO,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACtC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,WAAW;YACvB,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;QACD,UAAU,CAAC,UAAU;YACnB,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;gBAChC,OAAO,IAAI,wBAAwB,EAAE,CAAC;YACxC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,eAAe,UAAU,wBAAwB,CAAC,CAAC;QACrE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type AccountTransportAccount, type AccountTransportAcquireInput, type AccountTransportAcquisition } from '../account-transports.js';
|
|
2
|
+
import type { EnrollmentProvider, EnrollmentSession, StartEnrollmentInput } from '../enrollment/contracts.js';
|
|
3
|
+
import type { ConfigResolver, KeyringAdapter } from './facade.js';
|
|
4
|
+
export declare class LocalAccountTransportService {
|
|
5
|
+
private readonly keyring;
|
|
6
|
+
private readonly providers;
|
|
7
|
+
private readonly configResolver;
|
|
8
|
+
private readonly coordinator;
|
|
9
|
+
private readonly accountsMap;
|
|
10
|
+
private readonly credentialVersions;
|
|
11
|
+
private readonly refreshInFlight;
|
|
12
|
+
constructor(keyring: KeyringAdapter, providers: Map<string, EnrollmentProvider>, configResolver: ConfigResolver);
|
|
13
|
+
enroll(providerId: string, input: StartEnrollmentInput): Promise<EnrollmentSession>;
|
|
14
|
+
waitForCallback(enrollmentId: string): Promise<{
|
|
15
|
+
accountId: string;
|
|
16
|
+
label: string;
|
|
17
|
+
}>;
|
|
18
|
+
pollForCompletion(enrollmentId: string): Promise<{
|
|
19
|
+
accountId: string;
|
|
20
|
+
label: string;
|
|
21
|
+
}>;
|
|
22
|
+
cancel(enrollmentId: string): Promise<void>;
|
|
23
|
+
registerAccount(account: AccountTransportAccount, configVersion?: string): void;
|
|
24
|
+
acquire(input: AccountTransportAcquireInput): Promise<AccountTransportAcquisition>;
|
|
25
|
+
release(_acquisition: AccountTransportAcquisition): Promise<void>;
|
|
26
|
+
private completeEnrollment;
|
|
27
|
+
private refreshToken;
|
|
28
|
+
private persistCredential;
|
|
29
|
+
private markReauthRequired;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=local-account-transport-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-account-transport-service.d.ts","sourceRoot":"","sources":["../../src/service/local-account-transport-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,4BAA4B,EACjC,KAAK,2BAA2B,EACjC,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAIV,kBAAkB,EAClB,iBAAiB,EAGjB,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElE,qBAAa,4BAA4B;IAOrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IARjC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8C;IAC1E,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA6B;IAChE,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkD;gBAG/D,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,EAC1C,cAAc,EAAE,cAAc;IAM3C,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAQnF,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IASpF,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAsCtF,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASjD,eAAe,CAAC,OAAO,EAAE,uBAAuB,EAAE,aAAa,SAAW,GAAG,IAAI;IAO3E,OAAO,CAAC,KAAK,EAAE,4BAA4B,GAAG,OAAO,CAAC,2BAA2B,CAAC;IA0ElF,OAAO,CAAC,YAAY,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;YAMzD,kBAAkB;YAIlB,YAAY;YA0BZ,iBAAiB;YAQjB,kBAAkB;CAMjC"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { AccountTransportAcquireError, InMemoryAccountTransportCoordinator, } from '../account-transports.js';
|
|
2
|
+
export class LocalAccountTransportService {
|
|
3
|
+
keyring;
|
|
4
|
+
providers;
|
|
5
|
+
configResolver;
|
|
6
|
+
coordinator;
|
|
7
|
+
accountsMap = new Map();
|
|
8
|
+
credentialVersions = new Map();
|
|
9
|
+
refreshInFlight = new Map();
|
|
10
|
+
constructor(keyring, providers, configResolver) {
|
|
11
|
+
this.keyring = keyring;
|
|
12
|
+
this.providers = providers;
|
|
13
|
+
this.configResolver = configResolver;
|
|
14
|
+
this.coordinator = new InMemoryAccountTransportCoordinator();
|
|
15
|
+
}
|
|
16
|
+
// ── Enrollment (called via facade by h2a CLI) ──────────────────────────
|
|
17
|
+
async enroll(providerId, input) {
|
|
18
|
+
const provider = this.providers.get(providerId);
|
|
19
|
+
if (!provider) {
|
|
20
|
+
throw new Error(`Enrollment provider '${providerId}' not registered`);
|
|
21
|
+
}
|
|
22
|
+
return provider.start(input);
|
|
23
|
+
}
|
|
24
|
+
async waitForCallback(enrollmentId) {
|
|
25
|
+
const provider = this.providers.get('cloud-code');
|
|
26
|
+
if (!provider || !('waitForCallback' in provider) || typeof provider.waitForCallback !== 'function') {
|
|
27
|
+
throw new Error("No enrollment provider with 'waitForCallback' registered");
|
|
28
|
+
}
|
|
29
|
+
const res = await provider.waitForCallback(enrollmentId);
|
|
30
|
+
return { accountId: res.accountId, label: res.label };
|
|
31
|
+
}
|
|
32
|
+
async pollForCompletion(enrollmentId) {
|
|
33
|
+
const provider = this.providers.get('codex');
|
|
34
|
+
if (!provider || !('pollForCompletion' in provider) || typeof provider.pollForCompletion !== 'function') {
|
|
35
|
+
throw new Error("No enrollment provider with 'pollForCompletion' registered");
|
|
36
|
+
}
|
|
37
|
+
const res = await provider.pollForCompletion(enrollmentId);
|
|
38
|
+
if (res.credential) {
|
|
39
|
+
// P0-4: Persist credentials obtained via device flow poll into keyring/accounts
|
|
40
|
+
this.registerAccount({
|
|
41
|
+
accountId: res.accountId,
|
|
42
|
+
targetProviderId: 'codex',
|
|
43
|
+
transportProviderId: 'codex',
|
|
44
|
+
accessToken: res.credential.accessToken,
|
|
45
|
+
refreshToken: res.credential.refreshToken,
|
|
46
|
+
expiresAt: res.credential.expiresAt,
|
|
47
|
+
status: 'active',
|
|
48
|
+
});
|
|
49
|
+
await this.persistCredential({
|
|
50
|
+
accountId: res.accountId,
|
|
51
|
+
accountLabel: res.label,
|
|
52
|
+
providerId: 'codex',
|
|
53
|
+
status: 'active',
|
|
54
|
+
createdAt: new Date().toISOString(),
|
|
55
|
+
updatedAt: new Date().toISOString(),
|
|
56
|
+
}, {
|
|
57
|
+
accountId: res.accountId,
|
|
58
|
+
accessToken: res.credential.accessToken,
|
|
59
|
+
refreshToken: res.credential.refreshToken,
|
|
60
|
+
expiresAt: res.credential.expiresAt,
|
|
61
|
+
authClientConfigVersion: res.credential.authClientConfigVersion,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
return { accountId: res.accountId, label: res.label };
|
|
65
|
+
}
|
|
66
|
+
async cancel(enrollmentId) {
|
|
67
|
+
for (const provider of this.providers.values()) {
|
|
68
|
+
if (provider.cancel) {
|
|
69
|
+
await provider.cancel(enrollmentId);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ── Account Registration for Coordinator ──────────────────────────────
|
|
74
|
+
registerAccount(account, configVersion = 'v1.0.0') {
|
|
75
|
+
this.accountsMap.set(account.accountId, account);
|
|
76
|
+
this.credentialVersions.set(account.accountId, configVersion);
|
|
77
|
+
this.coordinator.addAccount(account);
|
|
78
|
+
}
|
|
79
|
+
// ── Runtime (called via facade by h2a gateway) ─────────────────────────
|
|
80
|
+
async acquire(input) {
|
|
81
|
+
// Attempt coordinator acquisition
|
|
82
|
+
let acquisition;
|
|
83
|
+
try {
|
|
84
|
+
acquisition = await this.coordinator.acquire(input);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (err instanceof AccountTransportAcquireError) {
|
|
88
|
+
throw err;
|
|
89
|
+
}
|
|
90
|
+
throw new AccountTransportAcquireError(`Acquire failed for ${input.transportProviderId}`, 'no_active_account');
|
|
91
|
+
}
|
|
92
|
+
const account = this.accountsMap.get(acquisition.material.accountId ?? '');
|
|
93
|
+
const nowMs = typeof input.now === 'number' ? input.now : Date.now();
|
|
94
|
+
// Check if access token is expired
|
|
95
|
+
if (account && account.expiresAt) {
|
|
96
|
+
const expiresAtMs = new Date(account.expiresAt).getTime();
|
|
97
|
+
if (expiresAtMs <= nowMs) {
|
|
98
|
+
try {
|
|
99
|
+
const version = this.credentialVersions.get(account.accountId) ?? 'v1.0.0';
|
|
100
|
+
const refreshed = await this.refreshToken({
|
|
101
|
+
accountId: account.accountId,
|
|
102
|
+
refreshToken: account.refreshToken ?? undefined,
|
|
103
|
+
credentialVersion: version,
|
|
104
|
+
});
|
|
105
|
+
// Atomic persistence of updated credentials
|
|
106
|
+
account.accessToken = refreshed.accessToken;
|
|
107
|
+
if (refreshed.refreshToken) {
|
|
108
|
+
account.refreshToken = refreshed.refreshToken;
|
|
109
|
+
}
|
|
110
|
+
account.expiresAt = refreshed.expiresAt;
|
|
111
|
+
await this.persistCredential({
|
|
112
|
+
accountId: account.accountId,
|
|
113
|
+
accountLabel: account.accountLabel ?? undefined,
|
|
114
|
+
providerId: account.transportProviderId,
|
|
115
|
+
status: 'active',
|
|
116
|
+
createdAt: new Date().toISOString(),
|
|
117
|
+
updatedAt: new Date().toISOString(),
|
|
118
|
+
}, {
|
|
119
|
+
accountId: account.accountId,
|
|
120
|
+
accessToken: refreshed.accessToken,
|
|
121
|
+
refreshToken: refreshed.refreshToken,
|
|
122
|
+
expiresAt: refreshed.expiresAt,
|
|
123
|
+
authClientConfigVersion: refreshed.authClientConfigVersion,
|
|
124
|
+
});
|
|
125
|
+
// Update material with refreshed token
|
|
126
|
+
acquisition.material.accessToken = refreshed.accessToken;
|
|
127
|
+
if (refreshed.refreshToken) {
|
|
128
|
+
acquisition.material.refreshToken = refreshed.refreshToken;
|
|
129
|
+
}
|
|
130
|
+
acquisition.material.expiresAt = refreshed.expiresAt;
|
|
131
|
+
}
|
|
132
|
+
catch (refreshErr) {
|
|
133
|
+
await this.markReauthRequired(account.accountId);
|
|
134
|
+
throw new AccountTransportAcquireError(`Account ${account.accountId} token refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}`, 'no_active_account');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return acquisition;
|
|
139
|
+
}
|
|
140
|
+
async release(_acquisition) {
|
|
141
|
+
// Q2B abort -> release reservation without recording an outcome / zero account impact
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
// ── Internal — never exposed to h2a ───────────────────────────────────────
|
|
145
|
+
async completeEnrollment(_input) {
|
|
146
|
+
// Handled internally by EnrollmentProvider.complete()
|
|
147
|
+
}
|
|
148
|
+
async refreshToken(input) {
|
|
149
|
+
// P0-5: Single-flight refresh map to prevent parallel refresh races
|
|
150
|
+
if (this.refreshInFlight.has(input.accountId)) {
|
|
151
|
+
return this.refreshInFlight.get(input.accountId);
|
|
152
|
+
}
|
|
153
|
+
const refreshPromise = (async () => {
|
|
154
|
+
try {
|
|
155
|
+
const account = this.accountsMap.get(input.accountId);
|
|
156
|
+
const providerId = account?.transportProviderId ?? 'cloud-code';
|
|
157
|
+
const provider = this.providers.get(providerId);
|
|
158
|
+
if (!provider) {
|
|
159
|
+
throw new Error(`No provider registered for refresh: ${providerId}`);
|
|
160
|
+
}
|
|
161
|
+
return await provider.refresh(input);
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
this.refreshInFlight.delete(input.accountId);
|
|
165
|
+
}
|
|
166
|
+
})();
|
|
167
|
+
this.refreshInFlight.set(input.accountId, refreshPromise);
|
|
168
|
+
return refreshPromise;
|
|
169
|
+
}
|
|
170
|
+
async persistCredential(pub, env) {
|
|
171
|
+
await this.keyring.setSecret(`sentropic-llm-mesh:${pub.accountId}:public`, JSON.stringify(pub));
|
|
172
|
+
await this.keyring.setSecret(`sentropic-llm-mesh:${pub.accountId}:envelope`, JSON.stringify(env));
|
|
173
|
+
}
|
|
174
|
+
async markReauthRequired(accountId) {
|
|
175
|
+
const account = this.accountsMap.get(accountId);
|
|
176
|
+
if (account) {
|
|
177
|
+
account.status = 'reauth_required';
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=local-account-transport-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-account-transport-service.js","sourceRoot":"","sources":["../../src/service/local-account-transport-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AccountTransportAcquisition } from '../account-transports.js';
|
|
2
|
+
import type { ProviderAdapter, ProviderEvent, ProviderRequest } from '../service/facade.js';
|
|
3
|
+
export declare const CLOUD_CODE_STREAM_URL = "https://daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse";
|
|
4
|
+
export declare const CLOUD_CODE_USER_AGENT = "antigravity/cli/1.1.10 (aidev_client; os_type=linux; arch=amd64; auth_method=consumer)";
|
|
5
|
+
export interface CloudCodeEnvelope {
|
|
6
|
+
project: string;
|
|
7
|
+
requestId: string;
|
|
8
|
+
model: string;
|
|
9
|
+
userAgent: string;
|
|
10
|
+
request: {
|
|
11
|
+
contents: unknown[];
|
|
12
|
+
generationConfig?: unknown;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export declare function buildCloudCodeRequest(acquisition: AccountTransportAcquisition, request: ProviderRequest): {
|
|
16
|
+
url: string;
|
|
17
|
+
headers: Record<string, string>;
|
|
18
|
+
body: CloudCodeEnvelope;
|
|
19
|
+
};
|
|
20
|
+
export declare function parseCloudCodeSSE(stream: ReadableStream<Uint8Array>): AsyncIterable<ProviderEvent>;
|
|
21
|
+
export declare class CloudCodeProviderAdapter implements ProviderAdapter {
|
|
22
|
+
private readonly fetchFn;
|
|
23
|
+
constructor(fetchFn?: typeof fetch);
|
|
24
|
+
execute(acquisition: AccountTransportAcquisition, request: ProviderRequest, signal: AbortSignal): AsyncIterable<ProviderEvent>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=cloud-code-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-code-transport.d.ts","sourceRoot":"","sources":["../../src/transport/cloud-code-transport.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,eAAe,EAChB,MAAM,sBAAsB,CAAC;AAE9B,eAAO,MAAM,qBAAqB,uFACoD,CAAC;AACvF,eAAO,MAAM,qBAAqB,2FACwD,CAAC;AAE3F,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;KAC5B,CAAC;CACH;AAED,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,2BAA2B,EACxC,OAAO,EAAE,eAAe,GACvB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,CAsC3E;AAED,wBAAuB,iBAAiB,CACtC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,aAAa,CAAC,aAAa,CAAC,CA+D9B;AAED,qBAAa,wBAAyB,YAAW,eAAe;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,GAAE,OAAO,KAAa;IAEnD,OAAO,CACZ,WAAW,EAAE,2BAA2B,EACxC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,aAAa,CAAC,aAAa,CAAC;CA6HhC"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { randomUUID } from 'crypto';
|
|
2
|
+
export const CLOUD_CODE_STREAM_URL = 'https://daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse';
|
|
3
|
+
export const CLOUD_CODE_USER_AGENT = 'antigravity/cli/1.1.10 (aidev_client; os_type=linux; arch=amd64; auth_method=consumer)';
|
|
4
|
+
export function buildCloudCodeRequest(acquisition, request) {
|
|
5
|
+
const project = acquisition.runtime.metadata?.cloudaicompanionProject ??
|
|
6
|
+
acquisition.material.metadata?.cloudaicompanionProject;
|
|
7
|
+
if (!project || typeof project !== 'string' || project.trim().length === 0) {
|
|
8
|
+
throw new Error('Cloud Code transport error: cloudaicompanionProject is required in acquisition runtime metadata');
|
|
9
|
+
}
|
|
10
|
+
// P1-2: Always generate a valid UUID v4 for envelope requestId
|
|
11
|
+
const requestId = randomUUID();
|
|
12
|
+
const headers = {
|
|
13
|
+
Authorization: `Bearer ${acquisition.material.accessToken}`,
|
|
14
|
+
'User-Agent': CLOUD_CODE_USER_AGENT,
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
Accept: 'text/event-stream',
|
|
17
|
+
...(acquisition.runtime.headers ?? {}),
|
|
18
|
+
};
|
|
19
|
+
const body = {
|
|
20
|
+
project: project.trim(),
|
|
21
|
+
requestId,
|
|
22
|
+
model: request.modelId,
|
|
23
|
+
userAgent: 'antigravity',
|
|
24
|
+
request: {
|
|
25
|
+
contents: request.contents,
|
|
26
|
+
...(request.generationConfig ? { generationConfig: request.generationConfig } : {}),
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
url: CLOUD_CODE_STREAM_URL,
|
|
31
|
+
headers,
|
|
32
|
+
body,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export async function* parseCloudCodeSSE(stream) {
|
|
36
|
+
const reader = stream.getReader();
|
|
37
|
+
const decoder = new TextDecoder();
|
|
38
|
+
let buffer = '';
|
|
39
|
+
let lastUsage = null;
|
|
40
|
+
try {
|
|
41
|
+
while (true) {
|
|
42
|
+
const { done, value } = await reader.read();
|
|
43
|
+
if (done)
|
|
44
|
+
break;
|
|
45
|
+
buffer += decoder.decode(value, { stream: true });
|
|
46
|
+
const lines = buffer.split('\n');
|
|
47
|
+
buffer = lines.pop() ?? '';
|
|
48
|
+
for (const line of lines) {
|
|
49
|
+
const trimmed = line.trim();
|
|
50
|
+
if (!trimmed.startsWith('data:'))
|
|
51
|
+
continue;
|
|
52
|
+
const dataStr = trimmed.slice(5).trim();
|
|
53
|
+
if (!dataStr || dataStr === '[DONE]')
|
|
54
|
+
continue;
|
|
55
|
+
try {
|
|
56
|
+
const parsed = JSON.parse(dataStr);
|
|
57
|
+
if (parsed.error) {
|
|
58
|
+
yield {
|
|
59
|
+
kind: 'error',
|
|
60
|
+
code: String(parsed.error.code ?? 'sse_error'),
|
|
61
|
+
message: parsed.error.message ?? 'Cloud Code SSE stream error',
|
|
62
|
+
};
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const parts = parsed.candidates?.[0]?.content?.parts;
|
|
66
|
+
if (parts) {
|
|
67
|
+
for (const part of parts) {
|
|
68
|
+
if (part.text) {
|
|
69
|
+
yield { kind: 'content', delta: part.text };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (parsed.usageMetadata) {
|
|
74
|
+
lastUsage = parsed.usageMetadata;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Ignore unparseable SSE data lines
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// P1-1: Yield done event exactly once after stream completion
|
|
83
|
+
yield { kind: 'done', usage: lastUsage ?? {} };
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
reader.releaseLock();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
export class CloudCodeProviderAdapter {
|
|
90
|
+
fetchFn;
|
|
91
|
+
constructor(fetchFn = fetch) {
|
|
92
|
+
this.fetchFn = fetchFn;
|
|
93
|
+
}
|
|
94
|
+
async *execute(acquisition, request, signal) {
|
|
95
|
+
if (signal.aborted) {
|
|
96
|
+
// Q2B: abort = 0 outcome, handle via release
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const { url, headers, body } = buildCloudCodeRequest(acquisition, request);
|
|
100
|
+
let response;
|
|
101
|
+
try {
|
|
102
|
+
response = await this.fetchFn(url, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers,
|
|
105
|
+
body: JSON.stringify(body),
|
|
106
|
+
signal,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
if (signal.aborted) {
|
|
111
|
+
// Abort -> no outcome recorded
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
await acquisition.recordOutcome({
|
|
115
|
+
status: 'failed',
|
|
116
|
+
errorCode: 'network_error',
|
|
117
|
+
});
|
|
118
|
+
yield {
|
|
119
|
+
kind: 'error',
|
|
120
|
+
code: 'network_error',
|
|
121
|
+
message: err instanceof Error ? err.message : String(err),
|
|
122
|
+
};
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (signal.aborted) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (response.status === 401 || response.status === 403) {
|
|
129
|
+
await acquisition.recordOutcome({
|
|
130
|
+
status: 'auth_failed',
|
|
131
|
+
providerStatusCode: response.status,
|
|
132
|
+
});
|
|
133
|
+
yield {
|
|
134
|
+
kind: 'error',
|
|
135
|
+
code: 'auth_failed',
|
|
136
|
+
message: `Cloud Code authentication failed (${response.status})`,
|
|
137
|
+
};
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
if (response.status === 429) {
|
|
141
|
+
const retryAfterHeader = response.headers.get('Retry-After');
|
|
142
|
+
let retryAfterMs;
|
|
143
|
+
if (retryAfterHeader) {
|
|
144
|
+
const parsedSeconds = Number.parseInt(retryAfterHeader, 10);
|
|
145
|
+
if (Number.isFinite(parsedSeconds) && parsedSeconds > 0) {
|
|
146
|
+
retryAfterMs = parsedSeconds * 1000;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
await acquisition.recordOutcome({
|
|
150
|
+
status: 'rate_limited',
|
|
151
|
+
providerStatusCode: 429,
|
|
152
|
+
retryAfterMs,
|
|
153
|
+
});
|
|
154
|
+
yield {
|
|
155
|
+
kind: 'error',
|
|
156
|
+
code: 'rate_limited',
|
|
157
|
+
message: 'Cloud Code rate limit exceeded (429)',
|
|
158
|
+
};
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
await acquisition.recordOutcome({
|
|
163
|
+
status: 'failed',
|
|
164
|
+
providerStatusCode: response.status,
|
|
165
|
+
});
|
|
166
|
+
yield {
|
|
167
|
+
kind: 'error',
|
|
168
|
+
code: 'http_error',
|
|
169
|
+
message: `Cloud Code HTTP error (${response.status})`,
|
|
170
|
+
};
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (!response.body) {
|
|
174
|
+
await acquisition.recordOutcome({ status: 'failed', errorCode: 'no_body' });
|
|
175
|
+
yield { kind: 'error', code: 'no_body', message: 'No response body received' };
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
let hasError = false;
|
|
179
|
+
// P0-6: Wrap SSE iteration in try-catch to guarantee recordOutcome on network/stream exception
|
|
180
|
+
try {
|
|
181
|
+
for await (const event of parseCloudCodeSSE(response.body)) {
|
|
182
|
+
if (signal.aborted) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (event.kind === 'error') {
|
|
186
|
+
hasError = true;
|
|
187
|
+
}
|
|
188
|
+
yield event;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (streamErr) {
|
|
192
|
+
if (signal.aborted) {
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
await acquisition.recordOutcome({
|
|
196
|
+
status: 'failed',
|
|
197
|
+
errorCode: 'stream_error',
|
|
198
|
+
});
|
|
199
|
+
yield {
|
|
200
|
+
kind: 'error',
|
|
201
|
+
code: 'stream_error',
|
|
202
|
+
message: streamErr instanceof Error ? streamErr.message : String(streamErr),
|
|
203
|
+
};
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
if (!signal.aborted) {
|
|
207
|
+
await acquisition.recordOutcome({
|
|
208
|
+
status: hasError ? 'failed' : 'success',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=cloud-code-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloud-code-transport.js","sourceRoot":"","sources":["../../src/transport/cloud-code-transport.ts"],"names":[],"mappings":"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"}
|