Commit Graph

3080 Commits

Author SHA1 Message Date
ismeth
f6cdba07ec fix(athena): resolve 4 compatibility and correctness issues
- Use case-insensitive casing in duplicate name test to verify actual logic
- Align permission type with SDK AgentConfig pattern (as AgentConfig["permission"])
- Move duplicate-name validation from schema to runtime for graceful fallback
- Place skipped members details before 'end your turn' in council guard prompt
2026-02-24 22:26:11 +09:00
ismeth
2eb8f5741a rename: fallback-handoff.ts → terminal-detection.ts
The file no longer contains any fallback/handoff logic after the Athena
NLP removal — only generic terminal-event helpers (isTerminalFinishValue,
isTerminalStepFinishPart). Name now matches content.
2026-02-24 22:26:11 +09:00
ismeth
77034fec7e refactor(agent-switch): remove Athena-specific NLP fallback from hook
The fallback scanned Athena's message text for natural-language handoff
phrases ("switching to Atlas", etc.) and synthetically created a pending
switch when the switch_agent tool wasn't called. In practice this path
never fired in real sessions — Athena always correctly called the tool.

Removes ~135 lines of Athena-coupled code, keeping the generic
switch_agent → apply path fully intact.
2026-02-24 22:26:11 +09:00
ismeth
11a4d457bf fix(athena): address 9 council-audit findings — dead code, bugs, and hardening
Fixes from multi-model council audit (7 members, 19 findings, 9 selected):

