Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
97ecf81
feat(groups): add TASK_FORCE discussion style for collaborative task …
ginccc Jun 25, 2026
40ebf1b
fix(groups): code review fixes β€” thread safety, verification parser, …
ginccc Jun 25, 2026
8b15c9d
fix(groups): final review β€” duplicate task bug, regression tests, def…
ginccc Jun 25, 2026
498b828
docs(changelog): final review entry β€” duplicate task fix, 20 regressi…
ginccc Jun 25, 2026
32dc3e5
fix(groups): enforce tenant quota abort in group conversations
ginccc Jun 25, 2026
35b25f3
docs(changelog): tenant quota enforcement fix entry
ginccc Jun 25, 2026
38ce028
fix(groups): quota errors propagate regardless of onAgentFailure policy
ginccc Jun 25, 2026
320e246
docs(changelog): add SKIP policy review finding to quota entry
ginccc Jun 25, 2026
26e584a
feat(groups): dynamic agent system β€” create, recruit, delegate at run…
ginccc Jun 25, 2026
eaa3867
fix(dynamic-agents): critical code review fixes β€” shared tracking lis…
ginccc Jun 25, 2026
d123784
refactor(dynamic-agents): post-review cleanup β€” dead code, teardown o…
ginccc Jun 25, 2026
a8576c3
fix: address CI review findings β€” CodeQL, Copilot, CodeRabbit
ginccc Jun 25, 2026
336fe99
test: comprehensive branch coverage for dynamic agent tools and task …
ginccc Jun 25, 2026
99fdbb2
docs: update changelog with comprehensive test coverage entry
ginccc Jun 25, 2026
9fa4e14
fix: wire dynamic agent tracking lists to GroupConversation (PR review)
ginccc Jun 25, 2026
832ad00
test(SharedTaskList): add concurrency and deadlock safety tests
ginccc Jun 26, 2026
23a1c91
fix: critical bugs in dynamic agent tracking propagation
ginccc Jun 26, 2026
5d593cf
fix: defensive copies in SharedTaskList, regression tests for trackin…
ginccc Jun 26, 2026
1bd4f84
feat(mcp): add async discussion, delete tool, fix @Blocking on discus…
ginccc Jun 26, 2026
5394303
fix(dynamic-agents): propagate group DynamicAgentConfig, null-safety,…
ginccc Jun 26, 2026
f5b381f
feat(docs,mcp,groups): comprehensive doc update, MCP tool filter fix,…
ginccc Jun 27, 2026
6ab502c
chore: update Manager UI assets (Manager@a11080db)
ginccc Jun 27, 2026
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 AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ Follow this order unless the user explicitly requests something different.
| 7 | Security & Compliance | Secrets Vault, Audit Ledger (EU AI Act), tenant quota stub |
| 8 | MCP Integration | MCP Server (33 tools), MCP Client, agent discovery, managed conversations |
| 8c | RAG Foundation | Config-driven vector store retrieval, pgvector, httpCall RAG |
| 10 | Group Conversations | Multi-agent debate orchestration, 5 styles, group-of-groups |
| 10 | Group Conversations | Multi-agent debate orchestration, 6 styles (incl. Task Force), group-of-groups |
| β€” | A2A Protocol | Agent-to-Agent peer communication, Agent Cards, skill discovery |
| β€” | Multi-Model Cascading | Sequential model escalation with confidence routing |
| β€” | LLM Provider Expansion | 7 β†’ 12 providers (Mistral, Azure OpenAI, Bedrock, Oracle GenAI) |
Expand Down
6 changes: 3 additions & 3 deletions HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -555,18 +555,18 @@ All hooks are **non-fatal** β€” if schedule operations fail, the primary agent o

### Phase 10: Group Conversations β€” Multi-Agent Debate Orchestration βœ…

Phase-based orchestration engine enabling structured multi-agent discussions with 5 preset styles, nested group-of-groups support, and moderator synthesis.
Phase-based orchestration engine enabling structured multi-agent discussions with 6 preset styles, nested group-of-groups support, and moderator synthesis.

