Skip to content

Commit f5a69ea

Browse files
committed
Merge branch 'main' of github.com:continuedev/continue into jacob/con-3563
2 parents 60d0056 + 148a9ea commit f5a69ea

File tree

65 files changed

+1047
-254
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1047
-254
lines changed

.continue/prompts/update-llm-info.prompt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Retrieve the following sites per these providers, and consider these notes on ho
5252
// TODO: add info for openai, ollama, etc
5353

5454
For any other providers, search the web for "latest [provider] models" and find the most relevant model information using your best judgement.
55-
Generally, ignore models that do not support text output. These models will be used in a coding assistant client that only supports text/image input and text/output, so extraneous capabilities can be ignored.
55+
Generally, ignore models that do not support text output. These models will be used in a coding agent client that only supports text/image input and text/output, so extraneous capabilities can be ignored.
5656
Sometimes, "Experimental", "Preview", or similar versions of models are available. The latest-date version of each should have its own information maintained.
5757

5858
3. UPDATE THE INFORMATION

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ body:
2929
- **Continue version**: v0.9.4
3030
- **IDE version**: VSCode 1.85.1
3131
- Model: Claude Sonnet 3.5
32-
- Assistant configuration
32+
- Agent configuration
3333
value: |
3434
- OS:
3535
- Continue version:
@@ -39,7 +39,7 @@ body:
3939
```yaml
4040
4141
```
42-
OR link to assistant in Continue hub:
42+
OR link to agent in Continue hub:
4343
render: Markdown
4444
validations:
4545
required: false

.github/workflows/main-build.yaml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,19 @@ jobs:
2424

2525
- name: Get merged PR number
2626
id: get-pr
27+
env:
28+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2729
run: |
28-
# Get the commit message of the merge commit
29-
COMMIT_MSG=$(git log --format=%B -n 1 HEAD)
30-
echo "Commit message: $COMMIT_MSG"
30+
# Get PR number for the current commit using GitHub API
31+
COMMIT_SHA=$(git rev-parse HEAD)
32+
echo "Getting PR for commit: $COMMIT_SHA"
3133
32-
# Extract PR number from merge commit message (format: "Merge pull request #123 from...")
33-
PR_NUMBER=$(echo "$COMMIT_MSG" | grep -o "Merge pull request #[0-9]*" | grep -o "[0-9]*" || echo "6723")
34+
PR_NUMBER=$(curl -s -H "Authorization: token $GH_TOKEN" \
35+
"https://api.github.com/repos/${{ github.repository }}/commits/$COMMIT_SHA/pulls" \
36+
| jq -r '.[0].number // empty')
3437
3538
if [ -z "$PR_NUMBER" ]; then
36-
echo "❌ Could not extract PR number from commit message. This might not be a PR merge."
37-
echo "Commit message was: $COMMIT_MSG"
39+
echo "❌ Could not find PR for commit $COMMIT_SHA"
3840
exit 1
3941
fi
4042

.github/workflows/reusable-release.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ jobs:
5151
with:
5252
fetch-depth: 0
5353

54+
- name: Setup packages
55+
uses: ./.github/actions/setup-packages
56+
5457
- name: Use Node.js from .nvmrc
5558
uses: actions/setup-node@v4
5659
with:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,5 @@ extensions/.continue-debug/
170170

