mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
Merge branch 'feat/local-model-harness-choice' into feat/local-model-skill-agents
This commit is contained in:
commit
d04fb63837
5 files changed
+117
-12
No files matched your search
@@ -510,6 +510,71 @@ describe('the local model window (real Chromium)', () => {
|
||||
expect(overflow).toBeLessThanOrEqual(0);
|
||||
});
|
||||
|
||||
it('the coding agents: chips that wrap inside the window at every width, the install command included', async () => {
|
||||
const agents = [
|
||||
{ cli: 'opencode', cliLabel: 'OpenCode', default: true, status: 'ready', actions: ['start-session'] },
|
||||
{
|
||||
cli: 'claude',
|
||||
cliLabel: 'Claude Code',
|
||||
default: false,
|
||||
status: 'ready',
|
||||
slowFirstTurn: true,
|
||||
actions: ['start-session'],
|
||||
},
|
||||
{
|
||||
cli: 'pi',
|
||||
cliLabel: 'Pi',
|
||||
default: false,
|
||||
status: 'installable',
|
||||
installCommand: 'npm install -g --ignore-scripts @earendil-works/pi-coding-agent',
|
||||
actions: ['install'],
|
||||
},
|
||||
{ cli: 'deepseek', cliLabel: 'DeepSeek', default: false, status: 'setup-needed', actions: [] },
|
||||
];
|
||||
const answer = {
|
||||
...INSTALLED,
|
||||
install: {
|
||||
...INSTALLED.install,
|
||||
harnesses: agents,
|
||||
actions: [...INSTALLED.install.actions, 'install-agent'],
|
||||
},
|
||||
};
|
||||
for (const [width, height] of [
|
||||
[1440, 900],
|
||||
[390, 844],
|
||||
[320, 640],
|
||||
]) {
|
||||
await load(width, height, answer);
|
||||
await open();
|
||||
// The agent that is not on this Mac: its command is the longest line of the block.
|
||||
await p.locator('.lm-agent', { hasText: 'Pi' }).click();
|
||||
const seen = await p.evaluate(() => {
|
||||
const frame = document.querySelector('.local-model-window')!.getBoundingClientRect();
|
||||
const body = document.getElementById('localModelWindowBody')!;
|
||||
const outside = [...document.querySelectorAll('.lm-agent, .lm-agents .lm-command, .lm-buttons button')]
|
||||
.map((el) => el.getBoundingClientRect())
|
||||
.filter((box) => box.width > 0 && (box.left < frame.left - 0.5 || box.right > frame.right + 0.5)).length;
|
||||
const chips = [...document.querySelectorAll<HTMLElement>('.lm-agent')];
|
||||
return {
|
||||
chips: chips.length,
|
||||
outside,
|
||||
sideways: body.scrollWidth - body.clientWidth,
|
||||
checked: document.querySelector('.lm-agent[aria-checked="true"] .lm-agent-name')!.textContent,
|
||||
tabStops: chips.filter((chip) => chip.tabIndex === 0).length,
|
||||
main: document.querySelector('.lm-buttons .wt-btn-primary')!.textContent,
|
||||
};
|
||||
});
|
||||
expect(seen, `${width}px`).toEqual({
|
||||
chips: 4,
|
||||
outside: 0,
|
||||
sideways: 0,
|
||||
checked: 'Pi',
|
||||
tabStops: 1,
|
||||
main: 'Install Pi',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('paints above App Settings when it is opened from there', async () => {
|
||||
await load(1440);
|
||||
await p.evaluate(() => document.getElementById('appSettingsModal')!.classList.add('active'));
|
||||
|
||||
@@ -2898,7 +2898,7 @@ describe('the coding agents of an installed model', () => {
|
||||
expect(frameOf(page.body).querySelectorAll('.lm-buttons .wt-btn-primary')).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('starts the session with the selected agent, and this device remembers the choice', async () => {
|
||||
it('starts the session with the selected agent, and this device remembers the agent it started', async () => {
|
||||
const page = mount();
|
||||
const { app } = await opened(page, WITH_AGENTS);
|
||||
const launch = launcher(app);
|
||||
@@ -2907,11 +2907,13 @@ describe('the coding agents of an installed model', () => {
|
||||
// What the catalogue says about its first answer.
|
||||
expect(texts(page.body, '.lm-agent-about .lm-aside')).toEqual(['The first answer can take minutes.']);
|
||||
expect(verbs(app)).toEqual([]);
|
||||
// Looking at a chip is not a choice yet.
|
||||
expect(page.dom.window.localStorage.getItem('codeman-local-model-agent')).toBeNull();
|
||||
press(page.body, 'Start a session');
|
||||
await settle();
|
||||
expect(launch).toHaveBeenCalledWith('claude', 'local-ollama');
|
||||
|
||||
// The window opened again later: the last choice stands, not the default.
|
||||
// The window opened again later: the agent last started stands, not the default.
|
||||
expect(page.dom.window.localStorage.getItem('codeman-local-model-agent')).toBe('claude');
|
||||
const again = page.newApp(ok(WITH_AGENTS));
|
||||
await again.loadLocalModel();
|
||||
@@ -2920,6 +2922,27 @@ describe('the coding agents of an installed model', () => {
|
||||
expect(chosen(page)).toBe('Claude Code');
|
||||
});
|
||||
|
||||
it('a chip that was only looked at never hides Start a session when the window is opened again', async () => {
|
||||
const page = mount();
|
||||
const { app } = await opened(page, WITH_AGENTS);
|
||||
pick(page, 'DeepSeek');
|
||||
expect(buttons(page.body)).toEqual(['Remove', 'Stop']);
|
||||
app.closeLocalModelWindow();
|
||||
app.openLocalModelWindow();
|
||||
await settle();
|
||||
// Back on the default agent, with the main action in reach.
|
||||
expect(chosen(page)).toBe('OpenCode');
|
||||
expect(buttons(page.body)).toEqual(['Remove', 'Stop', 'Start a session']);
|
||||
|
||||
// And an agent that was started once and has since been uninstalled does not win either.
|
||||
page.dom.window.localStorage.setItem('codeman-local-model-agent', 'pi');
|
||||
app.closeLocalModelWindow();
|
||||
app.openLocalModelWindow();
|
||||
await settle();
|
||||
expect(chosen(page)).toBe('OpenCode');
|
||||
expect(buttons(page.body)).toEqual(['Remove', 'Stop', 'Start a session']);
|
||||
});
|
||||
|
||||
it('a remembered agent the server no longer lists falls back to the default', async () => {
|
||||
const page = mount();
|
||||
page.dom.window.localStorage.setItem('codeman-local-model-agent', 'gone');
|
||||
|
||||
Reference in new issue
Block a user