GigaChat: respect runtime auth metadata
This commit is contained in:
parent
9134eb7af2
commit
95a75ffe01
@ -467,4 +467,17 @@ describe("getApiKeyForModel", () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it("resolveEnvApiKey('gigachat') ignores password-only basic-auth envs", async () => {
|
||||
await withEnvAsync(
|
||||
{
|
||||
GIGACHAT_CREDENTIALS: undefined,
|
||||
GIGACHAT_PASSWORD: "gigachat-basic-password",
|
||||
},
|
||||
async () => {
|
||||
const resolved = resolveEnvApiKey("gigachat");
|
||||
expect(resolved).toBeUndefined();
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -6,6 +6,7 @@ import {
|
||||
composeSystemPromptWithHookContext,
|
||||
isOllamaCompatProvider,
|
||||
prependSystemPromptAddition,
|
||||
resolveGigachatAuthProfileMetadata,
|
||||
resolveAttemptFsWorkspaceOnly,
|
||||
resolveOllamaCompatNumCtxEnabled,
|
||||
resolvePromptBuildHookResult,
|
||||
@ -106,6 +107,69 @@ describe("resolvePromptBuildHookResult", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveGigachatAuthProfileMetadata", () => {
|
||||
it("prefers the active GigaChat auth profile metadata over the default profile", () => {
|
||||
expect(
|
||||
resolveGigachatAuthProfileMetadata(
|
||||
{
|
||||
profiles: {
|
||||
"gigachat:default": {
|
||||
type: "api_key",
|
||||
provider: "gigachat",
|
||||
metadata: { scope: "GIGACHAT_API_PERS", insecureTls: "false" },
|
||||
},
|
||||
"gigachat:business": {
|
||||
type: "api_key",
|
||||
provider: "gigachat",
|
||||
metadata: { scope: "GIGACHAT_API_B2B", insecureTls: "true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"gigachat:business",
|
||||
),
|
||||
).toEqual({ scope: "GIGACHAT_API_B2B", insecureTls: "true" });
|
||||
});
|
||||
|
||||
it("falls back to the default GigaChat profile metadata when the active profile is absent", () => {
|
||||
expect(
|
||||
resolveGigachatAuthProfileMetadata(
|
||||
{
|
||||
profiles: {
|
||||
"gigachat:default": {
|
||||
type: "api_key",
|
||||
provider: "gigachat",
|
||||
metadata: { scope: "GIGACHAT_API_PERS", insecureTls: "false" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"gigachat:business",
|
||||
),
|
||||
).toEqual({ scope: "GIGACHAT_API_PERS", insecureTls: "false" });
|
||||
});
|
||||
|
||||
it("ignores non-GigaChat active profiles when resolving metadata", () => {
|
||||
expect(
|
||||
resolveGigachatAuthProfileMetadata(
|
||||
{
|
||||
profiles: {
|
||||
"gigachat:default": {
|
||||
type: "api_key",
|
||||
provider: "gigachat",
|
||||
metadata: { scope: "GIGACHAT_API_PERS" },
|
||||
},
|
||||
"openai:p1": {
|
||||
type: "api_key",
|
||||
provider: "openai",
|
||||
metadata: { scope: "not-gigachat" },
|
||||
},
|
||||
},
|
||||
},
|
||||
"openai:p1",
|
||||
),
|
||||
).toEqual({ scope: "GIGACHAT_API_PERS" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("composeSystemPromptWithHookContext", () => {
|
||||
it("returns undefined when no hook system context is provided", () => {
|
||||
expect(composeSystemPromptWithHookContext({ baseSystemPrompt: "base" })).toBeUndefined();
|
||||
|
||||
@ -35,6 +35,7 @@ import { resolveOpenClawAgentDir } from "../../agent-paths.js";
|
||||
import { resolveSessionAgentIds } from "../../agent-scope.js";
|
||||
import { createAnthropicPayloadLogger } from "../../anthropic-payload-log.js";
|
||||
import { ensureAuthProfileStore } from "../../auth-profiles.js";
|
||||
import type { ApiKeyCredential, AuthProfileStore } from "../../auth-profiles.js";
|
||||
import {
|
||||
analyzeBootstrapBudget,
|
||||
buildBootstrapPromptWarning,
|
||||
@ -218,6 +219,25 @@ function createYieldAbortedResponse(model: { api?: string; provider?: string; id
|
||||
};
|
||||
}
|
||||
|
||||
export function resolveGigachatAuthProfileMetadata(
|
||||
store: Pick<AuthProfileStore, "profiles">,
|
||||
authProfileId?: string,
|
||||
): Record<string, string> | undefined {
|
||||
const profileIds = [authProfileId?.trim(), "gigachat:default"].filter(
|
||||
(profileId): profileId is string => Boolean(profileId),
|
||||
);
|
||||
for (const profileId of profileIds) {
|
||||
const credential = store.profiles[profileId];
|
||||
if (
|
||||
credential?.type === "api_key" &&
|
||||
(credential as ApiKeyCredential).provider === "gigachat"
|
||||
) {
|
||||
return credential.metadata;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Queue a hidden steering message so pi-agent-core skips any remaining tool calls.
|
||||
function queueSessionsYieldInterruptMessage(activeSession: {
|
||||
agent: { steer: (message: AgentMessage) => void };
|
||||
@ -1913,8 +1933,10 @@ export async function runEmbeddedAttempt(
|
||||
|
||||
// Read GigaChat-specific config from auth profile credential metadata.
|
||||
const gigachatStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });
|
||||
const gigachatCred = gigachatStore.profiles["gigachat:default"];
|
||||
const gigachatMeta = gigachatCred?.type === "api_key" ? gigachatCred.metadata : undefined;
|
||||
const gigachatMeta = resolveGigachatAuthProfileMetadata(
|
||||
gigachatStore,
|
||||
params.attempt.authProfileId,
|
||||
);
|
||||
|
||||
const gigachatStreamFn = createGigachatStreamFn({
|
||||
baseUrl,
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
PROVIDER_AUTH_ENV_VAR_CANDIDATES,
|
||||
PROVIDER_ENV_VARS,
|
||||
listKnownProviderAuthEnvVarNames,
|
||||
listKnownSecretEnvVarNames,
|
||||
omitEnvKeysCaseInsensitive,
|
||||
@ -42,4 +44,9 @@ describe("provider env vars", () => {
|
||||
expect.arrayContaining(["GIGACHAT_CREDENTIALS", "GIGACHAT_PASSWORD"]),
|
||||
);
|
||||
});
|
||||
|
||||
it("does not treat GigaChat password-only env vars as API-key candidates", () => {
|
||||
expect(PROVIDER_AUTH_ENV_VAR_CANDIDATES.gigachat).toEqual(["GIGACHAT_CREDENTIALS"]);
|
||||
expect(PROVIDER_ENV_VARS.gigachat).toEqual(["GIGACHAT_CREDENTIALS", "GIGACHAT_PASSWORD"]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -15,7 +15,7 @@ const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
|
||||
qianfan: ["QIANFAN_API_KEY"],
|
||||
xai: ["XAI_API_KEY"],
|
||||
mistral: ["MISTRAL_API_KEY"],
|
||||
gigachat: ["GIGACHAT_CREDENTIALS", "GIGACHAT_PASSWORD"],
|
||||
gigachat: ["GIGACHAT_CREDENTIALS"],
|
||||
kilocode: ["KILOCODE_API_KEY"],
|
||||
modelstudio: ["MODELSTUDIO_API_KEY"],
|
||||
volcengine: ["VOLCANO_ENGINE_API_KEY"],
|
||||
@ -25,6 +25,7 @@ const CORE_PROVIDER_AUTH_ENV_VAR_CANDIDATES = {
|
||||
const CORE_PROVIDER_SETUP_ENV_VAR_OVERRIDES = {
|
||||
anthropic: ["ANTHROPIC_API_KEY", "ANTHROPIC_OAUTH_TOKEN"],
|
||||
chutes: ["CHUTES_API_KEY", "CHUTES_OAUTH_TOKEN"],
|
||||
gigachat: ["GIGACHAT_CREDENTIALS", "GIGACHAT_PASSWORD"],
|
||||
"minimax-cn": ["MINIMAX_API_KEY"],
|
||||
} as const;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user