Skip to content

Commit 6da8390

Browse files
committed
refactor: standardize agent factory access, Gemini provider settings, and pass WorkerContext to agent loaders.
2 parents d7c546e + 131bbf4 commit 6da8390

File tree

11 files changed

+46
-83
lines changed

11 files changed

+46
-83
lines changed
Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
2-
"name": "@chatgpt-telegram-workers/local",
3-
"type": "module",
4-
"version": "1.10.7",
5-
"main": "./dist/index.js",
6-
"types": "./dist/index.d.ts",
7-
"dependencies": {
8-
"cloudflare-worker-adapter": "^1.3.9",
9-
"telegramify-markdown": "^1.3.2"
10-
}
11-
}
2+
"name": "@chatgpt-telegram-workers/local",
3+
"type": "module",
4+
"version": "1.10.7",
5+
"main": "./dist/index.js",
6+
"types": "./dist/index.d.ts",
7+
"dependencies": {
8+
"cloudflare-worker-adapter": "^1.3.9",
9+
"telegramify-markdown": "^1.3.2"
10+
}
11+
}

packages/apps/local/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as fs from 'node:fs';
22
import * as process from 'node:process';
3-
import { CHAT_AGENTS, createRouter, ENV, handleUpdate } from '@chatgpt-telegram-workers/core';
3+
import { CHAT_AGENT_FACTORIES, createRouter, ENV, handleUpdate } from '@chatgpt-telegram-workers/core';
44
import { injectNextChatAgent } from '@chatgpt-telegram-workers/next';
55
import { createCache, defaultRequestBuilder, initEnv, installFetchProxy, startServerV2 } from 'cloudflare-worker-adapter';
66
import convert from 'telegramify-markdown';
@@ -46,7 +46,7 @@ ENV.CUSTOM_MESSAGE_RENDER = (parse_mode, message) => {
4646

4747
// 注入 Next.js Chat Agent
4848
if (NEXT_ENABLE !== '0') {
49-
injectNextChatAgent(CHAT_AGENTS);
49+
injectNextChatAgent(CHAT_AGENT_FACTORIES);
5050
}
5151
if (config.proxy) {
5252
installFetchProxy(config.proxy);

packages/apps/vercel/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { VercelRequest, VercelResponse } from '@vercel/node';
22
import * as process from 'node:process';
3-
import { CHAT_AGENTS, createRouter, ENV } from '@chatgpt-telegram-workers/core';
3+
import { CHAT_AGENT_FACTORIES, createRouter, ENV } from '@chatgpt-telegram-workers/core';
44
import { injectNextChatAgent } from '@chatgpt-telegram-workers/next';
55
import { UpStashRedis } from 'cloudflare-worker-adapter';
66
import convert from 'telegramify-markdown';
@@ -33,7 +33,7 @@ export default async function (request: VercelRequest, response: VercelResponse)
3333
}
3434
return message;
3535
};
36-
injectNextChatAgent(CHAT_AGENTS); // remove this line if you don't use vercel ai sdk
36+
injectNextChatAgent(CHAT_AGENT_FACTORIES); // remove this line if you don't use vercel ai sdk
3737
const router = createRouter();
3838
let body: any | null = null;
3939
if (request.body) {
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { CHAT_AGENTS, Workers } from '@chatgpt-telegram-workers/core';
1+
import { CHAT_AGENT_FACTORIES, Workers } from '@chatgpt-telegram-workers/core';
22
import { injectNextChatAgent } from '@chatgpt-telegram-workers/next';
33

4-
injectNextChatAgent(CHAT_AGENTS);
4+
injectNextChatAgent(CHAT_AGENT_FACTORIES);
55
export default Workers;

packages/lib/core/src/agent/agent.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,7 @@ function loadAgentFromFactories<AgentType>(
3030
return null;
3131
}
3232

33-
export const CHAT_AGENT_FACTORIES: ChatAgentFactory[] = CHAT_PROVIDER_FACTORIES.map((factory) => {
34-
return {
35-
name: factory.name,
36-
create: (context: AgentUserConfig): ChatAgent | null => {
37-
return factory.create(context);
38-
},
39-
};
40-
});
41-
export const CHAT_AGENTS = CHAT_AGENT_FACTORIES;
33+
export const CHAT_AGENT_FACTORIES: ChatAgentFactory[] = CHAT_PROVIDER_FACTORIES;
4234

4335
const CHAT_PROVIDER_MODEL_KEYS = new Map<string, string>(
4436
CHAT_PROVIDER_FACTORIES.map(factory => [factory.name, factory.modelKey]),
@@ -56,15 +48,7 @@ export function loadChatLLM(context: AgentUserConfig): ChatAgent | null {
5648
return loadAgentFromFactories(CHAT_AGENT_FACTORIES, context.AI_PROVIDER, context);
5749
}
5850

59-
export const IMAGE_AGENT_FACTORIES: ImageAgentFactory[] = IMAGE_PROVIDER_FACTORIES.map((factory) => {
60-
return {
61-
name: factory.name,
62-
create: (context: AgentUserConfig): ImageAgent | null => {
63-
return factory.create(context);
64-
},
65-
};
66-
});
67-
export const IMAGE_AGENTS = IMAGE_AGENT_FACTORIES;
51+
export const IMAGE_AGENT_FACTORIES: ImageAgentFactory[] = IMAGE_PROVIDER_FACTORIES;
6852

6953
const IMAGE_PROVIDER_MODEL_KEYS = new Map<string, string>(
7054
IMAGE_PROVIDER_FACTORIES.map(factory => [factory.name, factory.modelKey]),

packages/lib/core/src/agent/provider_settings.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { AgentUserConfig } from '#/config';
22
import type { AnthropicSettings } from './providers/anthropic';
33
import type { AzureChatSettings, AzureImageSettings } from './providers/azure';
4-
import type { GeminiSettings } from './providers/gemini';
54
import type { DallESettings, OpenAICompatibleSettings } from './providers/openai';
65
import type { WorkersChatSettings, WorkersImageSettings } from './providers/workers';
76
import { ENV } from '#/config';
@@ -19,7 +18,7 @@ export function isWorkersEnabled(context: AgentUserConfig): boolean {
1918
return !!(context.CLOUDFLARE_ACCOUNT_ID && context.CLOUDFLARE_TOKEN);
2019
}
2120

22-
function randomOpenAIApiKey(keys: string[]): string | null {
21+
export function randomOpenAIApiKey(keys: string[]): string | null {
2322
const length = keys.length;
2423
if (length <= 0) {
2524
return null;
@@ -84,13 +83,13 @@ export function createAnthropicSettings(context: AgentUserConfig): AnthropicSett
8483
};
8584
}
8685

87-
export function createGeminiSettings(context: AgentUserConfig): GeminiSettings {
86+
export function createGeminiSettings(context: AgentUserConfig): OpenAICompatibleSettings {
8887
return {
89-
apiBase: context.GOOGLE_API_BASE,
90-
apiKey: context.GOOGLE_API_KEY,
91-
chatModel: context.GOOGLE_CHAT_MODEL,
92-
chatModelsList: context.GOOGLE_CHAT_MODELS_LIST,
93-
chatExtraParams: context.GOOGLE_CHAT_EXTRA_PARAMS || undefined,
88+
base: context.GOOGLE_API_BASE,
89+
key: context.GOOGLE_API_KEY,
90+
model: context.GOOGLE_CHAT_MODEL,
91+
modelsList: context.GOOGLE_CHAT_MODELS_LIST,
92+
extraParams: context.GOOGLE_CHAT_EXTRA_PARAMS || undefined,
9493
};
9594
}
9695

packages/lib/core/src/agent/providers/gemini/index.ts

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,41 +3,26 @@ import type { OpenAICompatibleSettings } from '#/agent/providers/openai';
33
import { loadModelsList } from '#/agent/core/utils';
44
import { createOpenAIRequest, defaultOpenAIRequestBuilder, ImageSupportFormat } from '#/agent/providers/openai';
55

6-
export interface GeminiSettings {
7-
apiBase: string;
8-
apiKey: string | null;
9-
chatModel: string;
10-
chatModelsList: string;
11-
chatExtraParams?: Record<string, any>;
12-
}
13-
146
export class Gemini implements ChatAgent {
157
readonly name = 'gemini';
168
readonly model: string;
179
readonly modelList: () => Promise<string[]>;
1810
readonly request: ChatAgent['request'];
1911

20-
constructor(private readonly settings: GeminiSettings) {
21-
this.model = settings.chatModel;
12+
constructor(private readonly settings: OpenAICompatibleSettings) {
13+
this.model = settings.model;
2214
this.modelList = async (): Promise<string[]> => {
23-
const modelsList = settings.chatModelsList || `${settings.apiBase}/models`;
15+
const modelsList = settings.modelsList || `${settings.base}/models`;
2416
return loadModelsList(modelsList, async (url): Promise<string[]> => {
25-
const data = await fetch(`${url}?key=${settings.apiKey || ''}`).then(r => r.json());
17+
const data = await fetch(`${url}?key=${settings.key || ''}`).then(r => r.json());
2618
return data?.models
2719
?.filter((model: any) => model.supportedGenerationMethods?.includes('generateContent'))
2820
.map((model: any) => model.name.split('/').pop()) ?? [];
2921
});
3022
};
31-
const openAISettings: OpenAICompatibleSettings = {
32-
base: settings.apiBase,
33-
key: settings.apiKey,
34-
model: settings.chatModel,
35-
modelsList: settings.chatModelsList,
36-
extraParams: settings.chatExtraParams,
37-
};
3823
this.request = createOpenAIRequest(
3924
defaultOpenAIRequestBuilder('/openai/chat/completions', [ImageSupportFormat.BASE64]),
40-
openAISettings,
25+
settings,
4126
);
4227
}
4328
}

packages/lib/core/src/agent/providers/openai/index.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { SseChatCompatibleOptions } from '#/agent/core/request';
2+
import { randomOpenAIApiKey } from '#/agent/provider_settings';
23
import type {
34
ChatAgent,
45
ChatAgentRequest,
@@ -87,10 +88,7 @@ async function renderOpenAIMessage(item: HistoryItem, supportImage?: ImageSuppor
8788
return res;
8889
}
8990

90-
function openAIApiKey(keys: string[]): string {
91-
const length = keys.length;
92-
return keys[Math.floor(Math.random() * length)];
93-
}
91+
9492

9593
export async function renderOpenAIMessages(prompt: string | undefined, items: HistoryItem[], supportImage?: ImageSupportFormat[] | null): Promise<any[]> {
9694
const messages = await Promise.all(items.map(r => renderOpenAIMessage(r, supportImage)));
@@ -190,7 +188,7 @@ export class Dalle implements ImageAgent {
190188
this.modelList = () => loadModelsList(settings.modelsList);
191189
this.request = async (prompt: string): Promise<string | Blob> => {
192190
const url = `${settings.apiBase}/images/generations`;
193-
const header = bearerHeader(openAIApiKey(settings.apiKeys));
191+
const header = bearerHeader(randomOpenAIApiKey(settings.apiKeys) || '');
194192
const body: any = {
195193
prompt,
196194
n: 1,

packages/lib/core/src/telegram/callback_query/system.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,37 @@ import { MessageSender } from '../sender';
1717
export class AgentListCallbackQueryHandler implements CallbackQueryHandler {
1818
prefix: string;
1919
changeAgentPrefix: string;
20-
agentLoader: () => string[];
20+
agentLoader: (context: WorkerContext) => string[];
2121

2222
needAuth = TELEGRAM_AUTH_CHECKER.shareModeGroup;
2323

24-
constructor(prefix: string, changeAgentPrefix: string, agentLoader: () => string[]) {
24+
constructor(prefix: string, changeAgentPrefix: string, agentLoader: (context: WorkerContext) => string[]) {
2525
this.prefix = prefix;
2626
this.changeAgentPrefix = changeAgentPrefix;
2727
this.agentLoader = agentLoader;
2828
this.createKeyboard = this.createKeyboard.bind(this);
2929
}
3030

3131
static Chat(): AgentListCallbackQueryHandler {
32-
return new AgentListCallbackQueryHandler('al:', 'ca:', () => {
32+
return new AgentListCallbackQueryHandler('al:', 'ca:', (context: WorkerContext) => {
3333
return CHAT_AGENT_FACTORIES
34-
.map(factory => factory.create(ENV.USER_CONFIG))
34+
.map(factory => factory.create(context.USER_CONFIG))
3535
.filter(agent => agent !== null)
3636
.map(agent => agent.name);
3737
});
3838
}
3939

4040
static Image(): AgentListCallbackQueryHandler {
41-
return new AgentListCallbackQueryHandler('ial:', 'ica:', () => {
41+
return new AgentListCallbackQueryHandler('ial:', 'ica:', (context: WorkerContext) => {
4242
return IMAGE_AGENT_FACTORIES
43-
.map(factory => factory.create(ENV.USER_CONFIG))
43+
.map(factory => factory.create(context.USER_CONFIG))
4444
.filter(agent => agent !== null)
4545
.map(agent => agent.name);
4646
});
4747
}
4848

4949
handle = async (query: Telegram.CallbackQuery, data: string, context: WorkerContext): Promise<Response> => {
50-
const names = this.agentLoader();
50+
const names = this.agentLoader(context);
5151
const sender = MessageSender.fromCallbackQuery(context.SHARE_CONTEXT.botToken, query);
5252
const params: Telegram.EditMessageTextParams = {
5353
chat_id: query.message?.chat.id || 0,
@@ -115,7 +115,7 @@ function loadAgentContext<T = any>(
115115
if (!agent) {
116116
throw new Error(`agent not found: ${agent}`);
117117
}
118-
const conf: AgentUserConfig = changeAgentType(ENV.USER_CONFIG, agent);
118+
const conf: AgentUserConfig = changeAgentType(context.USER_CONFIG, agent);
119119
const theAgent = agentLoader(conf);
120120
if (!theAgent) {
121121
throw new Error(`agent not found: ${agent}`);

packages/lib/core/src/telegram/command/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,7 @@ export async function handleCommandMessage(message: Telegram.Message, context: W
105105
text = ENV.CUSTOM_COMMAND[text].value;
106106
}
107107

108-
if (ENV.DEV_MODE) {
109-
// 插入调试命令
108+
if (ENV.DEV_MODE && !SYSTEM_COMMANDS.some(c => c.command === '/echo')) {
110109
SYSTEM_COMMANDS.push(new EchoCommandHandler());
111110
}
112111

0 commit comments

Comments
 (0)