Skip to content

Commit 0261e93

Browse files
committed
feat(ai): add multi-provider support for AI models
1 parent 7a7cde4 commit 0261e93

5 files changed

Lines changed: 92 additions & 29 deletions

File tree

.taskmaster/config.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
{
22
"models": {
33
"main": {
4-
"provider": "gemini-cli",
5-
"modelId": "gemini-2.5-pro",
4+
"provider": "openrouter",
5+
"modelId": "qwen/qwen3-coder:free",
66
"maxTokens": 65536,
77
"temperature": 0.2
88
},
99
"research": {
10-
"provider": "gemini-cli",
11-
"modelId": "gemini-2.5-pro",
10+
"provider": "openrouter",
11+
"modelId": "qwen/qwen3-coder:free",
1212
"maxTokens": 65536,
1313
"temperature": 0.1
1414
},
1515
"fallback": {
16-
"provider": "gemini-cli",
17-
"modelId": "gemini-2.5-pro",
16+
"provider": "openrouter",
17+
"modelId": "qwen/qwen3-coder:free",
1818
"maxTokens": 65536,
1919
"temperature": 0.2
2020
}

src/@types/index.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
11
export type T_PackageManager = "npm" | "pnpm" | "bun";
2+
3+
export const VALID_PROVIDERS = [
4+
"openrouter",
5+
"ollama",
6+
"bedrock",
7+
"azure",
8+
"vertex",
9+
] as const;
10+
11+
export type T_Provider = (typeof VALID_PROVIDERS)[number];
12+
13+
export interface I_AIModel {
14+
name: string;
15+
value: string;
16+
provider: T_Provider | null;
17+
}

src/constants/index.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
/* libs */
2+
import chalk from "chalk";
3+
4+
/* types */
5+
import type { I_AIModel } from "@/@types/index";
6+
7+
// ===============================
8+
19
// dev
210
export const DEV_MODE = true;
311

@@ -74,9 +82,22 @@ export const LANG = [
7482
] as const;
7583

7684
// ai models configuration
77-
export const AI_MODELS = [
78-
{ name: "Gemini 2.5 Pro", value: "gemini-2.5-pro" },
79-
{ name: "Gemini 2.5 Flash", value: "gemini-2.5-flash" },
85+
export const AI_MODELS: I_AIModel[] = [
86+
{
87+
name: `Gemini 2.5 Pro ${chalk.gray("(google | free)")}`,
88+
value: "gemini-2.5-pro",
89+
provider: null,
90+
},
91+
{
92+
name: `Gemini 2.5 Flash ${chalk.gray("(google | free)")}`,
93+
value: "gemini-2.5-flash",
94+
provider: null,
95+
},
96+
{
97+
name: `Qwen 3 coder ${chalk.gray("(openrouter | free)")}`,
98+
value: "qwen/qwen3-coder:free",
99+
provider: "openrouter",
100+
},
80101
];
81102

82103
// task conversion rules

src/core/TaskMaster.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -627,11 +627,13 @@ export class TaskMaster {
627627
* @param mainModel The main AI model to use
628628
* @param researchModel The research AI model to use
629629
* @param fallbackModel The fallback AI model to use
630+
* @param provider Optional provider for the models
630631
*/
631632
public async configModelsAsync(
632633
mainModel: string,
633634
researchModel: string,
634635
fallbackModel: string,
636+
provider?: string,
635637
): Promise<void> {
636638
const oraOptions = {
637639
text: "Configuring AI models...",
@@ -640,24 +642,21 @@ export class TaskMaster {
640642
};
641643

642644
await oraPromise(async () => {
643-
await runCommandAsync(
644-
this._mainCommand,
645-
["models", "--set-main", mainModel],
646-
false,
647-
false,
648-
);
649-
await runCommandAsync(
650-
this._mainCommand,
651-
["models", "--set-research", researchModel],
652-
false,
653-
false,
654-
);
655-
await runCommandAsync(
656-
this._mainCommand,
657-
["models", "--set-fallback", fallbackModel],
658-
false,
659-
false,
660-
);
645+
const mainArgs = provider
646+
? ["models", "--set-main", mainModel, `--${provider}`]
647+
: ["models", "--set-main", mainModel];
648+
649+
const researchArgs = provider
650+
? ["models", "--set-research", researchModel, `--${provider}`]
651+
: ["models", "--set-research", researchModel];
652+
653+
const fallbackArgs = provider
654+
? ["models", "--set-fallback", fallbackModel, `--${provider}`]
655+
: ["models", "--set-fallback", fallbackModel];
656+
657+
await runCommandAsync(this._mainCommand, mainArgs, false, false);
658+
await runCommandAsync(this._mainCommand, researchArgs, false, false);
659+
await runCommandAsync(this._mainCommand, fallbackArgs, false, false);
661660
}, oraOptions);
662661
}
663662

src/core/exec.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@ import inquirer from "inquirer";
33
import path from "node:path";
44

55
/* constants */
6-
import { MAIN_COMMAND, TASKS_PATH, TASKS_STATUSES } from "@/constants";
6+
import {
7+
AI_MODELS,
8+
MAIN_COMMAND,
9+
TASKS_PATH,
10+
TASKS_STATUSES,
11+
} from "@/constants";
712

813
/* core */
914
import { TaskMaster } from "@/core/TaskMaster";
@@ -70,7 +75,29 @@ export async function tmaiInitAsync() {
7075
await tmai.interactiveConfigModelAsync();
7176
} else if (choice.tmaiInitMenu === "tmai-config") {
7277
const { mainModel, researchModel, fallbackModel } = await askModelsAsync();
73-
await tmai.configModelsAsync(mainModel, researchModel, fallbackModel);
78+
79+
// Get provider from AI_MODELS configuration
80+
const mainModelObj = AI_MODELS.find((model) => model.value === mainModel);
81+
const researchModelObj = AI_MODELS.find(
82+
(model) => model.value === researchModel,
83+
);
84+
const fallbackModelObj = AI_MODELS.find(
85+
(model) => model.value === fallbackModel,
86+
);
87+
88+
// Use the first provider that is defined and not null
89+
const provider =
90+
mainModelObj?.provider ||
91+
researchModelObj?.provider ||
92+
fallbackModelObj?.provider ||
93+
undefined;
94+
95+
await tmai.configModelsAsync(
96+
mainModel,
97+
researchModel,
98+
fallbackModel,
99+
provider,
100+
);
74101
} else if (choice.tmaiInitMenu === "tmai-lang") {
75102
const lang = await askLangAsync();
76103
await tmai.setLangAsync(lang);

0 commit comments

Comments
 (0)