| Sub-Phase | Deliverables |
|---|---|
| **10.1** Data Models + Stores | `AgentGroupConfiguration`, `GroupConversation`, group/conversation stores (DB-agnostic) |
| **10.2** Orchestration Service | `GroupConversationService` (~680 lines) β€” phases, context scoping, templates |
| **10.3** REST + SSE + MCP | REST endpoints, SSE streaming, `McpGroupTools` (9 tools) |
| **10.5** Discussion Styles | `DiscussionPhase`, `DiscussionStylePresets` β€” 5 styles + custom phases |
| **10.5** Discussion Styles | `DiscussionPhase`, `DiscussionStylePresets` β€” 6 styles + custom phases |
| **10.5b** MCP/REST Usability | `describe_discussion_styles`, `list_group_conversations`, `GET /styles` |
| **10.6** Group-of-Groups | `MemberType.GROUP`, recursive `executeGroupMemberTurn()`, `memberTypes` param |

**Discussion styles:** `ROUND_TABLE`, `PEER_REVIEW`, `DEVIL_ADVOCATE`, `DELPHI`, `DEBATE` (+ fully custom phases)
**Discussion styles:** `ROUND_TABLE`, `PEER_REVIEW`, `DEVIL_ADVOCATE`, `DELPHI`, `DEBATE`, `TASK_FORCE` (+ fully custom phases)

**Group-of-Groups:** Members can be other groups β€” sub-group synthesized answer becomes member's response. Depth tracking prevents infinite recursion (`eddi.groups.max-depth`, default: 3).

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ Most multi-agent frameworks (LangGraph, CrewAI, AutoGen) are Python/Node librari
### πŸ€– Multi-Agent Orchestration

- πŸ”€ **Intelligent Routing** β€” Direct conversations to different agents based on context, rules, and intent
- πŸ—£οΈ **Group Conversations** β€” Multi-agent debates with 5 built-in discussion styles: Round Table, Peer Review, Devil's Advocate, Delphi, and Debate
- πŸ—£οΈ **Group Conversations** β€” Multi-agent debates with 6 built-in discussion styles: Round Table, Peer Review, Devil's Advocate, Delphi, Debate, and Task Force
- πŸ’¬ **Slack Integration** β€” Deploy agents to Slack channels and run multi-agent debates directly in threads
- πŸͺ† **Nested Groups** β€” Compose groups of groups for tournament brackets, red-team vs blue-team, and panel reviews
- πŸ‘₯ **Managed Conversations** β€” Intent-based auto-routing with one conversation per user per intent
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,7 @@ A `GroupConversationService` orchestrates discussions through configurable phase

**Key capabilities:**

- **5 built-in discussion styles**: Round Table, Peer Review, Devil's Advocate, Delphi, and Debate β€” each with distinct phase flows and turn-taking rules
- **6 built-in discussion styles**: Round Table, Peer Review, Devil's Advocate, Delphi, Debate, and Task Force — each with distinct phase flows and turn-taking rules. Task Force uses a 4-phase pipeline (PLAN→EXECUTE→VERIFY→SYNTHESIS) for structured task decomposition and parallel execution
- **Custom phases**: Define your own phase sequences with configurable context scopes (independent, full transcript, anonymous, own-feedback-only)
- **Group-of-groups**: Members can themselves be groups, enabling hierarchical multi-agent composition with configurable depth limits
- **Fault tolerance**: Per-agent timeouts, configurable failure policies (skip, retry, abort), and graceful degradation when members are unavailable
Expand Down
157 changes: 157 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,165 @@

---

## πŸ§ͺ Comprehensive Branch Coverage for Dynamic Agent System (2026-06-25)

**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** Added 60+ targeted unit tests to cover all uncovered branches in the Task Force / Dynamic Agent feature. Coverage improved from 0.88β†’0.89 instructions (unit tests only; CI with integration tests will exceed 0.90/0.80 thresholds).

