@aman_asmuei/aman-agent 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +414 -360
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -952,135 +952,244 @@ function createClaudeCodeClient(model) {
|
|
|
952
952
|
}
|
|
953
953
|
|
|
954
954
|
// src/llm/copilot.ts
|
|
955
|
-
import
|
|
956
|
-
|
|
957
|
-
var GITHUB_MODELS_BASE_URL = "https://models.inference.ai.azure.com";
|
|
958
|
-
function isGhCliInstalled() {
|
|
955
|
+
import { spawn as spawn2, execFileSync as execFileSync2 } from "child_process";
|
|
956
|
+
function isCopilotCliInstalled() {
|
|
959
957
|
try {
|
|
960
|
-
execFileSync2("which", ["
|
|
958
|
+
execFileSync2("which", ["copilot"], { stdio: "ignore" });
|
|
961
959
|
return true;
|
|
962
960
|
} catch {
|
|
963
961
|
return false;
|
|
964
962
|
}
|
|
965
963
|
}
|
|
966
|
-
function
|
|
964
|
+
function isCopilotCliAuthenticated() {
|
|
967
965
|
try {
|
|
968
|
-
const result = execFileSync2("
|
|
969
|
-
stdio: ["ignore", "pipe", "
|
|
966
|
+
const result = execFileSync2("copilot", ["--version"], {
|
|
967
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
970
968
|
timeout: 5e3
|
|
971
969
|
});
|
|
972
|
-
return
|
|
970
|
+
return result.toString().trim().length > 0;
|
|
973
971
|
} catch {
|
|
974
972
|
return false;
|
|
975
973
|
}
|
|
976
974
|
}
|
|
977
|
-
function
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
if (
|
|
984
|
-
|
|
975
|
+
function extractText2(content) {
|
|
976
|
+
if (typeof content === "string") return content;
|
|
977
|
+
return content.map((block) => {
|
|
978
|
+
if (block.type === "text") return block.text;
|
|
979
|
+
if (block.type === "tool_result")
|
|
980
|
+
return `[Tool result for ${block.tool_use_id}]: ${block.content}`;
|
|
981
|
+
if (block.type === "tool_use") return `[Used tool: ${block.name}]`;
|
|
982
|
+
return "";
|
|
983
|
+
}).filter(Boolean).join("\n");
|
|
984
|
+
}
|
|
985
|
+
function formatConversation2(systemPrompt, messages, tools) {
|
|
986
|
+
const parts = [];
|
|
987
|
+
let fullSystem = systemPrompt;
|
|
988
|
+
if (tools && tools.length > 0) {
|
|
989
|
+
fullSystem += "\n\n## Available Tools\n";
|
|
990
|
+
fullSystem += "You have access to the following tools. To use a tool, respond with a JSON block in this exact format:\n";
|
|
991
|
+
fullSystem += '```json\n{"tool_use": {"id": "call_1", "name": "tool_name", "input": {\u2026}}}\n```\n\n';
|
|
992
|
+
for (const tool of tools) {
|
|
993
|
+
fullSystem += `### ${tool.name}
|
|
994
|
+
${tool.description}
|
|
995
|
+
Parameters: ${JSON.stringify(tool.input_schema)}
|
|
996
|
+
|
|
997
|
+
`;
|
|
985
998
|
}
|
|
986
|
-
|
|
987
|
-
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
)
|
|
999
|
+
fullSystem += "You may include multiple tool_use blocks. After each tool use, you will receive the result and can continue.\n";
|
|
1000
|
+
}
|
|
1001
|
+
if (messages.length > 1) {
|
|
1002
|
+
parts.push("<conversation_history>");
|
|
1003
|
+
for (let i = 0; i < messages.length - 1; i++) {
|
|
1004
|
+
const msg = messages[i];
|
|
1005
|
+
const role = msg.role === "user" ? "User" : "Assistant";
|
|
1006
|
+
const text3 = extractText2(msg.content);
|
|
1007
|
+
parts.push(`[${role}]: ${text3}`);
|
|
1008
|
+
}
|
|
1009
|
+
parts.push("</conversation_history>\n");
|
|
991
1010
|
}
|
|
1011
|
+
const lastMsg = messages[messages.length - 1];
|
|
1012
|
+
if (lastMsg) {
|
|
1013
|
+
parts.push(extractText2(lastMsg.content));
|
|
1014
|
+
}
|
|
1015
|
+
return { prompt: parts.join("\n"), systemPrompt: fullSystem };
|
|
1016
|
+
}
|
|
1017
|
+
function parseToolUses2(text3) {
|
|
1018
|
+
const toolUses = [];
|
|
1019
|
+
const codeBlockRegex = /```json\s*\n?([\s\S]*?)```/g;
|
|
1020
|
+
let match;
|
|
1021
|
+
while ((match = codeBlockRegex.exec(text3)) !== null) {
|
|
1022
|
+
try {
|
|
1023
|
+
const parsed = JSON.parse(match[1].trim());
|
|
1024
|
+
if (parsed.tool_use) {
|
|
1025
|
+
toolUses.push({
|
|
1026
|
+
id: parsed.tool_use.id || `call_${toolUses.length + 1}`,
|
|
1027
|
+
name: parsed.tool_use.name,
|
|
1028
|
+
input: parsed.tool_use.input || {}
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
} catch {
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
if (toolUses.length === 0) {
|
|
1035
|
+
const inlineRegex = /\{"tool_use"\s*:\s*\{[^}]*"name"\s*:\s*"[^"]+?"[^}]*\}\s*\}/g;
|
|
1036
|
+
while ((match = inlineRegex.exec(text3)) !== null) {
|
|
1037
|
+
try {
|
|
1038
|
+
const parsed = JSON.parse(match[0]);
|
|
1039
|
+
if (parsed.tool_use) {
|
|
1040
|
+
toolUses.push({
|
|
1041
|
+
id: parsed.tool_use.id || `call_${toolUses.length + 1}`,
|
|
1042
|
+
name: parsed.tool_use.name,
|
|
1043
|
+
input: parsed.tool_use.input || {}
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
} catch {
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
return toolUses;
|
|
992
1051
|
}
|
|
993
1052
|
function createCopilotClient(model) {
|
|
994
1053
|
return {
|
|
995
1054
|
async chat(systemPrompt, messages, onChunk, tools, options) {
|
|
996
|
-
const
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1055
|
+
const { prompt, systemPrompt: fullSystem } = formatConversation2(
|
|
1056
|
+
systemPrompt,
|
|
1057
|
+
messages,
|
|
1058
|
+
tools
|
|
1059
|
+
);
|
|
1060
|
+
return new Promise((resolve, reject) => {
|
|
1061
|
+
const args = [
|
|
1062
|
+
"--print",
|
|
1063
|
+
"--output-format",
|
|
1064
|
+
"json",
|
|
1065
|
+
"--silent",
|
|
1066
|
+
"--no-custom-instructions"
|
|
1067
|
+
];
|
|
1068
|
+
if (model) {
|
|
1069
|
+
args.push("--model", model);
|
|
1070
|
+
}
|
|
1071
|
+
args.push(prompt);
|
|
1072
|
+
const proc = spawn2("copilot", args, {
|
|
1073
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
1074
|
+
env: {
|
|
1075
|
+
...process.env,
|
|
1076
|
+
COPILOT_SYSTEM_PROMPT: fullSystem
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1004
1079
|
let fullText = "";
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1080
|
+
let buffer = "";
|
|
1081
|
+
let stderrOutput = "";
|
|
1082
|
+
proc.stdout.on("data", (data) => {
|
|
1083
|
+
buffer += data.toString();
|
|
1084
|
+
const lines = buffer.split("\n");
|
|
1085
|
+
buffer = lines.pop() || "";
|
|
1086
|
+
for (const line of lines) {
|
|
1087
|
+
if (!line.trim()) continue;
|
|
1088
|
+
try {
|
|
1089
|
+
const event = JSON.parse(line);
|
|
1090
|
+
if (event.type === "assistant" && event.content) {
|
|
1091
|
+
fullText += event.content;
|
|
1092
|
+
onChunk({ type: "text", text: event.content });
|
|
1093
|
+
} else if (event.type === "message" && event.message?.content) {
|
|
1094
|
+
for (const block of event.message.content) {
|
|
1095
|
+
if (block.type === "text" && block.text) {
|
|
1096
|
+
fullText += block.text;
|
|
1097
|
+
onChunk({ type: "text", text: block.text });
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
} else if (event.type === "content_block_delta") {
|
|
1101
|
+
if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
1102
|
+
fullText += event.delta.text;
|
|
1103
|
+
onChunk({ type: "text", text: event.delta.text });
|
|
1104
|
+
}
|
|
1105
|
+
} else if (event.role === "assistant" && event.content) {
|
|
1106
|
+
const text3 = typeof event.content === "string" ? event.content : event.content.map((b) => b.text || "").join("");
|
|
1107
|
+
if (text3) {
|
|
1108
|
+
fullText += text3;
|
|
1109
|
+
onChunk({ type: "text", text: text3 });
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
} catch {
|
|
1113
|
+
if (line.trim()) {
|
|
1114
|
+
fullText += line;
|
|
1115
|
+
onChunk({ type: "text", text: line });
|
|
1116
|
+
}
|
|
1019
1117
|
}
|
|
1020
|
-
}));
|
|
1021
|
-
}
|
|
1022
|
-
const stream = await client.chat.completions.create(
|
|
1023
|
-
createParams
|
|
1024
|
-
);
|
|
1025
|
-
for await (const chunk of stream) {
|
|
1026
|
-
const delta = chunk.choices[0]?.delta;
|
|
1027
|
-
if (!delta) continue;
|
|
1028
|
-
if (delta.content) {
|
|
1029
|
-
fullText += delta.content;
|
|
1030
|
-
onChunk({ type: "text", text: delta.content });
|
|
1031
1118
|
}
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1119
|
+
});
|
|
1120
|
+
proc.stderr.on("data", (data) => {
|
|
1121
|
+
stderrOutput += data.toString();
|
|
1122
|
+
});
|
|
1123
|
+
proc.on("close", (code) => {
|
|
1124
|
+
if (buffer.trim()) {
|
|
1125
|
+
try {
|
|
1126
|
+
const event = JSON.parse(buffer);
|
|
1127
|
+
if (event.type === "assistant" && event.content) {
|
|
1128
|
+
fullText += event.content;
|
|
1129
|
+
onChunk({ type: "text", text: event.content });
|
|
1130
|
+
} else if (event.role === "assistant" && typeof event.content === "string") {
|
|
1131
|
+
fullText += event.content;
|
|
1132
|
+
onChunk({ type: "text", text: event.content });
|
|
1133
|
+
}
|
|
1134
|
+
} catch {
|
|
1135
|
+
if (buffer.trim()) {
|
|
1136
|
+
fullText += buffer;
|
|
1137
|
+
onChunk({ type: "text", text: buffer });
|
|
1039
1138
|
}
|
|
1040
|
-
if (tc.id) acc.id = tc.id;
|
|
1041
|
-
if (tc.function?.name) acc.name = tc.function.name;
|
|
1042
|
-
if (tc.function?.arguments) acc.arguments += tc.function.arguments;
|
|
1043
1139
|
}
|
|
1044
1140
|
}
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1141
|
+
onChunk({ type: "done" });
|
|
1142
|
+
if (code !== 0 && !fullText) {
|
|
1143
|
+
reject(
|
|
1144
|
+
new Error(
|
|
1145
|
+
`Copilot CLI exited with code ${code}${stderrOutput ? `: ${stderrOutput.trim()}` : ""}`
|
|
1146
|
+
)
|
|
1147
|
+
);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
const hasTools = tools && tools.length > 0;
|
|
1151
|
+
if (hasTools) {
|
|
1152
|
+
const toolUses = parseToolUses2(fullText);
|
|
1153
|
+
if (toolUses.length > 0) {
|
|
1154
|
+
let cleanText = fullText;
|
|
1155
|
+
const stripRegex = /```json\s*\n?\s*\{"tool_use"[\s\S]*?```/g;
|
|
1156
|
+
cleanText = cleanText.replace(stripRegex, "").trim();
|
|
1157
|
+
const contentBlocks = [];
|
|
1158
|
+
if (cleanText) {
|
|
1159
|
+
contentBlocks.push({ type: "text", text: cleanText });
|
|
1160
|
+
}
|
|
1161
|
+
for (const tu of toolUses) {
|
|
1162
|
+
contentBlocks.push({
|
|
1163
|
+
type: "tool_use",
|
|
1164
|
+
id: tu.id,
|
|
1165
|
+
name: tu.name,
|
|
1166
|
+
input: tu.input
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
resolve({
|
|
1170
|
+
message: { role: "assistant", content: contentBlocks },
|
|
1171
|
+
toolUses
|
|
1172
|
+
});
|
|
1173
|
+
return;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
resolve({
|
|
1177
|
+
message: { role: "assistant", content: fullText },
|
|
1178
|
+
toolUses: []
|
|
1179
|
+
});
|
|
1180
|
+
});
|
|
1181
|
+
proc.on("error", (err) => {
|
|
1182
|
+
if (err.code === "ENOENT") {
|
|
1183
|
+
reject(
|
|
1184
|
+
new Error(
|
|
1185
|
+
"Copilot CLI not found. Install it from: https://docs.github.com/copilot/how-tos/copilot-cli"
|
|
1186
|
+
)
|
|
1187
|
+
);
|
|
1188
|
+
} else {
|
|
1189
|
+
reject(err);
|
|
1190
|
+
}
|
|
1191
|
+
});
|
|
1192
|
+
});
|
|
1084
1193
|
}
|
|
1085
1194
|
};
|
|
1086
1195
|
}
|
|
@@ -3184,6 +3293,17 @@ function progressBar(pct) {
|
|
|
3184
3293
|
}
|
|
3185
3294
|
|
|
3186
3295
|
// src/commands.ts
|
|
3296
|
+
import {
|
|
3297
|
+
getIdentity as acoreGetIdentity,
|
|
3298
|
+
updateSection as acoreUpdateSection
|
|
3299
|
+
} from "@aman_asmuei/acore-core";
|
|
3300
|
+
import {
|
|
3301
|
+
listRuleCategories as arulesListCategories,
|
|
3302
|
+
addRule as arulesAddRule,
|
|
3303
|
+
removeRule as arulesRemoveRule,
|
|
3304
|
+
toggleRuleAt as arulesToggleRule
|
|
3305
|
+
} from "@aman_asmuei/arules-core";
|
|
3306
|
+
var AGENT_SCOPE = process.env.AMAN_AGENT_SCOPE ?? "dev:agent";
|
|
3187
3307
|
function readEcosystemFile(filePath, label) {
|
|
3188
3308
|
if (!fs12.existsSync(filePath)) {
|
|
3189
3309
|
return pc5.dim(`No ${label} file found at ${filePath}`);
|
|
@@ -3209,17 +3329,26 @@ async function mcpWrite(ctx, layer, tool, args) {
|
|
|
3209
3329
|
}
|
|
3210
3330
|
return pc5.green(result);
|
|
3211
3331
|
}
|
|
3212
|
-
async function handleIdentityCommand(action, args,
|
|
3213
|
-
const home2 = os11.homedir();
|
|
3332
|
+
async function handleIdentityCommand(action, args, _ctx) {
|
|
3214
3333
|
if (!action) {
|
|
3215
|
-
const
|
|
3216
|
-
|
|
3334
|
+
const identity = await acoreGetIdentity(AGENT_SCOPE);
|
|
3335
|
+
if (!identity) {
|
|
3336
|
+
return {
|
|
3337
|
+
handled: true,
|
|
3338
|
+
output: pc5.dim(
|
|
3339
|
+
`No identity configured for ${AGENT_SCOPE}. Run: npx @aman_asmuei/acore`
|
|
3340
|
+
)
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
return { handled: true, output: identity.content.trim() };
|
|
3217
3344
|
}
|
|
3218
3345
|
if (action === "update") {
|
|
3219
3346
|
if (args.length === 0) {
|
|
3220
3347
|
return {
|
|
3221
3348
|
handled: true,
|
|
3222
|
-
output: pc5.yellow(
|
|
3349
|
+
output: pc5.yellow(
|
|
3350
|
+
"Usage: /identity update <section>\nTip: describe changes in natural language and the AI will update via acore-core."
|
|
3351
|
+
)
|
|
3223
3352
|
};
|
|
3224
3353
|
}
|
|
3225
3354
|
const section = args[0];
|
|
@@ -3227,60 +3356,161 @@ async function handleIdentityCommand(action, args, ctx) {
|
|
|
3227
3356
|
if (!content) {
|
|
3228
3357
|
return {
|
|
3229
3358
|
handled: true,
|
|
3230
|
-
output: pc5.yellow(
|
|
3359
|
+
output: pc5.yellow(
|
|
3360
|
+
"Usage: /identity update <section> <new content...>\nExample: /identity update Personality Warm, curious, and direct."
|
|
3361
|
+
)
|
|
3362
|
+
};
|
|
3363
|
+
}
|
|
3364
|
+
try {
|
|
3365
|
+
await acoreUpdateSection(section, content, AGENT_SCOPE);
|
|
3366
|
+
return { handled: true, output: pc5.green(`Updated section: ${section}`) };
|
|
3367
|
+
} catch (err) {
|
|
3368
|
+
return {
|
|
3369
|
+
handled: true,
|
|
3370
|
+
output: pc5.red(
|
|
3371
|
+
`Failed to update ${section}: ${err instanceof Error ? err.message : String(err)}`
|
|
3372
|
+
)
|
|
3231
3373
|
};
|
|
3232
3374
|
}
|
|
3233
|
-
const output = await mcpWrite(ctx, "identity", "identity_update_section", { section, content });
|
|
3234
|
-
return { handled: true, output };
|
|
3235
3375
|
}
|
|
3236
3376
|
if (action === "help") {
|
|
3237
|
-
return {
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3377
|
+
return {
|
|
3378
|
+
handled: true,
|
|
3379
|
+
output: [
|
|
3380
|
+
pc5.bold("Identity commands:"),
|
|
3381
|
+
` ${pc5.cyan("/identity")} View current identity`,
|
|
3382
|
+
` ${pc5.cyan("/identity update")} <section> Update a section`
|
|
3383
|
+
].join("\n")
|
|
3384
|
+
};
|
|
3242
3385
|
}
|
|
3243
|
-
return {
|
|
3386
|
+
return {
|
|
3387
|
+
handled: true,
|
|
3388
|
+
output: pc5.yellow(
|
|
3389
|
+
`Unknown action: /identity ${action}. Try /identity --help`
|
|
3390
|
+
)
|
|
3391
|
+
};
|
|
3244
3392
|
}
|
|
3245
|
-
async function handleRulesCommand(action, args,
|
|
3246
|
-
const home2 = os11.homedir();
|
|
3393
|
+
async function handleRulesCommand(action, args, _ctx) {
|
|
3247
3394
|
if (!action) {
|
|
3248
|
-
const
|
|
3249
|
-
|
|
3395
|
+
const cats = await arulesListCategories(AGENT_SCOPE);
|
|
3396
|
+
if (cats.length === 0) {
|
|
3397
|
+
return {
|
|
3398
|
+
handled: true,
|
|
3399
|
+
output: pc5.dim(
|
|
3400
|
+
`No rules configured for ${AGENT_SCOPE}. Run: npx @aman_asmuei/arules`
|
|
3401
|
+
)
|
|
3402
|
+
};
|
|
3403
|
+
}
|
|
3404
|
+
const lines = [];
|
|
3405
|
+
for (const cat of cats) {
|
|
3406
|
+
lines.push(pc5.bold(`## ${cat.name}`));
|
|
3407
|
+
for (const rule of cat.rules) {
|
|
3408
|
+
lines.push(` - ${rule}`);
|
|
3409
|
+
}
|
|
3410
|
+
lines.push("");
|
|
3411
|
+
}
|
|
3412
|
+
return { handled: true, output: lines.join("\n").trim() };
|
|
3250
3413
|
}
|
|
3251
3414
|
if (action === "add") {
|
|
3252
3415
|
if (args.length < 2) {
|
|
3253
|
-
return {
|
|
3416
|
+
return {
|
|
3417
|
+
handled: true,
|
|
3418
|
+
output: pc5.yellow("Usage: /rules add <category> <rule text...>")
|
|
3419
|
+
};
|
|
3254
3420
|
}
|
|
3255
3421
|
const category = args[0];
|
|
3256
3422
|
const rule = args.slice(1).join(" ");
|
|
3257
|
-
|
|
3258
|
-
|
|
3423
|
+
try {
|
|
3424
|
+
await arulesAddRule(category, rule, AGENT_SCOPE);
|
|
3425
|
+
return {
|
|
3426
|
+
handled: true,
|
|
3427
|
+
output: pc5.green(`Added rule to "${category}": ${rule}`)
|
|
3428
|
+
};
|
|
3429
|
+
} catch (err) {
|
|
3430
|
+
return {
|
|
3431
|
+
handled: true,
|
|
3432
|
+
output: pc5.red(
|
|
3433
|
+
`Failed: ${err instanceof Error ? err.message : String(err)}`
|
|
3434
|
+
)
|
|
3435
|
+
};
|
|
3436
|
+
}
|
|
3259
3437
|
}
|
|
3260
3438
|
if (action === "remove") {
|
|
3261
3439
|
if (args.length < 2) {
|
|
3262
|
-
return {
|
|
3440
|
+
return {
|
|
3441
|
+
handled: true,
|
|
3442
|
+
output: pc5.yellow("Usage: /rules remove <category> <index>")
|
|
3443
|
+
};
|
|
3444
|
+
}
|
|
3445
|
+
const category = args[0];
|
|
3446
|
+
const idx = parseInt(args[1], 10);
|
|
3447
|
+
if (isNaN(idx) || idx < 1) {
|
|
3448
|
+
return {
|
|
3449
|
+
handled: true,
|
|
3450
|
+
output: pc5.yellow("Index must be a positive integer.")
|
|
3451
|
+
};
|
|
3452
|
+
}
|
|
3453
|
+
try {
|
|
3454
|
+
await arulesRemoveRule(category, idx, AGENT_SCOPE);
|
|
3455
|
+
return {
|
|
3456
|
+
handled: true,
|
|
3457
|
+
output: pc5.green(`Removed rule ${idx} from "${category}"`)
|
|
3458
|
+
};
|
|
3459
|
+
} catch (err) {
|
|
3460
|
+
return {
|
|
3461
|
+
handled: true,
|
|
3462
|
+
output: pc5.red(
|
|
3463
|
+
`Failed: ${err instanceof Error ? err.message : String(err)}`
|
|
3464
|
+
)
|
|
3465
|
+
};
|
|
3263
3466
|
}
|
|
3264
|
-
const output = await mcpWrite(ctx, "rules", "rules_remove", { category: args[0], index: parseInt(args[1], 10) });
|
|
3265
|
-
return { handled: true, output };
|
|
3266
3467
|
}
|
|
3267
3468
|
if (action === "toggle") {
|
|
3268
3469
|
if (args.length < 2) {
|
|
3269
|
-
return {
|
|
3470
|
+
return {
|
|
3471
|
+
handled: true,
|
|
3472
|
+
output: pc5.yellow("Usage: /rules toggle <category> <index>")
|
|
3473
|
+
};
|
|
3474
|
+
}
|
|
3475
|
+
const category = args[0];
|
|
3476
|
+
const idx = parseInt(args[1], 10);
|
|
3477
|
+
if (isNaN(idx) || idx < 1) {
|
|
3478
|
+
return {
|
|
3479
|
+
handled: true,
|
|
3480
|
+
output: pc5.yellow("Index must be a positive integer.")
|
|
3481
|
+
};
|
|
3482
|
+
}
|
|
3483
|
+
try {
|
|
3484
|
+
await arulesToggleRule(category, idx, AGENT_SCOPE);
|
|
3485
|
+
return {
|
|
3486
|
+
handled: true,
|
|
3487
|
+
output: pc5.green(`Toggled rule ${idx} in "${category}"`)
|
|
3488
|
+
};
|
|
3489
|
+
} catch (err) {
|
|
3490
|
+
return {
|
|
3491
|
+
handled: true,
|
|
3492
|
+
output: pc5.red(
|
|
3493
|
+
`Failed: ${err instanceof Error ? err.message : String(err)}`
|
|
3494
|
+
)
|
|
3495
|
+
};
|
|
3270
3496
|
}
|
|
3271
|
-
const output = await mcpWrite(ctx, "rules", "rules_toggle", { category: args[0], index: parseInt(args[1], 10) });
|
|
3272
|
-
return { handled: true, output };
|
|
3273
3497
|
}
|
|
3274
3498
|
if (action === "help") {
|
|
3275
|
-
return {
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3499
|
+
return {
|
|
3500
|
+
handled: true,
|
|
3501
|
+
output: [
|
|
3502
|
+
pc5.bold("Rules commands:"),
|
|
3503
|
+
` ${pc5.cyan("/rules")} View current rules`,
|
|
3504
|
+
` ${pc5.cyan("/rules add")} <category> <text> Add a rule`,
|
|
3505
|
+
` ${pc5.cyan("/rules remove")} <category> <idx> Remove a rule`,
|
|
3506
|
+
` ${pc5.cyan("/rules toggle")} <category> <idx> Toggle a rule`
|
|
3507
|
+
].join("\n")
|
|
3508
|
+
};
|
|
3282
3509
|
}
|
|
3283
|
-
return {
|
|
3510
|
+
return {
|
|
3511
|
+
handled: true,
|
|
3512
|
+
output: pc5.yellow(`Unknown action: /rules ${action}. Try /rules --help`)
|
|
3513
|
+
};
|
|
3284
3514
|
}
|
|
3285
3515
|
async function handleWorkflowsCommand(action, args, ctx) {
|
|
3286
3516
|
const home2 = os11.homedir();
|
|
@@ -3312,205 +3542,29 @@ async function handleWorkflowsCommand(action, args, ctx) {
|
|
|
3312
3542
|
}
|
|
3313
3543
|
return { handled: true, output: pc5.yellow(`Unknown action: /workflows ${action}. Try /workflows --help`) };
|
|
3314
3544
|
}
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
{
|
|
3329
|
-
{
|
|
3330
|
-
{
|
|
3331
|
-
{
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
return JSON.parse(fs12.readFileSync(filePath, "utf-8"));
|
|
3339
|
-
} catch {
|
|
3340
|
-
return [];
|
|
3341
|
-
}
|
|
3342
|
-
}
|
|
3343
|
-
function saveAkitInstalled(tools) {
|
|
3344
|
-
const dir = path12.join(os11.homedir(), ".akit");
|
|
3345
|
-
fs12.mkdirSync(dir, { recursive: true });
|
|
3346
|
-
fs12.writeFileSync(path12.join(dir, "installed.json"), JSON.stringify(tools, null, 2) + "\n", "utf-8");
|
|
3347
|
-
}
|
|
3348
|
-
function addToAmanAgentConfig(name, mcpConfig) {
|
|
3349
|
-
const configPath = path12.join(os11.homedir(), ".aman-agent", "config.json");
|
|
3350
|
-
if (!fs12.existsSync(configPath)) return;
|
|
3351
|
-
try {
|
|
3352
|
-
const config = JSON.parse(fs12.readFileSync(configPath, "utf-8"));
|
|
3353
|
-
if (!config.mcpServers) config.mcpServers = {};
|
|
3354
|
-
config.mcpServers[name] = mcpConfig;
|
|
3355
|
-
fs12.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
3356
|
-
} catch {
|
|
3357
|
-
}
|
|
3358
|
-
}
|
|
3359
|
-
function removeFromAmanAgentConfig(name) {
|
|
3360
|
-
const configPath = path12.join(os11.homedir(), ".aman-agent", "config.json");
|
|
3361
|
-
if (!fs12.existsSync(configPath)) return;
|
|
3362
|
-
try {
|
|
3363
|
-
const config = JSON.parse(fs12.readFileSync(configPath, "utf-8"));
|
|
3364
|
-
if (config.mcpServers) {
|
|
3365
|
-
delete config.mcpServers[name];
|
|
3366
|
-
fs12.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
3367
|
-
}
|
|
3368
|
-
} catch {
|
|
3369
|
-
}
|
|
3370
|
-
}
|
|
3371
|
-
function handleAkitCommand(action, args) {
|
|
3372
|
-
const installed = loadAkitInstalled();
|
|
3373
|
-
const installedNames = new Set(installed.map((t) => t.name));
|
|
3374
|
-
if (action === "add") {
|
|
3375
|
-
const available2 = AKIT_REGISTRY.filter((t) => !installedNames.has(t.name));
|
|
3376
|
-
if (args.length < 1) {
|
|
3377
|
-
if (available2.length === 0) {
|
|
3378
|
-
return { handled: true, output: pc5.green("All tools are installed!") };
|
|
3379
|
-
}
|
|
3380
|
-
const lines3 = [pc5.bold("Select a tool to install:"), ""];
|
|
3381
|
-
available2.forEach((tool2, i) => {
|
|
3382
|
-
const num2 = pc5.cyan(String(i + 1).padStart(2));
|
|
3383
|
-
lines3.push(` ${num2} ${tool2.name.padEnd(16)} ${pc5.dim(tool2.description)}`);
|
|
3384
|
-
});
|
|
3385
|
-
lines3.push("");
|
|
3386
|
-
lines3.push(` Type: ${pc5.cyan("/akit add <number>")} or ${pc5.cyan("/akit add <name>")}`);
|
|
3387
|
-
lines3.push(` Custom: ${pc5.cyan("/akit add custom <name> <command> <args...>")}`);
|
|
3388
|
-
return { handled: true, output: lines3.join("\n") };
|
|
3389
|
-
}
|
|
3390
|
-
if (args[0].toLowerCase() === "custom") {
|
|
3391
|
-
if (args.length < 3) {
|
|
3392
|
-
return { handled: true, output: pc5.yellow("Usage: /akit add custom <name> <command> <args...>\nExample: /akit add custom my-tool npx -y @org/my-mcp-server") };
|
|
3393
|
-
}
|
|
3394
|
-
const customName = args[1];
|
|
3395
|
-
const customCommand = args[2];
|
|
3396
|
-
const customArgs = args.slice(3);
|
|
3397
|
-
if (installedNames.has(customName)) {
|
|
3398
|
-
return { handled: true, output: pc5.yellow(`${customName} is already installed.`) };
|
|
3399
|
-
}
|
|
3400
|
-
installed.push({
|
|
3401
|
-
name: customName,
|
|
3402
|
-
installedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
3403
|
-
mcpConfigured: true
|
|
3404
|
-
});
|
|
3405
|
-
saveAkitInstalled(installed);
|
|
3406
|
-
addToAmanAgentConfig(customName, { command: customCommand, args: customArgs });
|
|
3407
|
-
return {
|
|
3408
|
-
handled: true,
|
|
3409
|
-
output: [
|
|
3410
|
-
pc5.green(`\u2713 Added ${pc5.bold(customName)}`) + pc5.dim(` (custom MCP: ${customCommand} ${customArgs.join(" ")})`),
|
|
3411
|
-
pc5.dim(" Restart aman-agent to load the new tool.")
|
|
3412
|
-
].join("\n")
|
|
3413
|
-
};
|
|
3414
|
-
}
|
|
3415
|
-
const input = args[0].toLowerCase();
|
|
3416
|
-
let tool;
|
|
3417
|
-
const num = parseInt(input, 10);
|
|
3418
|
-
if (!isNaN(num) && num >= 1 && num <= available2.length) {
|
|
3419
|
-
tool = available2[num - 1];
|
|
3420
|
-
} else {
|
|
3421
|
-
tool = AKIT_REGISTRY.find((t) => t.name === input);
|
|
3422
|
-
}
|
|
3423
|
-
if (!tool) {
|
|
3424
|
-
return {
|
|
3425
|
-
handled: true,
|
|
3426
|
-
output: [
|
|
3427
|
-
pc5.red(`Tool "${input}" not found.`),
|
|
3428
|
-
`Type ${pc5.cyan("/akit add")} to see available tools.`
|
|
3429
|
-
].join("\n")
|
|
3430
|
-
};
|
|
3431
|
-
}
|
|
3432
|
-
if (installedNames.has(tool.name)) {
|
|
3433
|
-
return { handled: true, output: pc5.yellow(`${tool.name} is already installed.`) };
|
|
3434
|
-
}
|
|
3435
|
-
installed.push({
|
|
3436
|
-
name: tool.name,
|
|
3437
|
-
installedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
3438
|
-
mcpConfigured: tool.mcp !== null
|
|
3439
|
-
});
|
|
3440
|
-
saveAkitInstalled(installed);
|
|
3441
|
-
if (tool.mcp) {
|
|
3442
|
-
addToAmanAgentConfig(tool.name, {
|
|
3443
|
-
command: tool.mcp.command,
|
|
3444
|
-
args: tool.mcp.args
|
|
3445
|
-
});
|
|
3446
|
-
}
|
|
3447
|
-
const lines2 = [
|
|
3448
|
-
pc5.green(`\u2713 Added ${pc5.bold(tool.name)}`) + (tool.mcp ? pc5.dim(` (MCP: ${tool.mcp.package})`) : "")
|
|
3449
|
-
];
|
|
3450
|
-
if (tool.envHint) {
|
|
3451
|
-
lines2.push(pc5.yellow(` \u26A0 ${tool.envHint}`));
|
|
3452
|
-
}
|
|
3453
|
-
if (tool.mcp) {
|
|
3454
|
-
lines2.push(pc5.dim(" Restart aman-agent to load the new tool."));
|
|
3455
|
-
}
|
|
3456
|
-
return { handled: true, output: lines2.join("\n") };
|
|
3457
|
-
}
|
|
3458
|
-
if (action === "remove") {
|
|
3459
|
-
if (args.length < 1) {
|
|
3460
|
-
return { handled: true, output: pc5.yellow("Usage: /akit remove <tool>") };
|
|
3461
|
-
}
|
|
3462
|
-
const toolName = args[0].toLowerCase();
|
|
3463
|
-
if (!installedNames.has(toolName)) {
|
|
3464
|
-
return { handled: true, output: pc5.red(`${toolName} is not installed.`) };
|
|
3465
|
-
}
|
|
3466
|
-
const updated = installed.filter((t) => t.name !== toolName);
|
|
3467
|
-
saveAkitInstalled(updated);
|
|
3468
|
-
removeFromAmanAgentConfig(toolName);
|
|
3469
|
-
return {
|
|
3470
|
-
handled: true,
|
|
3471
|
-
output: pc5.green(`\u2713 Removed ${pc5.bold(toolName)}`) + pc5.dim(" (restart aman-agent to apply)")
|
|
3472
|
-
};
|
|
3473
|
-
}
|
|
3474
|
-
if (action === "help") {
|
|
3475
|
-
return {
|
|
3476
|
-
handled: true,
|
|
3477
|
-
output: [
|
|
3478
|
-
pc5.bold("akit \u2014 Tool Management"),
|
|
3479
|
-
"",
|
|
3480
|
-
` ${pc5.cyan("/akit")} List installed & available tools`,
|
|
3481
|
-
` ${pc5.cyan("/akit add <tool>")} Install a tool`,
|
|
3482
|
-
` ${pc5.cyan("/akit remove <tool>")} Uninstall a tool`
|
|
3483
|
-
].join("\n")
|
|
3484
|
-
};
|
|
3485
|
-
}
|
|
3486
|
-
const available = AKIT_REGISTRY.filter((t) => !installedNames.has(t.name));
|
|
3487
|
-
const lines = [pc5.bold("akit \u2014 AI Tool Manager"), ""];
|
|
3488
|
-
if (installed.length > 0) {
|
|
3489
|
-
lines.push(` ${pc5.bold(`Installed (${installed.length})`)}`);
|
|
3490
|
-
for (const tool of installed) {
|
|
3491
|
-
const mcp = tool.mcpConfigured ? pc5.green("MCP") : pc5.dim("manual");
|
|
3492
|
-
lines.push(` ${pc5.green("\u25CF")} ${pc5.bold(tool.name.padEnd(16))} ${mcp} ${pc5.dim(tool.installedAt)}`);
|
|
3493
|
-
}
|
|
3494
|
-
lines.push("");
|
|
3495
|
-
}
|
|
3496
|
-
if (available.length > 0) {
|
|
3497
|
-
lines.push(` ${pc5.bold(`Available (${available.length})`)}`);
|
|
3498
|
-
const byCategory = /* @__PURE__ */ new Map();
|
|
3499
|
-
for (const tool of available) {
|
|
3500
|
-
if (!byCategory.has(tool.category)) byCategory.set(tool.category, []);
|
|
3501
|
-
byCategory.get(tool.category).push(tool);
|
|
3502
|
-
}
|
|
3503
|
-
for (const [category, tools] of byCategory) {
|
|
3504
|
-
lines.push(` ${pc5.dim(category)}`);
|
|
3505
|
-
for (const tool of tools) {
|
|
3506
|
-
lines.push(` ${pc5.dim("\u25CB")} ${tool.name.padEnd(16)} ${pc5.dim(tool.description)}`);
|
|
3507
|
-
}
|
|
3508
|
-
}
|
|
3509
|
-
lines.push("");
|
|
3510
|
-
}
|
|
3511
|
-
lines.push(` ${pc5.cyan("/akit add <tool>")} Install a tool`);
|
|
3512
|
-
lines.push(` ${pc5.cyan("/akit remove <tool>")} Uninstall a tool`);
|
|
3513
|
-
return { handled: true, output: lines.join("\n") };
|
|
3545
|
+
function handleAkitCommand(_action, _args) {
|
|
3546
|
+
return {
|
|
3547
|
+
handled: true,
|
|
3548
|
+
output: [
|
|
3549
|
+
pc5.bold("akit \u2014 Tool Management"),
|
|
3550
|
+
"",
|
|
3551
|
+
pc5.dim(
|
|
3552
|
+
"Tool management is now handled by the standalone akit CLI rather than"
|
|
3553
|
+
),
|
|
3554
|
+
pc5.dim(
|
|
3555
|
+
"duplicated inside aman-agent. The akit slash command is informational only."
|
|
3556
|
+
),
|
|
3557
|
+
"",
|
|
3558
|
+
` ${pc5.cyan("npx @aman_asmuei/akit list")} List installed tools`,
|
|
3559
|
+
` ${pc5.cyan("npx @aman_asmuei/akit search <query>")} Search the tool registry`,
|
|
3560
|
+
` ${pc5.cyan("npx @aman_asmuei/akit add <tool>")} Install a tool`,
|
|
3561
|
+
` ${pc5.cyan("npx @aman_asmuei/akit remove <tool>")} Uninstall a tool`,
|
|
3562
|
+
"",
|
|
3563
|
+
pc5.dim(
|
|
3564
|
+
"Restart aman-agent after installing/removing tools to pick up changes."
|
|
3565
|
+
)
|
|
3566
|
+
].join("\n")
|
|
3567
|
+
};
|
|
3514
3568
|
}
|
|
3515
3569
|
async function handleSkillsCommand(action, args, ctx) {
|
|
3516
3570
|
const home2 = os11.homedir();
|
|
@@ -3914,7 +3968,7 @@ function handleReset(action) {
|
|
|
3914
3968
|
function handleUpdate() {
|
|
3915
3969
|
try {
|
|
3916
3970
|
const current = execFileSync3("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
|
|
3917
|
-
const local = true ? "0.
|
|
3971
|
+
const local = true ? "0.22.0" : "unknown";
|
|
3918
3972
|
if (current === local) {
|
|
3919
3973
|
return { handled: true, output: `${pc5.green("Up to date")} \u2014 v${local}` };
|
|
3920
3974
|
}
|
|
@@ -6369,7 +6423,7 @@ function bootstrapEcosystem() {
|
|
|
6369
6423
|
return true;
|
|
6370
6424
|
}
|
|
6371
6425
|
var program = new Command();
|
|
6372
|
-
program.name("aman-agent").description("Your AI companion, running locally").version("0.
|
|
6426
|
+
program.name("aman-agent").description("Your AI companion, running locally").version("0.22.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
|
|
6373
6427
|
p3.intro(pc8.bold("aman agent") + pc8.dim(" \u2014 your AI companion"));
|
|
6374
6428
|
let config = loadConfig();
|
|
6375
6429
|
if (!config) {
|
|
@@ -6491,68 +6545,68 @@ program.name("aman-agent").description("Your AI companion, running locally").ver
|
|
|
6491
6545
|
` ${pc8.cyan("Business")} $19/user/mo Team admin + policy controls`,
|
|
6492
6546
|
` ${pc8.cyan("Enterprise")} $39/user/mo SSO, audit logs, IP indemnity`,
|
|
6493
6547
|
"",
|
|
6494
|
-
`${pc8.dim("Authentication is handled by the
|
|
6548
|
+
`${pc8.dim("Authentication is handled by the Copilot CLI.")}`,
|
|
6495
6549
|
`${pc8.dim("Subscribe at: https://github.com/features/copilot")}`
|
|
6496
6550
|
].join("\n"),
|
|
6497
6551
|
"Copilot Plans"
|
|
6498
6552
|
);
|
|
6499
|
-
if (!
|
|
6500
|
-
p3.log.error("
|
|
6553
|
+
if (!isCopilotCliInstalled()) {
|
|
6554
|
+
p3.log.error("Copilot CLI is not installed.");
|
|
6501
6555
|
p3.log.info("Install it from:");
|
|
6502
|
-
p3.log.step(pc8.bold("https://
|
|
6556
|
+
p3.log.step(pc8.bold("https://docs.github.com/copilot/how-tos/copilot-cli"));
|
|
6503
6557
|
p3.log.info(pc8.dim("Then re-run aman-agent to continue setup."));
|
|
6504
6558
|
process.exit(1);
|
|
6505
6559
|
}
|
|
6506
|
-
p3.log.success("
|
|
6507
|
-
const
|
|
6508
|
-
if (
|
|
6509
|
-
p3.log.success("
|
|
6560
|
+
p3.log.success("Copilot CLI detected.");
|
|
6561
|
+
const copilotAuth = isCopilotCliAuthenticated();
|
|
6562
|
+
if (copilotAuth) {
|
|
6563
|
+
p3.log.success("Copilot authentication found.");
|
|
6510
6564
|
} else {
|
|
6511
|
-
p3.log.warn("Not logged in to
|
|
6565
|
+
p3.log.warn("Not logged in to Copilot.");
|
|
6512
6566
|
const authAction = await p3.select({
|
|
6513
6567
|
message: "Authentication",
|
|
6514
6568
|
options: [
|
|
6515
|
-
{ value: "login", label: "Log in now", hint: "runs:
|
|
6569
|
+
{ value: "login", label: "Log in now", hint: "runs: copilot login" },
|
|
6516
6570
|
{ value: "skip", label: "Skip (I'll log in later)" }
|
|
6517
6571
|
]
|
|
6518
6572
|
});
|
|
6519
6573
|
if (p3.isCancel(authAction)) process.exit(0);
|
|
6520
6574
|
if (authAction === "login") {
|
|
6521
|
-
p3.log.step("Launching
|
|
6575
|
+
p3.log.step("Launching Copilot login...");
|
|
6522
6576
|
const { spawnSync } = await import("child_process");
|
|
6523
|
-
const loginResult = spawnSync("
|
|
6577
|
+
const loginResult = spawnSync("copilot", ["login"], {
|
|
6524
6578
|
stdio: "inherit"
|
|
6525
6579
|
});
|
|
6526
6580
|
if (loginResult.status !== 0) {
|
|
6527
6581
|
p3.log.error("Login failed or was cancelled.");
|
|
6528
6582
|
process.exit(1);
|
|
6529
6583
|
}
|
|
6530
|
-
p3.log.success("
|
|
6584
|
+
p3.log.success("Copilot login successful.");
|
|
6531
6585
|
}
|
|
6532
6586
|
}
|
|
6533
6587
|
apiKey = "copilot";
|
|
6534
6588
|
const modelChoice = await p3.select({
|
|
6535
6589
|
message: "Model",
|
|
6536
6590
|
options: [
|
|
6537
|
-
{ value: "
|
|
6538
|
-
{ value: "gpt-4o
|
|
6591
|
+
{ value: "default", label: "Default", hint: "Copilot's default model" },
|
|
6592
|
+
{ value: "gpt-4o", label: "GPT-4o", hint: "fast" },
|
|
6593
|
+
{ value: "gpt-5.2", label: "GPT-5.2", hint: "most capable" },
|
|
6539
6594
|
{ value: "o3-mini", label: "o3-mini", hint: "reasoning" },
|
|
6540
|
-
{ value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6", hint: "via GitHub Models" },
|
|
6541
|
-
{ value: "meta-llama-3.1-405b-instruct", label: "Llama 3.1 405B", hint: "open source" },
|
|
6542
|
-
{ value: "mistral-large-2411", label: "Mistral Large", hint: "open source" },
|
|
6543
6595
|
{ value: "custom", label: "Custom model ID" }
|
|
6544
6596
|
],
|
|
6545
|
-
initialValue: "
|
|
6597
|
+
initialValue: "default"
|
|
6546
6598
|
});
|
|
6547
6599
|
if (p3.isCancel(modelChoice)) process.exit(0);
|
|
6548
6600
|
if (modelChoice === "custom") {
|
|
6549
6601
|
const customModel = await p3.text({
|
|
6550
|
-
message: "Model ID",
|
|
6602
|
+
message: "Model ID (run copilot --help for available models)",
|
|
6551
6603
|
placeholder: "gpt-4o",
|
|
6552
6604
|
validate: (v) => v.length === 0 ? "Model ID is required" : void 0
|
|
6553
6605
|
});
|
|
6554
6606
|
if (p3.isCancel(customModel)) process.exit(0);
|
|
6555
6607
|
defaultModel = customModel;
|
|
6608
|
+
} else if (modelChoice === "default") {
|
|
6609
|
+
defaultModel = "";
|
|
6556
6610
|
} else {
|
|
6557
6611
|
defaultModel = modelChoice;
|
|
6558
6612
|
}
|