-
Notifications
You must be signed in to change notification settings - Fork 34
feat(goose): implement agent configuration for workspace preparation #2192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,11 +16,11 @@ | |
| * SPDX-License-Identifier: Apache-2.0 | ||
| ***********************************************************************/ | ||
|
|
||
| import type { Disposable, ExtensionContext } from '@openkaiden/api'; | ||
| import type { AgentConfigurationFile, AgentWorkspaceContext, Disposable, ExtensionContext } from '@openkaiden/api'; | ||
| import { agents } from '@openkaiden/api'; | ||
| import { beforeEach, describe, expect, test, vi } from 'vitest'; | ||
|
|
||
| import { activate } from './extension'; | ||
| import { activate, GOOSE_CONFIG_PATH } from './extension'; | ||
|
|
||
| const AGENT_DISPOSABLE_MOCK: Disposable = { dispose: vi.fn() }; | ||
|
|
||
|
|
@@ -74,4 +74,96 @@ describe('activate', () => { | |
| expect(agent.isSupportedModelType!({ name: 'gemini' })).toBe(true); | ||
| expect(agent.isSupportedModelType!({ name: 'openai' })).toBe(true); | ||
| }); | ||
|
|
||
| test('registers agent with config.yaml configuration file', async () => { | ||
| await activate(extensionContextMock); | ||
|
|
||
| const agent = vi.mocked(agents.registerAgent).mock.calls[0]![0]; | ||
| expect(agent.configurationFiles).toHaveLength(1); | ||
| expect(agent.configurationFiles[0]!.path).toBe(GOOSE_CONFIG_PATH); | ||
| }); | ||
|
|
||
| describe('preWorkspaceStart', () => { | ||
| function createContext(configFiles: AgentConfigurationFile[], modelLabel = 'gpt-4o'): AgentWorkspaceContext { | ||
| return { | ||
| model: { | ||
| model: { label: modelLabel }, | ||
| }, | ||
| configurationFiles: configFiles, | ||
| }; | ||
| } | ||
|
Comment on lines
+87
to
+94
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Description: Check if workspace property is required in AgentWorkspaceContext
# Find the interface definition
echo "=== AgentWorkspaceContext interface definition ==="
ast-grep --pattern $'export interface AgentWorkspaceContext {
$$$
}'
# Check for optional markers on workspace property
echo ""
echo "=== Checking workspace property definition ==="
rg -A2 -B2 'interface AgentWorkspaceContext' packages/extension-api/src/extension-api.d.tsRepository: openkaiden/kaiden Length of output: 1150 Add the required The 🤖 Prompt for AI Agents |
||
|
|
||
| function createConfigFile(content = ''): AgentConfigurationFile & { updateMock: ReturnType<typeof vi.fn> } { | ||
| const updateMock = vi.fn(); | ||
| const file: AgentConfigurationFile = { | ||
| path: GOOSE_CONFIG_PATH, | ||
| read: vi.fn().mockResolvedValue(content), | ||
| update: updateMock, | ||
| }; | ||
| return Object.assign(file, { updateMock }); | ||
| } | ||
|
|
||
| test('writes model configuration into config.yaml', async () => { | ||
| await activate(extensionContextMock); | ||
| const agent = vi.mocked(agents.registerAgent).mock.calls[0]![0]; | ||
|
|
||
| const configFile = createConfigFile(); | ||
| await agent.preWorkspaceStart(createContext([configFile])); | ||
|
|
||
| expect(configFile.updateMock).toHaveBeenCalledOnce(); | ||
| expect(configFile.updateMock.mock.calls[0]![0]).toBe('GOOSE_MODEL: gpt-4o\n'); | ||
| }); | ||
|
|
||
| test('preserves existing configuration fields', async () => { | ||
| await activate(extensionContextMock); | ||
| const agent = vi.mocked(agents.registerAgent).mock.calls[0]![0]; | ||
|
|
||
| const configFile = createConfigFile('GOOSE_PROVIDER: openai\nGOOSE_MODEL: old-model\n'); | ||
| await agent.preWorkspaceStart(createContext([configFile], 'claude-sonnet')); | ||
|
|
||
| const written = configFile.updateMock.mock.calls[0]![0] as string; | ||
| expect(written).toContain('GOOSE_PROVIDER: openai'); | ||
| expect(written).toContain('GOOSE_MODEL: claude-sonnet'); | ||
| expect(written).not.toContain('old-model'); | ||
| }); | ||
|
|
||
| test('preserves existing YAML comments', async () => { | ||
| await activate(extensionContextMock); | ||
| const agent = vi.mocked(agents.registerAgent).mock.calls[0]![0]; | ||
|
|
||
| const configFile = createConfigFile('# existing comment\nGOOSE_PROVIDER: openai\n'); | ||
| await agent.preWorkspaceStart(createContext([configFile], 'claude-sonnet')); | ||
|
|
||
| const written = configFile.updateMock.mock.calls[0]![0] as string; | ||
| expect(written).toContain('# existing comment'); | ||
| expect(written).toContain('GOOSE_PROVIDER: openai'); | ||
| expect(written).toContain('GOOSE_MODEL: claude-sonnet'); | ||
| }); | ||
|
|
||
| test('handles empty config file', async () => { | ||
| await activate(extensionContextMock); | ||
| const agent = vi.mocked(agents.registerAgent).mock.calls[0]![0]; | ||
|
|
||
| const configFile = createConfigFile(''); | ||
| await agent.preWorkspaceStart(createContext([configFile], 'gemini-2.5-pro')); | ||
|
|
||
| expect(configFile.updateMock.mock.calls[0]![0]).toBe('GOOSE_MODEL: gemini-2.5-pro\n'); | ||
| }); | ||
|
|
||
| test('does nothing when config file is not in context', async () => { | ||
| await activate(extensionContextMock); | ||
| const agent = vi.mocked(agents.registerAgent).mock.calls[0]![0]; | ||
|
|
||
| const updateMock = vi.fn(); | ||
| const otherFile: AgentConfigurationFile = { | ||
| path: 'some/other/path.yaml', | ||
| read: vi.fn(), | ||
| update: updateMock, | ||
| }; | ||
|
|
||
| await agent.preWorkspaceStart(createContext([otherFile])); | ||
|
|
||
| expect(updateMock).not.toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
| }); | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: openkaiden/kaiden
Length of output: 1591
Update yaml package from 2.8.2 to 2.9.0 to resolve a MODERATE severity vulnerability.
Version 2.8.2 is affected by a Stack Overflow vulnerability via deeply nested YAML collections (published 2026-03-25). The minimum safe version is 2.8.3, but the latest stable release 2.9.0 is recommended.
🤖 Prompt for AI Agents