### Files Modified (Tests)
- **DynamicAgentToolsTest** (+25 tests): initialMessage flow, extractResponse all branches, blank params, empty allow-lists, retain=false, general exceptions
- **TaskListParserTest** (+22 tests): all JSON key aliases, null/empty members, markdown formats, long text truncation, null displayName safety
- **SharedTaskListTest** (+12 tests): findTasksForAgent(null), wrong status transitions, nonexistent ID exceptions, failTask from various states, setTasks(null)
- **AgentGroupConfigurationTest** (+12 tests): LifecyclePolicy toJson/fromJson, TaskDefinition constructors, DiscussionPhase requiresApproval

### Notes
- Local `mvnw verify` shows 0.89/0.78 because ITs are skipped. CI runs `-DskipITs=false` β†’ exceeds thresholds.
- Total test count: 9,573 (0 failures, 0 errors)

---

## πŸ”§ Dynamic Agent System β€” Critical Code Review Fixes (2026-06-25)


**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** 3-reviewer code review uncovered 6 critical bugs and 8 medium issues. All critical and key medium issues fixed.

### Critical Fixes
- **C1: Shared tracking lists** β€” `AgentOrchestrator` was creating separate `createdAgentIds`/`retainedAgentIds` per whitelist tool call. TeardownAgentTool couldn't see agents created by CreateSubAgentTool. Fixed: shared lists created once, passed to all tools.
- **C2: Retain flag non-functional** β€” `CreateSubAgentTool` accepted `retain=true` but never populated `retainedAgentIds`. Agents were auto-deleted despite LLM requesting retention. Fixed: wired `Set<String> retainedAgentIds` to constructor + `retainedAgentIds.add(agentId)` when retain=true.
- **C3: Double quota counting** β€” `CreateSubAgentTool` called `acquireConversationSlot()` then `startConversation()` also called it internally. Each creation burned 2 quota slots. Fixed: removed explicit quota call from tool.
- **C4: Transcript race condition** β€” `GroupConversation.transcript` was a plain `ArrayList` accessed from parallel virtual threads. Fixed: `Collections.synchronizedList(new ArrayList<>())` + null-safe setter.
- **C5: Dead ERROR detection** β€” `ConverseWithAgentTool.extractResponse()` returned `""` instead of `null`, making `response == null` check dead code. Fixed: returns `null` for empty/missing outputs.
- **C6: Zero test coverage** β€” `ConverseWithAgentTool` had 154 lines of untested code. Added 8 tests covering new conversation, existing conversation, validation, timeout, error state, empty response.

### Medium Fixes
- **M1: LifecyclePolicy enum** β€” `lifecyclePolicy` changed from `String` to `LifecyclePolicy` enum with `@JsonValue`/`@JsonCreator` for kebab-case JSON. Typos now fail at deserialization instead of silently skipping cleanup.
- **M2: synchronizedList streaming** β€” `findMemberIncludingDynamic()` now wraps `findMember(dynamicMembers)` in `synchronized(dynamicMembers)` block.
- **M3: Cycle detection** β€” `SharedTaskList.detectCycles()` now called after task list dependency resolution. Circular deps throw `GroupDiscussionException` fail-fast.
- **M5: unretainAgent()** β€” New `@Tool` method on `TeardownAgentTool` to remove retention flags.
- **M6: Agent removal after teardown** β€” `createdAgentIds.remove(agentId)` after successful undeploy, so counter accurately reflects active agents.
- **M10: Case-insensitive guardrails** β€” Provider/model allow-list checks now use `equalsIgnoreCase()`.

### Test Updates
- `DynamicAgentToolsTest`: +8 ConverseWithAgentTool tests, updated quota test, updated enum assertions
- `GroupConversationTest`: Updated enum count assertions (TranscriptEntryType 11β†’14, GroupConversationState 5β†’6)
- **9,486 tests pass, 0 failures**

---

## ✨ Dynamic Agent System β€” Create, Recruit, Delegate (2026-06-25)