171171
.continuerules
172172
**/.continue/assistants/
173+
**/.continue/agents/
173174
keys

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,4 +288,4 @@ We require all contributors to accept the CLA and have made it as easy as commen
288288
I have read the CLA Document and I hereby sign the CLA
289289
```
290290

291-
3. The CLAAssistant bot records your signature in the repo and marks the status check as passed.
291+
3. The CLA-Assistant bot records your signature in the repo and marks the status check as passed.

core/config/ConfigHandler.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import { PolicySingleton } from "../control-plane/PolicySingleton.js";
2121
import { Logger } from "../util/Logger.js";
2222
import { Telemetry } from "../util/posthog.js";
2323
import {
24-
ASSISTANTS,
2524
getAllDotContinueDefinitionFiles,
2625
LoadAssistantFilesOptions,
2726
} from "./loadLocalAssistants.js";
@@ -339,7 +338,7 @@ export class ConfigHandler {
339338

340339
async getLocalProfiles(options: LoadAssistantFilesOptions) {
341340
/**
342-
* Users can define as many local assistants as they want in a `.continue/assistants` folder
341+
* Users can define as many local agents as they want in a `.continue/agents` (or previous .continue/assistants) folder
343342
*/
344343

345344
// Local customization disabled for on-premise deployments
@@ -358,9 +357,14 @@ export class ConfigHandler {
358357
const assistantFiles = await getAllDotContinueDefinitionFiles(
359358
this.ide,
360359
options,
361-
ASSISTANTS,
360+
"assistants",
362361
);
363-
const profiles = assistantFiles.map((assistant) => {
362+
const agentFiles = await getAllDotContinueDefinitionFiles(
363+
this.ide,
364+
options,
365+
"agents",
366+
);
367+
const profiles = [...assistantFiles, ...agentFiles].map((assistant) => {
364368
return new LocalProfileLoader(
365369
this.ide,
366370
this.ideSettingsPromise,

core/config/default.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ export const defaultContextProvidersJetBrains: NonNullable<
2121
];
2222

2323
export const defaultConfig: ConfigYaml = {
24-
name: "Local Assistant",
24+
name: "Local Agent",
2525
version: "1.0.0",
2626
schema: "v1",
2727
models: [],
2828
context: defaultContextProvidersVsCode,
2929
};
3030

3131
export const defaultConfigJetBrains: ConfigYaml = {
32-
name: "Local Assistant",
32+
name: "Local Agent",
3333
version: "1.0.0",
3434
schema: "v1",
3535
models: [],

core/config/loadLocalAssistants.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ import { getGlobalFolderWithName } from "../util/paths";
1010
import { localPathToUri } from "../util/pathToUri";
1111
import { joinPathsToUri } from "../util/uri";
1212

13-
export const ASSISTANTS = "assistants";
14-
export const ASSISTANTS_FOLDER = `.continue/${ASSISTANTS}`;
15-
1613
export function isLocalDefinitionFile(uri: string): boolean {
1714
if (!uri.endsWith(".yaml") && !uri.endsWith(".yml") && !uri.endsWith(".md")) {
1815
return false;
1916
}
2017

2118
const normalizedUri = URI.normalize(uri);
22-
return normalizedUri.includes(`/${ASSISTANTS_FOLDER}/`);
19+
return (
20+
normalizedUri.includes(`/.continue/agents/`) ||
21+
normalizedUri.includes(`/.continue/assistants/`)
22+
);
2323
}
2424

2525
async function getDefinitionFilesInDir(

core/config/loadLocalAssistants.vitest.ts

Lines changed: 230 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
getAllDotContinueDefinitionFiles,
77
LoadAssistantFilesOptions,
88
} from "./loadLocalAssistants";
9-
describe("getAllDotContinueDefinitionFiles with fileExtType option", () => {
9+
describe("ASSISTANTS getAllDotContinueDefinitionFiles with fileExtType option", () => {
1010
beforeEach(() => {
1111
setUpTestDir();
1212
walkDirCache.invalidate();
@@ -240,3 +240,232 @@ describe("getAllDotContinueDefinitionFiles with fileExtType option", () => {
240240
);
241241
});
242242
});
243+
244+
describe("AGENTS getAllDotContinueDefinitionFiles with fileExtType option", () => {
245+
beforeEach(() => {
246+
setUpTestDir();
247+
walkDirCache.invalidate();
248+
249+
// Add test files to the test directory
250+
addToTestDir([
251+
".continue/agents/",
252+
[".continue/agents/agent1.yaml", "yaml content 1"],
253+
[".continue/agents/agent2.yml", "yaml content 2"],
254+
[".continue/agents/agent3.md", "markdown content 1"],
255+
[".continue/agents/agent4.txt", "txt content"],
256+
]);
257+
});
258+
259+
afterEach(() => {
260+
tearDownTestDir();
261+
walkDirCache.invalidate();
262+
});
263+
264+
it("should return only YAML files when fileExtType is 'yaml'", async () => {
265+
const options: LoadAssistantFilesOptions = {
266+
includeGlobal: false, // Only test workspace for simplicity
267+
includeWorkspace: true,
268+
fileExtType: "yaml",
269+
};
270+
271+
const result = await getAllDotContinueDefinitionFiles(
272+
testIde,
273+
options,
274+
"agents",
275+
);
276+
expect(result).toHaveLength(2);
277+
expect(result.map((f) => f.path.split("/").pop())).toEqual(
278+
expect.arrayContaining(["agent1.yaml", "agent2.yml"]),
279+
);
280+
expect(result.map((f) => f.path.split("/").pop())).not.toContain(
281+
"agent3.md",
282+
);
283+
});
284+
285+
it("should return only Markdown files when fileExtType is 'markdown'", async () => {
286+
const options: LoadAssistantFilesOptions = {
287+
includeGlobal: false,
288+
includeWorkspace: true,
289+
fileExtType: "markdown",
290+
};
291+
292+
const result = await getAllDotContinueDefinitionFiles(
293+
testIde,
294+
options,
295+
"agents",
296+
);
297+
expect(result).toHaveLength(1);
298+
expect(result.map((f) => f.path.split("/").pop())).toEqual(["agent3.md"]);
299+
expect(result.map((f) => f.path.split("/").pop())).not.toContain(
300+
"agent1.yaml",
301+
);
302+
expect(result.map((f) => f.path.split("/").pop())).not.toContain(
303+
"agent2.yml",
304+
);
305+
});
306+
307+
it("should return all supported files when fileExtType is not specified", async () => {
308+
const options: LoadAssistantFilesOptions = {
309+
includeGlobal: false,
310+
includeWorkspace: true,
311+
// fileExtType not specified
312+
};
313+
314+
const result = await getAllDotContinueDefinitionFiles(
315+
testIde,
316+
options,
317+
"agents",
318+
);
319+
expect(result).toHaveLength(3);
320+
expect(result.map((f) => f.path.split("/").pop())).toEqual(
321+
expect.arrayContaining(["agent1.yaml", "agent2.yml", "agent3.md"]),
322+
);
323+
// Should not include .txt files
324+
expect(result.map((f) => f.path.split("/").pop())).not.toContain(
325+
"agent4.txt",
326+
);
327+
});
328+
329+
it("should respect includeWorkspace option with fileExtType", async () => {
330+
// Test with includeWorkspace: false
331+
const workspaceOffOptions: LoadAssistantFilesOptions = {
332+
includeGlobal: false,
333+
includeWorkspace: false,
334+
fileExtType: "yaml",
335+
};
336+
337+
const noWorkspaceResult = await getAllDotContinueDefinitionFiles(
338+
testIde,
339+
workspaceOffOptions,
340+
"agents",
341+
);
342+
expect(noWorkspaceResult).toHaveLength(0);
343+
344+
// Test with includeWorkspace: true
345+
const workspaceOnOptions: LoadAssistantFilesOptions = {
346+
includeGlobal: false,
347+
includeWorkspace: true,
348+
fileExtType: "yaml",
349+
};
350+
351+
const workspaceResult = await getAllDotContinueDefinitionFiles(
352+
testIde,
353+
workspaceOnOptions,
354+
"agents",
355+
);
356+
expect(workspaceResult).toHaveLength(2);
357+
expect(workspaceResult.map((f) => f.path.split("/").pop())).toEqual(
358+
expect.arrayContaining(["agent1.yaml", "agent2.yml"]),
359+
);
360+
});
361+
362+
it("should return empty array when no files match the specified extension type", async () => {
363+
// Create a test directory with only non-matching files
364+
tearDownTestDir();
365+
walkDirCache.invalidate();
366+
setUpTestDir();
367+
addToTestDir([
368+
".continue/agents/",
369+
[".continue/agents/nonmatch1.txt", "txt content"],
370+
[".continue/agents/nonmatch2.json", "json content"],
371+
]);
372+
373+
const options: LoadAssistantFilesOptions = {
374+
includeGlobal: false,
375+
includeWorkspace: true,
376+
377+
fileExtType: "yaml",
378+
};
379+
380+
const result = await getAllDotContinueDefinitionFiles(
381+
testIde,
382+
options,
383+
"agents",
384+
);
385+
expect(result).toHaveLength(0);
386+
});
387+
388+
it("should handle directories that don't exist", async () => {
389+
// Create a clean test directory without the agents folder
390+
tearDownTestDir();
391+
setUpTestDir();
392+
393+
const options: LoadAssistantFilesOptions = {
394+
includeGlobal: false,
395+
includeWorkspace: true,
396+
fileExtType: "yaml",
397+
};
398+
399+
const result = await getAllDotContinueDefinitionFiles(
400+
testIde,
401+
options,
402+
"agents",
403+
);
404+
expect(result).toHaveLength(0);
405+
});
406+
407+
it("should return correct file content", async () => {
408+
const options: LoadAssistantFilesOptions = {
409+
includeGlobal: false,
410+
includeWorkspace: true,
411+
fileExtType: "yaml",
412+
};
413+
414+
const result = await getAllDotContinueDefinitionFiles(
415+
testIde,
416+
options,
417+
"agents",
418+
);
419+
expect(result).toHaveLength(2);
420+
const yamlFile = result.find((f) => f.path.includes("agent1.yaml"));
421+
expect(yamlFile?.content).toBe("yaml content 1");
422+
});
423+
424+
it("should filter by file extension case sensitively", async () => {
425+
// Add files with uppercase extensions
426+
addToTestDir([
427+
[".continue/agents/agent5.YAML", "uppercase yaml"],
428+
[".continue/agents/agent6.YML", "uppercase yml"],
429+
[".continue/agents/agent7.MD", "uppercase md"],
430+
]);
431+
432+
const yamlOptions: LoadAssistantFilesOptions = {
433+
includeGlobal: false,
434+
includeWorkspace: true,
435+
fileExtType: "yaml",
436+
};
437+
438+
const yamlResult = await getAllDotContinueDefinitionFiles(
439+
testIde,
440+
yamlOptions,
441+
"agents",
442+
);
443+
// Should only get lowercase extensions (current implementation)
444+
expect(yamlResult).toHaveLength(2);
445+
expect(yamlResult.map((f) => f.path.split("/").pop())).toEqual(
446+
expect.arrayContaining(["agent1.yaml", "agent2.yml"]),
447+
);
448+
expect(yamlResult.map((f) => f.path.split("/").pop())).not.toContain(
449+
"agent5.YAML",
450+
);
451+
452+
const markdownOptions: LoadAssistantFilesOptions = {
453+
includeGlobal: false,
454+
includeWorkspace: true,
455+
fileExtType: "markdown",
456+
};
457+
458+
const markdownResult = await getAllDotContinueDefinitionFiles(
459+
testIde,
460+
markdownOptions,
461+
"agents",
462+
);
463+
expect(markdownResult).toHaveLength(1);
464+
expect(markdownResult.map((f) => f.path.split("/").pop())).toEqual([
465+
"agent3.md",
466+
]);
467+
expect(markdownResult.map((f) => f.path.split("/").pop())).not.toContain(
468+
"agent7.MD",
469+
);
470+
});
471+
});

0 commit comments

Comments
 (0)