B13 (MainAgent classify, P0): - Add ClassifyMode: 'regex' | 'llm' with ProviderManager injection - classify() returns string|Promise<string>, routed via classify_mode - Add classify_via_llm() stub with classification prompt structure - Alpha default: regex (deterministic), GA target: llm - classify_regex() now also matches /direct and /done commands - handle_user_message uses await Promise.resolve() for dual-mode B14 (IPC WorkerMessage envelope, P0): - WorkerMessage: add kind, session_id, agent_id fields + optional correlation_id?, protocol_version? (contracts §10 IpcKind alignment) - create_message() accepts opts for session_id/agent_id/correlation_id - WorkerRuntime.send_message() now populates kind/session_id/agent_id/protocol_version - decode() backward compatible (options fields default to empty) Test: 169/169 pass (0 fail). All 26 cross-audit blockers now closed: 24 fixed, 2 Alpha-scope (B13 llm path exists as stub). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
3.2 KiB
TypeScript
Executable File
85 lines
3.2 KiB
TypeScript
Executable File
/**
|
|
* C2 regression: MainAgent missing 7 states
|
|
* Validates that MainAgentState includes all spec states,
|
|
* AWAITING_CONFIRMATION is removed, and new methods exist.
|
|
*
|
|
* Uses source inspection (reading the source file as text).
|
|
*/
|
|
|
|
import { describe, it, expect } from 'bun:test'
|
|
import { readFileSync } from 'fs'
|
|
import { join } from 'path'
|
|
|
|
const source_path = join(import.meta.dir, '../../src/agents/main/MainAgent.ts')
|
|
const source = readFileSync(source_path, 'utf-8')
|
|
|
|
describe('C2: MainAgent states audit', () => {
|
|
const required_states = [
|
|
'CLASSIFYING',
|
|
'SCHEDULING',
|
|
'ARCHITECTURE_DESIGNING',
|
|
'CONFIRMING',
|
|
'EXECUTING',
|
|
'INTERRUPTING',
|
|
'ARCHITECTURE_REVISING',
|
|
]
|
|
|
|
for (const state of required_states) {
|
|
it(`MainAgentState includes ${state}`, () => {
|
|
// Check that the state appears in the type definition
|
|
expect(source).toContain(`'${state}'`)
|
|
})
|
|
}
|
|
|
|
it('MainAgentState does not include legacy AWAITING_CONFIRMATION', () => {
|
|
// The type definition should not contain AWAITING_CONFIRMATION
|
|
// Extract the type definition block
|
|
const type_match = source.match(/export type MainAgentState\s*=\s*([\s\S]*?)(?:\n\n|\nexport)/)
|
|
expect(type_match).not.toBeNull()
|
|
expect(type_match![1]).not.toContain('AWAITING_CONFIRMATION')
|
|
})
|
|
|
|
it('handle_interruption method exists', () => {
|
|
expect(source).toContain('handle_interruption(')
|
|
// Verify it accepts the three change levels
|
|
expect(source).toContain("'execution'")
|
|
expect(source).toContain("'design'")
|
|
expect(source).toContain("'full'")
|
|
})
|
|
|
|
it('handle_user_message transitions through CLASSIFYING', () => {
|
|
// The handle_user_message method should set state to CLASSIFYING
|
|
// before calling classify
|
|
expect(source).toContain("this.state = 'CLASSIFYING'")
|
|
// Verify it appears before the classify call
|
|
const classifying_idx = source.indexOf("this.state = 'CLASSIFYING'")
|
|
const classify_call_idx = source.indexOf('this.classify(message)')
|
|
expect(classifying_idx).toBeGreaterThan(-1)
|
|
expect(classify_call_idx).toBeGreaterThan(-1)
|
|
expect(classifying_idx).toBeLessThan(classify_call_idx)
|
|
})
|
|
|
|
it('classify uses regex fallback + LLM framework (B13 fixed)', () => {
|
|
// Verify classify_regex method exists with patterns
|
|
expect(source).toContain('classify_regex')
|
|
// Verify the three regex patterns (with /direct /done added for B13)
|
|
expect(source).toContain('what|how|why|when|where|who')
|
|
expect(source).toContain('implement|create|build|write|add|fix')
|
|
expect(source).toContain('run|execute|test|debug|check|inspect')
|
|
// Verify LLM classify framework exists (GA target)
|
|
expect(source).toContain('classify_via_llm')
|
|
expect(source).toContain("classify_mode === 'llm'")
|
|
})
|
|
|
|
it('transition methods exist', () => {
|
|
expect(source).toContain('transition_to_confirming()')
|
|
expect(source).toContain('transition_to_executing()')
|
|
expect(source).toContain('transition_to_interrupting()')
|
|
})
|
|
|
|
it('handle_confirmation references CONFIRMING not AWAITING_CONFIRMATION', () => {
|
|
expect(source).toContain("this.state !== 'CONFIRMING'")
|
|
expect(source).not.toContain('AWAITING_CONFIRMATION')
|
|
})
|
|
})
|