Skip to content

feat: add workspace chat agent participants#144

Open
ibourgeois wants to merge 5 commits intomainfrom
codex/feat-135-agent-chat-participants
Open

feat: add workspace chat agent participants#144
ibourgeois wants to merge 5 commits intomainfrom
codex/feat-135-agent-chat-participants

Conversation

@ibourgeois
Copy link
Copy Markdown
Contributor

Summary

  • add first-class workspace agent records and attach them to private workspace chats
  • let the chat composer include an optional agent participant and render agent-backed chats distinctly in the shell
  • harden the rollout with Surreal workspace-agent upgrade repairs and duplicate chat submit protection

Testing

  • php artisan test --compact tests/Feature/WorkspaceAgentParticipantTest.php tests/Feature/DesktopShellTest.php tests/Feature/WorkspaceChatManagementTest.php tests/Feature/WorkspaceManagementTest.php tests/Feature/InstanceConnectionManagementTest.php tests/Feature/DesktopUiFeatureFlagTest.php tests/Feature/SurrealWorkspaceModelTest.php
  • vendor/bin/pint --dirty --format agent

Closes #135

Copilot AI review requested due to automatic review settings March 27, 2026 17:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class workspace agent records and enables selecting an optional agent participant when creating private workspace chats, with UI cues to distinguish agent-backed chats and protections against duplicate chat submissions.

Changes:

  • Introduce WorkspaceAgent + seeding/repair flows and connect agents to chat participants.
  • Update chat creation to optionally attach an agent participant and render agent-backed chats distinctly in the shell.
  • Add a session-backed submission token to prevent duplicate chat creation, plus feature tests covering agent participation and duplicate submits.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/Feature/WorkspaceChatManagementTest.php Adds chat submission token coverage + blank-name and duplicate-submit tests.
tests/Feature/WorkspaceAgentParticipantTest.php Verifies default agent seeding, agent participant chat creation, and UI rendering.
tests/Feature/SurrealWorkspaceModelTest.php Adds Surreal migration/repair test for legacy keyagent_key workflow.
tests/Feature/DesktopShellTest.php Updates shell assertions to include agent participant UI text.
resources/views/welcome.blade.php Adds agent participant selector, submission token hidden input, and submit-once JS behavior; renders meta labels.
database/migrations/2026_03_27_152146_create_workspace_agents_table.php Creates workspace_agents table (with driver-specific constraints).
database/migrations/2026_03_27_152203_add_workspace_agent_id_to_workspace_chat_participants_table.php Adds nullable workspace_agent_id to chat participants (FK on non-Surreal).
database/migrations/2026_03_27_155657_repair_workspace_agents_agent_key_column.php Upgrade repair migration to add/populate agent_key from legacy key.
database/migrations/2026_03_27_160806_drop_legacy_key_column_from_workspace_agents_table.php Drops legacy key column after repair.
database/factories/WorkspaceChatParticipantFactory.php Adds workspace_agent_id + helper for creating agent participants.
database/factories/WorkspaceAgentFactory.php Adds factory + workspace guide preset.
app/Support/Connections/InstanceConnectionManager.php Ensures default agents exist for active/created workspaces.
app/Support/Chats/WorkspaceChatManager.php Supports optional agent participant and validates blank names / invalid workspace agents.
app/Support/Chats/WorkspaceAgentManager.php New manager to seed and fetch workspace agents.
app/Models/WorkspaceChatParticipant.php Adds workspace_agent_id fillable + agent() relation.
app/Models/WorkspaceAgent.php New model for workspace agents + relations.
app/Models/Workspace.php Adds agents() relation.
app/Http/Requests/StoreWorkspaceChatRequest.php Trims chat name and validates submission token + optional agent id.
app/Http/Controllers/HomeController.php Builds available agent list, sets chat submission token, and adds agent-backed chat rendering metadata.
app/Http/Controllers/ChatController.php Enforces one-time submission token check on chat creation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +60 to +68
$duplicateAgentIds = $existingAgents
->get($definition['agent_key'])
?->slice(1)
->map(fn (WorkspaceAgent $duplicateAgent): int => (int) $duplicateAgent->getKey())
->all() ?? [];

if ($duplicateAgentIds !== []) {
$workspace->agents()->whereKey($duplicateAgentIds)->delete();
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensureDefaults() deletes duplicate agents (same agent_key) unconditionally. If any existing workspace_chat_participants.workspace_agent_id rows reference one of the deleted duplicates, those participants will become orphaned (or null via FK nullOnDelete) and the chat will lose its agent association. Before deleting duplicates, re-point any related chat participants to the surviving agent (or skip deletion when duplicates are referenced) so repairs don’t silently drop existing agent-backed chats.

Copilot uses AI. Check for mistakes.
Comment on lines 22 to +51
@@ -36,8 +43,13 @@ public function store(
$chatManager->createChat($activeWorkspace, $request->user(), $viewerIdentity, [
'name' => $request->validated('chat_name'),
'kind' => $request->validated('chat_kind'),
'workspace_agent_id' => $request->integer('workspace_agent_id') ?: null,
]);

if (hash_equals((string) $request->session()->get('chat.create_token'), $submittedToken)) {
$request->session()->forget('chat.create_token');
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The submission-token protection isn’t race-safe: the token is validated, then the chat is created, and only afterwards the session token is cleared. Two near-simultaneous POSTs can both pass the initial hash_equals check and create duplicate chats. Consider consuming/invalidating the token before creating the chat (or using an atomic server-side idempotency mechanism such as a DB-backed unique token per user/workspace) so concurrent requests can’t both succeed.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +32
foreach ($chatIds as $chatId) {
DB::table('workspace_chats')
->where('id', $chatId)
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This backfill loops and runs one update per chat id inside each chunk. This can become very slow on large datasets. Prefer a single bulk update per chunk (e.g., whereIn('id', $chatIds)), or even a single update using a subquery/join where supported, to avoid N updates.

Suggested change
foreach ($chatIds as $chatId) {
DB::table('workspace_chats')
->where('id', $chatId)
if (! empty($chatIds)) {
DB::table('workspace_chats')
->whereIn('id', $chatIds)

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add agent participants to private chats

2 participants