agent-relay-server 0.71.0 → 0.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/openapi.json +1 -1
- package/package.json +2 -2
- package/public/assets/MessageBubble-BWdM9UCM.js +3 -0
- package/public/assets/MessageBubble-BWdM9UCM.js.map +1 -0
- package/public/assets/{PlanGraphPanel-BYmE8ldg.js → PlanGraphPanel-icESxd82.js} +2 -2
- package/public/assets/{PlanGraphPanel-BYmE8ldg.js.map → PlanGraphPanel-icESxd82.js.map} +1 -1
- package/public/assets/{activity-BzU196gP.js → activity-BR9I23hc.js} +2 -2
- package/public/assets/{activity-BzU196gP.js.map → activity-BR9I23hc.js.map} +1 -1
- package/public/assets/{agent-profiles-CQuoP8Nr.js → agent-profiles-BB0V-Tg1.js} +2 -2
- package/public/assets/{agent-profiles-CQuoP8Nr.js.map → agent-profiles-BB0V-Tg1.js.map} +1 -1
- package/public/assets/{agents-qH6q44nK.js → agents-Clkboz93.js} +2 -2
- package/public/assets/{agents-qH6q44nK.js.map → agents-Clkboz93.js.map} +1 -1
- package/public/assets/{analytics-EJH9GFID.js → analytics-DRlHs5ho.js} +3 -3
- package/public/assets/{analytics-EJH9GFID.js.map → analytics-DRlHs5ho.js.map} +1 -1
- package/public/assets/{automation-Dahmxg07.js → automation-DlnH_MPy.js} +2 -2
- package/public/assets/{automation-Dahmxg07.js.map → automation-DlnH_MPy.js.map} +1 -1
- package/public/assets/{badge-C6NJQ60B.js → badge-YQhT30dy.js} +2 -2
- package/public/assets/{badge-C6NJQ60B.js.map → badge-YQhT30dy.js.map} +1 -1
- package/public/assets/branch-state-badge-Dg1qnmF5.js +2 -0
- package/public/assets/{branch-state-badge-C7H8HY22.js.map → branch-state-badge-Dg1qnmF5.js.map} +1 -1
- package/public/assets/{button-DD2CCM3t.js → button-CaFI76Ja.js} +2 -2
- package/public/assets/{button-DD2CCM3t.js.map → button-CaFI76Ja.js.map} +1 -1
- package/public/assets/{card-GZqj3rMm.js → card-B_fQtKce.js} +2 -2
- package/public/assets/{card-GZqj3rMm.js.map → card-B_fQtKce.js.map} +1 -1
- package/public/assets/{channels-VhlwES_A.js → channels-BVYLrKUL.js} +2 -2
- package/public/assets/{channels-VhlwES_A.js.map → channels-BVYLrKUL.js.map} +1 -1
- package/public/assets/chat-ml_YzbK4.js +2 -0
- package/public/assets/chat-ml_YzbK4.js.map +1 -0
- package/public/assets/{connectors-C03pRoXx.js → connectors-BOyk5hC3.js} +2 -2
- package/public/assets/{connectors-C03pRoXx.js.map → connectors-BOyk5hC3.js.map} +1 -1
- package/public/assets/copy-button-m00JmflM.js +2 -0
- package/public/assets/{copy-button-DqAoeiPC.js.map → copy-button-m00JmflM.js.map} +1 -1
- package/public/assets/display-LAWaAboe.js.map +1 -1
- package/public/assets/{dist-DByqf8W0.js → dist-B_yrHbsb.js} +2 -2
- package/public/assets/{dist-DByqf8W0.js.map → dist-B_yrHbsb.js.map} +1 -1
- package/public/assets/{dist-C_XTOHbv.js → dist-C-viWls-.js} +2 -2
- package/public/assets/{dist-C_XTOHbv.js.map → dist-C-viWls-.js.map} +1 -1
- package/public/assets/{dist-DMD9fD99.js → dist-CYS2puT9.js} +2 -2
- package/public/assets/{dist-DMD9fD99.js.map → dist-CYS2puT9.js.map} +1 -1
- package/public/assets/{dist-CpugiXtB.js → dist-ChP4KvKi.js} +2 -2
- package/public/assets/{dist-CpugiXtB.js.map → dist-ChP4KvKi.js.map} +1 -1
- package/public/assets/{dist-CePvvSwo.js → dist-Cnlh_NpI.js} +2 -2
- package/public/assets/{dist-CePvvSwo.js.map → dist-Cnlh_NpI.js.map} +1 -1
- package/public/assets/{dist-DJ6ZVqRl.js → dist-CydxJz3m.js} +2 -2
- package/public/assets/{dist-DJ6ZVqRl.js.map → dist-CydxJz3m.js.map} +1 -1
- package/public/assets/{dist-Djf_WfhW.js → dist-D7K3qgp7.js} +2 -2
- package/public/assets/{dist-Djf_WfhW.js.map → dist-D7K3qgp7.js.map} +1 -1
- package/public/assets/{dist-otKoCUDq.js → dist-D8Yr1AIJ.js} +2 -2
- package/public/assets/{dist-otKoCUDq.js.map → dist-D8Yr1AIJ.js.map} +1 -1
- package/public/assets/{dist-BauUE17c.js → dist-DeAdFM5_.js} +2 -2
- package/public/assets/{dist-BauUE17c.js.map → dist-DeAdFM5_.js.map} +1 -1
- package/public/assets/{dist-CROpCfON.js → dist-DeM72J6a.js} +2 -2
- package/public/assets/{dist-CROpCfON.js.map → dist-DeM72J6a.js.map} +1 -1
- package/public/assets/{dist-CW_EpVCQ.js → dist-DfQP9-VC.js} +2 -2
- package/public/assets/{dist-CW_EpVCQ.js.map → dist-DfQP9-VC.js.map} +1 -1
- package/public/assets/{es2015-t3pwjvKi.js → es2015-C3DnXBqu.js} +2 -2
- package/public/assets/{es2015-t3pwjvKi.js.map → es2015-C3DnXBqu.js.map} +1 -1
- package/public/assets/{formatted-body-impl-DhvR8Z-A.js → formatted-body-impl-D2F76gPY.js} +2 -2
- package/public/assets/{formatted-body-impl-DhvR8Z-A.js.map → formatted-body-impl-D2F76gPY.js.map} +1 -1
- package/public/assets/index-CQQTCZxg.css +2 -0
- package/public/assets/index-DYmgI4s4.js +22 -0
- package/public/assets/{index-VGRP16ua.js.map → index-DYmgI4s4.js.map} +1 -1
- package/public/assets/{input-08ItMIki.js → input-Cqqq0OFl.js} +2 -2
- package/public/assets/{input-08ItMIki.js.map → input-Cqqq0OFl.js.map} +1 -1
- package/public/assets/{insights-v9noub5E.js → insights-DylYp2q4.js} +2 -2
- package/public/assets/{insights-v9noub5E.js.map → insights-DylYp2q4.js.map} +1 -1
- package/public/assets/{integrations-BEa3ArUw.js → integrations-B9ViWoJy.js} +2 -2
- package/public/assets/{integrations-BEa3ArUw.js.map → integrations-B9ViWoJy.js.map} +1 -1
- package/public/assets/{lib-CMqRPJG-.js → lib-6L4m0E3M.js} +2 -2
- package/public/assets/{lib-CMqRPJG-.js.map → lib-6L4m0E3M.js.map} +1 -1
- package/public/assets/{lucide-react-BbMYCUlW.js → lucide-react-DI8kTavp.js} +2 -2
- package/public/assets/{lucide-react-BbMYCUlW.js.map → lucide-react-DI8kTavp.js.map} +1 -1
- package/public/assets/{maintenance-DyRfVkhp.js → maintenance-inyZGLys.js} +2 -2
- package/public/assets/{maintenance-DyRfVkhp.js.map → maintenance-inyZGLys.js.map} +1 -1
- package/public/assets/{managed-agents-BSdMoBgG.js → managed-agents-CEFvMPN-.js} +2 -2
- package/public/assets/{managed-agents-BSdMoBgG.js.map → managed-agents-CEFvMPN-.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-DidsrMmn.js → markdown-preview-impl-CniyG4_g.js} +2 -2
- package/public/assets/{markdown-preview-impl-DidsrMmn.js.map → markdown-preview-impl-CniyG4_g.js.map} +1 -1
- package/public/assets/memory-DDYGuRzr.js +2 -0
- package/public/assets/{memory-DM8muGVW.js.map → memory-DDYGuRzr.js.map} +1 -1
- package/public/assets/{messages-BqjAkcBF.js → messages-BMFcsMMa.js} +2 -2
- package/public/assets/{messages-BqjAkcBF.js.map → messages-BMFcsMMa.js.map} +1 -1
- package/public/assets/{orchestrators-C_mjUDZg.js → orchestrators-D5nL4a52.js} +2 -2
- package/public/assets/{orchestrators-C_mjUDZg.js.map → orchestrators-D5nL4a52.js.map} +1 -1
- package/public/assets/{overview-Cpu2plX-.js → overview-DywDrPKE.js} +2 -2
- package/public/assets/{overview-Cpu2plX-.js.map → overview-DywDrPKE.js.map} +1 -1
- package/public/assets/{pairs--8_0A0lq.js → pairs-UvIyBk4w.js} +2 -2
- package/public/assets/{pairs--8_0A0lq.js.map → pairs-UvIyBk4w.js.map} +1 -1
- package/public/assets/{projects-nCww9PG1.js → projects-DXBjwPU5.js} +2 -2
- package/public/assets/{projects-nCww9PG1.js.map → projects-DXBjwPU5.js.map} +1 -1
- package/public/assets/{react-dom-HJwa4sZ-.js → react-dom-Ct8qXivQ.js} +2 -2
- package/public/assets/{react-dom-HJwa4sZ-.js.map → react-dom-Ct8qXivQ.js.map} +1 -1
- package/public/assets/{security-CwgoEvJT.js → security-Boe7MEIz.js} +2 -2
- package/public/assets/{security-CwgoEvJT.js.map → security-Boe7MEIz.js.map} +1 -1
- package/public/assets/{select-Bhx6zSZr.js → select-Dh5Q8rJ8.js} +2 -2
- package/public/assets/{select-Bhx6zSZr.js.map → select-Dh5Q8rJ8.js.map} +1 -1
- package/public/assets/{settings-BNQBnKXg.js → settings-Ch4jMDrE.js} +3 -3
- package/public/assets/{settings-BNQBnKXg.js.map → settings-Ch4jMDrE.js.map} +1 -1
- package/public/assets/{store-BB-YW24l.js → store-BRvMMH5T.js} +2 -2
- package/public/assets/{store-BB-YW24l.js.map → store-BRvMMH5T.js.map} +1 -1
- package/public/assets/{tasks-C5Kv18N7.js → tasks-DrW8R52c.js} +2 -2
- package/public/assets/{tasks-C5Kv18N7.js.map → tasks-DrW8R52c.js.map} +1 -1
- package/public/assets/{teams-D_Ttv7qD.js → teams-CJqpAwmO.js} +2 -2
- package/public/assets/{teams-D_Ttv7qD.js.map → teams-CJqpAwmO.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-5y8v9jNx.js → terminal-viewer-impl-1_7v8GfU.js} +3 -3
- package/public/assets/{terminal-viewer-impl-5y8v9jNx.js.map → terminal-viewer-impl-1_7v8GfU.js.map} +1 -1
- package/public/assets/{use-keyboard-viewport-CEmOxaNm.js → use-keyboard-viewport-DxmCAbQi.js} +2 -2
- package/public/assets/{use-keyboard-viewport-CEmOxaNm.js.map → use-keyboard-viewport-DxmCAbQi.js.map} +1 -1
- package/public/assets/work-queue-BnIi7evb.js +2 -0
- package/public/assets/{work-queue-BB7bYLIK.js.map → work-queue-BnIi7evb.js.map} +1 -1
- package/public/assets/workspaces-u5j6mOlA.js +3 -0
- package/public/assets/{workspaces-CrtAeVnv.js.map → workspaces-u5j6mOlA.js.map} +1 -1
- package/public/index.html +21 -21
- package/runner/src/adapter.ts +7 -1
- package/runner/src/config.ts +4 -0
- package/src/db/message-reads.ts +8 -46
- package/src/db/messages.ts +208 -0
- package/src/db/notification-subscriptions.ts +68 -12
- package/src/index.ts +1 -1
- package/src/mcp/tools-spawn.ts +1 -1
- package/src/mcp-notification-subscription-tools.ts +90 -4
- package/src/memory-service.ts +14 -0
- package/src/notification-router.ts +9 -75
- package/src/notification-rules.ts +3 -3
- package/src/notification-subscription-rules.ts +11 -0
- package/src/notification-types.ts +70 -0
- package/src/project-instructions.ts +82 -9
- package/src/services/send-message.ts +5 -0
- package/src/services/spawn-agent.ts +13 -12
- package/src/spawn-command.ts +2 -0
- package/src/sse.ts +39 -2
- package/public/assets/MessageBubble-DPcJxTJj.js +0 -3
- package/public/assets/MessageBubble-DPcJxTJj.js.map +0 -1
- package/public/assets/branch-state-badge-C7H8HY22.js +0 -2
- package/public/assets/chat-DJqvtoFT.js +0 -2
- package/public/assets/chat-DJqvtoFT.js.map +0 -1
- package/public/assets/copy-button-DqAoeiPC.js +0 -2
- package/public/assets/index-Dh7NjR-l.css +0 -2
- package/public/assets/index-VGRP16ua.js +0 -22
- package/public/assets/memory-DM8muGVW.js +0 -2
- package/public/assets/work-queue-BB7bYLIK.js +0 -2
- package/public/assets/workspaces-CrtAeVnv.js +0 -3
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { subscriptionDecisionFor } from "./db/notification-subscriptions";
|
|
2
|
+
import { setSubscriptionRules, type NotificationRule } from "./notification-rules";
|
|
3
|
+
|
|
4
|
+
const subscriptionRule: NotificationRule = {
|
|
5
|
+
name: "subscription:store",
|
|
6
|
+
evaluate: subscriptionDecisionFor,
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function installNotificationSubscriptionRule(): void {
|
|
10
|
+
setSubscriptionRules([subscriptionRule]);
|
|
11
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export type NotificationType =
|
|
2
|
+
| "landed-failure"
|
|
3
|
+
| "branch.landed"
|
|
4
|
+
| "agent.ready"
|
|
5
|
+
| "agent.exited"
|
|
6
|
+
| "agent.spawn_failed"
|
|
7
|
+
| "agent.context_threshold"
|
|
8
|
+
| "agent.resume_budget_exhausted"
|
|
9
|
+
| "agent.transient_land_hold"
|
|
10
|
+
| "agent.rate_limit_resume"
|
|
11
|
+
| "plan.bound_agent_exited"
|
|
12
|
+
| "workspace.steward_task"
|
|
13
|
+
| "workspace.conflict"
|
|
14
|
+
| "workspace.steward_reassigned"
|
|
15
|
+
| "workspace.stranded_escalation"
|
|
16
|
+
| "workspace.auto_abandoned"
|
|
17
|
+
| "workspace.review_request"
|
|
18
|
+
| "workspace.review_changes_requested";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The entities a notification is ABOUT: routing inputs (#442) and explainability subjects (#446).
|
|
22
|
+
* All optional because each emitter fills the fields it has in scope at the call site.
|
|
23
|
+
*/
|
|
24
|
+
export interface NotificationScope {
|
|
25
|
+
/** The agent whose work the notification concerns (branch author, workspace owner). */
|
|
26
|
+
author?: string;
|
|
27
|
+
/** The agent the notification is primarily about (lifecycle subject, advisory target). */
|
|
28
|
+
agentId?: string;
|
|
29
|
+
/** The spawn-parent that should hear about a child's lifecycle. */
|
|
30
|
+
parent?: string;
|
|
31
|
+
/** Team the notification belongs to (plan/coordination scope). */
|
|
32
|
+
teamId?: string;
|
|
33
|
+
/** Plan the notification concerns. */
|
|
34
|
+
planId?: string;
|
|
35
|
+
/** Repo checkout the notification concerns. */
|
|
36
|
+
repoRoot?: string;
|
|
37
|
+
/** Workspace the notification concerns. */
|
|
38
|
+
workspaceId?: string;
|
|
39
|
+
/** Files the notification concerns (path-scoped routing, #442). */
|
|
40
|
+
paths?: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const MINUTES = 60 * 1000;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Per-type default TTL (#451). Default-SAFE: anything about the recipient's own work or any
|
|
47
|
+
* obligation is `null` (never auto-expires). Only genuinely now-or-never pings get a short default.
|
|
48
|
+
*/
|
|
49
|
+
export const DEFAULT_TTL_MS: Record<NotificationType, number | null> = {
|
|
50
|
+
"landed-failure": null,
|
|
51
|
+
"branch.landed": null,
|
|
52
|
+
"agent.ready": null,
|
|
53
|
+
"agent.exited": null,
|
|
54
|
+
"agent.spawn_failed": null,
|
|
55
|
+
"agent.context_threshold": 15 * MINUTES,
|
|
56
|
+
"agent.resume_budget_exhausted": null,
|
|
57
|
+
"agent.transient_land_hold": null,
|
|
58
|
+
"agent.rate_limit_resume": 15 * MINUTES,
|
|
59
|
+
"plan.bound_agent_exited": null,
|
|
60
|
+
"workspace.steward_task": null,
|
|
61
|
+
"workspace.conflict": null,
|
|
62
|
+
"workspace.steward_reassigned": null,
|
|
63
|
+
"workspace.stranded_escalation": null,
|
|
64
|
+
"workspace.auto_abandoned": null,
|
|
65
|
+
"workspace.review_request": null,
|
|
66
|
+
"workspace.review_changes_requested": null,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/** Convenience TTL for emitter-supplied overrides on bystander/informational notifications. */
|
|
70
|
+
export const INFORMATIONAL_TTL_MS = 30 * MINUTES;
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// is that lever: the included-source set is a policy PARAMETER, and the `vanilla`
|
|
12
12
|
// policy includes `manual`+`promoted` while excluding `ingested`.
|
|
13
13
|
import { resolveProjectEntries } from "./db";
|
|
14
|
-
import { PROJECT_ENTRY_SOURCES, type AgentProfile, type Project, type ProjectEntryKind, type ProjectEntrySource, type ResolvedProjectEntry } from "./types";
|
|
14
|
+
import { PROJECT_ENTRY_SOURCES, type AgentProfile, type Project, type ProjectEntryKind, type ProjectEntrySource, type RelayInjectionCategory, type ResolvedProjectEntry } from "./types";
|
|
15
15
|
|
|
16
16
|
/** Named source policies — THE additive-from-empty lever (#403 decision 4).
|
|
17
17
|
* `all` — every source (manual + promoted + ingested host-CLAUDE.md content).
|
|
@@ -46,9 +46,28 @@ interface ComposeProjectInstructionsOptions {
|
|
|
46
46
|
maxBytes?: number;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
interface SpawnInstructionInjectionEvent {
|
|
50
|
+
category: RelayInjectionCategory;
|
|
51
|
+
summary: string;
|
|
52
|
+
detail: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
interface ComposedSpawnInstructions {
|
|
56
|
+
systemPromptAppend?: string;
|
|
57
|
+
relayInjectionEvents: SpawnInstructionInjectionEvent[];
|
|
58
|
+
}
|
|
59
|
+
|
|
49
60
|
const DEFAULT_KINDS: readonly ProjectEntryKind[] = ["rule", "fact"];
|
|
50
61
|
const DEFAULT_MAX_BYTES = 8192;
|
|
51
62
|
const TRUNCATION_NOTICE = "_(… additional project entries omitted to fit the instruction budget.)_";
|
|
63
|
+
const SPAWNED_CHILD_REPORTUP_INSTRUCTION = [
|
|
64
|
+
"Agent Relay report-up:",
|
|
65
|
+
"You are a spawned child agent. Just respond normally when your turn is complete; Relay automatically delivers your final response to your coordinator. Do not call a messaging tool only to report completion.",
|
|
66
|
+
].join("\n");
|
|
67
|
+
const COORDINATOR_CHILD_REPORTUP_INSTRUCTION = [
|
|
68
|
+
"Agent Relay child responses:",
|
|
69
|
+
"When you spawn child agents, their turn-final responses arrive automatically as Relay messages. Do not put report-up instructions or your own agent id in child briefs.",
|
|
70
|
+
].join("\n");
|
|
52
71
|
|
|
53
72
|
const KIND_HEADINGS: Record<ProjectEntryKind, string> = {
|
|
54
73
|
rule: "Rules",
|
|
@@ -170,24 +189,78 @@ export function composeProjectInstructions(
|
|
|
170
189
|
* Until #559 lands, the only knowledge scope is the project preamble below — a thin add, not
|
|
171
190
|
* a refactor.
|
|
172
191
|
*/
|
|
173
|
-
export function
|
|
192
|
+
export function composeSpawnInstructionsWithEvents(input: {
|
|
174
193
|
callerProject?: Pick<Project, "id" | "slug" | "title">;
|
|
175
194
|
projectInstructions?: ProjectInstructionPolicy;
|
|
176
|
-
profile?: Pick<AgentProfile, "instructions">;
|
|
195
|
+
profile?: Pick<AgentProfile, "instructions" | "maxSpawnedAgents">;
|
|
196
|
+
spawnedBy?: string;
|
|
177
197
|
callerSystemPromptAppend?: string;
|
|
178
|
-
}):
|
|
198
|
+
}): ComposedSpawnInstructions {
|
|
179
199
|
const appendBlocks: string[] = [];
|
|
200
|
+
const relayInjectionEvents: SpawnInstructionInjectionEvent[] = [];
|
|
180
201
|
if (input.projectInstructions && input.callerProject) {
|
|
181
202
|
const block = composeProjectInstructions(input.callerProject, {
|
|
182
203
|
...(input.projectInstructions.policy ? { policy: input.projectInstructions.policy } : {}),
|
|
183
204
|
});
|
|
184
|
-
if (block.trim())
|
|
205
|
+
if (block.trim()) {
|
|
206
|
+
appendBlocks.push(block);
|
|
207
|
+
relayInjectionEvents.push({
|
|
208
|
+
category: "knowledge",
|
|
209
|
+
summary: `injected project knowledge: ${input.callerProject.title?.trim() || input.callerProject.slug}`,
|
|
210
|
+
detail: {
|
|
211
|
+
source: "project-instructions",
|
|
212
|
+
project: input.callerProject,
|
|
213
|
+
policy: input.projectInstructions.policy ?? "all",
|
|
214
|
+
content: block,
|
|
215
|
+
},
|
|
216
|
+
});
|
|
217
|
+
}
|
|
185
218
|
}
|
|
186
219
|
// [#559 seam] profile/user-scoped knowledge preamble composes in here.
|
|
187
|
-
if (input.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
220
|
+
if (input.spawnedBy) {
|
|
221
|
+
appendBlocks.push(SPAWNED_CHILD_REPORTUP_INSTRUCTION);
|
|
222
|
+
relayInjectionEvents.push({
|
|
223
|
+
category: "instructions",
|
|
224
|
+
summary: "injected spawned-child report-up instructions",
|
|
225
|
+
detail: { source: "spawned-child-report-up", spawnedBy: input.spawnedBy, content: SPAWNED_CHILD_REPORTUP_INSTRUCTION },
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
if ((input.profile?.maxSpawnedAgents ?? 0) > 0) {
|
|
229
|
+
appendBlocks.push(COORDINATOR_CHILD_REPORTUP_INSTRUCTION);
|
|
230
|
+
relayInjectionEvents.push({
|
|
231
|
+
category: "instructions",
|
|
232
|
+
summary: "injected coordinator child-response instructions",
|
|
233
|
+
detail: { source: "coordinator-child-report-up", content: COORDINATOR_CHILD_REPORTUP_INSTRUCTION },
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
const profileSystem = input.profile?.instructions.system?.trim();
|
|
237
|
+
const profileAppend = input.profile?.instructions.append.filter((entry) => entry.trim()) ?? [];
|
|
238
|
+
if (profileSystem) appendBlocks.push(profileSystem);
|
|
239
|
+
appendBlocks.push(...profileAppend);
|
|
240
|
+
if (profileSystem || profileAppend.length) {
|
|
241
|
+
relayInjectionEvents.push({
|
|
242
|
+
category: "instructions",
|
|
243
|
+
summary: `injected profile instructions (${profileAppend.length + (profileSystem ? 1 : 0)} block${profileAppend.length + (profileSystem ? 1 : 0) === 1 ? "" : "s"})`,
|
|
244
|
+
detail: {
|
|
245
|
+
source: "agent-profile",
|
|
246
|
+
...(profileSystem ? { system: profileSystem } : {}),
|
|
247
|
+
append: profileAppend,
|
|
248
|
+
},
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
if (input.callerSystemPromptAppend?.trim()) {
|
|
252
|
+
appendBlocks.push(input.callerSystemPromptAppend);
|
|
253
|
+
relayInjectionEvents.push({
|
|
254
|
+
category: "context",
|
|
255
|
+
summary: "injected caller context",
|
|
256
|
+
detail: { source: "caller-system-prompt-append", content: input.callerSystemPromptAppend },
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return { systemPromptAppend: appendBlocks.length ? appendBlocks.join("\n\n") : input.callerSystemPromptAppend, relayInjectionEvents };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function composeSpawnInstructions(input: Parameters<typeof composeSpawnInstructionsWithEvents>[0]): string | undefined {
|
|
263
|
+
return composeSpawnInstructionsWithEvents(input).systemPromptAppend;
|
|
191
264
|
}
|
|
192
265
|
|
|
193
266
|
/**
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
ValidationError,
|
|
27
27
|
getMessage,
|
|
28
28
|
listAgents,
|
|
29
|
+
promoteLineageCapturedResponse,
|
|
29
30
|
sendMessageWithResult,
|
|
30
31
|
channelObligationAnsweredBy,
|
|
31
32
|
spawnObligationAnsweredBy,
|
|
@@ -188,10 +189,14 @@ export function sendMessageService(
|
|
|
188
189
|
} else {
|
|
189
190
|
emitNewMessage(result.message);
|
|
190
191
|
}
|
|
192
|
+
const promoted = promoteLineageCapturedResponse(result.message);
|
|
193
|
+
if (promoted?.created) emitNewMessage(promoted.message);
|
|
191
194
|
} else if (result.updated) {
|
|
192
195
|
// Session-step upsert (#parity): the row changed in place (same DB id). Re-emit so the
|
|
193
196
|
// dashboard's id-keyed merge replaces the existing step live — no duplicate row.
|
|
194
197
|
emitNewMessage(result.message);
|
|
198
|
+
const promoted = promoteLineageCapturedResponse(result.message);
|
|
199
|
+
if (promoted?.created) emitNewMessage(promoted.message);
|
|
195
200
|
}
|
|
196
201
|
return { message: result.message, created: result.created, receipt };
|
|
197
202
|
}
|
|
@@ -32,7 +32,7 @@ import { buildSpawnCommand, generateSpawnRequestId, resolveSpawnModelParams } fr
|
|
|
32
32
|
import { runnerRuntimeTokenEnv } from "../runtime-tokens";
|
|
33
33
|
import { selectSpawnOrchestrator } from "../spawn-targets";
|
|
34
34
|
import { DEFAULT_SPAWN_PROFILE_NAME, getAgentProfile } from "../config-store";
|
|
35
|
-
import {
|
|
35
|
+
import { composeSpawnInstructionsWithEvents, type ProjectInstructionPolicy } from "../project-instructions";
|
|
36
36
|
import { autoSeedProjectForCwd } from "./project";
|
|
37
37
|
import { hasComponentScope, isComponentAuthorizedFor } from "../security";
|
|
38
38
|
import { isPathWithinBase } from "../utils";
|
|
@@ -75,12 +75,9 @@ export interface SpawnAgentInput {
|
|
|
75
75
|
*/
|
|
76
76
|
projectInstructions?: ProjectInstructionPolicy;
|
|
77
77
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* that hands the child a prompt (a coordinator handing a worker a task almost always wants
|
|
82
|
-
* the result back); off for system/dashboard/automation spawns (no caller to report to).
|
|
83
|
-
* Pass false to opt a fire-and-forget agent spawn out.
|
|
78
|
+
* Legacy report-back contract flag. Spawned children now report up by lineage: their
|
|
79
|
+
* turn-final response is delivered to the spawner automatically, without a reply obligation.
|
|
80
|
+
* Explicit true is preserved in the command payload for compatibility only.
|
|
84
81
|
*/
|
|
85
82
|
expectReply?: boolean;
|
|
86
83
|
tags?: string[];
|
|
@@ -225,12 +222,15 @@ export async function spawnAgent(input: SpawnAgentInput, ctx: AuthContext): Prom
|
|
|
225
222
|
// carries the #559 scoped-knowledge seam. Spawns without profile/project material stay
|
|
226
223
|
// byte-identical to the caller-provided systemPromptAppend.
|
|
227
224
|
const projectInstructions = input.projectInstructions ?? agentProfile?.projectInstructions;
|
|
228
|
-
const
|
|
225
|
+
const composedInstructions = composeSpawnInstructionsWithEvents({
|
|
229
226
|
...(callerProject ? { callerProject } : {}),
|
|
230
227
|
...(projectInstructions ? { projectInstructions } : {}),
|
|
231
228
|
...(agentProfile ? { profile: agentProfile } : {}),
|
|
229
|
+
...(callerId ? { spawnedBy: callerId } : {}),
|
|
232
230
|
...(input.systemPromptAppend ? { callerSystemPromptAppend: input.systemPromptAppend } : {}),
|
|
233
231
|
});
|
|
232
|
+
const systemPromptAppend = composedInstructions.systemPromptAppend;
|
|
233
|
+
// TODO(#569): comms:delivered emitter — deferred, lives on the #575 delivery path.
|
|
234
234
|
|
|
235
235
|
// Child runner token. `agentInitiated` (set whenever an agent is the caller) forces a
|
|
236
236
|
// non-spawn-capable child (no grandchildren); `spawnedBy` stamps authoritative lineage the
|
|
@@ -254,10 +254,10 @@ export async function spawnAgent(input: SpawnAgentInput, ctx: AuthContext): Prom
|
|
|
254
254
|
...(callerProject ? { projectId: callerProject.id } : {}),
|
|
255
255
|
});
|
|
256
256
|
|
|
257
|
-
// #
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
const expectReply = input.expectReply
|
|
257
|
+
// #573 — no default reply obligation for spawned children. Report-up is lineage-routed from
|
|
258
|
+
// captured turn-final responses; explicit true is retained only for old clients inspecting the
|
|
259
|
+
// command payload.
|
|
260
|
+
const expectReply = input.expectReply === true;
|
|
261
261
|
|
|
262
262
|
const command = createCommand({
|
|
263
263
|
type: "agent.spawn",
|
|
@@ -280,6 +280,7 @@ export async function spawnAgent(input: SpawnAgentInput, ctx: AuthContext): Prom
|
|
|
280
280
|
providerArgs: input.providerArgs ?? [],
|
|
281
281
|
prompt: input.prompt,
|
|
282
282
|
systemPromptAppend,
|
|
283
|
+
relayInjectionEvents: composedInstructions.relayInjectionEvents,
|
|
283
284
|
...(expectReply ? { expectReply } : {}),
|
|
284
285
|
policyName: input.policyName,
|
|
285
286
|
spawnRequestId,
|
package/src/spawn-command.ts
CHANGED
|
@@ -95,6 +95,7 @@ interface BuildSpawnCommandOptions {
|
|
|
95
95
|
providerArgs?: string[];
|
|
96
96
|
prompt?: string;
|
|
97
97
|
systemPromptAppend?: string;
|
|
98
|
+
relayInjectionEvents?: unknown[];
|
|
98
99
|
/**
|
|
99
100
|
* #413 — when true, the child registering with this spawnRequestId gets a pending reply
|
|
100
101
|
* obligation back to its spawner, so the Stop hook refuses to let it idle until it delivers
|
|
@@ -149,6 +150,7 @@ export function buildSpawnCommand(opts: BuildSpawnCommandOptions): Record<string
|
|
|
149
150
|
...def(opts.providerArgs, "providerArgs"),
|
|
150
151
|
...def(opts.prompt, "prompt"),
|
|
151
152
|
...def(opts.systemPromptAppend, "systemPromptAppend"),
|
|
153
|
+
...def(opts.relayInjectionEvents, "relayInjectionEvents"),
|
|
152
154
|
...def(opts.expectReply, "expectReply"),
|
|
153
155
|
...def(opts.headless, "headless"),
|
|
154
156
|
...def(opts.policyName, "policyName"),
|
package/src/sse.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { getAgent, getOrchestrator, matchingDeliveryAgents, onWorkspaceChange } from "./db";
|
|
1
|
+
import { getAgent, getOrchestrator, matchingDeliveryAgents, onWorkspaceChange, sendMessageWithResult } from "./db";
|
|
2
2
|
import { projectAgentStatusData } from "./agent-card-projection";
|
|
3
3
|
import { emitRelayEvent, subscribeRelayEvents, type RelayEvent } from "./events";
|
|
4
4
|
import { messageMatchesAgent, targetMatchesAgent } from "./agent-ref";
|
|
5
|
-
import type { ActivityEvent, AgentCard, Message, RelayNotification, Task } from "./types";
|
|
5
|
+
import type { ActivityEvent, AgentCard, Message, RelayInjectionCategory, RelayNotification, Task } from "./types";
|
|
6
6
|
import { isRecord } from "agent-relay-sdk";
|
|
7
7
|
|
|
8
8
|
interface Connection {
|
|
@@ -105,6 +105,43 @@ export function emitNewMessage(msg: Message) {
|
|
|
105
105
|
if (notification) emitNotificationCreated(notification);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
+
interface RelayInjectionTimelineInput {
|
|
109
|
+
agentId: string;
|
|
110
|
+
category: RelayInjectionCategory;
|
|
111
|
+
summary: string;
|
|
112
|
+
detail: Record<string, unknown>;
|
|
113
|
+
timestamp?: number;
|
|
114
|
+
source?: string;
|
|
115
|
+
idempotencyKey?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function emitRelayInjectionEvent(input: RelayInjectionTimelineInput): Message {
|
|
119
|
+
const timestamp = input.timestamp ?? Date.now();
|
|
120
|
+
const result = sendMessageWithResult({
|
|
121
|
+
from: input.source ?? input.agentId,
|
|
122
|
+
to: input.source ? input.agentId : "user",
|
|
123
|
+
kind: "session",
|
|
124
|
+
body: input.summary,
|
|
125
|
+
replyExpected: false,
|
|
126
|
+
occurredAt: timestamp,
|
|
127
|
+
...(input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : {}),
|
|
128
|
+
payload: {
|
|
129
|
+
session: {
|
|
130
|
+
type: "relay-injection",
|
|
131
|
+
relayInjection: {
|
|
132
|
+
category: input.category,
|
|
133
|
+
summary: input.summary,
|
|
134
|
+
detail: input.detail,
|
|
135
|
+
agentId: input.agentId,
|
|
136
|
+
timestamp,
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
if (result.created || result.updated) emitNewMessage(result.message);
|
|
142
|
+
return result.message;
|
|
143
|
+
}
|
|
144
|
+
|
|
108
145
|
export function emitAgentStatus(agentId: string) {
|
|
109
146
|
const agent = getAgent(agentId);
|
|
110
147
|
// Enrich with the branch-state badge fields (#236) and the resolved issueRepo (#533) so
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{An as t,Bn as n,Ct as r,F as i,Hn as a,Pt as o,Qn as s,Qt as c,R as l,Rn as u,St as d,Wt as f,at as p,b as m,bn as h,c as g,cn as _,ct as v,fn as ee,h as y,i as b,jn as x,ln as S,mn as C,nn as te,p as w,pn as T,r as E,tn as D,un as O,y as k,z as A}from"./lucide-react-BbMYCUlW.js";import{g as j,r as M,t as N}from"./store-BB-YW24l.js";import{D as P,I as F,M as ne,W as I,at as L,b as re,d as ie,f as ae,j as R,w as z,z as oe}from"./display-LAWaAboe.js";import{C as se,a as ce,i as le,o as ue,t as B}from"./index-VGRP16ua.js";var V=e(s(),1),H={online:`came online`,offline:`went offline`,shutdown:`shut down`,restarted:`restarted`,"compaction-requested":`compaction requested`,compacting:`compaction started`,compacted:`context compacted`,"compaction-stalled":`compaction stalled — may need manual intervention`,"clear-requested":`clear requested`,"clearing-context":`clear started`,"context-cleared":`context cleared`,"clear-stalled":`context clear stalled — may need manual intervention`,"shutting-down":`shutting down`},de=new Set(Object.keys(H)),fe=3e3;function U(e){return new Date(e.occurredAt??e.createdAt).getTime()}function pe(e){if(e.kind!==`session`)return null;let t=e.payload?.session;return!t||t.type!==`narration`&&t.type!==`reasoning`&&t.type!==`tool`?null:{id:e.id,kind:t.type,label:typeof t.label==`string`?t.label:void 0,text:e.body,ts:U(e),turnId:typeof t.turnId==`string`?t.turnId:void 0}}function me(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`notice`)return null;let n=typeof t.label==`string`&&t.label?t.label:`compacted`;return{id:`notice-${e.id}`,status:n,timestamp:U(e)}}function W(e,t){let n=e.trim();for(let e of t){let t=e.trim();if(t){if(n===t)break;n.startsWith(`${t}\n\n`)&&(n=n.slice(t.length+2).trimStart())}}return n.trim()||e.trim()}function G(e){return e.kind===`system`&&e.from===`system`}var he=new Set([`agent.ready`,`agent.exited`,`agent.spawn_failed`]);function K(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function ge(e){let t=e.filter(e=>de.has(e.status)).slice().sort((e,t)=>e.timestamp-t.timestamp),n=[];for(let e of t)n.some(t=>t.id===e.id)||n.some(t=>t.status===e.status&&Math.abs(t.timestamp-e.timestamp)<=fe)||n.push(e);return n}function _e(e,t,n,r=[],i){let a=[];for(let e of r){let t=e.entries.reduce((e,t)=>Math.min(e,I(t.originalCreatedAt)),1/0),n=Number.isFinite(t)?t-1:e.importedAt;a.push({ts:n,entry:{type:`import-boundary`,history:e,timestamp:n}});for(let t of e.entries)a.push({ts:I(t.originalCreatedAt),entry:{type:`imported-message`,history:e,entry:t}})}if(n){let e=new Date(n).getTime();Number.isFinite(e)&&a.push({ts:e,entry:{type:`created`,timestamp:e}})}if(i?.spawnedBy){let e=n?new Date(n).getTime():0,t=Number.isFinite(e)?e:0;a.push({ts:t,entry:{type:`agent-action`,direction:`spawned-by`,agentId:i.spawnedBy.agentId,provider:i.spawnedBy.provider,status:`ready`,timestamp:t}})}let o=i?.spawnedBy?.agentId,s=null,c=1/0;for(let t of e){if(t.kind===`session`||G(t)||z(t)||!(t.from===`user`||o!==void 0&&t.from===o)||!P(t).trim())continue;let e=U(t);e<c&&(c=e,s=t.id)}let l=new Map,u=new Map,d=new Map;for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type===`narration`&&typeof e.turnId==`string`){let n=u.get(e.turnId)??[];n.push({id:t.id,body:t.body.trim()}),u.set(e.turnId,n)}else if(e?.type===`response`&&typeof e.turnId==`string`){let n=l.get(e.turnId)??[];n.push(t.body.trim()),l.set(e.turnId,n)}}let f=new Map;for(let[e,t]of l){let n=(u.get(e)??[]).map(e=>e.body);f.set(e,t.map(e=>W(e,n)))}for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type!==`response`||typeof e.turnId!=`string`)continue;let n=W(t.body,(u.get(e.turnId)??[]).map(e=>e.body));n&&n!==t.body&&d.set(t.id,n)}let p=new Set;for(let[e,t]of f){let n=u.get(e)??[];for(let e of t)for(let t=n.length-1;t>=0;t--){let r=n[t];if(!p.has(r.id)&&oe(e,r.body)){p.add(r.id);break}}}let m=new Map,h=[];for(let t of e){if(G(t)){let e=typeof t.payload?.kind==`string`?t.payload.kind:``;if(he.has(e)){let n=t.payload,r=typeof n.agentId==`string`?n.agentId:``,i=U(t);if(!r){a.push({ts:i,entry:{type:`notice`,msg:t}});continue}let o=e===`agent.ready`?`ready`:e===`agent.exited`?`exited`:`failed`,s=m.get(r);if(s)s.entry.status=o,typeof n.reason==`string`&&(s.entry.reason=n.reason),s.entry.timestamp=i,s.ts=i;else{let e={ts:i,entry:{type:`agent-action`,direction:`spawned-child`,agentId:r,provider:typeof n.provider==`string`?n.provider:void 0,status:o,reason:typeof n.reason==`string`?n.reason:void 0,timestamp:i}};m.set(r,e),a.push(e)}continue}a.push({ts:U(t),entry:{type:`notice`,msg:t}});continue}let e=me(t);if(e){h.push(e);continue}let n=pe(t);if(n){if(n.kind===`narration`&&p.has(n.id))continue;a.push({ts:n.ts,entry:{type:`activity`,steps:[n],timestamp:n.ts}});continue}if(t.kind===`session`){let e=t.payload?.session;if(e?.type===`response`&&typeof e.turnId==`string`){let e=d.get(t.id);if(e&&e!==t.body){a.push({ts:U(t),entry:{type:`message`,msg:{...t,body:e}}});continue}}}let r=t.id===s?`initial-prompt`:`message`;a.push({ts:U(t),entry:{type:r,msg:t}})}for(let e of ge([...t,...h]))a.push({ts:e.timestamp,entry:{type:`status`,event:e}});let g={created:0,date:1,"import-boundary":2,"imported-message":3,"initial-prompt":4,message:4,activity:4,notice:4,"agent-action":4,status:5};a.sort((e,t)=>{let n=e.ts-t.ts;return Math.abs(n)<3e3&&g[e.entry.type]-g[t.entry.type]||n});let _=[],v=``;for(let{ts:e,entry:t}of a){if(t.type===`created`){_.push(t);continue}let n=K(e);if(n!==v&&(_.push({type:`date`,date:n,timestamp:e}),v=n),t.type===`activity`){let e=_[_.length-1];if(e&&e.type===`activity`&&be(e,t)){e.steps.push(...t.steps);continue}}_.push(t)}return _}function ve(e){return e.type===`message`?`msg-${e.msg.id}`:e.type===`initial-prompt`?`initprompt-${e.msg.id}`:e.type===`notice`?`notice-${e.msg.id}`:e.type===`agent-action`?`agent-action-${e.direction}-${e.agentId}`:e.type===`activity`?`act-${e.steps[0]?.id??e.timestamp}`:e.type===`import-boundary`?`import-${e.history.id}`:e.type===`imported-message`?`import-msg-${e.history.id}-${e.entry.originalMessageId}-${e.entry.position}`:e.type===`status`?`status-${e.event.id}`:e.type===`date`?`date-${e.date}`:`created-${e.timestamp}`}function ye(e){return e.type===`message`||e.type===`initial-prompt`||e.type===`notice`?(e.msg.subject?`${e.msg.subject} `:``)+P(e.msg):e.type===`imported-message`?P(e.entry.message):e.type===`activity`?e.steps.map(e=>[e.label,e.text].filter(Boolean).join(` `)).join(`
|
|
2
|
-
`):``}function be(e,t){let n=e.steps[e.steps.length-1]?.turnId,r=t.steps[0]?.turnId;return n&&r?n===r:!n&&!r}function xe(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Se(e,t){if(t.startsWith(`/`))return t;let n=`${e.replace(/\/+$/,``)}/${t}`.split(`/`),r=[];for(let e of n)!e||e===`.`||(e===`..`?r.pop():r.push(e));return`/`+r.join(`/`)}function Ce(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n>0?t.slice(0,n):`/`}function we(e,t){return e.filter(e=>e.status===`online`&&F(t,e.baseDir)).sort((e,t)=>R(t.baseDir).length-R(e.baseDir).length)[0]||e.find(e=>e.status===`online`)}function Te(){return typeof window<`u`&&window.matchMedia(`(min-width: 1280px)`).matches}function q(){return typeof window<`u`&&!!window.getSelection()?.toString()}function Ee(e){let t=e.payload?.attachments;return Array.isArray(t)?t.filter(e=>!!(e&&typeof e==`object`&&typeof e.artifactId==`string`)):[]}var De=[`👍`,`❤️`,`✅`,`👀`];function Oe(e){let t=new Map;for(let n of e.reactions||[]){let e=ne(n.emoji),r=t.get(e)??{emoji:e,count:0,mine:!1,actors:[]};r.count+=1,r.mine=r.mine||n.actorId===`user`,r.actors.push(n.actorId),t.set(e,r)}return[...t.values()].sort((e,t)=>t.count-e.count||e.emoji.localeCompare(t.emoji))}function J(e){return z(e)}function ke(e,t){let n=e.readBy||[],r=e.resolvedToAgent||t||e.to,i=r?n.includes(r):!1,a=n.some(e=>e!==L);if(i||a){let e=i?r:n.find(e=>e!==L);return{label:`read`,title:e?`Read by ${e}`:`Read by agent`,tone:`ok`,icon:C}}if(e.deliveryStatus===`delivered`)return{label:`delivered`,title:`Delivered to agent inbox`,tone:`ok`,icon:C};if(e.deliveryStatus===`queued`)return{label:`queued`,title:`Queued until the target agent is available`,tone:`warn`,icon:c};if(e.deliveryStatus===`failed`||e.deliveryStatus===`dead`){let t=e.deliveryPoisonReason||e.deliveryLastError||e.deliveryStatus;return{label:e.deliveryStatus,title:t,tone:`danger`,icon:_}}return{label:`sent`,title:`Accepted by Relay`,tone:`muted`,icon:T}}function Ae(e){let t=I(e.createdAt);return(e.reactions||[]).reduce((e,t)=>Math.max(e,I(t.updatedAt||t.createdAt)),t)}function je(e){return e?e.messages.reduce((e,t)=>Math.max(e,Ae(t)),0):0}function Me(e,t,n){return(e-t)*n}function Ne(e){if(!e)return 0;let t=0;for(let n of e.messages)re(n)&&(t=Math.max(t,I(n.createdAt)));return t}function Y(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function Pe(e){for(let t of e)t.previewUrl&&URL.revokeObjectURL(t.previewUrl)}function Fe(e,t,n,r){if(e?.teamId)return{teamId:e.teamId};let i=[...t];n&&!i.some(e=>e.id===n.id)&&i.push(n);let a=i.filter(e=>e.threadId).reverse(),o=a.find(e=>!!r[M(e.threadId,e.channel)])??a[0];return o?.threadId?{threadId:o.threadId,...o.channel?{channel:o.channel}:{}}:null}var X=n(),Ie={online:`text-emerald-400`,offline:`text-zinc-400`,shutdown:`text-zinc-400`,restarted:`text-blue-400`,"compaction-requested":`text-zinc-400`,compacting:`text-amber-400`,compacted:`text-amber-400`,"compaction-stalled":`text-red-400`,"clear-requested":`text-zinc-400`,"clearing-context":`text-amber-400`,"context-cleared":`text-amber-400`,"clear-stalled":`text-red-400`,"shutting-down":`text-zinc-400`};function Le(e){let t=new Date,[n,r,i]=e.split(`-`).map(Number),a=new Date(n,r-1,i);if(e===K(t.getTime()))return`Today`;let o=new Date(t);return o.setDate(o.getDate()-1),e===K(o.getTime())?`Yesterday`:a.toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`,year:a.getFullYear()===t.getFullYear()?void 0:`numeric`})}function Re({event:e}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,X.jsx)(D,{className:u(`w-2 h-2 fill-current`,Ie[e.status]||`text-zinc-400`)}),(0,X.jsx)(`span`,{children:H[e.status]||e.status}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60`,children:Y(e.timestamp)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var ze={"branch.landed":d,"context.warning":w,"agent.context_threshold":w,"agent.resume_budget_exhausted":w,"agent.rate_limit_resume":A},Be={"branch.landed":`branch landed`,"context.warning":`context warning`,"agent.context_threshold":`context threshold reached`};function Ve(e){return e&&(e.includes(`.`)?e.slice(e.indexOf(`.`)+1):e).replace(/[._-]+/g,` `).trim()||`system signal`}function Z({agentId:e,fallbackLabel:t,className:n}){let r=N(t=>t.agentsById[e])||null,i=N(e=>e.openInboxThread),a=N(e=>e.switchView),o=r?ie(r):t||e;return(0,X.jsxs)(`button`,{type:`button`,className:u(`inline-flex max-w-full items-center gap-1 rounded px-1 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground`,n),onClick:t=>{t.stopPropagation(),i(e),a(`chat`)},title:`Open chat for ${o}`,children:[(0,X.jsx)(se,{agent:r,className:`w-4 h-4 text-[10px]`}),(0,X.jsx)(`span`,{className:`max-w-[160px] truncate`,children:o})]})}function He({msg:e}){let t=e.payload??{},n=typeof t.sha==`string`?t.sha:``,r=n?n.slice(0,7):``,i=typeof t.author==`string`?t.author:``,a=typeof t.branch==`string`?t.branch:``,o=typeof t.base==`string`?t.base:``,s=t.pushed;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex max-w-full flex-wrap items-center justify-center gap-x-1.5 gap-y-0.5 rounded-full border border-emerald-500/25 bg-emerald-500/10 px-2.5 py-1 text-xs text-emerald-300/90`,children:[(0,X.jsx)(d,{className:`h-3 w-3 shrink-0 text-emerald-400`}),(0,X.jsx)(`span`,{className:`text-emerald-300`,children:`branch landed`}),a&&o&&(0,X.jsxs)(`span`,{className:`font-mono text-emerald-200/70`,title:`${a} → ${o}`,children:[a,(0,X.jsx)(`span`,{className:`opacity-50`,children:` → `}),o]}),r&&(0,X.jsx)(`span`,{className:`rounded bg-emerald-500/15 px-1 font-mono text-emerald-200`,title:n,children:r}),i&&(0,X.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-emerald-300/80`,children:[(0,X.jsx)(`span`,{className:`opacity-70`,children:`by`}),(0,X.jsx)(Z,{agentId:i,className:`text-emerald-300/90 hover:text-emerald-100`})]}),s===!1&&(0,X.jsx)(`span`,{className:`text-amber-300/80`,title:`Local-only land — not pushed to origin`,children:`· local only`}),(0,X.jsx)(`span`,{className:`text-emerald-300/50`,children:Y(e.occurredAt??e.createdAt)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function Ue({msg:e}){let t=typeof e.payload?.kind==`string`?e.payload.kind:``;if(t===`branch.landed`)return(0,X.jsx)(He,{msg:e});let n=ze[t]??i,r=Be[t]??Ve(t);return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-2.5 py-1 text-xs text-muted-foreground`,children:[(0,X.jsx)(n,{className:`h-3 w-3`}),(0,X.jsx)(`span`,{children:r}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60`,children:Y(e.occurredAt??e.createdAt)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var We={"spawned-child":{ready:`spawned`,exited:`spawned · exited`,failed:`spawn failed`},"spawned-by":{ready:`spawned by`,exited:`spawned by`,failed:`spawned by`}},Ge={"spawned-child-ready":l,"spawned-child-exited":p,"spawned-child-failed":_,"spawned-by-ready":x,"spawned-by-exited":x,"spawned-by-failed":x},Ke={"spawned-child-ready":`text-emerald-400`,"spawned-child-exited":`text-zinc-400`,"spawned-child-failed":`text-red-400`,"spawned-by-ready":`text-blue-400`,"spawned-by-exited":`text-blue-400`,"spawned-by-failed":`text-blue-400`};function qe({entry:e}){let t=`${e.direction}-${e.status}`,n=We[e.direction]?.[e.status]??e.direction,r=Ge[t]??i,a=Ke[t]??`text-muted-foreground`,o=e.status===`failed`;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:u(`flex items-center gap-1.5 rounded-full border bg-muted/30 px-2.5 py-1 text-xs`,o?`border-red-500/30`:`border-border`),children:[(0,X.jsx)(r,{className:u(`h-3 w-3 shrink-0`,a)}),(0,X.jsx)(`span`,{className:`text-muted-foreground`,children:n}),(0,X.jsx)(Z,{agentId:e.agentId}),e.reason&&o&&(0,X.jsxs)(`span`,{className:`text-red-400/80 max-w-[120px] truncate`,title:e.reason,children:[`— `,e.reason]}),(0,X.jsx)(`span`,{className:`text-muted-foreground/60 shrink-0`,children:Y(e.timestamp)})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function Je({blockedLabel:e,onInterrupt:t}){return e?(0,X.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,X.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-red-500/30 px-4`,children:[(0,X.jsx)(_,{className:`w-3.5 h-3.5 text-red-400`}),(0,X.jsxs)(`span`,{className:`text-xs text-red-300`,children:[`blocked: `,e]})]})}):(0,X.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,X.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-foreground/10 px-4`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_infinite]`}),(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.2s_infinite]`}),(0,X.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.4s_infinite]`})]}),(0,X.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`working`}),t&&(0,X.jsxs)(`button`,{onClick:t,title:`Interrupt`,className:`ml-1 flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs text-muted-foreground hover:text-red-300 hover:bg-red-500/10 transition-colors`,children:[(0,X.jsx)(te,{className:`w-3.5 h-3.5`}),`Stop`]})]})})}var Q=`agent-relay:chat-hide-tools`,$=(()=>{let e=new Set,t=(()=>{try{return window.localStorage.getItem(Q)===`on`}catch{return!1}})(),n=()=>e.forEach(e=>e());return typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===Q&&(t=e.newValue===`on`,n())}),{subscribe(t){return e.add(t),()=>e.delete(t)},get:()=>t,toggle(){t=!t;try{window.localStorage.setItem(Q,t?`on`:`off`)}catch{}n()}}})();function Ye(){return[(0,V.useSyncExternalStore)($.subscribe,$.get,()=>!1),$.toggle]}function Xe({steps:e,showReasoning:t,issueRepo:n}){let[r,i]=Ye(),a=t?e:e.filter(e=>e.kind!==`reasoning`);if(!a.length)return null;let o=a.filter(e=>e.kind===`tool`).length;return(0,X.jsx)(`div`,{className:`flex justify-start mb-2`,children:(0,X.jsxs)(`div`,{className:`max-w-[85%] md:max-w-[75%] min-w-0 space-y-1.5`,children:[a.map(e=>e.kind===`narration`?(0,X.jsx)(B,{text:e.text,issueRepo:n,className:`text-sm leading-relaxed break-words text-foreground/90 min-w-0`},e.id):e.kind===`reasoning`?(0,X.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground/80`,children:[(0,X.jsx)(h,{className:`w-3.5 h-3.5 mt-0.5 shrink-0 opacity-70`}),(0,X.jsx)(B,{text:e.text,issueRepo:n,className:`italic break-words min-w-0`})]},e.id):r?null:(0,X.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground`,children:[(0,X.jsx)(y,{className:`w-3 h-3 mt-0.5 shrink-0 opacity-70`}),(0,X.jsxs)(`span`,{className:`min-w-0 break-words`,children:[(0,X.jsx)(`span`,{className:`font-medium`,children:e.label||`tool`}),e.text&&e.text.trim()&&e.text.trim()!==(e.label??``).trim()?(0,X.jsxs)(`span`,{className:`opacity-70`,children:[` — `,e.text]}):null]})]},e.id)),o>0&&(0,X.jsxs)(`button`,{onClick:i,className:`flex items-center gap-1 text-[11px] text-muted-foreground/50 hover:text-muted-foreground transition-colors text-left`,children:[(0,X.jsx)(O,{className:u(`w-3 h-3 shrink-0 transition-transform`,!r&&`rotate-90`)}),(0,X.jsx)(`span`,{children:r?`show ${o} tool step${o===1?``:`s`}`:`hide tool steps`})]})]})})}function Ze({date:e}){return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-3 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:Le(e)}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function Qe({timestamp:e}){let t=new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`span`,{className:`text-xs text-muted-foreground/60`,children:[`created `,t]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function $e({history:e}){let t=e.sourceAgentLabel||e.sourcePeerId,n=e.entries.length;return(0,X.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-dashed border-border bg-muted/30 px-2 py-1 text-[11px] text-muted-foreground`,children:[(0,X.jsx)(r,{className:`h-3 w-3`}),(0,X.jsxs)(`span`,{children:[`forked history from `,t]}),(0,X.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[n,` `,n===1?`entry`:`entries`]})]}),(0,X.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function et({entry:e,sourceLabel:t,issueRepo:n}){let r=e.message,i=P(r),a=e.originalFrom===L;return(0,X.jsx)(`div`,{className:u(`flex mb-3 opacity-80`,a?`justify-end`:`justify-start`),children:(0,X.jsx)(`div`,{className:`max-w-[85%] md:max-w-[75%]`,children:(0,X.jsxs)(`div`,{className:u(`rounded-2xl border border-dashed px-3.5 py-2 text-sm select-text`,a?`border-primary/25 bg-primary/10 text-foreground rounded-br-sm`:`border-border bg-card/70 rounded-bl-sm`),children:[(0,X.jsxs)(`div`,{className:u(`mb-1 text-[10px] uppercase tracking-normal`,a?`text-primary/70`:`text-muted-foreground`),children:[`forked history · `,a?`you`:t||e.originalFrom]}),(0,X.jsx)(B,{text:i,rawBody:r.body,issueRepo:n,className:`leading-relaxed`}),(0,X.jsxs)(`p`,{className:u(`mt-1 flex items-center justify-end gap-1.5 text-xs`,a?`text-primary/60`:`text-muted-foreground`),children:[(0,X.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.originalMessageId]}),(0,X.jsx)(`span`,{children:Y(e.originalCreatedAt)})]})]})})})}function tt({msg:e,issueRepo:t}){let n=P(e),r=Y(e.occurredAt??e.createdAt);return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:`mb-3`,children:(0,X.jsxs)(`div`,{className:`rounded-xl border border-primary/30 bg-primary/[0.06] px-3.5 py-2.5 shadow-sm`,children:[(0,X.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary/80`,children:[(0,X.jsx)(k,{className:`h-3.5 w-3.5`}),(0,X.jsx)(`span`,{children:`Initial prompt`}),(0,X.jsx)(`span`,{className:`ml-auto text-[10px] font-normal normal-case text-muted-foreground/60`,children:r})]}),(0,X.jsx)(B,{text:n,rawBody:e.body,issueRepo:t,className:`text-sm leading-relaxed text-foreground`})]})})}function nt({scrollEl:e,timeline:t}){let[n,r]=(0,V.useState)(!0),[i,a]=(0,V.useState)(null),[o,s]=(0,V.useState)(null),[c,l]=(0,V.useState)(!1),d=(0,V.useMemo)(()=>{for(let e=t.length-1;e>=0;e--){let n=t[e];if(!(!n||n.type!==`message`&&n.type!==`initial-prompt`)&&n.msg.from===`user`)return{id:n.msg.id,body:P(n.msg)}}return null},[t]);if((0,V.useEffect)(()=>{if(!d||!e){r(!0);return}let t=null,n=null,i=()=>{let i=e.querySelector(`[data-msg-id="${d.id}"]`);if(!i){t?.disconnect(),t=null,n=null,r(!1);return}let a=i.getBoundingClientRect(),o=e.getBoundingClientRect();l(a.top<o.top),i!==n&&(t?.disconnect(),n=i,t=new IntersectionObserver(([e])=>{e&&r(e.isIntersecting)},{root:e,threshold:0}),t.observe(i))};return i(),e.addEventListener(`scroll`,i,{passive:!0}),()=>{t?.disconnect(),e.removeEventListener(`scroll`,i)}},[d?.id,e]),n||!d||!d.body.trim())return null;let f=i?.id===d.id?i.value:!1,p=o?.id===d.id?o.value:!1;function m(){!e||!d||e.querySelector(`[data-msg-id="${d.id}"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})}let h=c?`↑`:`↓`;return p?(0,X.jsx)(`div`,{className:`flex shrink-0 bg-card/45 border-b border-border`,children:(0,X.jsxs)(`button`,{type:`button`,className:`w-full flex items-center justify-center gap-1.5 py-1 text-[11px] text-primary/60 hover:text-primary transition-colors`,onClick:()=>s({id:d.id,value:!1}),children:[(0,X.jsx)(`span`,{children:`Your prompt`}),(0,X.jsx)(ee,{className:`w-3 h-3`})]})}):(0,X.jsxs)(`section`,{className:`flex shrink-0 flex-col border-b border-border bg-card/45 px-3 py-2`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground mb-0.5`,children:[(0,X.jsx)(`span`,{className:`font-medium text-primary/70`,children:`Your prompt`}),(0,X.jsxs)(`button`,{type:`button`,className:`ml-auto hover:text-foreground transition-colors`,onClick:m,children:[h,` scroll to original`]}),(0,X.jsx)(`button`,{type:`button`,className:`hover:text-foreground transition-colors`,onClick:()=>s({id:d.id,value:!0}),title:`Minimize`,children:(0,X.jsx)(S,{className:`w-3 h-3`})})]}),(0,X.jsx)(`p`,{className:u(`text-sm text-foreground leading-snug cursor-pointer`,!f&&`line-clamp-2`),onClick:()=>a({id:d.id,value:!f}),children:d.body})]})}function rt(){return(0,V.useSyncExternalStore)(e=>j.subscribe(e),()=>j.getPlayingKey(),()=>null)}function it({attachment:e,outbound:t}){let n=e.kind===`image`,r=e.title||e.artifactId,[i,s]=(0,V.useState)(null),[c,l]=(0,V.useState)(null),[d,p]=(0,V.useState)(!1),[m,h]=(0,V.useState)(!1);(0,V.useEffect)(()=>{let t=!1,n=null;async function r(){p(!0),l(null),s(null);try{let r=await a(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(r),s(n)}catch(e){t||l(e.message)}finally{t||p(!1)}}return r(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function g(){if(!i)return;let e=document.createElement(`a`);e.href=i,e.download=r,document.body.appendChild(e),e.click(),e.remove()}return n?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`button`,{type:`button`,onClick:()=>i&&h(!0),disabled:!i,className:`group/img mt-2 block overflow-hidden rounded-md border border-foreground/10 bg-black/10 text-left disabled:cursor-default relative`,children:i?(0,X.jsxs)(X.Fragment,{children:[(0,X.jsx)(`img`,{src:i,alt:r,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,X.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,X.jsx)(E,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,X.jsxs)(`span`,{className:u(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,c?`text-red-400`:`text-muted-foreground`),children:[d?(0,X.jsx)(v,{className:`h-4 w-4 animate-spin`}):(0,X.jsx)(_,{className:`h-4 w-4`}),c||`Loading image`]})}),i&&(0,X.jsx)(le,{open:m,onOpenChange:h,children:(0,X.jsxs)(ce,{className:`max-w-[95vw] max-h-[95vh] w-auto p-0 bg-black/95 border-zinc-800 gap-0 overflow-hidden`,showCloseButton:!1,children:[(0,X.jsx)(ue,{className:`sr-only`,children:r}),(0,X.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,X.jsx)(`img`,{src:i,alt:r,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,X.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,X.jsx)(`button`,{type:`button`,onClick:g,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,X.jsx)(f,{className:`w-4 h-4`})}),(0,X.jsx)(`button`,{type:`button`,onClick:()=>h(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,X.jsx)(b,{className:`w-4 h-4`})})]})]})]})})]}):(0,X.jsxs)(`button`,{type:`button`,onClick:g,disabled:!i,className:u(`mt-2 flex w-full items-center gap-2 rounded-md border px-2.5 py-2 text-left text-xs transition-colors disabled:cursor-default disabled:opacity-70`,t?`border-primary-foreground/20 bg-primary-foreground/10 hover:bg-primary-foreground/15`:`border-border bg-background hover:bg-muted`),children:[d?(0,X.jsx)(v,{className:`h-4 w-4 shrink-0 animate-spin`}):c?(0,X.jsx)(_,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,X.jsx)(o,{className:`h-4 w-4 shrink-0`}),(0,X.jsx)(`span`,{className:u(`min-w-0 flex-1 truncate`,c&&`text-red-400`),children:c||r}),(0,X.jsx)(f,{className:`h-3.5 w-3.5 shrink-0`})]})}function at({open:e,onToggle:t,onReact:n}){return(0,X.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,X.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:u(`inline-flex h-5 w-6 items-center justify-center rounded-full border border-border bg-popover text-muted-foreground shadow-sm transition hover:bg-muted hover:text-foreground`,e?`opacity-100`:`opacity-0 pointer-events-none md:group-hover/msg:opacity-100 md:group-hover/msg:pointer-events-auto`),children:(0,X.jsx)(m,{className:`h-3 w-3`})}),e&&(0,X.jsx)(`div`,{className:`absolute bottom-full left-0 z-30 mb-1 flex gap-0.5 rounded-full border border-border bg-popover p-0.5 shadow-md`,children:De.map(e=>(0,X.jsx)(`button`,{type:`button`,title:`React ${e}`,onClick:()=>n(e),className:`inline-flex h-6 w-7 items-center justify-center rounded-full text-xs transition-colors hover:bg-muted`,children:e},e))})]})}function ot({msg:e,peer:n}){let[r,i]=(0,V.useState)(!1),a=N(e=>e.agentsById),o=e.from===n,s=(o?e.to:e.from)||``,c=a[o?n:s]?.issueRepo??a[n]?.issueRepo,l=!s||s===`broadcast`||s.includes(`:`),d=P(e),f=Y(e.occurredAt??e.createdAt),p=o?t:x;return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,X.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,X.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>i(e=>!e),children:[(0,X.jsx)(O,{className:u(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,r&&`rotate-90`)}),(0,X.jsx)(p,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,X.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,o?`to`:`from`]}),l?(0,X.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:ae(s,a)}):(0,X.jsx)(Z,{agentId:s,className:`shrink-0 px-0.5 text-foreground/80`}),!r&&(0,X.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:d}),(0,X.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:f})]}),r&&(0,X.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,X.jsx)(B,{text:d,rawBody:e.body,issueRepo:c,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var st=(0,V.memo)(function({msg:e,peer:t,onOpenReferencedPath:n,onPreviewReferencedPath:r,onPreviewReferencedPathEnd:i}){if(e.from!==`user`&&e.to!==`user`)return(0,X.jsx)(ot,{msg:e,peer:t});let a=e.from===L,o=N(e=>e.reactToMessage),s=N(e=>e.voiceTtsEnabled),c=rt(),l=N(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),d=N(e=>e.agentsById[t]?.issueRepo),[f,p]=(0,V.useState)(!1),m=(0,V.useRef)(null),h=(0,V.useRef)(null),_=(0,V.useRef)(!1),v=P(e),ee=Y(e.occurredAt??e.createdAt),y=Ee(e),b=Oe(e),x=a?ke(e,t):null,S=x?.icon,C=c===String(e.id),w=s&&!a&&!J(e)&&v.trim().length>0;function T(t){t.stopPropagation(),C?j.bargeIn():j.speak(e.body,String(e.id))}(0,V.useEffect)(()=>{if(!f)return;function e(e){q()||m.current&&!m.current.contains(e.target)&&p(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[f]);function E(e){return Se(l||`/`,e)}function D(e,t){let r=E(e);n?.(r,t)}function O(e,t,n){let i=E(e);r?.(i,t,n)}function k(t){o(e,t),p(!1)}function A(e){e.button===0&&(h.current={x:e.clientX,y:e.clientY},_.current=!1)}function M(e){let t=h.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(_.current=!0)}function F(t){if(!(J(e)||a)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(_.current||q()){_.current=!1;return}p(e=>!e)}}return(0,X.jsx)(`div`,{"data-msg-id":e.id,className:u(`group/msg flex mb-3`,a?`justify-end`:`justify-start`),children:(0,X.jsxs)(`div`,{ref:m,className:`relative max-w-[85%] md:max-w-[75%]`,children:[w&&(0,X.jsx)(`button`,{type:`button`,title:C?`Stop playback`:`Play aloud`,onClick:T,className:u(`absolute -top-2 -right-2 z-20 inline-flex h-6 w-6 items-center justify-center rounded-full border bg-popover shadow-sm transition`,C?`border-primary/50 text-primary opacity-100`:`border-border text-muted-foreground opacity-70 hover:bg-muted hover:text-foreground hover:opacity-100 [@media(hover:hover)]:md:opacity-0 [@media(hover:hover)]:md:group-hover/msg:opacity-100`),children:C?(0,X.jsx)(te,{className:`h-3.5 w-3.5 animate-pulse`}):(0,X.jsx)(g,{className:`h-3.5 w-3.5`})}),(0,X.jsxs)(`div`,{className:u(`rounded-2xl px-3.5 py-2 text-sm select-text`,!a&&!J(e)&&`cursor-pointer`,a?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:A,onPointerMove:M,onClick:F,children:[e.subject&&(0,X.jsx)(`p`,{className:u(`text-xs font-semibold mb-1`,a?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,X.jsx)(B,{text:v,rawBody:e.body,issueRepo:d,className:`leading-relaxed`,onOpenPath:D,onPreviewPath:O,onPreviewPathEnd:i,resolvePathTitle:(e,t)=>`${E(e)}${t?`:${t}`:``}`}),y.map(t=>(0,X.jsx)(it,{attachment:t,outbound:a},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,X.jsxs)(`p`,{className:u(`text-xs mt-1 flex items-center gap-1.5`,a?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,X.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,X.jsx)(`span`,{children:ee}),x&&S&&(0,X.jsxs)(`span`,{className:u(`inline-flex items-center gap-1`,x.tone===`ok`&&`text-emerald-300`,x.tone===`warn`&&`text-amber-200`,x.tone===`danger`&&`text-red-200`),title:x.title,children:[(0,X.jsx)(S,{className:`h-3 w-3`}),x.label]})]})]}),!J(e)&&b.length>0&&(0,X.jsxs)(`div`,{className:u(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,a?`justify-end pr-2`:`justify-start pl-2`),children:[!a&&(0,X.jsx)(at,{open:f,onToggle:()=>p(e=>!e),onReact:k}),b.map(e=>(0,X.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>k(e.emoji),className:u(`inline-flex h-5 items-center gap-0.5 rounded-full border px-1.5 text-[11px] shadow-sm transition-colors`,e.mine?`border-primary/40 bg-primary/10 text-primary`:`border-border bg-background hover:bg-muted text-foreground`),children:[(0,X.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,X.jsx)(`span`,{children:e.count})]},e.emoji))]}),!J(e)&&!a&&b.length===0&&(0,X.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,X.jsx)(at,{open:f,onToggle:()=>p(e=>!e),onReact:k})})]})})});export{ve as C,_e as S,Ce as _,Qe as a,Te as b,et as c,Re as d,nt as f,we as g,Ne as h,Je as i,tt as l,xe as m,Xe as n,Ze as o,Me as p,qe as r,$e as s,st as t,Ue as u,Fe as v,ye as w,je as x,Pe as y};
|
|
3
|
-
//# sourceMappingURL=MessageBubble-DPcJxTJj.js.map
|