@lenylvt/pi-ai 0.64.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 +203 -0
- package/dist/api-registry.d.ts +20 -0
- package/dist/api-registry.d.ts.map +1 -0
- package/dist/api-registry.js +44 -0
- package/dist/api-registry.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +119 -0
- package/dist/cli.js.map +1 -0
- package/dist/env-api-keys.d.ts +7 -0
- package/dist/env-api-keys.d.ts.map +1 -0
- package/dist/env-api-keys.js +13 -0
- package/dist/env-api-keys.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/models.d.ts +24 -0
- package/dist/models.d.ts.map +1 -0
- package/dist/models.generated.d.ts +2332 -0
- package/dist/models.generated.d.ts.map +1 -0
- package/dist/models.generated.js +2186 -0
- package/dist/models.generated.js.map +1 -0
- package/dist/models.js +60 -0
- package/dist/models.js.map +1 -0
- package/dist/oauth.d.ts +2 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +2 -0
- package/dist/oauth.js.map +1 -0
- package/dist/providers/anthropic.d.ts +40 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +749 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/faux.d.ts +56 -0
- package/dist/providers/faux.d.ts.map +1 -0
- package/dist/providers/faux.js +367 -0
- package/dist/providers/faux.js.map +1 -0
- package/dist/providers/github-copilot-headers.d.ts +8 -0
- package/dist/providers/github-copilot-headers.d.ts.map +1 -0
- package/dist/providers/github-copilot-headers.js +29 -0
- package/dist/providers/github-copilot-headers.js.map +1 -0
- package/dist/providers/openai-codex-responses.d.ts +9 -0
- package/dist/providers/openai-codex-responses.d.ts.map +1 -0
- package/dist/providers/openai-codex-responses.js +741 -0
- package/dist/providers/openai-codex-responses.js.map +1 -0
- package/dist/providers/openai-completions.d.ts +15 -0
- package/dist/providers/openai-completions.d.ts.map +1 -0
- package/dist/providers/openai-completions.js +687 -0
- package/dist/providers/openai-completions.js.map +1 -0
- package/dist/providers/openai-responses-shared.d.ts +17 -0
- package/dist/providers/openai-responses-shared.d.ts.map +1 -0
- package/dist/providers/openai-responses-shared.js +458 -0
- package/dist/providers/openai-responses-shared.js.map +1 -0
- package/dist/providers/openai-responses.d.ts +13 -0
- package/dist/providers/openai-responses.d.ts.map +1 -0
- package/dist/providers/openai-responses.js +190 -0
- package/dist/providers/openai-responses.js.map +1 -0
- package/dist/providers/register-builtins.d.ts +16 -0
- package/dist/providers/register-builtins.d.ts.map +1 -0
- package/dist/providers/register-builtins.js +140 -0
- package/dist/providers/register-builtins.js.map +1 -0
- package/dist/providers/simple-options.d.ts +8 -0
- package/dist/providers/simple-options.d.ts.map +1 -0
- package/dist/providers/simple-options.js +35 -0
- package/dist/providers/simple-options.js.map +1 -0
- package/dist/providers/transform-messages.d.ts +8 -0
- package/dist/providers/transform-messages.d.ts.map +1 -0
- package/dist/providers/transform-messages.js +155 -0
- package/dist/providers/transform-messages.js.map +1 -0
- package/dist/stream.d.ts +8 -0
- package/dist/stream.d.ts.map +1 -0
- package/dist/stream.js +27 -0
- package/dist/stream.js.map +1 -0
- package/dist/types.d.ts +283 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/event-stream.d.ts +21 -0
- package/dist/utils/event-stream.d.ts.map +1 -0
- package/dist/utils/event-stream.js +81 -0
- package/dist/utils/event-stream.js.map +1 -0
- package/dist/utils/hash.d.ts +3 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +14 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/json-parse.d.ts +9 -0
- package/dist/utils/json-parse.d.ts.map +1 -0
- package/dist/utils/json-parse.js +29 -0
- package/dist/utils/json-parse.js.map +1 -0
- package/dist/utils/oauth/anthropic.d.ts +25 -0
- package/dist/utils/oauth/anthropic.d.ts.map +1 -0
- package/dist/utils/oauth/anthropic.js +335 -0
- package/dist/utils/oauth/anthropic.js.map +1 -0
- package/dist/utils/oauth/github-copilot.d.ts +30 -0
- package/dist/utils/oauth/github-copilot.d.ts.map +1 -0
- package/dist/utils/oauth/github-copilot.js +292 -0
- package/dist/utils/oauth/github-copilot.js.map +1 -0
- package/dist/utils/oauth/index.d.ts +36 -0
- package/dist/utils/oauth/index.d.ts.map +1 -0
- package/dist/utils/oauth/index.js +92 -0
- package/dist/utils/oauth/index.js.map +1 -0
- package/dist/utils/oauth/oauth-page.d.ts +3 -0
- package/dist/utils/oauth/oauth-page.d.ts.map +1 -0
- package/dist/utils/oauth/oauth-page.js +105 -0
- package/dist/utils/oauth/oauth-page.js.map +1 -0
- package/dist/utils/oauth/openai-codex.d.ts +34 -0
- package/dist/utils/oauth/openai-codex.d.ts.map +1 -0
- package/dist/utils/oauth/openai-codex.js +373 -0
- package/dist/utils/oauth/openai-codex.js.map +1 -0
- package/dist/utils/oauth/pkce.d.ts +13 -0
- package/dist/utils/oauth/pkce.d.ts.map +1 -0
- package/dist/utils/oauth/pkce.js +31 -0
- package/dist/utils/oauth/pkce.js.map +1 -0
- package/dist/utils/oauth/types.d.ts +47 -0
- package/dist/utils/oauth/types.d.ts.map +1 -0
- package/dist/utils/oauth/types.js +2 -0
- package/dist/utils/oauth/types.js.map +1 -0
- package/dist/utils/overflow.d.ts +53 -0
- package/dist/utils/overflow.d.ts.map +1 -0
- package/dist/utils/overflow.js +119 -0
- package/dist/utils/overflow.js.map +1 -0
- package/dist/utils/sanitize-unicode.d.ts +22 -0
- package/dist/utils/sanitize-unicode.d.ts.map +1 -0
- package/dist/utils/sanitize-unicode.js +26 -0
- package/dist/utils/sanitize-unicode.js.map +1 -0
- package/dist/utils/typebox-helpers.d.ts +17 -0
- package/dist/utils/typebox-helpers.d.ts.map +1 -0
- package/dist/utils/typebox-helpers.js +21 -0
- package/dist/utils/typebox-helpers.js.map +1 -0
- package/dist/utils/validation.d.ts +18 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +80 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +89 -0
- package/src/api-registry.ts +98 -0
- package/src/cli.ts +136 -0
- package/src/env-api-keys.ts +22 -0
- package/src/index.ts +29 -0
- package/src/models.generated.ts +2188 -0
- package/src/models.ts +82 -0
- package/src/oauth.ts +1 -0
- package/src/providers/anthropic.ts +905 -0
- package/src/providers/faux.ts +498 -0
- package/src/providers/github-copilot-headers.ts +37 -0
- package/src/providers/openai-codex-responses.ts +929 -0
- package/src/providers/openai-completions.ts +811 -0
- package/src/providers/openai-responses-shared.ts +513 -0
- package/src/providers/openai-responses.ts +251 -0
- package/src/providers/register-builtins.ts +232 -0
- package/src/providers/simple-options.ts +46 -0
- package/src/providers/transform-messages.ts +172 -0
- package/src/stream.ts +59 -0
- package/src/types.ts +294 -0
- package/src/utils/event-stream.ts +87 -0
- package/src/utils/hash.ts +13 -0
- package/src/utils/json-parse.ts +28 -0
- package/src/utils/oauth/anthropic.ts +402 -0
- package/src/utils/oauth/github-copilot.ts +396 -0
- package/src/utils/oauth/index.ts +123 -0
- package/src/utils/oauth/oauth-page.ts +109 -0
- package/src/utils/oauth/openai-codex.ts +450 -0
- package/src/utils/oauth/pkce.ts +34 -0
- package/src/utils/oauth/types.ts +59 -0
- package/src/utils/overflow.ts +125 -0
- package/src/utils/sanitize-unicode.ts +25 -0
- package/src/utils/typebox-helpers.ts +24 -0
- package/src/utils/validation.ts +93 -0
package/README.md
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# @lenylvt/pi-ai
|
|
2
|
+
|
|
3
|
+
Unified LLM client layer for the four built-in providers kept in this fork:
|
|
4
|
+
|
|
5
|
+
- `anthropic`
|
|
6
|
+
- `github-copilot`
|
|
7
|
+
- `openai-codex`
|
|
8
|
+
- `openrouter`
|
|
9
|
+
|
|
10
|
+
The package ships built-in model catalogs for those providers only. Custom models and custom providers are still possible through the generic `Model<Api>` and registry APIs.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bun add @lenylvt/pi-ai
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
TypeBox exports are re-exported from `@lenylvt/pi-ai`: `Type`, `Static`, and `TSchema`.
|
|
19
|
+
|
|
20
|
+
## Built-in Providers
|
|
21
|
+
|
|
22
|
+
| Provider | Auth | Notes |
|
|
23
|
+
|----------|------|-------|
|
|
24
|
+
| `anthropic` | OAuth or API key | Claude Pro/Max or `ANTHROPIC_API_KEY` |
|
|
25
|
+
| `github-copilot` | OAuth or token | `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN` |
|
|
26
|
+
| `openai-codex` | OAuth | ChatGPT Plus/Pro subscription |
|
|
27
|
+
| `openrouter` | API key | `OPENROUTER_API_KEY` |
|
|
28
|
+
|
|
29
|
+
## Built-in APIs
|
|
30
|
+
|
|
31
|
+
- `anthropic-messages`
|
|
32
|
+
- `openai-completions`
|
|
33
|
+
- `openai-responses`
|
|
34
|
+
- `openai-codex-responses`
|
|
35
|
+
|
|
36
|
+
`github-copilot` uses a mix of `anthropic-messages`, `openai-completions`, and `openai-responses` depending on the selected model. `openrouter` uses `openai-completions`. `openai-codex` uses `openai-codex-responses`.
|
|
37
|
+
|
|
38
|
+
## Quick Start
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { complete, getModel, Type, type Context, type Tool } from "@lenylvt/pi-ai";
|
|
42
|
+
|
|
43
|
+
const model = getModel("anthropic", "claude-sonnet-4-5");
|
|
44
|
+
|
|
45
|
+
const tools: Tool[] = [
|
|
46
|
+
{
|
|
47
|
+
name: "get_time",
|
|
48
|
+
description: "Get the current time",
|
|
49
|
+
parameters: Type.Object({
|
|
50
|
+
timezone: Type.Optional(Type.String()),
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const context: Context = {
|
|
56
|
+
systemPrompt: "You are a helpful assistant.",
|
|
57
|
+
messages: [{ role: "user", content: "What time is it?", timestamp: Date.now() }],
|
|
58
|
+
tools,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const message = await complete(model, context);
|
|
62
|
+
console.log(message.content);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Providers and Models
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
import { getModel, getModels, getProviders } from "@lenylvt/pi-ai";
|
|
69
|
+
|
|
70
|
+
console.log(getProviders());
|
|
71
|
+
// ["anthropic", "github-copilot", "openai-codex", "openrouter"]
|
|
72
|
+
|
|
73
|
+
const anthropicModels = getModels("anthropic");
|
|
74
|
+
const codex = getModel("openai-codex", "gpt-5.4");
|
|
75
|
+
const openRouter = getModel("openrouter", "openai/gpt-5.1-codex");
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Environment Variables
|
|
79
|
+
|
|
80
|
+
| Provider | Environment Variable(s) |
|
|
81
|
+
|----------|-------------------------|
|
|
82
|
+
| `anthropic` | `ANTHROPIC_API_KEY` or `ANTHROPIC_OAUTH_TOKEN` |
|
|
83
|
+
| `github-copilot` | `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, or `GITHUB_TOKEN` |
|
|
84
|
+
| `openrouter` | `OPENROUTER_API_KEY` |
|
|
85
|
+
|
|
86
|
+
`openai-codex` does not use a static API key in this fork. Authenticate with OAuth.
|
|
87
|
+
|
|
88
|
+
You can inspect environment-based auth with `getEnvApiKey()`:
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { getEnvApiKey } from "@lenylvt/pi-ai";
|
|
92
|
+
|
|
93
|
+
const anthropicKey = getEnvApiKey("anthropic");
|
|
94
|
+
const openRouterKey = getEnvApiKey("openrouter");
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## OAuth
|
|
98
|
+
|
|
99
|
+
OAuth helpers are exported from `@lenylvt/pi-ai/oauth`.
|
|
100
|
+
|
|
101
|
+
### CLI Login
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
bunx @lenylvt/pi-ai login
|
|
105
|
+
bunx @lenylvt/pi-ai login anthropic
|
|
106
|
+
bunx @lenylvt/pi-ai login github-copilot
|
|
107
|
+
bunx @lenylvt/pi-ai login openai-codex
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Programmatic OAuth
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import {
|
|
114
|
+
getOAuthApiKey,
|
|
115
|
+
loginAnthropic,
|
|
116
|
+
loginGitHubCopilot,
|
|
117
|
+
loginOpenAICodex,
|
|
118
|
+
type OAuthCredentials,
|
|
119
|
+
} from "@lenylvt/pi-ai/oauth";
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Stored credentials are the caller's responsibility.
|
|
123
|
+
|
|
124
|
+
## Thinking / Reasoning
|
|
125
|
+
|
|
126
|
+
Use `streamSimple()` or `completeSimple()` with a unified reasoning level:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { completeSimple, getModel } from "@lenylvt/pi-ai";
|
|
130
|
+
|
|
131
|
+
const model = getModel("openrouter", "openai/gpt-5.1-codex");
|
|
132
|
+
|
|
133
|
+
const response = await completeSimple(
|
|
134
|
+
model,
|
|
135
|
+
{
|
|
136
|
+
messages: [{ role: "user", content: "Refactor this function", timestamp: Date.now() }],
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
reasoning: "medium",
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Streaming
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
import { getModel, stream } from "@lenylvt/pi-ai";
|
|
148
|
+
|
|
149
|
+
const model = getModel("github-copilot", "gpt-5");
|
|
150
|
+
const s = stream(model, {
|
|
151
|
+
messages: [{ role: "user", content: "Summarize this diff", timestamp: Date.now() }],
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
for await (const event of s) {
|
|
155
|
+
if (event.type === "text_delta") {
|
|
156
|
+
process.stdout.write(event.delta);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Custom Models
|
|
162
|
+
|
|
163
|
+
Custom models still work. Use `openai-completions` or `anthropic-messages` for the common proxy patterns supported by this fork.
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import type { Model } from "@lenylvt/pi-ai";
|
|
167
|
+
|
|
168
|
+
const openRouterModel: Model<"openai-completions"> = {
|
|
169
|
+
id: "openai/gpt-5.4-mini",
|
|
170
|
+
name: "OpenRouter GPT-5.4 Mini",
|
|
171
|
+
api: "openai-completions",
|
|
172
|
+
provider: "openrouter",
|
|
173
|
+
baseUrl: "https://openrouter.ai/api/v1",
|
|
174
|
+
reasoning: true,
|
|
175
|
+
input: ["text"],
|
|
176
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
177
|
+
contextWindow: 128000,
|
|
178
|
+
maxTokens: 16384,
|
|
179
|
+
compat: {
|
|
180
|
+
supportsDeveloperRole: true,
|
|
181
|
+
supportsReasoningEffort: false,
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Public Exports
|
|
187
|
+
|
|
188
|
+
Provider-specific option types kept in this fork:
|
|
189
|
+
|
|
190
|
+
- `AnthropicOptions`
|
|
191
|
+
- `OpenAICompletionsOptions`
|
|
192
|
+
- `OpenAIResponsesOptions`
|
|
193
|
+
- `OpenAICodexResponsesOptions`
|
|
194
|
+
|
|
195
|
+
## Notes
|
|
196
|
+
|
|
197
|
+
- `openai-codex` requires ChatGPT Plus or Pro.
|
|
198
|
+
- `github-copilot` can require enabling some models in VS Code before the token can use them.
|
|
199
|
+
- `openrouter` is the source of truth for its model availability; use the published model list bundled with each release.
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
MIT
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Api, AssistantMessageEventStream, Context, Model, SimpleStreamOptions, StreamFunction, StreamOptions } from "./types.js";
|
|
2
|
+
export type ApiStreamFunction = (model: Model<Api>, context: Context, options?: StreamOptions) => AssistantMessageEventStream;
|
|
3
|
+
export type ApiStreamSimpleFunction = (model: Model<Api>, context: Context, options?: SimpleStreamOptions) => AssistantMessageEventStream;
|
|
4
|
+
export interface ApiProvider<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> {
|
|
5
|
+
api: TApi;
|
|
6
|
+
stream: StreamFunction<TApi, TOptions>;
|
|
7
|
+
streamSimple: StreamFunction<TApi, SimpleStreamOptions>;
|
|
8
|
+
}
|
|
9
|
+
interface ApiProviderInternal {
|
|
10
|
+
api: Api;
|
|
11
|
+
stream: ApiStreamFunction;
|
|
12
|
+
streamSimple: ApiStreamSimpleFunction;
|
|
13
|
+
}
|
|
14
|
+
export declare function registerApiProvider<TApi extends Api, TOptions extends StreamOptions>(provider: ApiProvider<TApi, TOptions>, sourceId?: string): void;
|
|
15
|
+
export declare function getApiProvider(api: Api): ApiProviderInternal | undefined;
|
|
16
|
+
export declare function getApiProviders(): ApiProviderInternal[];
|
|
17
|
+
export declare function unregisterApiProviders(sourceId: string): void;
|
|
18
|
+
export declare function clearApiProviders(): void;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=api-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-registry.d.ts","sourceRoot":"","sources":["../src/api-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,GAAG,EACH,2BAA2B,EAC3B,OAAO,EACP,KAAK,EACL,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,iBAAiB,GAAG,CAC/B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,aAAa,KACnB,2BAA2B,CAAC;AAEjC,MAAM,MAAM,uBAAuB,GAAG,CACrC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,mBAAmB,KACzB,2BAA2B,CAAC;AAEjC,MAAM,WAAW,WAAW,CAAC,IAAI,SAAS,GAAG,GAAG,GAAG,EAAE,QAAQ,SAAS,aAAa,GAAG,aAAa;IAClG,GAAG,EAAE,IAAI,CAAC;IACV,MAAM,EAAE,cAAc,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACvC,YAAY,EAAE,cAAc,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;CACxD;AAED,UAAU,mBAAmB;IAC5B,GAAG,EAAE,GAAG,CAAC;IACT,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,uBAAuB,CAAC;CACtC;AAiCD,wBAAgB,mBAAmB,CAAC,IAAI,SAAS,GAAG,EAAE,QAAQ,SAAS,aAAa,EACnF,QAAQ,EAAE,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,EACrC,QAAQ,CAAC,EAAE,MAAM,GACf,IAAI,CASN;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,GAAG,mBAAmB,GAAG,SAAS,CAExE;AAED,wBAAgB,eAAe,IAAI,mBAAmB,EAAE,CAEvD;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM7D;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC","sourcesContent":["import type {\n\tApi,\n\tAssistantMessageEventStream,\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n} from \"./types.js\";\n\nexport type ApiStreamFunction = (\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: StreamOptions,\n) => AssistantMessageEventStream;\n\nexport type ApiStreamSimpleFunction = (\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n) => AssistantMessageEventStream;\n\nexport interface ApiProvider<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> {\n\tapi: TApi;\n\tstream: StreamFunction<TApi, TOptions>;\n\tstreamSimple: StreamFunction<TApi, SimpleStreamOptions>;\n}\n\ninterface ApiProviderInternal {\n\tapi: Api;\n\tstream: ApiStreamFunction;\n\tstreamSimple: ApiStreamSimpleFunction;\n}\n\ntype RegisteredApiProvider = {\n\tprovider: ApiProviderInternal;\n\tsourceId?: string;\n};\n\nconst apiProviderRegistry = new Map<string, RegisteredApiProvider>();\n\nfunction wrapStream<TApi extends Api, TOptions extends StreamOptions>(\n\tapi: TApi,\n\tstream: StreamFunction<TApi, TOptions>,\n): ApiStreamFunction {\n\treturn (model, context, options) => {\n\t\tif (model.api !== api) {\n\t\t\tthrow new Error(`Mismatched api: ${model.api} expected ${api}`);\n\t\t}\n\t\treturn stream(model as Model<TApi>, context, options as TOptions);\n\t};\n}\n\nfunction wrapStreamSimple<TApi extends Api>(\n\tapi: TApi,\n\tstreamSimple: StreamFunction<TApi, SimpleStreamOptions>,\n): ApiStreamSimpleFunction {\n\treturn (model, context, options) => {\n\t\tif (model.api !== api) {\n\t\t\tthrow new Error(`Mismatched api: ${model.api} expected ${api}`);\n\t\t}\n\t\treturn streamSimple(model as Model<TApi>, context, options);\n\t};\n}\n\nexport function registerApiProvider<TApi extends Api, TOptions extends StreamOptions>(\n\tprovider: ApiProvider<TApi, TOptions>,\n\tsourceId?: string,\n): void {\n\tapiProviderRegistry.set(provider.api, {\n\t\tprovider: {\n\t\t\tapi: provider.api,\n\t\t\tstream: wrapStream(provider.api, provider.stream),\n\t\t\tstreamSimple: wrapStreamSimple(provider.api, provider.streamSimple),\n\t\t},\n\t\tsourceId,\n\t});\n}\n\nexport function getApiProvider(api: Api): ApiProviderInternal | undefined {\n\treturn apiProviderRegistry.get(api)?.provider;\n}\n\nexport function getApiProviders(): ApiProviderInternal[] {\n\treturn Array.from(apiProviderRegistry.values(), (entry) => entry.provider);\n}\n\nexport function unregisterApiProviders(sourceId: string): void {\n\tfor (const [api, entry] of apiProviderRegistry.entries()) {\n\t\tif (entry.sourceId === sourceId) {\n\t\t\tapiProviderRegistry.delete(api);\n\t\t}\n\t}\n}\n\nexport function clearApiProviders(): void {\n\tapiProviderRegistry.clear();\n}\n"]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const apiProviderRegistry = new Map();
|
|
2
|
+
function wrapStream(api, stream) {
|
|
3
|
+
return (model, context, options) => {
|
|
4
|
+
if (model.api !== api) {
|
|
5
|
+
throw new Error(`Mismatched api: ${model.api} expected ${api}`);
|
|
6
|
+
}
|
|
7
|
+
return stream(model, context, options);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function wrapStreamSimple(api, streamSimple) {
|
|
11
|
+
return (model, context, options) => {
|
|
12
|
+
if (model.api !== api) {
|
|
13
|
+
throw new Error(`Mismatched api: ${model.api} expected ${api}`);
|
|
14
|
+
}
|
|
15
|
+
return streamSimple(model, context, options);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export function registerApiProvider(provider, sourceId) {
|
|
19
|
+
apiProviderRegistry.set(provider.api, {
|
|
20
|
+
provider: {
|
|
21
|
+
api: provider.api,
|
|
22
|
+
stream: wrapStream(provider.api, provider.stream),
|
|
23
|
+
streamSimple: wrapStreamSimple(provider.api, provider.streamSimple),
|
|
24
|
+
},
|
|
25
|
+
sourceId,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function getApiProvider(api) {
|
|
29
|
+
return apiProviderRegistry.get(api)?.provider;
|
|
30
|
+
}
|
|
31
|
+
export function getApiProviders() {
|
|
32
|
+
return Array.from(apiProviderRegistry.values(), (entry) => entry.provider);
|
|
33
|
+
}
|
|
34
|
+
export function unregisterApiProviders(sourceId) {
|
|
35
|
+
for (const [api, entry] of apiProviderRegistry.entries()) {
|
|
36
|
+
if (entry.sourceId === sourceId) {
|
|
37
|
+
apiProviderRegistry.delete(api);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function clearApiProviders() {
|
|
42
|
+
apiProviderRegistry.clear();
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=api-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-registry.js","sourceRoot":"","sources":["../src/api-registry.ts"],"names":[],"mappings":"AAuCA,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAiC,CAAC;AAErE,SAAS,UAAU,CAClB,GAAS,EACT,MAAsC,EAClB;IACpB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,GAAG,aAAa,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,MAAM,CAAC,KAAoB,EAAE,OAAO,EAAE,OAAmB,CAAC,CAAC;IAAA,CAClE,CAAC;AAAA,CACF;AAED,SAAS,gBAAgB,CACxB,GAAS,EACT,YAAuD,EAC7B;IAC1B,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,mBAAmB,KAAK,CAAC,GAAG,aAAa,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;QACD,OAAO,YAAY,CAAC,KAAoB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAAA,CAC5D,CAAC;AAAA,CACF;AAED,MAAM,UAAU,mBAAmB,CAClC,QAAqC,EACrC,QAAiB,EACV;IACP,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,EAAE;QACrC,QAAQ,EAAE;YACT,GAAG,EAAE,QAAQ,CAAC,GAAG;YACjB,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC;YACjD,YAAY,EAAE,gBAAgB,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,YAAY,CAAC;SACnE;QACD,QAAQ;KACR,CAAC,CAAC;AAAA,CACH;AAED,MAAM,UAAU,cAAc,CAAC,GAAQ,EAAmC;IACzE,OAAO,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC;AAAA,CAC9C;AAED,MAAM,UAAU,eAAe,GAA0B;IACxD,OAAO,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAAA,CAC3E;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAgB,EAAQ;IAC9D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,mBAAmB,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1D,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,mBAAmB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;AAAA,CACD;AAED,MAAM,UAAU,iBAAiB,GAAS;IACzC,mBAAmB,CAAC,KAAK,EAAE,CAAC;AAAA,CAC5B","sourcesContent":["import type {\n\tApi,\n\tAssistantMessageEventStream,\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n\tStreamOptions,\n} from \"./types.js\";\n\nexport type ApiStreamFunction = (\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: StreamOptions,\n) => AssistantMessageEventStream;\n\nexport type ApiStreamSimpleFunction = (\n\tmodel: Model<Api>,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n) => AssistantMessageEventStream;\n\nexport interface ApiProvider<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> {\n\tapi: TApi;\n\tstream: StreamFunction<TApi, TOptions>;\n\tstreamSimple: StreamFunction<TApi, SimpleStreamOptions>;\n}\n\ninterface ApiProviderInternal {\n\tapi: Api;\n\tstream: ApiStreamFunction;\n\tstreamSimple: ApiStreamSimpleFunction;\n}\n\ntype RegisteredApiProvider = {\n\tprovider: ApiProviderInternal;\n\tsourceId?: string;\n};\n\nconst apiProviderRegistry = new Map<string, RegisteredApiProvider>();\n\nfunction wrapStream<TApi extends Api, TOptions extends StreamOptions>(\n\tapi: TApi,\n\tstream: StreamFunction<TApi, TOptions>,\n): ApiStreamFunction {\n\treturn (model, context, options) => {\n\t\tif (model.api !== api) {\n\t\t\tthrow new Error(`Mismatched api: ${model.api} expected ${api}`);\n\t\t}\n\t\treturn stream(model as Model<TApi>, context, options as TOptions);\n\t};\n}\n\nfunction wrapStreamSimple<TApi extends Api>(\n\tapi: TApi,\n\tstreamSimple: StreamFunction<TApi, SimpleStreamOptions>,\n): ApiStreamSimpleFunction {\n\treturn (model, context, options) => {\n\t\tif (model.api !== api) {\n\t\t\tthrow new Error(`Mismatched api: ${model.api} expected ${api}`);\n\t\t}\n\t\treturn streamSimple(model as Model<TApi>, context, options);\n\t};\n}\n\nexport function registerApiProvider<TApi extends Api, TOptions extends StreamOptions>(\n\tprovider: ApiProvider<TApi, TOptions>,\n\tsourceId?: string,\n): void {\n\tapiProviderRegistry.set(provider.api, {\n\t\tprovider: {\n\t\t\tapi: provider.api,\n\t\t\tstream: wrapStream(provider.api, provider.stream),\n\t\t\tstreamSimple: wrapStreamSimple(provider.api, provider.streamSimple),\n\t\t},\n\t\tsourceId,\n\t});\n}\n\nexport function getApiProvider(api: Api): ApiProviderInternal | undefined {\n\treturn apiProviderRegistry.get(api)?.provider;\n}\n\nexport function getApiProviders(): ApiProviderInternal[] {\n\treturn Array.from(apiProviderRegistry.values(), (entry) => entry.provider);\n}\n\nexport function unregisterApiProviders(sourceId: string): void {\n\tfor (const [api, entry] of apiProviderRegistry.entries()) {\n\t\tif (entry.sourceId === sourceId) {\n\t\t\tapiProviderRegistry.delete(api);\n\t\t}\n\t}\n}\n\nexport function clearApiProviders(): void {\n\tapiProviderRegistry.clear();\n}\n"]}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env bun\n\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { createInterface } from \"readline\";\nimport { getOAuthProvider, getOAuthProviders } from \"./utils/oauth/index.js\";\nimport type { OAuthCredentials, OAuthProviderId } from \"./utils/oauth/types.js\";\n\nconst AUTH_FILE = \"auth.json\";\nconst PROVIDERS = getOAuthProviders();\n\nfunction prompt(rl: ReturnType<typeof createInterface>, question: string): Promise<string> {\n\treturn new Promise((resolve) => rl.question(question, resolve));\n}\n\nfunction loadAuth(): Record<string, { type: \"oauth\" } & OAuthCredentials> {\n\tif (!existsSync(AUTH_FILE)) return {};\n\ttry {\n\t\treturn JSON.parse(readFileSync(AUTH_FILE, \"utf-8\"));\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction saveAuth(auth: Record<string, { type: \"oauth\" } & OAuthCredentials>): void {\n\twriteFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), \"utf-8\");\n}\n\nasync function login(providerId: OAuthProviderId): Promise<void> {\n\tconst provider = getOAuthProvider(providerId);\n\tif (!provider) {\n\t\tconsole.error(`Unknown provider: ${providerId}`);\n\t\tprocess.exit(1);\n\t}\n\n\tconst rl = createInterface({ input: process.stdin, output: process.stdout });\n\tconst promptFn = (msg: string) => prompt(rl, `${msg} `);\n\n\ttry {\n\t\tconst credentials = await provider.login({\n\t\t\tonAuth: (info) => {\n\t\t\t\tconsole.log(`\\nOpen this URL in your browser:\\n${info.url}`);\n\t\t\t\tif (info.instructions) console.log(info.instructions);\n\t\t\t\tconsole.log();\n\t\t\t},\n\t\t\tonPrompt: async (p) => {\n\t\t\t\treturn await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : \"\"}:`);\n\t\t\t},\n\t\t\tonProgress: (msg) => console.log(msg),\n\t\t});\n\n\t\tconst auth = loadAuth();\n\t\tauth[providerId] = { type: \"oauth\", ...credentials };\n\t\tsaveAuth(auth);\n\n\t\tconsole.log(`\\nCredentials saved to ${AUTH_FILE}`);\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function main(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\tconst command = args[0];\n\n\tif (!command || command === \"help\" || command === \"--help\" || command === \"-h\") {\n\t\tconst providerList = PROVIDERS.map((p) => ` ${p.id.padEnd(20)} ${p.name}`).join(\"\\n\");\n\t\tconsole.log(`Usage: bunx @lenylvt/pi-ai <command> [provider]\n\nCommands:\n login [provider] Login to an OAuth provider\n list List available providers\n\nProviders:\n${providerList}\n\nExamples:\n bunx @lenylvt/pi-ai login # interactive provider selection\n bunx @lenylvt/pi-ai login anthropic # login to specific provider\n bunx @lenylvt/pi-ai list # list providers\n`);\n\t\treturn;\n\t}\n\n\tif (command === \"list\") {\n\t\tconsole.log(\"Available OAuth providers:\\n\");\n\t\tfor (const p of PROVIDERS) {\n\t\t\tconsole.log(` ${p.id.padEnd(20)} ${p.name}`);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (command === \"login\") {\n\t\tlet provider = args[1] as OAuthProviderId | undefined;\n\n\t\tif (!provider) {\n\t\t\tconst rl = createInterface({\n\t\t\t\tinput: process.stdin,\n\t\t\t\toutput: process.stdout,\n\t\t\t});\n\t\t\tconsole.log(\"Select a provider:\\n\");\n\t\t\tfor (let i = 0; i < PROVIDERS.length; i++) {\n\t\t\t\tconsole.log(` ${i + 1}. ${PROVIDERS[i].name}`);\n\t\t\t}\n\t\t\tconsole.log();\n\n\t\t\tconst choice = await prompt(rl, `Enter number (1-${PROVIDERS.length}): `);\n\t\t\trl.close();\n\n\t\t\tconst index = parseInt(choice, 10) - 1;\n\t\t\tif (index < 0 || index >= PROVIDERS.length) {\n\t\t\t\tconsole.error(\"Invalid selection\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tprovider = PROVIDERS[index].id;\n\t\t}\n\n\t\tif (!PROVIDERS.some((p) => p.id === provider)) {\n\t\t\tconsole.error(`Unknown provider: ${provider}`);\n\t\t\tconsole.error(`Use 'bunx @lenylvt/pi-ai list' to see available providers`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsole.log(`Logging in to ${provider}...`);\n\t\tawait login(provider);\n\t\treturn;\n\t}\n\n\tconsole.error(`Unknown command: ${command}`);\n\tconsole.error(`Use 'bunx @lenylvt/pi-ai --help' for usage`);\n\tprocess.exit(1);\n}\n\nmain().catch((err) => {\n\tconsole.error(\"Error:\", err.message);\n\tprocess.exit(1);\n});\n"]}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
3
|
+
import { createInterface } from "readline";
|
|
4
|
+
import { getOAuthProvider, getOAuthProviders } from "./utils/oauth/index.js";
|
|
5
|
+
const AUTH_FILE = "auth.json";
|
|
6
|
+
const PROVIDERS = getOAuthProviders();
|
|
7
|
+
function prompt(rl, question) {
|
|
8
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
9
|
+
}
|
|
10
|
+
function loadAuth() {
|
|
11
|
+
if (!existsSync(AUTH_FILE))
|
|
12
|
+
return {};
|
|
13
|
+
try {
|
|
14
|
+
return JSON.parse(readFileSync(AUTH_FILE, "utf-8"));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function saveAuth(auth) {
|
|
21
|
+
writeFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), "utf-8");
|
|
22
|
+
}
|
|
23
|
+
async function login(providerId) {
|
|
24
|
+
const provider = getOAuthProvider(providerId);
|
|
25
|
+
if (!provider) {
|
|
26
|
+
console.error(`Unknown provider: ${providerId}`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
30
|
+
const promptFn = (msg) => prompt(rl, `${msg} `);
|
|
31
|
+
try {
|
|
32
|
+
const credentials = await provider.login({
|
|
33
|
+
onAuth: (info) => {
|
|
34
|
+
console.log(`\nOpen this URL in your browser:\n${info.url}`);
|
|
35
|
+
if (info.instructions)
|
|
36
|
+
console.log(info.instructions);
|
|
37
|
+
console.log();
|
|
38
|
+
},
|
|
39
|
+
onPrompt: async (p) => {
|
|
40
|
+
return await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : ""}:`);
|
|
41
|
+
},
|
|
42
|
+
onProgress: (msg) => console.log(msg),
|
|
43
|
+
});
|
|
44
|
+
const auth = loadAuth();
|
|
45
|
+
auth[providerId] = { type: "oauth", ...credentials };
|
|
46
|
+
saveAuth(auth);
|
|
47
|
+
console.log(`\nCredentials saved to ${AUTH_FILE}`);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
rl.close();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function main() {
|
|
54
|
+
const args = process.argv.slice(2);
|
|
55
|
+
const command = args[0];
|
|
56
|
+
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
57
|
+
const providerList = PROVIDERS.map((p) => ` ${p.id.padEnd(20)} ${p.name}`).join("\n");
|
|
58
|
+
console.log(`Usage: bunx @lenylvt/pi-ai <command> [provider]
|
|
59
|
+
|
|
60
|
+
Commands:
|
|
61
|
+
login [provider] Login to an OAuth provider
|
|
62
|
+
list List available providers
|
|
63
|
+
|
|
64
|
+
Providers:
|
|
65
|
+
${providerList}
|
|
66
|
+
|
|
67
|
+
Examples:
|
|
68
|
+
bunx @lenylvt/pi-ai login # interactive provider selection
|
|
69
|
+
bunx @lenylvt/pi-ai login anthropic # login to specific provider
|
|
70
|
+
bunx @lenylvt/pi-ai list # list providers
|
|
71
|
+
`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (command === "list") {
|
|
75
|
+
console.log("Available OAuth providers:\n");
|
|
76
|
+
for (const p of PROVIDERS) {
|
|
77
|
+
console.log(` ${p.id.padEnd(20)} ${p.name}`);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (command === "login") {
|
|
82
|
+
let provider = args[1];
|
|
83
|
+
if (!provider) {
|
|
84
|
+
const rl = createInterface({
|
|
85
|
+
input: process.stdin,
|
|
86
|
+
output: process.stdout,
|
|
87
|
+
});
|
|
88
|
+
console.log("Select a provider:\n");
|
|
89
|
+
for (let i = 0; i < PROVIDERS.length; i++) {
|
|
90
|
+
console.log(` ${i + 1}. ${PROVIDERS[i].name}`);
|
|
91
|
+
}
|
|
92
|
+
console.log();
|
|
93
|
+
const choice = await prompt(rl, `Enter number (1-${PROVIDERS.length}): `);
|
|
94
|
+
rl.close();
|
|
95
|
+
const index = parseInt(choice, 10) - 1;
|
|
96
|
+
if (index < 0 || index >= PROVIDERS.length) {
|
|
97
|
+
console.error("Invalid selection");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
provider = PROVIDERS[index].id;
|
|
101
|
+
}
|
|
102
|
+
if (!PROVIDERS.some((p) => p.id === provider)) {
|
|
103
|
+
console.error(`Unknown provider: ${provider}`);
|
|
104
|
+
console.error(`Use 'bunx @lenylvt/pi-ai list' to see available providers`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
console.log(`Logging in to ${provider}...`);
|
|
108
|
+
await login(provider);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
console.error(`Unknown command: ${command}`);
|
|
112
|
+
console.error(`Use 'bunx @lenylvt/pi-ai --help' for usage`);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
main().catch((err) => {
|
|
116
|
+
console.error("Error:", err.message);
|
|
117
|
+
process.exit(1);
|
|
118
|
+
});
|
|
119
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env bun\n\nimport { existsSync, readFileSync, writeFileSync } from \"fs\";\nimport { createInterface } from \"readline\";\nimport { getOAuthProvider, getOAuthProviders } from \"./utils/oauth/index.js\";\nimport type { OAuthCredentials, OAuthProviderId } from \"./utils/oauth/types.js\";\n\nconst AUTH_FILE = \"auth.json\";\nconst PROVIDERS = getOAuthProviders();\n\nfunction prompt(rl: ReturnType<typeof createInterface>, question: string): Promise<string> {\n\treturn new Promise((resolve) => rl.question(question, resolve));\n}\n\nfunction loadAuth(): Record<string, { type: \"oauth\" } & OAuthCredentials> {\n\tif (!existsSync(AUTH_FILE)) return {};\n\ttry {\n\t\treturn JSON.parse(readFileSync(AUTH_FILE, \"utf-8\"));\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nfunction saveAuth(auth: Record<string, { type: \"oauth\" } & OAuthCredentials>): void {\n\twriteFileSync(AUTH_FILE, JSON.stringify(auth, null, 2), \"utf-8\");\n}\n\nasync function login(providerId: OAuthProviderId): Promise<void> {\n\tconst provider = getOAuthProvider(providerId);\n\tif (!provider) {\n\t\tconsole.error(`Unknown provider: ${providerId}`);\n\t\tprocess.exit(1);\n\t}\n\n\tconst rl = createInterface({ input: process.stdin, output: process.stdout });\n\tconst promptFn = (msg: string) => prompt(rl, `${msg} `);\n\n\ttry {\n\t\tconst credentials = await provider.login({\n\t\t\tonAuth: (info) => {\n\t\t\t\tconsole.log(`\\nOpen this URL in your browser:\\n${info.url}`);\n\t\t\t\tif (info.instructions) console.log(info.instructions);\n\t\t\t\tconsole.log();\n\t\t\t},\n\t\t\tonPrompt: async (p) => {\n\t\t\t\treturn await promptFn(`${p.message}${p.placeholder ? ` (${p.placeholder})` : \"\"}:`);\n\t\t\t},\n\t\t\tonProgress: (msg) => console.log(msg),\n\t\t});\n\n\t\tconst auth = loadAuth();\n\t\tauth[providerId] = { type: \"oauth\", ...credentials };\n\t\tsaveAuth(auth);\n\n\t\tconsole.log(`\\nCredentials saved to ${AUTH_FILE}`);\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function main(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\tconst command = args[0];\n\n\tif (!command || command === \"help\" || command === \"--help\" || command === \"-h\") {\n\t\tconst providerList = PROVIDERS.map((p) => ` ${p.id.padEnd(20)} ${p.name}`).join(\"\\n\");\n\t\tconsole.log(`Usage: bunx @lenylvt/pi-ai <command> [provider]\n\nCommands:\n login [provider] Login to an OAuth provider\n list List available providers\n\nProviders:\n${providerList}\n\nExamples:\n bunx @lenylvt/pi-ai login # interactive provider selection\n bunx @lenylvt/pi-ai login anthropic # login to specific provider\n bunx @lenylvt/pi-ai list # list providers\n`);\n\t\treturn;\n\t}\n\n\tif (command === \"list\") {\n\t\tconsole.log(\"Available OAuth providers:\\n\");\n\t\tfor (const p of PROVIDERS) {\n\t\t\tconsole.log(` ${p.id.padEnd(20)} ${p.name}`);\n\t\t}\n\t\treturn;\n\t}\n\n\tif (command === \"login\") {\n\t\tlet provider = args[1] as OAuthProviderId | undefined;\n\n\t\tif (!provider) {\n\t\t\tconst rl = createInterface({\n\t\t\t\tinput: process.stdin,\n\t\t\t\toutput: process.stdout,\n\t\t\t});\n\t\t\tconsole.log(\"Select a provider:\\n\");\n\t\t\tfor (let i = 0; i < PROVIDERS.length; i++) {\n\t\t\t\tconsole.log(` ${i + 1}. ${PROVIDERS[i].name}`);\n\t\t\t}\n\t\t\tconsole.log();\n\n\t\t\tconst choice = await prompt(rl, `Enter number (1-${PROVIDERS.length}): `);\n\t\t\trl.close();\n\n\t\t\tconst index = parseInt(choice, 10) - 1;\n\t\t\tif (index < 0 || index >= PROVIDERS.length) {\n\t\t\t\tconsole.error(\"Invalid selection\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\t\t\tprovider = PROVIDERS[index].id;\n\t\t}\n\n\t\tif (!PROVIDERS.some((p) => p.id === provider)) {\n\t\t\tconsole.error(`Unknown provider: ${provider}`);\n\t\t\tconsole.error(`Use 'bunx @lenylvt/pi-ai list' to see available providers`);\n\t\t\tprocess.exit(1);\n\t\t}\n\n\t\tconsole.log(`Logging in to ${provider}...`);\n\t\tawait login(provider);\n\t\treturn;\n\t}\n\n\tconsole.error(`Unknown command: ${command}`);\n\tconsole.error(`Use 'bunx @lenylvt/pi-ai --help' for usage`);\n\tprocess.exit(1);\n}\n\nmain().catch((err) => {\n\tconsole.error(\"Error:\", err.message);\n\tprocess.exit(1);\n});\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { KnownProvider } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Get API key for a supported built-in provider from environment variables.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getEnvApiKey(provider: KnownProvider): string | undefined;
|
|
6
|
+
export declare function getEnvApiKey(provider: string): string | undefined;
|
|
7
|
+
//# sourceMappingURL=env-api-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-api-keys.d.ts","sourceRoot":"","sources":["../src/env-api-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAC1E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC","sourcesContent":["import type { KnownProvider } from \"./types.js\";\n\n/**\n * Get API key for a supported built-in provider from environment variables.\n */\nexport function getEnvApiKey(provider: KnownProvider): string | undefined;\nexport function getEnvApiKey(provider: string): string | undefined;\nexport function getEnvApiKey(provider: string): string | undefined {\n\tif (provider === \"anthropic\") {\n\t\treturn process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;\n\t}\n\n\tif (provider === \"github-copilot\") {\n\t\treturn process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;\n\t}\n\n\tif (provider === \"openrouter\") {\n\t\treturn process.env.OPENROUTER_API_KEY;\n\t}\n\n\treturn undefined;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function getEnvApiKey(provider) {
|
|
2
|
+
if (provider === "anthropic") {
|
|
3
|
+
return process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;
|
|
4
|
+
}
|
|
5
|
+
if (provider === "github-copilot") {
|
|
6
|
+
return process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
|
|
7
|
+
}
|
|
8
|
+
if (provider === "openrouter") {
|
|
9
|
+
return process.env.OPENROUTER_API_KEY;
|
|
10
|
+
}
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=env-api-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-api-keys.js","sourceRoot":"","sources":["../src/env-api-keys.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAsB;IAClE,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC3E,CAAC;IAED,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC7F,CAAC;IAED,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;IACvC,CAAC;IAED,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["import type { KnownProvider } from \"./types.js\";\n\n/**\n * Get API key for a supported built-in provider from environment variables.\n */\nexport function getEnvApiKey(provider: KnownProvider): string | undefined;\nexport function getEnvApiKey(provider: string): string | undefined;\nexport function getEnvApiKey(provider: string): string | undefined {\n\tif (provider === \"anthropic\") {\n\t\treturn process.env.ANTHROPIC_OAUTH_TOKEN || process.env.ANTHROPIC_API_KEY;\n\t}\n\n\tif (provider === \"github-copilot\") {\n\t\treturn process.env.COPILOT_GITHUB_TOKEN || process.env.GH_TOKEN || process.env.GITHUB_TOKEN;\n\t}\n\n\tif (provider === \"openrouter\") {\n\t\treturn process.env.OPENROUTER_API_KEY;\n\t}\n\n\treturn undefined;\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type { Static, TSchema } from "@sinclair/typebox";
|
|
2
|
+
export { Type } from "@sinclair/typebox";
|
|
3
|
+
export * from "./api-registry.js";
|
|
4
|
+
export * from "./env-api-keys.js";
|
|
5
|
+
export * from "./models.js";
|
|
6
|
+
export type { AnthropicOptions } from "./providers/anthropic.js";
|
|
7
|
+
export * from "./providers/faux.js";
|
|
8
|
+
export type { OpenAICodexResponsesOptions } from "./providers/openai-codex-responses.js";
|
|
9
|
+
export type { OpenAICompletionsOptions } from "./providers/openai-completions.js";
|
|
10
|
+
export type { OpenAIResponsesOptions } from "./providers/openai-responses.js";
|
|
11
|
+
export * from "./providers/register-builtins.js";
|
|
12
|
+
export * from "./stream.js";
|
|
13
|
+
export * from "./types.js";
|
|
14
|
+
export * from "./utils/event-stream.js";
|
|
15
|
+
export * from "./utils/json-parse.js";
|
|
16
|
+
export type { OAuthAuthInfo, OAuthCredentials, OAuthLoginCallbacks, OAuthPrompt, OAuthProvider, OAuthProviderId, OAuthProviderInfo, OAuthProviderInterface, } from "./utils/oauth/types.js";
|
|
17
|
+
export * from "./utils/overflow.js";
|
|
18
|
+
export * from "./utils/typebox-helpers.js";
|
|
19
|
+
export * from "./utils/validation.js";
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AACjE,cAAc,qBAAqB,CAAC;AACpC,YAAY,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AACzF,YAAY,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAClF,YAAY,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAC9E,cAAc,kCAAkC,CAAC;AACjD,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,YAAY,EACX,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,sBAAsB,GACtB,MAAM,wBAAwB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC","sourcesContent":["export type { Static, TSchema } from \"@sinclair/typebox\";\nexport { Type } from \"@sinclair/typebox\";\n\nexport * from \"./api-registry.js\";\nexport * from \"./env-api-keys.js\";\nexport * from \"./models.js\";\nexport type { AnthropicOptions } from \"./providers/anthropic.js\";\nexport * from \"./providers/faux.js\";\nexport type { OpenAICodexResponsesOptions } from \"./providers/openai-codex-responses.js\";\nexport type { OpenAICompletionsOptions } from \"./providers/openai-completions.js\";\nexport type { OpenAIResponsesOptions } from \"./providers/openai-responses.js\";\nexport * from \"./providers/register-builtins.js\";\nexport * from \"./stream.js\";\nexport * from \"./types.js\";\nexport * from \"./utils/event-stream.js\";\nexport * from \"./utils/json-parse.js\";\nexport type {\n\tOAuthAuthInfo,\n\tOAuthCredentials,\n\tOAuthLoginCallbacks,\n\tOAuthPrompt,\n\tOAuthProvider,\n\tOAuthProviderId,\n\tOAuthProviderInfo,\n\tOAuthProviderInterface,\n} from \"./utils/oauth/types.js\";\nexport * from \"./utils/overflow.js\";\nexport * from \"./utils/typebox-helpers.js\";\nexport * from \"./utils/validation.js\";\n"]}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { Type } from "@sinclair/typebox";
|
|
2
|
+
export * from "./api-registry.js";
|
|
3
|
+
export * from "./env-api-keys.js";
|
|
4
|
+
export * from "./models.js";
|
|
5
|
+
export * from "./providers/faux.js";
|
|
6
|
+
export * from "./providers/register-builtins.js";
|
|
7
|
+
export * from "./stream.js";
|
|
8
|
+
export * from "./types.js";
|
|
9
|
+
export * from "./utils/event-stream.js";
|
|
10
|
+
export * from "./utils/json-parse.js";
|
|
11
|
+
export * from "./utils/overflow.js";
|
|
12
|
+
export * from "./utils/typebox-helpers.js";
|
|
13
|
+
export * from "./utils/validation.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAE5B,cAAc,qBAAqB,CAAC;AAIpC,cAAc,kCAAkC,CAAC;AACjD,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AAWtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC","sourcesContent":["export type { Static, TSchema } from \"@sinclair/typebox\";\nexport { Type } from \"@sinclair/typebox\";\n\nexport * from \"./api-registry.js\";\nexport * from \"./env-api-keys.js\";\nexport * from \"./models.js\";\nexport type { AnthropicOptions } from \"./providers/anthropic.js\";\nexport * from \"./providers/faux.js\";\nexport type { OpenAICodexResponsesOptions } from \"./providers/openai-codex-responses.js\";\nexport type { OpenAICompletionsOptions } from \"./providers/openai-completions.js\";\nexport type { OpenAIResponsesOptions } from \"./providers/openai-responses.js\";\nexport * from \"./providers/register-builtins.js\";\nexport * from \"./stream.js\";\nexport * from \"./types.js\";\nexport * from \"./utils/event-stream.js\";\nexport * from \"./utils/json-parse.js\";\nexport type {\n\tOAuthAuthInfo,\n\tOAuthCredentials,\n\tOAuthLoginCallbacks,\n\tOAuthPrompt,\n\tOAuthProvider,\n\tOAuthProviderId,\n\tOAuthProviderInfo,\n\tOAuthProviderInterface,\n} from \"./utils/oauth/types.js\";\nexport * from \"./utils/overflow.js\";\nexport * from \"./utils/typebox-helpers.js\";\nexport * from \"./utils/validation.js\";\n"]}
|
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MODELS } from "./models.generated.js";
|
|
2
|
+
import { type Api, type KnownProvider, type Model, type Usage } from "./types.js";
|
|
3
|
+
type ModelApi<TProvider extends KnownProvider, TModelId extends keyof (typeof MODELS)[TProvider]> = (typeof MODELS)[TProvider][TModelId] extends {
|
|
4
|
+
api: infer TApi;
|
|
5
|
+
} ? (TApi extends Api ? TApi : never) : never;
|
|
6
|
+
export declare function getModel<TProvider extends KnownProvider, TModelId extends keyof (typeof MODELS)[TProvider]>(provider: TProvider, modelId: TModelId): Model<ModelApi<TProvider, TModelId>>;
|
|
7
|
+
export declare function getProviders(): KnownProvider[];
|
|
8
|
+
export declare function getModels<TProvider extends KnownProvider>(provider: TProvider): Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[];
|
|
9
|
+
export declare function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): Usage["cost"];
|
|
10
|
+
/**
|
|
11
|
+
* Check if a model supports xhigh thinking level.
|
|
12
|
+
*
|
|
13
|
+
* Supported today:
|
|
14
|
+
* - GPT-5.2 / GPT-5.3 / GPT-5.4 model families
|
|
15
|
+
* - Opus 4.6 models (xhigh maps to adaptive effort "max" on Anthropic-compatible providers)
|
|
16
|
+
*/
|
|
17
|
+
export declare function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Check if two models are equal by comparing both their id and provider.
|
|
20
|
+
* Returns false if either model is null or undefined.
|
|
21
|
+
*/
|
|
22
|
+
export declare function modelsAreEqual<TApi extends Api>(a: Model<TApi> | null | undefined, b: Model<TApi> | null | undefined): boolean;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,aAAa,EAAE,KAAK,KAAK,EAAuB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAkBvG,KAAK,QAAQ,CACZ,SAAS,SAAS,aAAa,EAC/B,QAAQ,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,IAC9C,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,CAAC,IAAI,SAAS,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;AAEjH,wBAAgB,QAAQ,CAAC,SAAS,SAAS,aAAa,EAAE,QAAQ,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,EAC1G,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,QAAQ,GACf,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAGtC;AAED,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAE9C;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAS,aAAa,EACxD,QAAQ,EAAE,SAAS,GACjB,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAGhE;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAO/F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAU3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS,GAAG,EAC9C,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,EACjC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAGT","sourcesContent":["import { MODELS } from \"./models.generated.js\";\nimport { type Api, type KnownProvider, type Model, SUPPORTED_PROVIDERS, type Usage } from \"./types.js\";\n\nconst modelRegistry: Map<string, Map<string, Model<Api>>> = new Map();\nconst supportedProviders = new Set<string>(SUPPORTED_PROVIDERS);\n\n// Initialize registry from MODELS on module load\nfor (const [provider, models] of Object.entries(MODELS)) {\n\tif (!supportedProviders.has(provider)) {\n\t\tcontinue;\n\t}\n\n\tconst providerModels = new Map<string, Model<Api>>();\n\tfor (const [id, model] of Object.entries(models)) {\n\t\tproviderModels.set(id, model as Model<Api>);\n\t}\n\tmodelRegistry.set(provider, providerModels);\n}\n\ntype ModelApi<\n\tTProvider extends KnownProvider,\n\tTModelId extends keyof (typeof MODELS)[TProvider],\n> = (typeof MODELS)[TProvider][TModelId] extends { api: infer TApi } ? (TApi extends Api ? TApi : never) : never;\n\nexport function getModel<TProvider extends KnownProvider, TModelId extends keyof (typeof MODELS)[TProvider]>(\n\tprovider: TProvider,\n\tmodelId: TModelId,\n): Model<ModelApi<TProvider, TModelId>> {\n\tconst providerModels = modelRegistry.get(provider);\n\treturn providerModels?.get(modelId as string) as Model<ModelApi<TProvider, TModelId>>;\n}\n\nexport function getProviders(): KnownProvider[] {\n\treturn Array.from(modelRegistry.keys()) as KnownProvider[];\n}\n\nexport function getModels<TProvider extends KnownProvider>(\n\tprovider: TProvider,\n): Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[] {\n\tconst models = modelRegistry.get(provider);\n\treturn models ? (Array.from(models.values()) as Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[]) : [];\n}\n\nexport function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): Usage[\"cost\"] {\n\tusage.cost.input = (model.cost.input / 1000000) * usage.input;\n\tusage.cost.output = (model.cost.output / 1000000) * usage.output;\n\tusage.cost.cacheRead = (model.cost.cacheRead / 1000000) * usage.cacheRead;\n\tusage.cost.cacheWrite = (model.cost.cacheWrite / 1000000) * usage.cacheWrite;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n\treturn usage.cost;\n}\n\n/**\n * Check if a model supports xhigh thinking level.\n *\n * Supported today:\n * - GPT-5.2 / GPT-5.3 / GPT-5.4 model families\n * - Opus 4.6 models (xhigh maps to adaptive effort \"max\" on Anthropic-compatible providers)\n */\nexport function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean {\n\tif (model.id.includes(\"gpt-5.2\") || model.id.includes(\"gpt-5.3\") || model.id.includes(\"gpt-5.4\")) {\n\t\treturn true;\n\t}\n\n\tif (model.id.includes(\"opus-4-6\") || model.id.includes(\"opus-4.6\")) {\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if two models are equal by comparing both their id and provider.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual<TApi extends Api>(\n\ta: Model<TApi> | null | undefined,\n\tb: Model<TApi> | null | undefined,\n): boolean {\n\tif (!a || !b) return false;\n\treturn a.id === b.id && a.provider === b.provider;\n}\n"]}
|