@corbat-tech/coco 2.25.9 → 2.25.10
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/cli/index.js +71 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -121,6 +121,7 @@ function createDefaultConfigObject(projectName, language = "typescript") {
|
|
|
121
121
|
temperature: 0,
|
|
122
122
|
timeout: 12e4
|
|
123
123
|
},
|
|
124
|
+
providerModels: {},
|
|
124
125
|
quality: {
|
|
125
126
|
minScore: 85,
|
|
126
127
|
minCoverage: 80,
|
|
@@ -300,6 +301,7 @@ var init_schema = __esm({
|
|
|
300
301
|
temperature: 0,
|
|
301
302
|
timeout: 12e4
|
|
302
303
|
}),
|
|
304
|
+
providerModels: z.record(z.string(), z.string()).optional(),
|
|
303
305
|
quality: QualityConfigSchema.default({
|
|
304
306
|
minScore: 85,
|
|
305
307
|
minCoverage: 80,
|
|
@@ -597,6 +599,7 @@ function deepMergeConfig(base, override) {
|
|
|
597
599
|
...override,
|
|
598
600
|
project: { ...base.project, ...override.project },
|
|
599
601
|
provider: { ...base.provider, ...override.provider },
|
|
602
|
+
providerModels: { ...base.providerModels, ...override.providerModels },
|
|
600
603
|
quality: { ...base.quality, ...override.quality },
|
|
601
604
|
persistence: { ...base.persistence, ...override.persistence },
|
|
602
605
|
// Merge optional sections only if present in either base or override
|
|
@@ -2588,6 +2591,10 @@ async function getLastUsedProvider() {
|
|
|
2588
2591
|
async function getLastUsedModel(provider) {
|
|
2589
2592
|
try {
|
|
2590
2593
|
const config = await loadConfig(CONFIG_PATHS.config);
|
|
2594
|
+
const perProviderModel = normalizeConfiguredModel(config.providerModels?.[provider]);
|
|
2595
|
+
if (perProviderModel) {
|
|
2596
|
+
return perProviderModel;
|
|
2597
|
+
}
|
|
2591
2598
|
if (config.provider.type === provider) {
|
|
2592
2599
|
return normalizeConfiguredModel(config.provider.model);
|
|
2593
2600
|
}
|
|
@@ -2627,6 +2634,11 @@ async function saveProviderPreference(provider, model) {
|
|
|
2627
2634
|
}
|
|
2628
2635
|
config.provider.type = provider;
|
|
2629
2636
|
const normalizedModel = normalizeConfiguredModel(model);
|
|
2637
|
+
const persistedModel = normalizedModel ?? getDefaultModel(provider);
|
|
2638
|
+
config.providerModels = {
|
|
2639
|
+
...config.providerModels,
|
|
2640
|
+
[provider]: persistedModel
|
|
2641
|
+
};
|
|
2630
2642
|
if (normalizedModel) {
|
|
2631
2643
|
config.provider.model = normalizedModel;
|
|
2632
2644
|
} else {
|
|
@@ -2725,11 +2737,25 @@ async function migrateOldPreferences() {
|
|
|
2725
2737
|
}
|
|
2726
2738
|
if (oldPrefs.provider && VALID_PROVIDERS.includes(oldPrefs.provider)) {
|
|
2727
2739
|
config.provider.type = oldPrefs.provider;
|
|
2740
|
+
config.providerModels = {
|
|
2741
|
+
...config.providerModels
|
|
2742
|
+
};
|
|
2743
|
+
for (const [providerName, modelName] of Object.entries(oldPrefs.models ?? {})) {
|
|
2744
|
+
if (VALID_PROVIDERS.includes(providerName)) {
|
|
2745
|
+
const normalized = normalizeConfiguredModel(modelName);
|
|
2746
|
+
if (normalized) {
|
|
2747
|
+
config.providerModels[providerName] = normalized;
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2728
2751
|
const modelForProvider = oldPrefs.provider ? oldPrefs.models?.[oldPrefs.provider] : void 0;
|
|
2729
|
-
|
|
2730
|
-
|
|
2752
|
+
const normalizedMigratedModel = normalizeConfiguredModel(modelForProvider);
|
|
2753
|
+
if (normalizedMigratedModel) {
|
|
2754
|
+
config.provider.model = normalizedMigratedModel;
|
|
2755
|
+
config.providerModels[oldPrefs.provider] = normalizedMigratedModel;
|
|
2731
2756
|
} else {
|
|
2732
2757
|
config.provider.model = getDefaultModel(oldPrefs.provider);
|
|
2758
|
+
config.providerModels[oldPrefs.provider] = config.provider.model;
|
|
2733
2759
|
}
|
|
2734
2760
|
await saveConfig(config, void 0, true);
|
|
2735
2761
|
}
|
|
@@ -34614,8 +34640,9 @@ ${newProvider.emoji} ${newProvider.name} is not configured.`));
|
|
|
34614
34640
|
newApiKeyForSaving = key;
|
|
34615
34641
|
}
|
|
34616
34642
|
}
|
|
34643
|
+
const rememberedModel = await getLastUsedModel(newProvider.id);
|
|
34617
34644
|
const recommendedModel = getRecommendedModel(newProvider.id);
|
|
34618
|
-
const newModel = recommendedModel?.id || newProvider.models[0]?.id || "";
|
|
34645
|
+
const newModel = rememberedModel || recommendedModel?.id || newProvider.models[0]?.id || "";
|
|
34619
34646
|
const spinner18 = p26.spinner();
|
|
34620
34647
|
spinner18.start(`Connecting to ${newProvider.name}...`);
|
|
34621
34648
|
try {
|
|
@@ -53074,6 +53101,8 @@ async function startRepl(options = {}) {
|
|
|
53074
53101
|
);
|
|
53075
53102
|
}
|
|
53076
53103
|
let mcpManager = null;
|
|
53104
|
+
let configuredMcpServers = [];
|
|
53105
|
+
const registeredMcpServers = /* @__PURE__ */ new Set();
|
|
53077
53106
|
const logger2 = (await Promise.resolve().then(() => (init_logger(), logger_exports))).getLogger();
|
|
53078
53107
|
try {
|
|
53079
53108
|
const { getMCPServerManager: getMCPServerManager2 } = await Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports));
|
|
@@ -53090,6 +53119,7 @@ async function startRepl(options = {}) {
|
|
|
53090
53119
|
cocoConfigServers.filter((s) => s.enabled !== false),
|
|
53091
53120
|
projectServers.filter((s) => s.enabled !== false)
|
|
53092
53121
|
);
|
|
53122
|
+
configuredMcpServers = enabledServers;
|
|
53093
53123
|
if (enabledServers.length > 0) {
|
|
53094
53124
|
mcpManager = getMCPServerManager2();
|
|
53095
53125
|
let connections;
|
|
@@ -53109,6 +53139,7 @@ async function startRepl(options = {}) {
|
|
|
53109
53139
|
for (const connection of connections.values()) {
|
|
53110
53140
|
try {
|
|
53111
53141
|
const wrapped = await registerMCPTools2(toolRegistry, connection.name, connection.client);
|
|
53142
|
+
registeredMcpServers.add(connection.name);
|
|
53112
53143
|
if (wrapped.length === 0) {
|
|
53113
53144
|
logger2.warn(
|
|
53114
53145
|
`[MCP] Server '${connection.name}' connected but exposed 0 tools (check server auth/scopes).`
|
|
@@ -53137,6 +53168,42 @@ async function startRepl(options = {}) {
|
|
|
53137
53168
|
`[MCP] Initialization failed: ${mcpError instanceof Error ? mcpError.message : String(mcpError)}`
|
|
53138
53169
|
);
|
|
53139
53170
|
}
|
|
53171
|
+
async function ensureRequestedMcpConnections(message) {
|
|
53172
|
+
if (!mcpManager || configuredMcpServers.length === 0) return;
|
|
53173
|
+
const normalizedMessage = message.toLowerCase();
|
|
53174
|
+
const explicitlyRequestsMcp = /\bmcp\b/.test(normalizedMessage) || /\b(use|using|usa|usar|utiliza|utilizar)\b.{0,24}\bmcp\b/.test(normalizedMessage);
|
|
53175
|
+
const matchingServers = configuredMcpServers.filter((server) => {
|
|
53176
|
+
if (mcpManager?.getConnection(server.name)) return false;
|
|
53177
|
+
if (explicitlyRequestsMcp) return true;
|
|
53178
|
+
const loweredName = server.name.toLowerCase();
|
|
53179
|
+
if (normalizedMessage.includes(loweredName)) return true;
|
|
53180
|
+
if (loweredName.includes("atlassian")) {
|
|
53181
|
+
return /\b(atlassian|jira|confluence)\b/.test(normalizedMessage);
|
|
53182
|
+
}
|
|
53183
|
+
return false;
|
|
53184
|
+
});
|
|
53185
|
+
for (const server of matchingServers) {
|
|
53186
|
+
try {
|
|
53187
|
+
const connection = await mcpManager.startServer(server);
|
|
53188
|
+
if (!registeredMcpServers.has(connection.name)) {
|
|
53189
|
+
await (await Promise.resolve().then(() => (init_tools(), tools_exports))).registerMCPTools(
|
|
53190
|
+
toolRegistry,
|
|
53191
|
+
connection.name,
|
|
53192
|
+
connection.client
|
|
53193
|
+
);
|
|
53194
|
+
registeredMcpServers.add(connection.name);
|
|
53195
|
+
}
|
|
53196
|
+
} catch (error) {
|
|
53197
|
+
logger2.warn(
|
|
53198
|
+
`[MCP] On-demand connect failed for '${server.name}': ${error instanceof Error ? error.message : String(error)}`
|
|
53199
|
+
);
|
|
53200
|
+
}
|
|
53201
|
+
}
|
|
53202
|
+
}
|
|
53203
|
+
function extractMessageText(content) {
|
|
53204
|
+
if (typeof content === "string") return content;
|
|
53205
|
+
return content.filter((block) => block.type === "text").map((block) => block.text).join(" ");
|
|
53206
|
+
}
|
|
53140
53207
|
let hookRegistry;
|
|
53141
53208
|
let hookExecutor;
|
|
53142
53209
|
try {
|
|
@@ -53584,6 +53651,7 @@ ${imagePrompts}`.trim() : imagePrompts;
|
|
|
53584
53651
|
let streamStarted = false;
|
|
53585
53652
|
let llmCallCount = 0;
|
|
53586
53653
|
let lastToolGroup = null;
|
|
53654
|
+
await ensureRequestedMcpConnections(extractMessageText(effectiveMessage));
|
|
53587
53655
|
const result = await executeAgentTurn(session, effectiveMessage, provider, toolRegistry, {
|
|
53588
53656
|
onStream: (chunk) => {
|
|
53589
53657
|
if (!streamStarted) {
|