@oh-my-pi/pi-ai 13.6.0 → 13.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-ai",
|
|
4
|
-
"version": "13.6.
|
|
4
|
+
"version": "13.6.1",
|
|
5
5
|
"description": "Unified LLM API with automatic model discovery and provider configuration",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@aws-sdk/client-bedrock-runtime": "^3.1000",
|
|
42
42
|
"@bufbuild/protobuf": "^2.11",
|
|
43
43
|
"@google/genai": "^1.43",
|
|
44
|
-
"@oh-my-pi/pi-utils": "13.6.
|
|
44
|
+
"@oh-my-pi/pi-utils": "13.6.1",
|
|
45
45
|
"@sinclair/typebox": "^0.34",
|
|
46
46
|
"@smithy/node-http-handler": "^4.4",
|
|
47
47
|
"ajv": "^8.18",
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type OpenAICompatibleModelMapperContext,
|
|
8
8
|
type OpenAICompatibleModelRecord,
|
|
9
9
|
} from "../utils/discovery/openai-compatible";
|
|
10
|
+
import { getGitHubCopilotBaseUrl } from "../utils/oauth/github-copilot";
|
|
10
11
|
|
|
11
12
|
const MODELS_DEV_URL = "https://models.dev/api.json";
|
|
12
13
|
const ANTHROPIC_BASE_URL = "https://api.anthropic.com/v1";
|
|
@@ -1286,7 +1287,11 @@ function extractCopilotLimits(entry: OpenAICompatibleModelRecord): {
|
|
|
1286
1287
|
|
|
1287
1288
|
export function githubCopilotModelManagerOptions(config?: GithubCopilotModelManagerConfig): ModelManagerOptions<Api> {
|
|
1288
1289
|
const apiKey = config?.apiKey;
|
|
1289
|
-
const
|
|
1290
|
+
const configuredBaseUrl = config?.baseUrl ?? "https://api.individual.githubcopilot.com";
|
|
1291
|
+
const baseUrl =
|
|
1292
|
+
apiKey?.includes("proxy-ep=") && configuredBaseUrl.includes("githubcopilot.com")
|
|
1293
|
+
? getGitHubCopilotBaseUrl(apiKey)
|
|
1294
|
+
: configuredBaseUrl;
|
|
1290
1295
|
const references = createBundledReferenceMap<Api>("github-copilot");
|
|
1291
1296
|
const globalReferences = createGlobalReferenceMap();
|
|
1292
1297
|
return {
|
|
@@ -32,7 +32,11 @@ import { isAnthropicOAuthToken, normalizeToolCallId, resolveCacheRetention } fro
|
|
|
32
32
|
import { AssistantMessageEventStream } from "../utils/event-stream";
|
|
33
33
|
import { finalizeErrorMessage, type RawHttpRequestDump } from "../utils/http-inspector";
|
|
34
34
|
import { parseStreamingJson } from "../utils/json-parse";
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
buildCopilotDynamicHeaders,
|
|
37
|
+
hasCopilotVisionInput,
|
|
38
|
+
resolveGitHubCopilotBaseUrl,
|
|
39
|
+
} from "./github-copilot-headers";
|
|
36
40
|
import { transformMessages } from "./transform-messages";
|
|
37
41
|
|
|
38
42
|
export type AnthropicHeaderOptions = {
|
|
@@ -396,7 +400,10 @@ function normalizeBaseUrl(baseUrl: string | undefined): string | undefined {
|
|
|
396
400
|
return trimmed ? trimmed.replace(/\/+$/, "") : undefined;
|
|
397
401
|
}
|
|
398
402
|
|
|
399
|
-
function resolveAnthropicBaseUrl(model: Model<"anthropic-messages"
|
|
403
|
+
function resolveAnthropicBaseUrl(model: Model<"anthropic-messages">, apiKey?: string): string | undefined {
|
|
404
|
+
if (model.provider === "github-copilot") {
|
|
405
|
+
return normalizeBaseUrl(resolveGitHubCopilotBaseUrl(model.baseUrl, apiKey) ?? model.baseUrl);
|
|
406
|
+
}
|
|
400
407
|
if (model.provider === "anthropic" && isFoundryEnabled()) {
|
|
401
408
|
const foundryBaseUrl = normalizeBaseUrl($env.FOUNDRY_BASE_URL);
|
|
402
409
|
if (foundryBaseUrl) {
|
|
@@ -583,7 +590,7 @@ export const streamAnthropic: StreamFunction<"anthropic-messages"> = (
|
|
|
583
590
|
|
|
584
591
|
try {
|
|
585
592
|
const apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? "";
|
|
586
|
-
const baseUrl = resolveAnthropicBaseUrl(model) ?? "https://api.anthropic.com";
|
|
593
|
+
const baseUrl = resolveAnthropicBaseUrl(model, apiKey) ?? "https://api.anthropic.com";
|
|
587
594
|
|
|
588
595
|
const { client, isOAuthToken } = createClient(model, {
|
|
589
596
|
model,
|
|
@@ -932,7 +939,7 @@ export function buildAnthropicClientOptions(args: AnthropicClientOptionsArgs): A
|
|
|
932
939
|
isOAuth,
|
|
933
940
|
} = args;
|
|
934
941
|
const oauthToken = isOAuth ?? isAnthropicOAuthToken(apiKey);
|
|
935
|
-
const baseUrl = resolveAnthropicBaseUrl(model);
|
|
942
|
+
const baseUrl = resolveAnthropicBaseUrl(model, apiKey);
|
|
936
943
|
const foundryCustomHeaders = resolveAnthropicCustomHeaders(model);
|
|
937
944
|
const tlsFetchOptions = buildClaudeCodeTlsFetchOptions(model, baseUrl);
|
|
938
945
|
if (model.provider === "github-copilot") {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Message } from "../types";
|
|
2
|
+
import { getGitHubCopilotBaseUrl } from "../utils/oauth/github-copilot";
|
|
2
3
|
/**
|
|
3
4
|
* Infer whether the current request to Copilot is user-initiated or agent-initiated.
|
|
4
5
|
* Accepts `unknown[]` because providers may pass pre-converted message shapes.
|
|
@@ -10,6 +11,14 @@ export type CopilotDynamicHeaders = {
|
|
|
10
11
|
initiator: CopilotInitiator;
|
|
11
12
|
premiumRequests: CopilotPremiumRequests;
|
|
12
13
|
};
|
|
14
|
+
export function resolveGitHubCopilotBaseUrl(
|
|
15
|
+
baseUrl: string | undefined,
|
|
16
|
+
apiKey: string | undefined,
|
|
17
|
+
): string | undefined {
|
|
18
|
+
if (!apiKey?.includes("proxy-ep=")) return baseUrl;
|
|
19
|
+
if (baseUrl && !baseUrl.includes("githubcopilot.com")) return baseUrl;
|
|
20
|
+
return getGitHubCopilotBaseUrl(apiKey);
|
|
21
|
+
}
|
|
13
22
|
export function inferCopilotInitiator(messages: unknown[]): CopilotInitiator {
|
|
14
23
|
if (messages.length === 0) return "user";
|
|
15
24
|
|
|
@@ -33,7 +33,11 @@ import { parseStreamingJson } from "../utils/json-parse";
|
|
|
33
33
|
import { getKimiCommonHeaders } from "../utils/oauth/kimi";
|
|
34
34
|
import { adaptSchemaForStrict, NO_STRICT } from "../utils/schema";
|
|
35
35
|
import { mapToOpenAICompletionsToolChoice } from "../utils/tool-choice";
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
buildCopilotDynamicHeaders,
|
|
38
|
+
hasCopilotVisionInput,
|
|
39
|
+
resolveGitHubCopilotBaseUrl,
|
|
40
|
+
} from "./github-copilot-headers";
|
|
37
41
|
import { transformMessages } from "./transform-messages";
|
|
38
42
|
|
|
39
43
|
/**
|
|
@@ -184,7 +188,12 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
184
188
|
|
|
185
189
|
try {
|
|
186
190
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
187
|
-
const { client, copilotPremiumRequests } = await createClient(
|
|
191
|
+
const { client, copilotPremiumRequests, baseUrl } = await createClient(
|
|
192
|
+
model,
|
|
193
|
+
context,
|
|
194
|
+
apiKey,
|
|
195
|
+
options?.headers,
|
|
196
|
+
);
|
|
188
197
|
const params = buildParams(model, context, options);
|
|
189
198
|
options?.onPayload?.(params);
|
|
190
199
|
rawRequestDump = {
|
|
@@ -192,7 +201,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
|
|
192
201
|
api: output.api,
|
|
193
202
|
model: model.id,
|
|
194
203
|
method: "POST",
|
|
195
|
-
url: `${
|
|
204
|
+
url: `${baseUrl ?? "https://api.openai.com/v1"}/chat/completions`,
|
|
196
205
|
body: params,
|
|
197
206
|
};
|
|
198
207
|
const openaiStream = await client.chat.completions.create(params, { signal: options?.signal });
|
|
@@ -509,6 +518,8 @@ async function createClient(
|
|
|
509
518
|
headers = { ...(await getKimiCommonHeaders()), ...headers };
|
|
510
519
|
}
|
|
511
520
|
let copilotPremiumRequests: number | undefined;
|
|
521
|
+
|
|
522
|
+
let baseUrl = model.baseUrl;
|
|
512
523
|
if (model.provider === "github-copilot") {
|
|
513
524
|
const hasImages = hasCopilotVisionInput(context.messages);
|
|
514
525
|
const copilot = buildCopilotDynamicHeaders({
|
|
@@ -519,17 +530,18 @@ async function createClient(
|
|
|
519
530
|
});
|
|
520
531
|
Object.assign(headers, copilot.headers);
|
|
521
532
|
copilotPremiumRequests = copilot.premiumRequests;
|
|
533
|
+
baseUrl = resolveGitHubCopilotBaseUrl(model.baseUrl, apiKey) ?? model.baseUrl;
|
|
522
534
|
}
|
|
523
|
-
|
|
524
535
|
return {
|
|
525
536
|
client: new OpenAI({
|
|
526
537
|
apiKey,
|
|
527
|
-
baseURL:
|
|
538
|
+
baseURL: baseUrl,
|
|
528
539
|
dangerouslyAllowBrowser: true,
|
|
529
540
|
maxRetries: 5,
|
|
530
541
|
defaultHeaders: headers,
|
|
531
542
|
}),
|
|
532
543
|
copilotPremiumRequests,
|
|
544
|
+
baseUrl,
|
|
533
545
|
};
|
|
534
546
|
}
|
|
535
547
|
|
|
@@ -34,7 +34,11 @@ import { finalizeErrorMessage, type RawHttpRequestDump } from "../utils/http-ins
|
|
|
34
34
|
import { parseStreamingJson } from "../utils/json-parse";
|
|
35
35
|
import { adaptSchemaForStrict, NO_STRICT } from "../utils/schema";
|
|
36
36
|
import { mapToOpenAIResponsesToolChoice } from "../utils/tool-choice";
|
|
37
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
buildCopilotDynamicHeaders,
|
|
39
|
+
hasCopilotVisionInput,
|
|
40
|
+
resolveGitHubCopilotBaseUrl,
|
|
41
|
+
} from "./github-copilot-headers";
|
|
38
42
|
import { transformMessages } from "./transform-messages";
|
|
39
43
|
|
|
40
44
|
/**
|
|
@@ -109,7 +113,7 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses"> = (
|
|
|
109
113
|
try {
|
|
110
114
|
// Create OpenAI client
|
|
111
115
|
const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
|
|
112
|
-
const { client, copilotPremiumRequests } = createClient(model, context, apiKey, options?.headers);
|
|
116
|
+
const { client, copilotPremiumRequests, baseUrl } = createClient(model, context, apiKey, options?.headers);
|
|
113
117
|
const params = buildParams(model, context, options);
|
|
114
118
|
options?.onPayload?.(params);
|
|
115
119
|
rawRequestDump = {
|
|
@@ -117,7 +121,7 @@ export const streamOpenAIResponses: StreamFunction<"openai-responses"> = (
|
|
|
117
121
|
api: output.api,
|
|
118
122
|
model: model.id,
|
|
119
123
|
method: "POST",
|
|
120
|
-
url: `${
|
|
124
|
+
url: `${baseUrl ?? "https://api.openai.com/v1"}/responses`,
|
|
121
125
|
body: params,
|
|
122
126
|
};
|
|
123
127
|
const openaiStream = await client.responses.create(
|
|
@@ -391,6 +395,8 @@ function createClient(
|
|
|
391
395
|
|
|
392
396
|
const headers = { ...(model.headers ?? {}), ...(extraHeaders ?? {}) };
|
|
393
397
|
let copilotPremiumRequests: number | undefined;
|
|
398
|
+
|
|
399
|
+
let baseUrl = model.baseUrl;
|
|
394
400
|
if (model.provider === "github-copilot") {
|
|
395
401
|
const hasImages = hasCopilotVisionInput(context.messages);
|
|
396
402
|
const copilot = buildCopilotDynamicHeaders({
|
|
@@ -401,17 +407,18 @@ function createClient(
|
|
|
401
407
|
});
|
|
402
408
|
Object.assign(headers, copilot.headers);
|
|
403
409
|
copilotPremiumRequests = copilot.premiumRequests;
|
|
410
|
+
baseUrl = resolveGitHubCopilotBaseUrl(model.baseUrl, apiKey) ?? model.baseUrl;
|
|
404
411
|
}
|
|
405
|
-
|
|
406
412
|
return {
|
|
407
413
|
client: new OpenAI({
|
|
408
414
|
apiKey,
|
|
409
|
-
baseURL:
|
|
415
|
+
baseURL: baseUrl,
|
|
410
416
|
dangerouslyAllowBrowser: true,
|
|
411
417
|
maxRetries: 5,
|
|
412
418
|
defaultHeaders: headers,
|
|
413
419
|
}),
|
|
414
420
|
copilotPremiumRequests,
|
|
421
|
+
baseUrl,
|
|
415
422
|
};
|
|
416
423
|
}
|
|
417
424
|
|