@almightygpt/core 0.7.2 → 0.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/dist/adapters/claude.d.ts +8 -1
- package/dist/adapters/claude.d.ts.map +1 -1
- package/dist/adapters/claude.js +26 -7
- package/dist/adapters/claude.js.map +1 -1
- package/dist/adapters/gemini.d.ts +5 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +23 -10
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/openai.d.ts +6 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +28 -16
- package/dist/adapters/openai.js.map +1 -1
- package/dist/auth/keychain.d.ts +30 -0
- package/dist/auth/keychain.d.ts.map +1 -0
- package/dist/auth/keychain.js +106 -0
- package/dist/auth/keychain.js.map +1 -0
- package/dist/auth/resolver.d.ts +32 -0
- package/dist/auth/resolver.d.ts.map +1 -0
- package/dist/auth/resolver.js +58 -0
- package/dist/auth/resolver.js.map +1 -0
- package/dist/auth/types.d.ts +45 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +51 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/validator.d.ts +33 -0
- package/dist/auth/validator.d.ts.map +1 -0
- package/dist/auth/validator.js +130 -0
- package/dist/auth/validator.js.map +1 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
- package/src/adapters/claude.ts +24 -7
- package/src/adapters/gemini.ts +21 -11
- package/src/adapters/openai.ts +26 -15
- package/src/auth/keychain.ts +132 -0
- package/src/auth/resolver.ts +81 -0
- package/src/auth/types.ts +68 -0
- package/src/auth/validator.ts +145 -0
- package/src/index.ts +22 -1
|
@@ -23,11 +23,18 @@ export interface ClaudeAdapterOptions {
|
|
|
23
23
|
export declare class ClaudeAdapter implements Adapter {
|
|
24
24
|
readonly name: string;
|
|
25
25
|
readonly provider = "anthropic";
|
|
26
|
-
private
|
|
26
|
+
private client;
|
|
27
|
+
private resolved;
|
|
28
|
+
private readonly explicitApiKey;
|
|
27
29
|
readonly defaultModel: string;
|
|
28
30
|
private readonly defaultMaxOutputTokens;
|
|
29
31
|
private readonly defaultTimeoutMs;
|
|
30
32
|
constructor(name?: string, options?: ClaudeAdapterOptions);
|
|
33
|
+
/**
|
|
34
|
+
* Lazily resolve the API key on first need. Goes through the
|
|
35
|
+
* unified resolver: explicit → env → keychain → missing.
|
|
36
|
+
*/
|
|
37
|
+
private ensureClient;
|
|
31
38
|
isAvailable(): Promise<boolean>;
|
|
32
39
|
execute(input: AdapterInput): Promise<AdapterOutput>;
|
|
33
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAiBpB,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,aAAc,YAAW,OAAO;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,eAAe;IAEhC,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,IAAI,SAAW,EAAE,OAAO,GAAE,oBAAyB;IAQ/D;;;OAGG;YACW,YAAY;IAUpB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAoG3D"}
|
package/dist/adapters/claude.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import Anthropic from "@anthropic-ai/sdk";
|
|
17
17
|
import { AdapterError, } from "./types.js";
|
|
18
|
+
import { resolveApiKey } from "../auth/resolver.js";
|
|
18
19
|
const PRICING_USD_PER_1M = {
|
|
19
20
|
// Claude 4.x family (current)
|
|
20
21
|
"claude-sonnet-4": { input: 3.0, output: 15.0 },
|
|
@@ -30,7 +31,9 @@ const DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
|
30
31
|
export class ClaudeAdapter {
|
|
31
32
|
name;
|
|
32
33
|
provider = "anthropic";
|
|
33
|
-
client;
|
|
34
|
+
client = null;
|
|
35
|
+
resolved = false;
|
|
36
|
+
explicitApiKey;
|
|
34
37
|
defaultModel;
|
|
35
38
|
defaultMaxOutputTokens;
|
|
36
39
|
defaultTimeoutMs;
|
|
@@ -39,15 +42,31 @@ export class ClaudeAdapter {
|
|
|
39
42
|
this.defaultModel = options.defaultModel ?? DEFAULT_MODEL;
|
|
40
43
|
this.defaultMaxOutputTokens = options.defaultMaxOutputTokens ?? 4096;
|
|
41
44
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? 120_000;
|
|
42
|
-
|
|
43
|
-
|
|
45
|
+
this.explicitApiKey = options.apiKey;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Lazily resolve the API key on first need. Goes through the
|
|
49
|
+
* unified resolver: explicit → env → keychain → missing.
|
|
50
|
+
*/
|
|
51
|
+
async ensureClient() {
|
|
52
|
+
if (this.resolved)
|
|
53
|
+
return this.client;
|
|
54
|
+
this.resolved = true;
|
|
55
|
+
const opts = this.explicitApiKey ? { explicit: this.explicitApiKey } : {};
|
|
56
|
+
const result = await resolveApiKey("anthropic", opts);
|
|
57
|
+
if (result.source === "missing")
|
|
58
|
+
return null;
|
|
59
|
+
this.client = new Anthropic({ apiKey: result.key });
|
|
60
|
+
return this.client;
|
|
44
61
|
}
|
|
45
62
|
async isAvailable() {
|
|
46
|
-
return this.
|
|
63
|
+
return (await this.ensureClient()) !== null;
|
|
47
64
|
}
|
|
48
65
|
async execute(input) {
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
const client = await this.ensureClient();
|
|
67
|
+
if (!client) {
|
|
68
|
+
throw new AdapterError('No Anthropic API key found. Run "almightygpt auth anthropic" ' +
|
|
69
|
+
"or export ANTHROPIC_API_KEY in your environment.", this.name);
|
|
51
70
|
}
|
|
52
71
|
const model = input.model ?? this.defaultModel;
|
|
53
72
|
const maxOutputTokens = input.maxOutputTokens ?? this.defaultMaxOutputTokens;
|
|
@@ -55,7 +74,7 @@ export class ClaudeAdapter {
|
|
|
55
74
|
const start = Date.now();
|
|
56
75
|
let response;
|
|
57
76
|
try {
|
|
58
|
-
response = await
|
|
77
|
+
response = await client.messages.create({
|
|
59
78
|
model,
|
|
60
79
|
max_tokens: maxOutputTokens,
|
|
61
80
|
// Pass system as a content-block array with cache_control:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EACL,YAAY,GAIb,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/adapters/claude.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,11 +31,15 @@ export interface GeminiAdapterOptions {
|
|
|
31
31
|
export declare class GeminiAdapter implements Adapter {
|
|
32
32
|
readonly name: string;
|
|
33
33
|
readonly provider = "google";
|
|
34
|
-
private
|
|
34
|
+
private client;
|
|
35
|
+
private resolved;
|
|
36
|
+
private readonly explicitApiKey;
|
|
35
37
|
readonly defaultModel: string;
|
|
36
38
|
private readonly defaultMaxOutputTokens;
|
|
37
39
|
private readonly defaultTimeoutMs;
|
|
38
40
|
constructor(name?: string, options?: GeminiAdapterOptions);
|
|
41
|
+
/** Lazily resolve via the unified resolver: explicit → env → keychain. */
|
|
42
|
+
private ensureClient;
|
|
39
43
|
isAvailable(): Promise<boolean>;
|
|
40
44
|
execute(input: AdapterInput): Promise<AdapterOutput>;
|
|
41
45
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAEL,KAAK,OAAO,EACZ,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAoBpB,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,aAAc,YAAW,OAAO;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,YAAY;IAE7B,OAAO,CAAC,MAAM,CAAmC;IACjD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,IAAI,SAAW,EAAE,OAAO,GAAE,oBAAyB;IAa/D,0EAA0E;YAC5D,YAAY;IAUpB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CAkF3D"}
|
package/dist/adapters/gemini.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
25
25
|
import { AdapterError, } from "./types.js";
|
|
26
|
+
import { resolveApiKey } from "../auth/resolver.js";
|
|
26
27
|
const PRICING_USD_PER_1M = {
|
|
27
28
|
"gemini-2.5-pro": { input: 1.25, output: 10.0 },
|
|
28
29
|
"gemini-2.5-flash": { input: 0.3, output: 2.5 },
|
|
@@ -41,7 +42,9 @@ const DEFAULT_MODEL = "gemini-2.5-flash";
|
|
|
41
42
|
export class GeminiAdapter {
|
|
42
43
|
name;
|
|
43
44
|
provider = "google";
|
|
44
|
-
client;
|
|
45
|
+
client = null;
|
|
46
|
+
resolved = false;
|
|
47
|
+
explicitApiKey;
|
|
45
48
|
defaultModel;
|
|
46
49
|
defaultMaxOutputTokens;
|
|
47
50
|
defaultTimeoutMs;
|
|
@@ -55,18 +58,28 @@ export class GeminiAdapter {
|
|
|
55
58
|
// below to make sure the visible response gets the full budget.
|
|
56
59
|
this.defaultMaxOutputTokens = options.defaultMaxOutputTokens ?? 8192;
|
|
57
60
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? 120_000;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
this.explicitApiKey = options.apiKey;
|
|
62
|
+
}
|
|
63
|
+
/** Lazily resolve via the unified resolver: explicit → env → keychain. */
|
|
64
|
+
async ensureClient() {
|
|
65
|
+
if (this.resolved)
|
|
66
|
+
return this.client;
|
|
67
|
+
this.resolved = true;
|
|
68
|
+
const opts = this.explicitApiKey ? { explicit: this.explicitApiKey } : {};
|
|
69
|
+
const result = await resolveApiKey("google", opts);
|
|
70
|
+
if (result.source === "missing")
|
|
71
|
+
return null;
|
|
72
|
+
this.client = new GoogleGenerativeAI(result.key);
|
|
73
|
+
return this.client;
|
|
62
74
|
}
|
|
63
75
|
async isAvailable() {
|
|
64
|
-
return this.
|
|
76
|
+
return (await this.ensureClient()) !== null;
|
|
65
77
|
}
|
|
66
78
|
async execute(input) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
const client = await this.ensureClient();
|
|
80
|
+
if (!client) {
|
|
81
|
+
throw new AdapterError('No Google API key found. Run "almightygpt auth google" ' +
|
|
82
|
+
"or export GOOGLE_API_KEY (or GEMINI_API_KEY) in your environment.", this.name);
|
|
70
83
|
}
|
|
71
84
|
const model = input.model ?? this.defaultModel;
|
|
72
85
|
const maxOutputTokens = input.maxOutputTokens ?? this.defaultMaxOutputTokens;
|
|
@@ -84,7 +97,7 @@ export class GeminiAdapter {
|
|
|
84
97
|
if (input.responseFormat === "json_object") {
|
|
85
98
|
generationConfig["responseMimeType"] = "application/json";
|
|
86
99
|
}
|
|
87
|
-
const generative =
|
|
100
|
+
const generative = client.getGenerativeModel({
|
|
88
101
|
model,
|
|
89
102
|
systemInstruction: input.systemPrompt,
|
|
90
103
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,YAAY,GAIb,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../src/adapters/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,11 +27,16 @@ export interface OpenAIAdapterOptions {
|
|
|
27
27
|
export declare class OpenAIAdapter implements Adapter {
|
|
28
28
|
readonly name: string;
|
|
29
29
|
readonly provider = "openai";
|
|
30
|
-
private
|
|
30
|
+
private client;
|
|
31
|
+
private resolved;
|
|
32
|
+
private readonly explicitApiKey;
|
|
33
|
+
private readonly organization;
|
|
31
34
|
readonly defaultModel: string;
|
|
32
35
|
private readonly defaultMaxOutputTokens;
|
|
33
36
|
private readonly defaultTimeoutMs;
|
|
34
37
|
constructor(name?: string, options?: OpenAIAdapterOptions);
|
|
38
|
+
/** Lazily resolve via the unified resolver: explicit → env → keychain. */
|
|
39
|
+
private ensureClient;
|
|
35
40
|
isAvailable(): Promise<boolean>;
|
|
36
41
|
execute(input: AdapterInput): Promise<AdapterOutput>;
|
|
37
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAgB,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAgB,KAAK,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAa/F,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kCAAkC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAAa,aAAc,YAAW,OAAO;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,YAAY;IAE7B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAGxC,IAAI,SAAU,EACd,OAAO,GAAE,oBAAyB;IAUpC,0EAA0E;YAC5D,YAAY;IAapB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;CA+E3D"}
|
package/dist/adapters/openai.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import OpenAI from "openai";
|
|
15
15
|
import { AdapterError } from "./types.js";
|
|
16
|
+
import { resolveApiKey } from "../auth/resolver.js";
|
|
16
17
|
/** USD per 1M tokens, by model. Lowercased keys. */
|
|
17
18
|
const PRICING_USD_PER_1M = {
|
|
18
19
|
"gpt-4o": { input: 2.5, output: 10.0 },
|
|
@@ -24,7 +25,10 @@ const DEFAULT_MODEL = "gpt-4o";
|
|
|
24
25
|
export class OpenAIAdapter {
|
|
25
26
|
name;
|
|
26
27
|
provider = "openai";
|
|
27
|
-
client;
|
|
28
|
+
client = null;
|
|
29
|
+
resolved = false;
|
|
30
|
+
explicitApiKey;
|
|
31
|
+
organization;
|
|
28
32
|
defaultModel;
|
|
29
33
|
defaultMaxOutputTokens;
|
|
30
34
|
defaultTimeoutMs;
|
|
@@ -33,24 +37,32 @@ export class OpenAIAdapter {
|
|
|
33
37
|
this.defaultModel = options.defaultModel ?? DEFAULT_MODEL;
|
|
34
38
|
this.defaultMaxOutputTokens = options.defaultMaxOutputTokens ?? 4096;
|
|
35
39
|
this.defaultTimeoutMs = options.defaultTimeoutMs ?? 120_000;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
this.explicitApiKey = options.apiKey;
|
|
41
|
+
this.organization = options.organization;
|
|
42
|
+
}
|
|
43
|
+
/** Lazily resolve via the unified resolver: explicit → env → keychain. */
|
|
44
|
+
async ensureClient() {
|
|
45
|
+
if (this.resolved)
|
|
46
|
+
return this.client;
|
|
47
|
+
this.resolved = true;
|
|
48
|
+
const opts = this.explicitApiKey ? { explicit: this.explicitApiKey } : {};
|
|
49
|
+
const result = await resolveApiKey("openai", opts);
|
|
50
|
+
if (result.source === "missing")
|
|
51
|
+
return null;
|
|
52
|
+
this.client = new OpenAI({
|
|
53
|
+
apiKey: result.key,
|
|
54
|
+
...(this.organization ? { organization: this.organization } : {}),
|
|
55
|
+
});
|
|
56
|
+
return this.client;
|
|
46
57
|
}
|
|
47
58
|
async isAvailable() {
|
|
48
|
-
return this.
|
|
59
|
+
return (await this.ensureClient()) !== null;
|
|
49
60
|
}
|
|
50
61
|
async execute(input) {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
62
|
+
const client = await this.ensureClient();
|
|
63
|
+
if (!client) {
|
|
64
|
+
throw new AdapterError('No OpenAI API key found. Run "almightygpt auth openai" ' +
|
|
65
|
+
"or export OPENAI_API_KEY in your environment.", this.name);
|
|
54
66
|
}
|
|
55
67
|
const model = input.model ?? this.defaultModel;
|
|
56
68
|
const maxOutputTokens = input.maxOutputTokens ?? this.defaultMaxOutputTokens;
|
|
@@ -58,7 +70,7 @@ export class OpenAIAdapter {
|
|
|
58
70
|
const start = Date.now();
|
|
59
71
|
let response;
|
|
60
72
|
try {
|
|
61
|
-
response = await
|
|
73
|
+
response = await client.chat.completions.create({
|
|
62
74
|
model,
|
|
63
75
|
max_tokens: maxOutputTokens,
|
|
64
76
|
messages: [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,YAAY,EAAuD,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/adapters/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS keychain wrapper — @napi-rs/keyring loaded via DYNAMIC IMPORT.
|
|
3
|
+
*
|
|
4
|
+
* The native binary is an OPTIONAL runtime capability:
|
|
5
|
+
* - If @napi-rs/keyring is installed and loads → real keychain access
|
|
6
|
+
* (macOS Keychain, Windows Credential Manager, Linux Secret Service).
|
|
7
|
+
* - If it's NOT installed (optionalDependencies skipped on exotic OS,
|
|
8
|
+
* or just plain missing) → returns an unavailable shim. Resolver
|
|
9
|
+
* falls through to env vars without crashing.
|
|
10
|
+
*
|
|
11
|
+
* This pattern means `npm install almightygpt` NEVER blocks on keychain
|
|
12
|
+
* binary failure. Codex's review explicitly flagged this as the
|
|
13
|
+
* correct strategy.
|
|
14
|
+
*
|
|
15
|
+
* Service name: `almightygpt` (consistent across all platforms; what
|
|
16
|
+
* users see in macOS Keychain Access.app, Windows credential UI, etc.)
|
|
17
|
+
*/
|
|
18
|
+
import type { ProviderId } from "./types.js";
|
|
19
|
+
export interface KeychainAdapter {
|
|
20
|
+
available: boolean;
|
|
21
|
+
get(provider: ProviderId): Promise<string | undefined>;
|
|
22
|
+
set(provider: ProviderId, key: string): Promise<void>;
|
|
23
|
+
remove(provider: ProviderId): Promise<boolean>;
|
|
24
|
+
/** Optional diagnostic — backend name, or "unavailable". */
|
|
25
|
+
describeBackend(): string;
|
|
26
|
+
}
|
|
27
|
+
export declare function getKeychain(): Promise<KeychainAdapter>;
|
|
28
|
+
/** Exposed for tests that want to reset the singleton between cases. */
|
|
29
|
+
export declare function _resetKeychainCache(): void;
|
|
30
|
+
//# sourceMappingURL=keychain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvD,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,4DAA4D;IAC5D,eAAe,IAAI,MAAM,CAAC;CAC3B;AASD,wBAAsB,WAAW,IAAI,OAAO,CAAC,eAAe,CAAC,CAI5D;AAsFD,wEAAwE;AACxE,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OS keychain wrapper — @napi-rs/keyring loaded via DYNAMIC IMPORT.
|
|
3
|
+
*
|
|
4
|
+
* The native binary is an OPTIONAL runtime capability:
|
|
5
|
+
* - If @napi-rs/keyring is installed and loads → real keychain access
|
|
6
|
+
* (macOS Keychain, Windows Credential Manager, Linux Secret Service).
|
|
7
|
+
* - If it's NOT installed (optionalDependencies skipped on exotic OS,
|
|
8
|
+
* or just plain missing) → returns an unavailable shim. Resolver
|
|
9
|
+
* falls through to env vars without crashing.
|
|
10
|
+
*
|
|
11
|
+
* This pattern means `npm install almightygpt` NEVER blocks on keychain
|
|
12
|
+
* binary failure. Codex's review explicitly flagged this as the
|
|
13
|
+
* correct strategy.
|
|
14
|
+
*
|
|
15
|
+
* Service name: `almightygpt` (consistent across all platforms; what
|
|
16
|
+
* users see in macOS Keychain Access.app, Windows credential UI, etc.)
|
|
17
|
+
*/
|
|
18
|
+
const KEYCHAIN_SERVICE = "almightygpt";
|
|
19
|
+
/**
|
|
20
|
+
* Lazy-loaded singleton. We never throw on import failure; instead the
|
|
21
|
+
* resulting adapter reports `available: false` and the resolver knows
|
|
22
|
+
* to skip it.
|
|
23
|
+
*/
|
|
24
|
+
let cached = null;
|
|
25
|
+
export async function getKeychain() {
|
|
26
|
+
if (cached)
|
|
27
|
+
return cached;
|
|
28
|
+
cached = await loadKeychain();
|
|
29
|
+
return cached;
|
|
30
|
+
}
|
|
31
|
+
async function loadKeychain() {
|
|
32
|
+
try {
|
|
33
|
+
// Dynamic import — never crashes the module if the package is
|
|
34
|
+
// missing or its native binary fails to load on the host.
|
|
35
|
+
const mod = (await import("@napi-rs/keyring"));
|
|
36
|
+
const entryFor = (provider) => new mod.Entry(KEYCHAIN_SERVICE, provider);
|
|
37
|
+
// Probe: try to construct an Entry. If the native binding throws
|
|
38
|
+
// (no Secret Service daemon on Linux, etc.), we degrade.
|
|
39
|
+
try {
|
|
40
|
+
entryFor("openai");
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return makeUnavailable("native binding failed to initialize");
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
available: true,
|
|
47
|
+
describeBackend: () => detectBackend(),
|
|
48
|
+
async get(provider) {
|
|
49
|
+
try {
|
|
50
|
+
const v = entryFor(provider).getPassword();
|
|
51
|
+
return v === null ? undefined : v;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
async set(provider, key) {
|
|
58
|
+
entryFor(provider).setPassword(key);
|
|
59
|
+
},
|
|
60
|
+
async remove(provider) {
|
|
61
|
+
try {
|
|
62
|
+
return entryFor(provider).deletePassword();
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
return makeUnavailable(err instanceof Error ? err.message : "import failed");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function makeUnavailable(reason) {
|
|
75
|
+
return {
|
|
76
|
+
available: false,
|
|
77
|
+
describeBackend: () => `unavailable (${reason})`,
|
|
78
|
+
async get() {
|
|
79
|
+
return undefined;
|
|
80
|
+
},
|
|
81
|
+
async set() {
|
|
82
|
+
throw new Error(`Keychain unavailable: ${reason}. Set the API key via an environment ` +
|
|
83
|
+
`variable instead (e.g. ANTHROPIC_API_KEY).`);
|
|
84
|
+
},
|
|
85
|
+
async remove() {
|
|
86
|
+
return false;
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function detectBackend() {
|
|
91
|
+
switch (process.platform) {
|
|
92
|
+
case "darwin":
|
|
93
|
+
return "macos-keychain";
|
|
94
|
+
case "win32":
|
|
95
|
+
return "windows-credential-manager";
|
|
96
|
+
case "linux":
|
|
97
|
+
return "linux-secret-service";
|
|
98
|
+
default:
|
|
99
|
+
return process.platform;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Exposed for tests that want to reset the singleton between cases. */
|
|
103
|
+
export function _resetKeychainCache() {
|
|
104
|
+
cached = null;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=keychain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/auth/keychain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAWvC;;;;GAIG;AACH,IAAI,MAAM,GAA2B,IAAI,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IAC9B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,YAAY;IACzB,IAAI,CAAC;QACH,8DAA8D;QAC9D,0DAA0D;QAC1D,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAM5C,CAAC;QAEF,MAAM,QAAQ,GAAG,CAAC,QAAoB,EAAE,EAAE,CACxC,IAAI,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QAE5C,iEAAiE;QACjE,yDAAyD;QACzD,IAAI,CAAC;YACH,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,eAAe,CAAC,qCAAqC,CAAC,CAAC;QAChE,CAAC;QAED,OAAO;YACL,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE;YACtC,KAAK,CAAC,GAAG,CAAC,QAAQ;gBAChB,IAAI,CAAC;oBACH,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;oBAC3C,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpC,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG;gBACrB,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YACtC,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,QAAQ;gBACnB,IAAI,CAAC;oBACH,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC,cAAc,EAAE,CAAC;gBAC7C,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,eAAe,CACpB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CACrD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO;QACL,SAAS,EAAE,KAAK;QAChB,eAAe,EAAE,GAAG,EAAE,CAAC,gBAAgB,MAAM,GAAG;QAChD,KAAK,CAAC,GAAG;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,KAAK,CAAC,GAAG;YACP,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,uCAAuC;gBACpE,4CAA4C,CAC/C,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,MAAM;YACV,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,aAAa;IACpB,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,QAAQ;YACX,OAAO,gBAAgB,CAAC;QAC1B,KAAK,OAAO;YACV,OAAO,4BAA4B,CAAC;QACtC,KAAK,OAAO;YACV,OAAO,sBAAsB,CAAC;QAChC;YACE,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,mBAAmB;IACjC,MAAM,GAAG,IAAI,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API key resolver — the single entry point every adapter must call
|
|
3
|
+
* to find its key. Replaces direct `process.env[...]` reads.
|
|
4
|
+
*
|
|
5
|
+
* Priority order (top to bottom):
|
|
6
|
+
* 1. Explicit parameter (caller passed a key — tests, extension handoff)
|
|
7
|
+
* 2. Environment variable (per-process override; wins over keychain)
|
|
8
|
+
* 3. OS keychain (persistent convenience; optional capability)
|
|
9
|
+
* 4. Missing → throw AuthMissingError
|
|
10
|
+
*
|
|
11
|
+
* Env wins over keychain by design — see types.ts header for the
|
|
12
|
+
* bug-class reasoning that drove the decision.
|
|
13
|
+
*/
|
|
14
|
+
import { type KeyResolution, type ProviderId } from "./types.js";
|
|
15
|
+
export interface ResolveOptions {
|
|
16
|
+
/** Optional caller-supplied key — wins over all other sources. */
|
|
17
|
+
explicit?: string;
|
|
18
|
+
/** Skip keychain lookup entirely (used by tests). */
|
|
19
|
+
skipKeychain?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve where the API key for `provider` lives.
|
|
23
|
+
* Returns a KeyResolution describing the source even when not found
|
|
24
|
+
* (caller can decide whether to throw).
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveApiKey(provider: ProviderId, options?: ResolveOptions): Promise<KeyResolution>;
|
|
27
|
+
/**
|
|
28
|
+
* Convenience wrapper that throws AuthMissingError on absence — for
|
|
29
|
+
* callers (adapters) that need the key or can't proceed.
|
|
30
|
+
*/
|
|
31
|
+
export declare function requireApiKey(provider: ProviderId, options?: ResolveOptions): Promise<string>;
|
|
32
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/auth/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,cAAc;IAC7B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,UAAU,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA2BxB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,UAAU,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAOjB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API key resolver — the single entry point every adapter must call
|
|
3
|
+
* to find its key. Replaces direct `process.env[...]` reads.
|
|
4
|
+
*
|
|
5
|
+
* Priority order (top to bottom):
|
|
6
|
+
* 1. Explicit parameter (caller passed a key — tests, extension handoff)
|
|
7
|
+
* 2. Environment variable (per-process override; wins over keychain)
|
|
8
|
+
* 3. OS keychain (persistent convenience; optional capability)
|
|
9
|
+
* 4. Missing → throw AuthMissingError
|
|
10
|
+
*
|
|
11
|
+
* Env wins over keychain by design — see types.ts header for the
|
|
12
|
+
* bug-class reasoning that drove the decision.
|
|
13
|
+
*/
|
|
14
|
+
import { getKeychain } from "./keychain.js";
|
|
15
|
+
import { AuthMissingError, PROVIDER_ENV_VARS, } from "./types.js";
|
|
16
|
+
/**
|
|
17
|
+
* Resolve where the API key for `provider` lives.
|
|
18
|
+
* Returns a KeyResolution describing the source even when not found
|
|
19
|
+
* (caller can decide whether to throw).
|
|
20
|
+
*/
|
|
21
|
+
export async function resolveApiKey(provider, options = {}) {
|
|
22
|
+
// 1. Explicit override
|
|
23
|
+
if (options.explicit) {
|
|
24
|
+
return { provider, source: "explicit", key: options.explicit };
|
|
25
|
+
}
|
|
26
|
+
// 2. Environment variable
|
|
27
|
+
for (const envVar of PROVIDER_ENV_VARS[provider]) {
|
|
28
|
+
const v = process.env[envVar];
|
|
29
|
+
if (v && v.length > 0) {
|
|
30
|
+
return { provider, source: "env", key: v, envVar };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// 3. OS keychain (optional)
|
|
34
|
+
if (!options.skipKeychain) {
|
|
35
|
+
const keychain = await getKeychain();
|
|
36
|
+
if (keychain.available) {
|
|
37
|
+
const v = await keychain.get(provider);
|
|
38
|
+
if (v && v.length > 0) {
|
|
39
|
+
return { provider, source: "keychain", key: v };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// 4. Missing
|
|
44
|
+
return { provider, source: "missing" };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Convenience wrapper that throws AuthMissingError on absence — for
|
|
48
|
+
* callers (adapters) that need the key or can't proceed.
|
|
49
|
+
*/
|
|
50
|
+
export async function requireApiKey(provider, options = {}) {
|
|
51
|
+
const resolved = await resolveApiKey(provider, options);
|
|
52
|
+
if (resolved.source === "missing") {
|
|
53
|
+
const primaryEnv = PROVIDER_ENV_VARS[provider][0];
|
|
54
|
+
throw new AuthMissingError(provider, primaryEnv);
|
|
55
|
+
}
|
|
56
|
+
return resolved.key;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/auth/resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,iBAAiB,GAGlB,MAAM,YAAY,CAAC;AASpB;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAoB,EACpB,UAA0B,EAAE;IAE5B,uBAAuB;IACvB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;IACjE,CAAC;IAED,0BAA0B;IAC1B,KAAK,MAAM,MAAM,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjD,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;QACrD,CAAC;IACH,CAAC;IAED,4BAA4B;IAC5B,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAC;QACrC,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa;IACb,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAoB,EACpB,UAA0B,EAAE;IAE5B,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAE,CAAC;QACnD,MAAM,IAAI,gBAAgB,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,QAAQ,CAAC,GAAI,CAAC;AACvB,CAAC"}
|