feat: 添加获取 OpenCode 可用模型列表的功能,并优化创建客户端的参数
This commit is contained in:
@@ -4,6 +4,50 @@ import { getClient } from './module/client.ts';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { Session } from '@opencode-ai/sdk';
|
import { Session } from '@opencode-ai/sdk';
|
||||||
|
|
||||||
|
app.route({
|
||||||
|
path: 'opencode-cnb',
|
||||||
|
key: 'models',
|
||||||
|
middleware: ['auth-admin'],
|
||||||
|
description: '获取 OpenCode 可用模型列表,返回 providerID 和 modelID',
|
||||||
|
metadata: {
|
||||||
|
args: {
|
||||||
|
baseUrl: z.string().optional().describe('OpenCode 服务地址,默认为 http://localhost:4096'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).define(async (ctx) => {
|
||||||
|
const { baseUrl } = ctx.query;
|
||||||
|
const client = await getClient({ baseUrl });
|
||||||
|
if (!client) {
|
||||||
|
ctx.body = { content: '获取 OpenCode 客户端失败' };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const res = await client.provider.list();
|
||||||
|
const providerData = (res as any)?.data ?? res;
|
||||||
|
const all: any[] = providerData?.all ?? [];
|
||||||
|
const connected: string[] = providerData?.connected ?? [];
|
||||||
|
const defaultModels: Record<string, string> = providerData?.default ?? {};
|
||||||
|
|
||||||
|
const models: Array<{ providerID: string; providerName: string; modelID: string; modelName: string; isDefault: boolean; isConnected: boolean }> = [];
|
||||||
|
for (const provider of all) {
|
||||||
|
const isConnected = connected.includes(provider.id);
|
||||||
|
for (const [modelKey, model] of Object.entries<any>(provider.models ?? {})) {
|
||||||
|
models.push({
|
||||||
|
providerID: provider.id,
|
||||||
|
providerName: provider.name,
|
||||||
|
modelID: modelKey,
|
||||||
|
modelName: model.name ?? modelKey,
|
||||||
|
isDefault: defaultModels[provider.id] === modelKey,
|
||||||
|
isConnected,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.body = {
|
||||||
|
content: `共 ${models.length} 个模型,已连接提供商: ${connected.join(', ') || '无'}`,
|
||||||
|
data: { models, connected, default: defaultModels },
|
||||||
|
};
|
||||||
|
}).addTo(app);
|
||||||
|
|
||||||
app.route({
|
app.route({
|
||||||
path: 'opencode-cnb',
|
path: 'opencode-cnb',
|
||||||
key: 'question',
|
key: 'question',
|
||||||
@@ -14,13 +58,16 @@ app.route({
|
|||||||
question: z.string().describe('问题'),
|
question: z.string().describe('问题'),
|
||||||
baseUrl: z.string().optional().describe('OpenCode 服务地址,默认为 http://localhost:4096'),
|
baseUrl: z.string().optional().describe('OpenCode 服务地址,默认为 http://localhost:4096'),
|
||||||
directory: z.string().optional().describe('运行目录,默认为根目录'),
|
directory: z.string().optional().describe('运行目录,默认为根目录'),
|
||||||
messageID: z.string().optional().describe('消息 ID,选填'),
|
messageId: z.string().optional().describe('消息 ID,选填'),
|
||||||
sessionId: z.string().optional().describe('会话 ID,选填'),
|
sessionId: z.string().optional().describe('会话 ID,选填'),
|
||||||
|
providerId: z.string().optional().describe('指定使用的提供商 ID,默认为空,表示使用默认提供商'),
|
||||||
|
modelId: z.string().optional().describe('指定使用的模型 ID,默认为空,表示使用默认模型'),
|
||||||
parts: z.array(z.any()).optional().describe('消息内容的分块,优先于 question 参数'),
|
parts: z.array(z.any()).optional().describe('消息内容的分块,优先于 question 参数'),
|
||||||
|
awaitAnswer: z.boolean().optional().describe('是否等待回答完成,默认为 false,开启后会在回答完成后返回完整回答内容')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).define(async (ctx) => {
|
}).define(async (ctx) => {
|
||||||
const { question, baseUrl, directory = '/workspace', messageID, sessionId, parts } = ctx.query;
|
const { question, baseUrl, directory = '/workspace', messageId, sessionId, parts, awaitAnswer = false, providerId, modelId } = ctx.query;
|
||||||
const client = await getClient({ baseUrl: baseUrl });
|
const client = await getClient({ baseUrl: baseUrl });
|
||||||
if (!client) {
|
if (!client) {
|
||||||
ctx.body = { content: `OpenCode 客户端获取失败` };
|
ctx.body = { content: `OpenCode 客户端获取失败` };
|
||||||
@@ -53,16 +100,24 @@ app.route({
|
|||||||
session = createSession.data;
|
session = createSession.data;
|
||||||
}
|
}
|
||||||
let _parts: any[] = parts ?? [{ type: "text", text: question }];
|
let _parts: any[] = parts ?? [{ type: "text", text: question }];
|
||||||
const message = await client.session.prompt({
|
let data: any = null;
|
||||||
|
let model = null;
|
||||||
|
if (providerId && modelId) {
|
||||||
|
model = { providerID: providerId, modelID: modelId };
|
||||||
|
}
|
||||||
|
const promptPromise = client.session.prompt({
|
||||||
body: {
|
body: {
|
||||||
messageID: messageID,
|
messageID: messageId,
|
||||||
parts: _parts,
|
parts: _parts,
|
||||||
|
model
|
||||||
},
|
},
|
||||||
path: {
|
path: {
|
||||||
id: sessionId || session.id,
|
id: sessionId || session.id,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const data = message.data;
|
if (awaitAnswer) {
|
||||||
|
const message = await promptPromise;
|
||||||
ctx.body = { content: `已经启动`, data };
|
data = message.data;
|
||||||
|
}
|
||||||
|
ctx.body = { content: awaitAnswer ? `已经完成` : `运行中`, data, sessionId: session.id, messageId: messageId };
|
||||||
}).addTo(app);
|
}).addTo(app);
|
||||||
Reference in New Issue
Block a user