- Use parseModelString() for cross-provider Anthropic thinking config (#3)
- Update stale AGENTS.md athena directory listing (#4)
- Replace prompt in appendMissingCouncilPrompt instead of appending (#5)
- Extract duplicated session cleanup logic in agent-switch hook (#6)
- Surface skipped council members when >=2 valid members exist (#9)
- Expand fallback handoff regex with negation guards (#11)
- Remove dead council-member agent from agentSources and tests (#12)
- Make runtime council member duplicate check case-insensitive (#14)
- Fix false-positive schema tests by adding required name field (#18)
2026-02-24 22:26:11 +09:00
ismeth
f0d0658eae fix(athena): provider-aware config + better council error messages
Use parsed.providerID/modelID in council member description instead of
raw model string (eliminates dead variable). Track skipped members with
reasons and surface them in the missing-council guard prompt so users
see why their council failed to register.
2026-02-24 22:26:11 +09:00
ismeth
9d0bafbe10 fix(athena): conditional prompt references for missing-council mode 2026-02-24 22:26:11 +09:00
ismeth
0cad3bf2ca chore(athena): remove dead exports and unused barrel file 2026-02-24 22:26:11 +09:00
ismeth
734ef10fbb fix(athena): add schema validation for unique names and sanitization 2026-02-24 22:26:11 +09:00
ismeth
21202ee877 refactor(athena): consolidate tool restriction deny lists to direct boolean records 2026-02-24 22:26:11 +09:00
ismeth
f9fdd08481 refactor(athena): use z.infer types from Zod schema, delete manual interfaces 2026-02-24 22:26:11 +09:00
ismeth
c4deb6bc5d refactor(athena): extract applyModelThinkingConfig shared utility 2026-02-24 22:26:11 +09:00
ismeth
01331af10c refactor(athena): consolidate parseModelString to single source of truth 2026-02-24 22:26:11 +09:00
ismeth
9748688983 fix(athena): replace unsafe type cast with type-safe construction 2026-02-24 22:26:11 +09:00
ismeth
0d30d717e1 fix(agent-switch): correct off-by-one in fallback message cap 2026-02-24 22:26:11 +09:00
ismeth
e44354e98e feat(athena): harden council config — mandatory name, guard prompt, no-crash duplicates
- Add council config guard prompt: when Athena has no valid council members,
  inject a STOP instruction telling the user how to configure council members
  instead of failing messily with generic agents
- Make council member 'name' field mandatory (was optional with auto-naming)
- Remove humanizeModelId and UPPERCASE_TOKENS — no more fragile auto-naming
- Replace throw on duplicate names with log + skip (graceful degradation)
- Update schema, types, tests (87 pass), and documentation
2026-02-24 22:26:11 +09:00
ismeth
6c98677d22 fix(skills): pass directory through skill resolution chain for Desktop mode
Skill discovery in the task tool failed to find project-level skills in
OpenCode Desktop because:

1. resolveSkillContent() never passed directory to the skill resolution
   functions, causing them to fall back to process.cwd() which differs
   from the project directory in Desktop mode.

2. getAllSkills() cache key only included browserProvider, not directory.
   A first call with the wrong directory would cache stale results that
   all subsequent calls (even with correct directory) would return.

3. The error message used discoverSkills() (discovered only) instead of
   getAllSkills() (discovered + builtins), hiding builtin skills from
   the Available list.

Changes:
- skill-resolver.ts: accept and pass directory; use getAllSkills for error msg
- tools.ts: pass options.directory to resolveSkillContent
- skill-discovery.ts: include directory in cache key; rename cache variable
- skill/types.ts + tools.ts: add directory to SkillLoadOptions for consistency
2026-02-24 22:26:01 +09:00
ismeth
0d88fe61f0 fix(athena): update stale test snapshots and keyword-detector log assertions 2026-02-24 22:25:32 +09:00
ismeth
2b73b3f306 docs(athena): remove stale file references and fix tool restriction table
Remove non-existent council-orchestrator.ts and council-prompt.ts from AGENTS.md structure listing. Fix Athena denied tools (add call_omo_agent) and Council-Member denied tools (remove non-existent athena_council). Add council-member-agents.ts to builtin-agents listing. Fix stale athena_council reference in docs/features.md.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:32 +09:00
ismeth
beddc4260e fix(athena): add non-interactive fallback and improve synthesis workflow
Add fallback for CLI run mode when Question tool is denied: auto-select all council members and auto-choose action by question type. Improve synthesis with numbered findings, question type classification (ACTIONABLE/INFORMATIONAL/CONVERSATIONAL), and multi-select finding selection.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
c1bf455b63 fix(athena): harden council registration with duplicate detection and count validation
Three registration improvements: gate council member registration on Athena enablement, throw on duplicate council member keys instead of silent overwrite, and disable council mode when valid members drop below 2 after model parsing.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
7b6d3206ce refactor(schema): replace deprecated .merge() with .extend() and add council-member override
Replace deprecated Zod .merge(z.object({...})) with .extend({...}) for AthenaOverrideConfigSchema. Add council-member to AgentOverridesSchema to match OverridableAgentNameSchema.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
d30d80abbd fix(agent-switch): clear fallback markers on session.error
processedFallbackMessages was only cleaned up on session.deleted, not session.error. This could leak memory for errored sessions. Mirrors the existing session.deleted cleanup pattern.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
74e519e545 fix(athena): add call_omo_agent to ATHENA_RESTRICTIONS for consistent tool denial
ATHENA_RESTRICTIONS only denied write and edit, missing call_omo_agent that the agent factory already denies. This caused 6 callers of getAgentToolRestrictions() to get incomplete restrictions.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
8db2648339 feat(athena): add temperature support to council member schema
Allow per-member temperature overrides in council config. Adds temperature field to CouncilMemberSchema (0-2 range), CouncilMemberConfig type, and auto-generated JSON schema.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
4bc4b36e75 fix(athena): update council member guards for new agent key format
The hasPendingCouncilMembers guard now matches the 'Council: ' prefix from COUNCIL_MEMBER_KEY_PREFIX instead of the old task.agent === 'council-member' check.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:26 +09:00
ismeth
8f0b5d2e1a fix(athena): grant task and question tool permissions
Add Athena to the task tool allow list and grant explicit question tool permission so it can launch council members and present multi-select prompts.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:25 +09:00
ismeth
0ab22daffb feat(athena): rewrite prompts to use task tool for council execution
Athena's system prompt now instructs it to launch council members via task(subagent_type=..., run_in_background=true) and collect results with background_wait. Council member prompt enhanced with structured analysis instructions. Deny call_omo_agent for Athena to prevent tool confusion.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:25 +09:00
ismeth
1413c24886 feat(athena): register council members as task-callable subagents
Each council member from config is now registered as a named agent (e.g. 'Council: Claude Opus 4.6') via registerCouncilMemberAgents(). Adds humanizeModelId() to derive friendly display names from model IDs. Athena's prompt gets the member list appended so it can call task(subagent_type=...) for each.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:25:25 +09:00
ismeth
9887d0a93d refactor(athena): remove athena_council from plugin wiring
Drop the barrel export, tool-registry registration, and agent-tool-restriction entry for the deleted athena_council tool.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
1349948957 refactor(athena): delete athena_council tool directory
Remove the entire custom tool implementation (constants, launcher, session-waiter, tool-helpers, tools, types, and all tests). Council members are now launched via the standard task tool.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
70f074f579 refactor(athena): remove council-orchestrator and council-prompt modules
Delete the orchestrator that launched council members via the custom athena_council tool. This logic is now replaced by standard task() calls from Athena's prompt.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
f5b809ccea refactor(athena): remove dead council types and stale barrel exports
Remove CouncilLaunchFailure, CouncilLaunchedMember, CouncilLaunchResult types and barrel exports for deleted council-orchestrator and council-prompt modules.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
f248a09d53 fix(athena): use background_wait for council progress instead of polling
Athena now uses background_wait (race-style) to collect council results with incremental progress instead of sequential background_output calls or rapid polling. Updated both the system prompt and tool description to guide Athena to the correct waiting pattern.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
b7a3b65106 feat(athena): add background_wait tool for race-style task collection
New tool that takes multiple task IDs and blocks until ANY one completes (Promise.race pattern). Returns the completed task's result plus a progress summary with remaining IDs. Enables Athena to show incremental council progress without polling.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
3d5c96e651 fix(background-output): prioritize block=true over fullSession auto-detection
The fullSession path auto-activated for running tasks and returned immediately, completely bypassing the block=true waiting loop. This caused background_output(block=true) to never actually block, leading to rapid polling spam when agents tried to wait for task completion.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:54 +09:00
ismeth
f29480be90 docs(athena): add Athena and Council-Member to AGENTS.md
- Add both agents to inventory table with model, mode, and fallback info
- Add tool restrictions for Athena (write, edit) and Council-Member
- Add athena/ directory structure to the STRUCTURE section
- Update agent count from 11 to 13

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
f04b73fae3 refactor(athena): remove type assertions and improve agent factories
- Replace 'as AgentConfig' casts with proper typing in agent.ts and council-member-agent.ts
- Extract permission into typed variable following Sisyphus pattern
- Add GPT/non-GPT model branching to council-member-agent
- Use parseModelString for schema validation instead of inline logic
- Add strict() to council and athena config schemas
- Fix athena restriction list (remove redundant athena_council deny)
- Add orchestrator logging for council execution
- Update system prompt to notification-based workflow

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
c8af90715a refactor(athena): extract tool helpers and improve type safety
- Extract helper functions from tools.ts into dedicated tool-helpers.ts
- Replace getToolContextProperty workaround with typed AthenaCouncilToolContext
- Remove dead code path in formatCouncilLaunchFailure
- Add logging for council member launch and session resolution
- Update tool description to reflect notification-based workflow

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
ef74577ccb fix(athena): reduce keyword-detector log noise for Athena sessions
Only log keyword skipping when there are actual keywords to skip, not on every Athena message.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
5dfe0a34fc fix(athena): enable retry and bound growth for agent-switch fallback markers
Delete marker from processedFallbackMessages on failure so message can be retried. Add MAX_PROCESSED_FALLBACK_MARKERS=500 with eviction to prevent unbounded Set growth.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
e8042fa445 fix(athena): harden council tool error handling and type safety
Improve not-configured error message with config file path. Wrap metadataFn in try/catch for best-effort metadata. Replace unsafe as-casts with getToolContextProperty helper. Show Name (model) format in errors. Return error directly for empty member selection.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
87487d8d25 fix(athena): add partial result tracking to session-waiter
Return CouncilSessionWaitResult with timedOut/aborted flags instead of raw array, so callers know when results are partial. Add 5 tests covering normal flow, abort, partial results, and edge cases.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
4da77be93f fix(athena): improve error extraction in council orchestrator
Replace String(result.reason) with proper instanceof Error check to produce clean error messages instead of [object Error] or full stack traces.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
750db54468 fix(athena): add permission restrictions to council-member agent
Add explicit tool denials (write, edit, task, call_omo_agent, athena_council) matching Oracle/Librarian pattern. Simplify static prompt to one-liner since council-prompt.ts provides full instructions.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
197dada95e fix(athena): enforce strict schema validation for council members
Add .strict() to CouncilMemberSchema to reject unknown fields like temperature. Remove unused Zod-inferred type exports. Add test verifying unknown fields are rejected.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
d8c988543f refactor(athena): remove dead session-guard code and unused types
Remove session-guard.ts (runtime gating uses hasPendingCouncilMembers instead), its test file, and dead snake_case type interfaces from types.ts that don't match the camelCase code.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-24 22:24:22 +09:00
ismeth
8381ea076a fix(prompts): normalize agent names for continuation injections 2026-02-24 22:24:22 +09:00
ismeth
21dc48e159 fix(agent-switch): make handoff durable and sync CLI TUI selection 2026-02-24 22:23:28 +09:00
ismeth
697c4c6341 fix(athena): parallelize council launches and gate handoff actions 2026-02-24 22:22:08 +09:00
ismeth
b0e2630db1 fix(athena): make council tool blocking — collect results directly instead of polling
The athena_council tool now waits for all council members to complete and
returns their collected results as markdown, eliminating the need for
Athena to repeatedly call background_output per member (which created
excessive UI noise).

- Add result-collector.ts that polls task status and fetches session content
- Update tool to accept BackgroundOutputClient and return formatted markdown
- Update Athena prompt to remove background_output polling steps
- Rewrite tests for new blocking behavior and markdown output format
2026-02-24 22:21:39 +09:00