**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** LLM agents in TASK_FORCE group conversations can now dynamically create, recruit, converse with, and teardown other agents at runtime. This enables agentic patterns where a moderator or specialist agent can spin up sub-agents on-the-fly to accomplish tasks.

### Config Model
- **`DynamicAgentConfig`** β€” new inner class on `AgentGroupConfiguration` with config switches for creation, recruitment, delegation, guardrails (provider/model whitelists, per-discussion caps), and lifecycle policy (ephemeral/keep-deployed/undeploy-only/agent-decides)
- **`GroupConversation`** β€” added `dynamicMembers`, `createdAgentIds`, `retainedAgentIds` fields for runtime tracking

### 4 LLM Tools (all `@Vetoed`, per-invocation constructed)
- **`CreateSubAgentTool`** β€” creates + deploys agent via `AgentSetupService`, quota-gated, guardrail-validated, optional initial message
- **`ConverseWithAgentTool`** β€” send messages to any deployed agent, supports multi-turn via conversationId
- **`FindAgentsByCapabilityTool`** β€” discover agents by skill via `CapabilityRegistryService`
- **`TeardownAgentTool`** β€” undeploy/delete created agents + `retainAgent` for lifecycle override

### Wiring
- `AgentOrchestrator` + `LlmTask` β€” 5 new CDI dependencies, whitelist-gated tool names: `create_sub_agent`, `converse_with_agent`, `find_agents_by_capability`, `teardown_agent`
- `GroupConversationService` β€” `findMemberIncludingDynamic()` for task assignment to dynamic members, `cleanupEphemeralAgents()` in finally block with lifecycle policy enforcement

### Tests
- **`DynamicAgentToolsTest`** β€” 22 tests: CreateSubAgent (8), FindAgents (4), Teardown (5), DynamicAgentConfig (2), GroupConversation fields (6)
- All existing test files updated for new constructor signatures (11 files)

---

## πŸ› Fix: Tenant Quota Enforcement in Group Conversations (2026-06-25)

**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** `QuotaExceededException` from `ConversationService` was being silently caught and treated as a per-agent skip/retry. Now detected at 4 levels and causes immediate abort β€” prevents burning N round-trips when quota is exhausted.

- `executeAgentTurn` β†’ `startConversation()`: immediate `GroupDiscussionException`
- `executeAgentTurn` β†’ `say()`: unwrap from `ExecutionException`, abort (bypasses retry policy)
- Task execution loop: quota error exits the agent's `CompletableFuture` immediately
- Parallel phase: quota propagates through `CompletionException`, cancels remaining futures
- Review fix: quota errors in task loop now propagate regardless of `onAgentFailure` policy (was silently lost with SKIP policy)
- +3 regression tests (startConversation quota, say() quota, no-retry-even-with-RETRY-policy). Total: 112 tests, 0 failures.

---

## πŸ› Fix: Final Review β€” Duplicate Task Bug, Regression Tests (2026-06-25)

**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** Second review pass found 3 remaining issues (1 CRITICAL, 1 MEDIUM, 1 dead code). All fixed. Added comprehensive regression tests.

- **C1-final**: `addTask→updateTask` — pre-configured dependency resolution was APPENDING tasks with same ID instead of REPLACING, silently breaking dependency ordering
- **M1-final**: `setMemberConversationIds` defensively wraps in `ConcurrentHashMap` (MongoDB deserialization was replacing with `LinkedHashMap`)
- **Dead code**: Removed unused `snapshotTranscript` from `executeTaskExecutionPhase`
- **New**: `SharedTaskList.updateTask()` public synchronized method
- **Regression tests**: +20 tests covering `resolveTaskAssignment` (7), `tryParseVerificationJson` (6), `handleTaskFailure` (2), `setMemberConversationIds` (2), `updateTask` (3). Total: 109 tests, 0 failures.

---

## πŸ› Fix: TASK_FORCE Code Review β€” Thread Safety, Verification Parser, Error Handling (2026-06-25)

