Skip to content

Commit 4f5449a

Browse files
committed
fix: replace inputs with secrets
1 parent 2162446 commit 4f5449a

File tree

8 files changed

+109
-57
lines changed

8 files changed

+109
-57
lines changed

core/config/yaml/loadLocalYamlBlocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export async function unrollLocalYamlBlocks(
3737
ide,
3838
),
3939
renderSecrets: true,
40+
replaceInputsWithSecrets: true,
4041
injectBlocks: packageIdentifiers,
4142
},
4243
);

extensions/cli/src/configLoader.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ export async function unrollPackageIdentifiersAsConfigYaml(
382382
platformClient: new CLIPlatformClient(organizationId, apiClient),
383383
renderSecrets: true,
384384
injectBlocks: packageIdentifiers,
385+
replaceInputsWithSecrets: true,
385386
},
386387
);
387388
if (!unrollResult?.config) {
@@ -515,7 +516,7 @@ async function loadAssistantSlug(
515516
}
516517
}
517518

518-
return result.config as AssistantUnrolled;
519+
return apiConfig;
519520
}
520521

521522
/**

extensions/cli/src/integration/rule-duplication.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { decodePackageIdentifier } from "@continuedev/config-yaml";
22
import { beforeEach, describe, expect, it, vi } from "vitest";
33

44
import { isStringRule } from "src/hubLoader.js";
5+
56
import { BaseCommandOptions } from "../commands/BaseCommandOptions.js";
67
import { ConfigService } from "../services/ConfigService.js";
78

extensions/cli/src/services/AgentFileService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
parseAgentFileRules,
33
parseAgentFileTools,
44
} from "@continuedev/config-yaml";
5+
56
import {
67
agentFileProcessor,
78
loadModelFromHub,

extensions/cli/src/services/ConfigService.test.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
import { beforeEach, describe, expect, test, vi } from "vitest";
2-
3-
// Mock modules
4-
vi.mock("../auth/workos.js");
5-
vi.mock("../configLoader.js");
6-
vi.mock("../util/logger.js");
7-
vi.mock("./ServiceContainer.js");
8-
vi.mock("@continuedev/config-yaml");
9-
// Don't mock hubLoader - use real isStringRule implementation
10-
111
import {
122
decodePackageIdentifier,
133
mergeUnrolledAssistants,
144
} from "@continuedev/config-yaml";
5+
import { beforeEach, describe, expect, test, vi } from "vitest";
6+
157
import * as workos from "../auth/workos.js";
168
import * as configLoader from "../configLoader.js";
179

1810
import { ConfigService } from "./ConfigService.js";
1911
import { serviceContainer } from "./ServiceContainer.js";
2012
import { AgentFileServiceState, SERVICE_NAMES } from "./types.js";
21-
13+
vi.mock("../auth/workos.js");
14+
vi.mock("../configLoader.js");
15+
vi.mock("../util/logger.js");
16+
vi.mock("./ServiceContainer.js");
17+
vi.mock("@continuedev/config-yaml");
2218
describe("ConfigService", () => {
2319
let service: ConfigService;
2420
const mockConfig = {

extensions/cli/src/services/ConfigService.ts

Lines changed: 90 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
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-
81
import {
92
AssistantUnrolled,
103
decodePackageIdentifier,
114
mergeUnrolledAssistants,
125
PackageIdentifier,
136
} from "@continuedev/config-yaml";
7+
import { DefaultApiInterface } from "@continuedev/sdk/dist/api/dist/index.js";
8+
149
import { isStringRule } from "src/hubLoader.js";
1510
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+
1617
import { BaseService, ServiceWithDependencies } from "./BaseService.js";
1718
import { serviceContainer } from "./ServiceContainer.js";
1819
import {
@@ -71,83 +72,129 @@ export class ConfigService
7172
prompts: [],
7273
};
7374

74-
const {
75-
model = [],
76-
mcp = [],
77-
rule = [],
78-
prompt = [],
79-
} = injectedConfigOptions || {};
75+
const options = injectedConfigOptions || {};
8076

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];
82105
if (agentFileState?.agentFile?.model) {
83-
model.push(agentFileState.agentFile.model);
106+
allModels.push(agentFileState.agentFile.model);
84107
}
85-
for (const _model of model) {
108+
109+
for (const model of allModels) {
86110
try {
87-
packageIdentifiers.push(decodePackageIdentifier(_model));
111+
packageIdentifiers.push(decodePackageIdentifier(model));
88112
} catch (e) {
89-
logger.warn(`Failed to add modl "${_model}": ${getErrorString(e)}`);
113+
logger.warn(`Failed to add model "${model}": ${getErrorString(e)}`);
90114
}
91115
}
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+
];
92128

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) {
96130
try {
97-
if (_mcp.startsWith("http://") || _mcp.startsWith("https://")) {
131+
if (this.isUrl(mcp)) {
98132
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,
102135
});
103136
} else {
104-
packageIdentifiers.push(decodePackageIdentifier(_mcp));
137+
packageIdentifiers.push(decodePackageIdentifier(mcp));
105138
}
106139
} catch (e) {
107-
logger.warn(`Failed to add MCP server "${_mcp}": ${getErrorString(e)}`);
140+
logger.warn(`Failed to add MCP server "${mcp}": ${getErrorString(e)}`);
108141
}
109142
}
143+
}
110144

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 || []) {
113150
try {
114-
packageIdentifiers.push(decodePackageIdentifier(r));
151+
packageIdentifiers.push(decodePackageIdentifier(rule));
115152
} catch (e) {
116153
logger.warn(
117-
`Failed to get rule "${r} (from agent file)": ${getErrorString(e)}`,
154+
`Failed to get rule "${rule} (from agent file)": ${getErrorString(e)}`,
118155
);
119156
}
120157
}
158+
}
121159

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) {
124169
try {
125-
if (isStringRule(_rule)) {
126-
additional.rules!.push(_rule);
170+
if (isStringRule(item)) {
171+
additional.rules!.push(item);
127172
} else {
128-
packageIdentifiers.push(decodePackageIdentifier(_rule));
173+
packageIdentifiers.push(decodePackageIdentifier(item));
129174
}
130175
} catch (e) {
131176
logger.warn(
132-
`Failed to load rule or prompt "${_rule}": ${getErrorString(e)}`,
177+
`Failed to load rule or prompt "${item}": ${getErrorString(e)}`,
133178
);
134179
}
135180
}
181+
}
136182

137-
// Agent file prompt can only be a string
183+
private processAgentFilePrompt(
184+
agentFileState: AgentFileServiceState | undefined,
185+
additional: AssistantUnrolled,
186+
): void {
138187
if (agentFileState?.agentFile?.prompt) {
139188
additional.prompts!.push({
140189
name: `Agent prompt (${agentFileState.agentFile.name})`,
141190
prompt: agentFileState.agentFile.prompt,
142191
description: agentFileState.agentFile.description,
143192
});
144193
}
194+
}
145195

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://");
151198
}
152199

153200
private async loadConfig(

extensions/cli/src/services/index.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { Configuration, DefaultApi } from "@continuedev/sdk/dist/api";
12
import { vi } from "vitest";
23

3-
import { Configuration, DefaultApi } from "@continuedev/sdk/dist/api";
44
import { initializeServices, services } from "./index.js";
55

66
// Mock the onboarding module

packages/config-yaml/src/load/unroll.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ export interface DoNotRenderSecretsUnrollAssistantOptions
215215
export interface RenderSecretsUnrollAssistantOptions
216216
extends BaseUnrollAssistantOptions {
217217
renderSecrets: true;
218+
replaceInputsWithSecrets?: boolean;
218219
orgScopeId: string | null;
219220
currentUserSlug: string;
220221
platformClient: PlatformClient;
@@ -294,7 +295,7 @@ export async function unrollAssistantFromContent(
294295

295296
// Convert all of the template variables to FQSNs
296297
// Secrets from the block will have the assistant slug prepended to the FQSN
297-
const templatedYaml = renderTemplateData(rawUnrolledYaml, {
298+
let templatedYaml = renderTemplateData(rawUnrolledYaml, {
298299
secrets: extractFQSNMap(rawUnrolledYaml, [id]),
299300
});
300301

@@ -306,6 +307,10 @@ export async function unrollAssistantFromContent(
306307
};
307308
}
308309

310+
if (options.replaceInputsWithSecrets) {
311+
templatedYaml = replaceInputsWithSecrets(templatedYaml);
312+
}
313+
309314
// Render secret values/locations for client
310315
const secrets = await extractRenderedSecretsMap(
311316
templatedYaml,

0 commit comments

Comments
 (0)