GigaChat: fix basic scope and Telegram picker callbacks
This commit is contained in:
parent
2c4f5203f5
commit
fd971e5b79
@ -1342,8 +1342,14 @@ export const registerTelegramHandlers = ({
|
||||
resolvedThreadId,
|
||||
senderId,
|
||||
});
|
||||
const configuredModelData = buildConfiguredModelsProviderData(cfg, sessionState.agentId);
|
||||
let modelData = configuredModelData;
|
||||
const configuredModelData = buildConfiguredModelsProviderData(
|
||||
runtimeCfg,
|
||||
sessionState.agentId,
|
||||
);
|
||||
let modelData = await telegramDeps.buildModelsProviderData(
|
||||
runtimeCfg,
|
||||
sessionState.agentId,
|
||||
);
|
||||
let { byProvider, providers } = modelData;
|
||||
|
||||
const editMessageWithButtons = async (
|
||||
@ -1434,12 +1440,12 @@ export const registerTelegramHandlers = ({
|
||||
if (modelCallback.type === "select") {
|
||||
let selection = resolveModelSelection({
|
||||
callback: modelCallback,
|
||||
providers,
|
||||
byProvider,
|
||||
providers: configuredModelData.providers,
|
||||
byProvider: configuredModelData.byProvider,
|
||||
});
|
||||
let selectionAllowed =
|
||||
selection.kind === "resolved" &&
|
||||
Boolean(byProvider.get(selection.provider)?.has(selection.model));
|
||||
Boolean(configuredModelData.byProvider.get(selection.provider)?.has(selection.model));
|
||||
|
||||
if (!selectionAllowed || selection.kind !== "resolved") {
|
||||
modelData = await telegramDeps.buildModelsProviderData(
|
||||
|
||||
@ -197,7 +197,31 @@ describe("createTelegramBot", () => {
|
||||
expect(answerCallbackQuerySpy).toHaveBeenCalledWith("cbq-1");
|
||||
});
|
||||
it("reloads callback model routing bindings without recreating the bot", async () => {
|
||||
const buildModelsProviderDataMock =
|
||||
telegramBotDepsForTest.buildModelsProviderData as unknown as ReturnType<typeof vi.fn>;
|
||||
let boundAgentId = "agent-a";
|
||||
buildModelsProviderDataMock.mockImplementation(
|
||||
async (_cfg: OpenClawConfig, agentId?: string) => {
|
||||
if (agentId === "agent-b") {
|
||||
return {
|
||||
byProvider: new Map([
|
||||
["anthropic", new Set(["claude-opus-4-5"])],
|
||||
["openai", new Set(["gpt-4.1"])],
|
||||
]),
|
||||
providers: ["anthropic", "openai"],
|
||||
resolvedDefault: { provider: "anthropic", model: "claude-opus-4-5" },
|
||||
};
|
||||
}
|
||||
return {
|
||||
byProvider: new Map([
|
||||
["gemini", new Set(["gemini-2.5-pro"])],
|
||||
["openai", new Set(["gpt-4.1"])],
|
||||
]),
|
||||
providers: ["gemini", "openai"],
|
||||
resolvedDefault: { provider: "openai", model: "gpt-4.1" },
|
||||
};
|
||||
},
|
||||
);
|
||||
loadConfig.mockImplementation(() => ({
|
||||
agents: {
|
||||
defaults: {
|
||||
@ -238,20 +262,32 @@ describe("createTelegramBot", () => {
|
||||
});
|
||||
};
|
||||
|
||||
buildModelsProviderDataMock.mockClear();
|
||||
editMessageTextSpy.mockClear();
|
||||
await sendModelCallback(1);
|
||||
expect(buildModelsProviderDataMock).toHaveBeenCalled();
|
||||
expect(buildModelsProviderDataMock.mock.calls.at(-1)?.[1]).toBe("agent-a");
|
||||
expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
|
||||
expect(editMessageTextSpy.mock.calls.at(-1)?.[3]).toEqual(
|
||||
expect.objectContaining({
|
||||
reply_markup: {
|
||||
inline_keyboard: [[{ text: "openai (1)", callback_data: "mdl_list_openai_1" }]],
|
||||
},
|
||||
}),
|
||||
expect(
|
||||
editMessageTextSpy.mock.calls.at(-1)?.[3]?.reply_markup?.inline_keyboard?.flat(),
|
||||
).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
text: "gemini (1)",
|
||||
callback_data: "mdl_list_gemini_1",
|
||||
}),
|
||||
expect.objectContaining({
|
||||
text: "openai (1)",
|
||||
callback_data: "mdl_list_openai_1",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
boundAgentId = "agent-b";
|
||||
buildModelsProviderDataMock.mockClear();
|
||||
editMessageTextSpy.mockClear();
|
||||
await sendModelCallback(2);
|
||||
expect(buildModelsProviderDataMock.mock.calls.at(-1)?.[1]).toBe("agent-b");
|
||||
expect(editMessageTextSpy).toHaveBeenCalledTimes(1);
|
||||
expect(
|
||||
editMessageTextSpy.mock.calls.at(-1)?.[3]?.reply_markup?.inline_keyboard?.flat(),
|
||||
|
||||
@ -653,6 +653,37 @@ describe("createGigachatStreamFn tool calling", () => {
|
||||
expect(clientConfigs[0]?.password).toBeUndefined();
|
||||
});
|
||||
|
||||
it("honors explicit basic auth scopes when metadata provides one", async () => {
|
||||
request.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
data: createSseStream(['data: {"choices":[{"delta":{"content":"done"}}]}', "data: [DONE]"]),
|
||||
});
|
||||
|
||||
const streamFn = createGigachatStreamFn({
|
||||
baseUrl: "https://gigachat.ift.sberdevices.ru/v1",
|
||||
authMode: "basic",
|
||||
scope: "GIGACHAT_API_B2B",
|
||||
});
|
||||
|
||||
const stream = await streamFn(
|
||||
{ api: "gigachat", provider: "gigachat", id: "GigaChat-2-Max" } as never,
|
||||
{ messages: [], tools: [] } as never,
|
||||
{ apiKey: "basic-user:basic-password" } as never,
|
||||
);
|
||||
|
||||
await expect(stream.result()).resolves.toMatchObject({
|
||||
content: [{ type: "text", text: "done" }],
|
||||
});
|
||||
|
||||
expect(clientConfigs).toHaveLength(1);
|
||||
expect(clientConfigs[0]).toMatchObject({
|
||||
user: "basic-user",
|
||||
password: "basic-password",
|
||||
scope: "GIGACHAT_API_B2B",
|
||||
});
|
||||
expect(clientConfigs[0]?.credentials).toBeUndefined();
|
||||
});
|
||||
|
||||
it("falls back to the SDK default oauth scope when no metadata scope is available", async () => {
|
||||
request.mockResolvedValueOnce({
|
||||
status: 200,
|
||||
|
||||
@ -544,6 +544,7 @@ export function createGigachatStreamFn(opts: GigachatStreamOptions): StreamFn {
|
||||
profanityCheck: undefined,
|
||||
timeout: 120,
|
||||
};
|
||||
const configuredScope = opts.scope?.trim();
|
||||
|
||||
if (insecureTls) {
|
||||
clientConfig.httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
||||
@ -553,10 +554,14 @@ export function createGigachatStreamFn(opts: GigachatStreamOptions): StreamFn {
|
||||
const { user, password } = parseGigachatBasicCredentials(apiKey);
|
||||
clientConfig.user = user;
|
||||
clientConfig.password = password;
|
||||
log.debug(`GigaChat auth: basic mode`);
|
||||
if (configuredScope) {
|
||||
clientConfig.scope = configuredScope;
|
||||
}
|
||||
log.debug(
|
||||
`GigaChat auth: basic mode${clientConfig.scope ? ` scope=${clientConfig.scope}` : ""}`,
|
||||
);
|
||||
} else {
|
||||
clientConfig.credentials = apiKey;
|
||||
const configuredScope = opts.scope?.trim();
|
||||
if (configuredScope) {
|
||||
clientConfig.scope = configuredScope;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user