**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** Three-pass code review identified 4 CRITICAL, 6 HIGH, and 4 MEDIUM issues. All fixed.

### Critical Fixes (C1–C4)
- **Thread safety**: All `SharedTaskList` public methods now `synchronized` β€” prevents race conditions during parallel EXECUTE phase
- **ConcurrentHashMap**: `GroupConversation.memberConversationIds` changed from `LinkedHashMap` to `ConcurrentHashMap`
- **Dependency resolution**: Pre-configured `TaskDefinition.dependsOn` subjects now resolved to actual task IDs (was silently dropped)
- **Null guard**: `resolveTaskAssignment` null returns no longer crash `assignTask`

### High Fixes (H1–H6)
- **Transcript snapshot**: EXECUTE phase now takes `List.copyOf(gc.getTranscript())` before launching parallel futures (consistent with `executeParallelPhase`)
- **Timeout semantics**: Changed from `timeout Γ— agentCount` to `timeout Γ— maxTasksPerAgent` (agents run in parallel, tasks per agent are sequential)
- **Round-robin assignment**: `resolveTaskAssignment("ALL")` now distributes evenly across non-moderator members (was always picking first)
- **Verification parser**: Dedicated JSON parser reads `passed` boolean directly (was using heuristic `contains("fail")`)
- **IllegalStateException**: Now caught alongside `GroupDiscussionException` in parallel EXECUTE lambda
- **Error events**: New `handleTaskFailure()` method emits transcript entry + SSE event for failed tasks

### Medium Fixes (M1–M4)
- **Slack**: `TASK_FORCE` added to `EXPANDED_STYLES` set
- **Cycle detection**: Changed from `ArrayList.contains()` O(n) to `HashSet.contains()` O(1)
- **Fallback**: `singleTaskFallback` now preserves LLM output as task description (was discarding it)
- **HITL placeholders**: `BLOCKED` and `AWAITING_APPROVAL` statuses documented as Phase 9b placeholders

### Documentation Updates (6 files)
- `architecture.md`, `group-conversations.md`, `README.md`, `AGENTS.md`, `mcp-server.md`, `slack-integration.md`, `HANDOFF.md` β€” all updated from "5 styles" to "6 styles" with TASK_FORCE entries

### New Tests (+18 tests)
- `SharedTaskListTest`: +11 tests (null findById, nonexistent IDs, verified deps, multiple deps, self-ref cycles, defensive copy, concurrent stress)
- `TaskListParserTest`: +7 tests (empty array, code-fenced JSON, empty members, missing fields, round-robin, tier-3 output preservation)

---

## ✨ Feature: TASK_FORCE Group Orchestration β€” Collaborative Task Accomplishment (2026-06-25)

**Repo:** EDDI (`feat/group-task-orchestration`)
**What changed:** Added a new `TASK_FORCE` discussion style to group conversations. Instead of debating, agents collaborate to accomplish concrete tasks together via a PLAN β†’ EXECUTE β†’ VERIFY β†’ SYNTHESIS pipeline.

### Key Design Decisions

1. **Config-driven**: Tasks can be pre-configured in `AgentGroupConfiguration.tasks[]` (skips PLAN phase) or dynamically generated by the LLM via `TaskListParser` (three-tier fallback: JSON β†’ Markdown β†’ single task).
2. **Reuses existing infrastructure**: Task execution goes through normal agent pipelines. No new REST endpoints.
3. **State embedded in GroupConversation**: `SharedTaskList` is a field on `GroupConversation`, persisted as part of the MongoDB document.
4. **HITL forward-compatible**: `AWAITING_APPROVAL` state added to both `GroupConversationState` and `TaskStatus` for Phase 9b.
5. **Parallel execution**: Tasks for different agents run in parallel; tasks for the same agent run sequentially.

### Files Changed (4 new, 12 modified)

