)
}
+
+function TargetPillIcon({ provider }: { provider: Provider }) {
+ if (provider.kind === 'acp') return
+ if (provider.type === 'browseros') return
+ return
+}
diff --git a/packages/browseros-agent/apps/agent/entrypoints/app/agent-command/home-compose.helpers.test.ts b/packages/browseros-agent/apps/agent/entrypoints/app/agent-command/home-compose.helpers.test.ts
new file mode 100644
index 000000000..d45bac5df
--- /dev/null
+++ b/packages/browseros-agent/apps/agent/entrypoints/app/agent-command/home-compose.helpers.test.ts
@@ -0,0 +1,55 @@
+import { describe, expect, it } from 'bun:test'
+import type { Provider } from '@/components/chat/chatComponentTypes'
+import { routeHomeSend } from './home-compose.helpers'
+
+const llm: Provider = {
+ id: 'browseros',
+ name: 'BrowserOS',
+ type: 'browseros',
+ kind: 'llm',
+}
+const acp: Provider = {
+ id: 'agent-1',
+ name: 'Review bot',
+ type: 'acp',
+ kind: 'acp',
+ agentId: 'agent-1',
+}
+
+describe('routeHomeSend', () => {
+ it('routes an LLM provider to the in-tab provider chat', () => {
+ expect(routeHomeSend(llm, 'hello')).toEqual({
+ kind: 'llm',
+ providerId: 'browseros',
+ path: '/home/chat?q=hello',
+ })
+ })
+
+ it('routes a named agent to its harness conversation', () => {
+ expect(routeHomeSend(acp, 'do a thing')).toEqual({
+ kind: 'acp',
+ agentId: 'agent-1',
+ path: '/home/agents/agent-1?q=do%20a%20thing',
+ })
+ })
+
+ it('encodes special characters in the query', () => {
+ expect(routeHomeSend(llm, 'a & b?')?.path).toBe(
+ '/home/chat?q=a%20%26%20b%3F',
+ )
+ })
+
+ it('returns null for an empty prompt', () => {
+ expect(routeHomeSend(llm, ' ')).toBeNull()
+ })
+
+ it('returns null for a malformed acp target with no agentId', () => {
+ const acpNoId: Provider = {
+ id: 'agent-x',
+ name: 'Broken',
+ type: 'acp',
+ kind: 'acp',
+ }
+ expect(routeHomeSend(acpNoId, 'hello')).toBeNull()
+ })
+})
diff --git a/packages/browseros-agent/apps/agent/entrypoints/app/agent-command/home-compose.helpers.ts b/packages/browseros-agent/apps/agent/entrypoints/app/agent-command/home-compose.helpers.ts
new file mode 100644
index 000000000..137f12ca7
--- /dev/null
+++ b/packages/browseros-agent/apps/agent/entrypoints/app/agent-command/home-compose.helpers.ts
@@ -0,0 +1,36 @@
+import type { Provider } from '@/components/chat/chatComponentTypes'
+
+export type HomeSendRoute =
+ | { kind: 'llm'; providerId: string; path: string }
+ | { kind: 'acp'; agentId: string; path: string }
+
+/**
+ * Decide where a home-composer submission goes from the selected target.
+ * LLM providers run in the in-tab provider chat (`/home/chat`); named agents
+ * run in their harness conversation (`/home/agents/:id`). Returns null for an
+ * empty prompt. Side effects (setDefaultProvider, setPendingInitialMessage)
+ * are the caller's job — this stays a pure routing decision so it's testable.
+ */
+export function routeHomeSend(
+ provider: Provider,
+ text: string,
+): HomeSendRoute | null {
+ const query = text.trim()
+ if (!query) return null
+ const encoded = encodeURIComponent(query)
+ if (provider.kind === 'acp') {
+ // A malformed acp target (missing agentId) must not silently misroute to
+ // the LLM chat with the agent id treated as a provider id — fail visibly.
+ if (!provider.agentId) return null
+ return {
+ kind: 'acp',
+ agentId: provider.agentId,
+ path: `/home/agents/${provider.agentId}?q=${encoded}`,
+ }
+ }
+ return {
+ kind: 'llm',
+ providerId: provider.id,
+ path: `/home/chat?q=${encoded}`,
+ }
+}
diff --git a/packages/browseros-agent/apps/agent/entrypoints/app/agents/AgentsEmptyState.tsx b/packages/browseros-agent/apps/agent/entrypoints/app/agents/AgentsEmptyState.tsx
index aeac58cde..5d079ddec 100644
--- a/packages/browseros-agent/apps/agent/entrypoints/app/agents/AgentsEmptyState.tsx
+++ b/packages/browseros-agent/apps/agent/entrypoints/app/agents/AgentsEmptyState.tsx
@@ -16,8 +16,8 @@ export const AgentsEmptyState: FC = ({
No agents yet
- Spin up a Claude Code, Codex, or Hermes agent to chat with, schedule, or
- run in the background.
+ Spin up a Claude Code or Codex agent to chat with, schedule, or run in
+ the background.