Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"./state/*": "./src/state/*.ts"
},
"scripts": {
"test": "bun test src/handlers/command-handler.test.ts && bun test src/handlers/clone.test.ts && bun test src/db/adapters/postgres.test.ts && bun test src/db/adapters/sqlite.test.ts src/db/codebases.test.ts src/db/connection.test.ts src/db/conversations.test.ts src/db/env-vars.test.ts src/db/isolation-environments.test.ts src/db/messages.test.ts src/db/sessions.test.ts src/db/workflow-events.test.ts src/db/workflows.test.ts src/utils/defaults-copy.test.ts src/utils/worktree-sync.test.ts src/utils/conversation-lock.test.ts src/utils/credential-sanitizer.test.ts src/utils/port-allocation.test.ts src/utils/error.test.ts src/utils/error-formatter.test.ts src/utils/github-graphql.test.ts src/config/ src/state/ && bun test src/utils/path-validation.test.ts && bun test src/services/cleanup-service.test.ts && bun test src/services/title-generator.test.ts && bun test src/workflows/ && bun test src/operations/workflow-operations.test.ts && bun test src/operations/isolation-operations.test.ts && bun test src/orchestrator/orchestrator.test.ts && bun test src/orchestrator/orchestrator-agent.test.ts && bun test src/orchestrator/orchestrator-isolation.test.ts",
"test": "bun test src/handlers/command-handler.test.ts && bun test src/handlers/clone.test.ts && bun test src/db/adapters/postgres.test.ts && bun test src/db/adapters/sqlite.test.ts src/db/codebases.test.ts src/db/connection.test.ts src/db/env-vars.test.ts src/db/isolation-environments.test.ts src/db/messages.test.ts src/db/sessions.test.ts src/db/workflow-events.test.ts src/db/workflows.test.ts src/utils/defaults-copy.test.ts src/utils/worktree-sync.test.ts src/utils/conversation-lock.test.ts src/utils/credential-sanitizer.test.ts src/utils/port-allocation.test.ts src/utils/error.test.ts src/utils/error-formatter.test.ts src/utils/github-graphql.test.ts src/config/ src/state/ && bun test src/db/conversations.test.ts && bun test src/utils/path-validation.test.ts && bun test src/services/cleanup-service.test.ts && bun test src/services/title-generator.test.ts && bun test src/workflows/ && bun test src/operations/workflow-operations.test.ts && bun test src/operations/isolation-operations.test.ts && bun test src/orchestrator/orchestrator.test.ts && bun test src/orchestrator/orchestrator-agent.test.ts && bun test src/orchestrator/orchestrator-isolation.test.ts",
"type-check": "bun x tsc --noEmit",
"build": "echo 'No build needed - Bun runs TypeScript directly'"
},
Expand Down
49 changes: 47 additions & 2 deletions packages/core/src/db/conversations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,23 @@ mock.module('./connection', () => ({
getDialect: () => mockPostgresDialect,
}));

// Module-level variable to control mock config assistant per test
let mockConfigAssistant = 'claude';

// Mock config-loader to control assistant type in tests without filesystem dependency
mock.module('../config/config-loader', () => ({
loadConfig: async () => ({
assistant: mockConfigAssistant,
assistants: { claude: {}, codex: {} },
botName: 'Archon',
streaming: { telegram: 'stream', discord: 'batch', slack: 'batch' },
paths: { workspaces: '/tmp', worktrees: '/tmp' },
concurrency: { maxConversations: 10 },
commands: { folder: undefined, autoLoad: true },
defaults: { copyDefaults: true, loadDefaultCommands: true, loadDefaultWorkflows: true },
}),
}));

import {
getOrCreateConversation,
updateConversation,
Expand All @@ -31,6 +48,8 @@ describe('conversations', () => {
// Save and clear env var to ensure test isolation
originalDefaultAiAssistant = process.env.DEFAULT_AI_ASSISTANT;
delete process.env.DEFAULT_AI_ASSISTANT;
// Reset mock config to default
mockConfigAssistant = 'claude';
});

afterEach(() => {
Expand All @@ -40,6 +59,7 @@ describe('conversations', () => {
} else {
process.env.DEFAULT_AI_ASSISTANT = originalDefaultAiAssistant;
}
// No need to reset mockConfigAssistant here — beforeEach resets it to 'claude' before each test
});

const existingConversation: Conversation = {
Expand Down Expand Up @@ -122,8 +142,10 @@ describe('conversations', () => {
});

test('uses DEFAULT_AI_ASSISTANT env var when set', async () => {
// Set env var for this test (afterEach will restore original)
// The mock returns mockConfigAssistant directly (env var contract tested in config-loader.test.ts).
// Set both so the test documents that loadConfig() honours DEFAULT_AI_ASSISTANT.
process.env.DEFAULT_AI_ASSISTANT = 'codex';
mockConfigAssistant = 'codex';

const newConversation: Conversation = {
...existingConversation,
Expand All @@ -144,7 +166,30 @@ describe('conversations', () => {
);
});

test('falls back to claude when codebase not found', async () => {
test('uses saved global config defaultAssistant when no env var', async () => {
// Simulate global config having defaultAssistant=codex (set via Settings page)
mockConfigAssistant = 'codex';

const newConversation: Conversation = {
...existingConversation,
id: 'conv-new',
ai_assistant_type: 'codex',
};

mockQuery.mockResolvedValueOnce(createQueryResult([]));
mockQuery.mockResolvedValueOnce(createQueryResult([newConversation]));

const result = await getOrCreateConversation('telegram', 'chat-new');

expect(result).toEqual(newConversation);
expect(mockQuery).toHaveBeenNthCalledWith(
2,
'INSERT INTO remote_agent_conversations (platform_type, platform_conversation_id, ai_assistant_type, codebase_id, cwd) VALUES ($1, $2, $3, $4, $5) RETURNING *',
['telegram', 'chat-new', 'codex', null, null]
);
});

test('uses config default assistant when codebase not found', async () => {
const newConversation: Conversation = {
...existingConversation,
id: 'conv-new',
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/db/conversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { pool, getDialect } from './connection';
import type { Conversation } from '../types';
import { ConversationNotFoundError } from '../types';
import { createLogger } from '@archon/paths';
import { loadConfig } from '../config/config-loader';

/** Lazy-initialized logger (deferred so test mocks can intercept createLogger) */
let cachedLog: ReturnType<typeof createLogger> | undefined;
Expand Down Expand Up @@ -72,7 +73,8 @@ export async function getOrCreateConversation(
// Check if we should inherit from a parent conversation (e.g., Discord thread inheriting from parent channel)
let inheritedCodebaseId: string | null = null;
let inheritedCwd: string | null = null;
let assistantType = process.env.DEFAULT_AI_ASSISTANT ?? 'claude';
const config = await loadConfig();
let assistantType = config.assistant;

if (parentConversationId) {
const parent = await pool.query<Conversation>(
Expand Down
Loading