- **New**: `SharedTaskList.java`, `TaskListParser.java`, `SharedTaskListTest.java` (18 tests), `TaskListParserTest.java` (12 tests)
- **Model**: `AgentGroupConfiguration.java` (TASK_FORCE style + enums), `GroupConversation.java` (taskList field + entry types)
- **Orchestration**: `GroupConversationService.java` (~400 LOC task phase logic), `DiscussionStylePresets.java` (expansion + templates)
- **API**: `GroupConversationEventSink.java`, `IGroupConversationService.java`, `RestGroupConversation.java`, `RestAgentGroupStore.java`, `McpGroupTools.java`, `SlackGroupDiscussionListener.java`
- **Tests**: `DiscussionStylePresetsTest.java` (+5 tests), `McpGroupToolsTest.java` (fixed for new param)

---

## πŸ› Fix: Swagger UI CSP Regression β€” Duplicate Header Causes Inline Script Block (2026-06-23)


**Repo:** EDDI (`fix/swagger-csp-duplicate-header`)
**What changed:** Swagger UI showed a blank page on Docker with `Content-Security-Policy` blocking inline scripts (`script-src-elem` violation).

Expand Down
11 changes: 11 additions & 0 deletions docs/group-conversations.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Group Conversations enable multiple agents to discuss a question. Each agent par
| `DEVIL_ADVOCATE` | Opinion β†’ Challenge β†’ Defense β†’ Synthesis | Risk assessment, stress-testing |
| `DELPHI` | Anonymous rounds β†’ convergence β†’ Synthesis | Forecasting, reducing groupthink |
| `DEBATE` | Pro β†’ Con β†’ Rebuttals β†’ Judge | Trade-off analysis, comparisons |
| `TASK_FORCE` | Plan β†’ Execute β†’ Verify β†’ Synthesis | Structured task decomposition, parallel execution |
| `CUSTOM` | Define your own phases | Any workflow |

## Quick Start (MCP)
Expand Down Expand Up @@ -144,6 +145,9 @@ For full control, define phases directly:
| `DEFENSE` | Defend position against challenges |
| `ARGUE` | Present argument for a side (debate) |
| `REBUTTAL` | Counter opposing arguments |
| `PLAN` | Decompose the question into sub-tasks |
| `EXECUTE` | Work on assigned sub-task |
| `VERIFY` | Review and validate another member's work |
| `SYNTHESIS` | Moderator produces balanced conclusion |

### Context Scopes
Expand All @@ -155,6 +159,12 @@ For full control, define phases directly:
| `LAST_PHASE` | Only the previous phase's entries |
| `ANONYMOUS` | Previous entries with speaker names removed |
| `OWN_FEEDBACK` | Only feedback addressed to this agent |
| `TASK_ONLY` | Only this agent's assigned task from the plan |
| `TASK_WITH_DEPS` | Assigned task plus outputs from dependency tasks |

### Pre-Configured Tasks (TASK_FORCE)

The TASK_FORCE style uses a 4-phase pipeline where the moderator first decomposes the question into sub-tasks (PLAN), agents execute their assigned tasks in parallel (EXECUTE), peers verify each other's work (VERIFY), and the moderator synthesizes the final result (SYNTHESIS). The `TASK_ONLY` and `TASK_WITH_DEPS` context scopes ensure agents see only the information relevant to their assigned work.

## Protocol Configuration

Expand Down Expand Up @@ -229,6 +239,7 @@ All discussion styles use the same rendering pattern in Slack:
| **DEVIL_ADVOCATE** | Agent posts β†’ Challenger threads challenges β†’ Agent threads defense β†’ Synthesis |
| **DEBATE** | PRO agent posts β†’ CON agent posts β†’ Rebuttals thread under opponents β†’ Judge synthesizes |
| **DELPHI** | Round 1 agents post β†’ Round 2 agents post (convergence) β†’ Synthesis |
| **TASK_FORCE** | Moderator posts plan β†’ Agents post task results β†’ Verifiers thread under targets β†’ Synthesis |

### Trigger Keywords

Expand Down
Loading
Loading