|
1 | | -import { DefaultApiInterface } from "@continuedev/sdk/dist/api/dist/index.js"; |
2 | | - |
3 | | -import { AuthConfig, loadAuthConfig } from "../auth/workos.js"; |
4 | | -import { BaseCommandOptions } from "../commands/BaseCommandOptions.js"; |
5 | | -import { loadConfiguration } from "../configLoader.js"; |
6 | | -import { logger } from "../util/logger.js"; |
7 | | - |
8 | 1 | import { |
9 | 2 | AssistantUnrolled, |
10 | 3 | decodePackageIdentifier, |
11 | 4 | mergeUnrolledAssistants, |
12 | 5 | PackageIdentifier, |
13 | 6 | } from "@continuedev/config-yaml"; |
| 7 | +import { DefaultApiInterface } from "@continuedev/sdk/dist/api/dist/index.js"; |
| 8 | + |
14 | 9 | import { isStringRule } from "src/hubLoader.js"; |
15 | 10 | import { getErrorString } from "src/util/error.js"; |
| 11 | + |
| 12 | +import { AuthConfig, loadAuthConfig } from "../auth/workos.js"; |
| 13 | +import { BaseCommandOptions } from "../commands/BaseCommandOptions.js"; |
| 14 | +import { loadConfiguration } from "../configLoader.js"; |
| 15 | +import { logger } from "../util/logger.js"; |
| 16 | + |
16 | 17 | import { BaseService, ServiceWithDependencies } from "./BaseService.js"; |
17 | 18 | import { serviceContainer } from "./ServiceContainer.js"; |
18 | 19 | import { |
@@ -71,83 +72,129 @@ export class ConfigService |
71 | 72 | prompts: [], |
72 | 73 | }; |
73 | 74 |
|
74 | | - const { |
75 | | - model = [], |
76 | | - mcp = [], |
77 | | - rule = [], |
78 | | - prompt = [], |
79 | | - } = injectedConfigOptions || {}; |
| 75 | + const options = injectedConfigOptions || {}; |
80 | 76 |
|
81 | | - // Models: all models will be package identifiers |
| 77 | + this.processModels(options.model || [], agentFileState, packageIdentifiers); |
| 78 | + this.processMcpServers( |
| 79 | + options.mcp || [], |
| 80 | + agentFileState, |
| 81 | + packageIdentifiers, |
| 82 | + additional, |
| 83 | + ); |
| 84 | + this.processAgentFileRules(agentFileState, packageIdentifiers); |
| 85 | + this.processRulesAndPrompts( |
| 86 | + options.rule || [], |
| 87 | + options.prompt || [], |
| 88 | + packageIdentifiers, |
| 89 | + additional, |
| 90 | + ); |
| 91 | + this.processAgentFilePrompt(agentFileState, additional); |
| 92 | + |
| 93 | + return { |
| 94 | + injected: packageIdentifiers, |
| 95 | + additional, |
| 96 | + }; |
| 97 | + } |
| 98 | + |
| 99 | + private processModels( |
| 100 | + models: string[], |
| 101 | + agentFileState: AgentFileServiceState | undefined, |
| 102 | + packageIdentifiers: PackageIdentifier[], |
| 103 | + ): void { |
| 104 | + const allModels = [...models]; |
82 | 105 | if (agentFileState?.agentFile?.model) { |
83 | | - model.push(agentFileState.agentFile.model); |
| 106 | + allModels.push(agentFileState.agentFile.model); |
84 | 107 | } |
85 | | - for (const _model of model) { |
| 108 | + |
| 109 | + for (const model of allModels) { |
86 | 110 | try { |
87 | | - packageIdentifiers.push(decodePackageIdentifier(_model)); |
| 111 | + packageIdentifiers.push(decodePackageIdentifier(model)); |
88 | 112 | } catch (e) { |
89 | | - logger.warn(`Failed to add modl "${_model}": ${getErrorString(e)}`); |
| 113 | + logger.warn(`Failed to add model "${model}": ${getErrorString(e)}`); |
90 | 114 | } |
91 | 115 | } |
| 116 | + } |
| 117 | + |
| 118 | + private processMcpServers( |
| 119 | + mcps: string[], |
| 120 | + agentFileState: AgentFileServiceState | undefined, |
| 121 | + packageIdentifiers: PackageIdentifier[], |
| 122 | + additional: AssistantUnrolled, |
| 123 | + ): void { |
| 124 | + const allMcps = [ |
| 125 | + ...mcps, |
| 126 | + ...(agentFileState?.parsedTools?.mcpServers || []), |
| 127 | + ]; |
92 | 128 |
|
93 | | - // MCPs can be package identifiers or URLs |
94 | | - mcp.push(...(agentFileState?.parsedTools?.mcpServers || [])); |
95 | | - for (const _mcp of mcp) { |
| 129 | + for (const mcp of allMcps) { |
96 | 130 | try { |
97 | | - if (_mcp.startsWith("http://") || _mcp.startsWith("https://")) { |
| 131 | + if (this.isUrl(mcp)) { |
98 | 132 | additional.mcpServers!.push({ |
99 | | - name: new URL(_mcp).hostname, |
100 | | - url: _mcp, |
101 | | - // type: "streamable-http", // no need to exclude sse yet |
| 133 | + name: new URL(mcp).hostname, |
| 134 | + url: mcp, |
102 | 135 | }); |
103 | 136 | } else { |
104 | | - packageIdentifiers.push(decodePackageIdentifier(_mcp)); |
| 137 | + packageIdentifiers.push(decodePackageIdentifier(mcp)); |
105 | 138 | } |
106 | 139 | } catch (e) { |
107 | | - logger.warn(`Failed to add MCP server "${_mcp}": ${getErrorString(e)}`); |
| 140 | + logger.warn(`Failed to add MCP server "${mcp}": ${getErrorString(e)}`); |
108 | 141 | } |
109 | 142 | } |
| 143 | + } |
110 | 144 |
|
111 | | - // agent file rules can only be package identifiers |
112 | | - for (const r of agentFileState?.parsedRules || []) { |
| 145 | + private processAgentFileRules( |
| 146 | + agentFileState: AgentFileServiceState | undefined, |
| 147 | + packageIdentifiers: PackageIdentifier[], |
| 148 | + ): void { |
| 149 | + for (const rule of agentFileState?.parsedRules || []) { |
113 | 150 | try { |
114 | | - packageIdentifiers.push(decodePackageIdentifier(r)); |
| 151 | + packageIdentifiers.push(decodePackageIdentifier(rule)); |
115 | 152 | } catch (e) { |
116 | 153 | logger.warn( |
117 | | - `Failed to get rule "${r} (from agent file)": ${getErrorString(e)}`, |
| 154 | + `Failed to get rule "${rule} (from agent file)": ${getErrorString(e)}`, |
118 | 155 | ); |
119 | 156 | } |
120 | 157 | } |
| 158 | + } |
121 | 159 |
|
122 | | - // Rule and prompt flags can be either package identifiers or strings |
123 | | - for (const _rule of [...rule, ...prompt]) { |
| 160 | + private processRulesAndPrompts( |
| 161 | + rules: string[], |
| 162 | + prompts: string[], |
| 163 | + packageIdentifiers: PackageIdentifier[], |
| 164 | + additional: AssistantUnrolled, |
| 165 | + ): void { |
| 166 | + const allRulesAndPrompts = [...rules, ...prompts]; |
| 167 | + |
| 168 | + for (const item of allRulesAndPrompts) { |
124 | 169 | try { |
125 | | - if (isStringRule(_rule)) { |
126 | | - additional.rules!.push(_rule); |
| 170 | + if (isStringRule(item)) { |
| 171 | + additional.rules!.push(item); |
127 | 172 | } else { |
128 | | - packageIdentifiers.push(decodePackageIdentifier(_rule)); |
| 173 | + packageIdentifiers.push(decodePackageIdentifier(item)); |
129 | 174 | } |
130 | 175 | } catch (e) { |
131 | 176 | logger.warn( |
132 | | - `Failed to load rule or prompt "${_rule}": ${getErrorString(e)}`, |
| 177 | + `Failed to load rule or prompt "${item}": ${getErrorString(e)}`, |
133 | 178 | ); |
134 | 179 | } |
135 | 180 | } |
| 181 | + } |
136 | 182 |
|
137 | | - // Agent file prompt can only be a string |
| 183 | + private processAgentFilePrompt( |
| 184 | + agentFileState: AgentFileServiceState | undefined, |
| 185 | + additional: AssistantUnrolled, |
| 186 | + ): void { |
138 | 187 | if (agentFileState?.agentFile?.prompt) { |
139 | 188 | additional.prompts!.push({ |
140 | 189 | name: `Agent prompt (${agentFileState.agentFile.name})`, |
141 | 190 | prompt: agentFileState.agentFile.prompt, |
142 | 191 | description: agentFileState.agentFile.description, |
143 | 192 | }); |
144 | 193 | } |
| 194 | + } |
145 | 195 |
|
146 | | - // Todo ensure --model models take priority over config models |
147 | | - return { |
148 | | - injected: packageIdentifiers, |
149 | | - additional, |
150 | | - }; |
| 196 | + private isUrl(value: string): boolean { |
| 197 | + return value.startsWith("http://") || value.startsWith("https://"); |
151 | 198 | } |
152 | 199 |
|
153 | 200 | private async loadConfig( |
|
0 commit comments