@tutti-os/agent-gui 0.0.99 → 0.0.100

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.
Files changed (95) hide show
  1. package/dist/{AgentGUI-Bkk2TRS0.d.ts → AgentGUI-DgBjACOL.d.ts} +12 -3
  2. package/dist/agent-conversation/index.d.ts +4 -4
  3. package/dist/agent-conversation/index.js +8 -9
  4. package/dist/agent-conversation/index.js.map +1 -1
  5. package/dist/agent-gui.d.ts +5 -4
  6. package/dist/agent-gui.js +19 -19
  7. package/dist/agent-message-center/index.d.ts +4 -6
  8. package/dist/agent-message-center/index.js +13 -52
  9. package/dist/agent-message-center/index.js.map +1 -1
  10. package/dist/agent-title-text.js +1 -1
  11. package/dist/{agentConversationVM-C335TR6S.d.ts → agentConversationVM-BzHZhwFP.d.ts} +1 -1
  12. package/dist/{agentGuiNodeTypes-DAsluxjv.d.ts → agentGuiNodeTypes-C-wBSM-Y.d.ts} +19 -4
  13. package/dist/app/renderer/agentactivity.css +141 -36
  14. package/dist/chunk-2RQM7PJN.js +16 -0
  15. package/dist/chunk-2RQM7PJN.js.map +1 -0
  16. package/dist/{chunk-FSKGEGGX.js → chunk-4E3QCW6L.js} +17 -3
  17. package/dist/chunk-4E3QCW6L.js.map +1 -0
  18. package/dist/{chunk-63BE6RGM.js → chunk-4YCCATI4.js} +14 -374
  19. package/dist/chunk-4YCCATI4.js.map +1 -0
  20. package/dist/{chunk-IYEXLOUE.js → chunk-4YVKAPKW.js} +5 -8
  21. package/dist/chunk-4YVKAPKW.js.map +1 -0
  22. package/dist/{chunk-PLCHNOXL.js → chunk-BQJOYTW2.js} +863 -679
  23. package/dist/chunk-BQJOYTW2.js.map +1 -0
  24. package/dist/{chunk-MRRICFWA.js → chunk-D7HMQLBO.js} +159 -55
  25. package/dist/chunk-D7HMQLBO.js.map +1 -0
  26. package/dist/{chunk-OTRZBTFQ.js → chunk-DWUVRWXD.js} +2 -2
  27. package/dist/{chunk-RHTZAODZ.js → chunk-E5AD46HP.js} +2 -2
  28. package/dist/{chunk-3NOJFKDV.js → chunk-EUW6VPIK.js} +414 -49
  29. package/dist/chunk-EUW6VPIK.js.map +1 -0
  30. package/dist/{chunk-Y35GDLP2.js → chunk-F5UR6EJG.js} +2 -17
  31. package/dist/chunk-F5UR6EJG.js.map +1 -0
  32. package/dist/{chunk-J7ZYAUPC.js → chunk-FAE7CXZO.js} +8 -6
  33. package/dist/chunk-FAE7CXZO.js.map +1 -0
  34. package/dist/{chunk-CPUEPDF7.js → chunk-GCW57WYQ.js} +646 -595
  35. package/dist/chunk-GCW57WYQ.js.map +1 -0
  36. package/dist/{chunk-7M77BK6K.js → chunk-JWHPVETQ.js} +154 -147
  37. package/dist/chunk-JWHPVETQ.js.map +1 -0
  38. package/dist/{chunk-4ROALW3K.js → chunk-KAV2WHTG.js} +82 -61
  39. package/dist/chunk-KAV2WHTG.js.map +1 -0
  40. package/dist/{chunk-T6PEJFRP.js → chunk-MES7BQWI.js} +378 -369
  41. package/dist/chunk-MES7BQWI.js.map +1 -0
  42. package/dist/chunk-MIJXEELH.js +96 -0
  43. package/dist/chunk-MIJXEELH.js.map +1 -0
  44. package/dist/{chunk-QWGJ5TEG.js → chunk-QY22OBJS.js} +28 -30
  45. package/dist/chunk-QY22OBJS.js.map +1 -0
  46. package/dist/{chunk-MASXZENX.js → chunk-UESYITH6.js} +21 -2
  47. package/dist/chunk-UESYITH6.js.map +1 -0
  48. package/dist/{chunk-SPZJCTBV.js → chunk-XFRY2WWB.js} +348 -322
  49. package/dist/chunk-XFRY2WWB.js.map +1 -0
  50. package/dist/context-mention-palette/index.d.ts +5 -1
  51. package/dist/context-mention-palette/index.js +10 -11
  52. package/dist/contribution-CTVBPN0R.d.ts +119 -0
  53. package/dist/i18n/index.d.ts +16 -2
  54. package/dist/i18n/index.js +2 -2
  55. package/dist/index.d.ts +8 -7
  56. package/dist/index.js +21 -20
  57. package/dist/index.js.map +1 -1
  58. package/dist/mention-search.d.ts +18 -6
  59. package/dist/mention-search.js +8 -9
  60. package/dist/workbench/contribution.d.ts +6 -107
  61. package/dist/workbench/contribution.js +7 -3
  62. package/dist/workbench/index.d.ts +6 -4
  63. package/dist/workbench/index.js +27 -21
  64. package/dist/workbench/launch.d.ts +13 -5
  65. package/dist/workbench/launch.js +1 -1
  66. package/dist/workbench/sessionTitle.d.ts +5 -7
  67. package/dist/workbench/sessionTitle.js +3 -4
  68. package/dist/workbench/state.js +3 -1
  69. package/dist/workspace-agent-generated-files.d.ts +8 -13
  70. package/dist/workspace-agent-generated-files.js +6 -21
  71. package/dist/{workspaceAgentActivityListTypes-C7gPWYiA.d.ts → workspaceAgentActivityListTypes-DZfS_HgG.d.ts} +3 -26
  72. package/package.json +12 -12
  73. package/dist/chunk-3NOJFKDV.js.map +0 -1
  74. package/dist/chunk-4ROALW3K.js.map +0 -1
  75. package/dist/chunk-63BE6RGM.js.map +0 -1
  76. package/dist/chunk-7M77BK6K.js.map +0 -1
  77. package/dist/chunk-CPUEPDF7.js.map +0 -1
  78. package/dist/chunk-FSKGEGGX.js.map +0 -1
  79. package/dist/chunk-GAD6Y3BF.js +0 -88
  80. package/dist/chunk-GAD6Y3BF.js.map +0 -1
  81. package/dist/chunk-GCBDIQDX.js +0 -22
  82. package/dist/chunk-GCBDIQDX.js.map +0 -1
  83. package/dist/chunk-IYEXLOUE.js.map +0 -1
  84. package/dist/chunk-J7ZYAUPC.js.map +0 -1
  85. package/dist/chunk-MASXZENX.js.map +0 -1
  86. package/dist/chunk-MRRICFWA.js.map +0 -1
  87. package/dist/chunk-PLCHNOXL.js.map +0 -1
  88. package/dist/chunk-QWGJ5TEG.js.map +0 -1
  89. package/dist/chunk-SPZJCTBV.js.map +0 -1
  90. package/dist/chunk-T6PEJFRP.js.map +0 -1
  91. package/dist/chunk-Y35GDLP2.js.map +0 -1
  92. package/dist/chunk-Y5M6Q6WX.js +0 -25
  93. package/dist/chunk-Y5M6Q6WX.js.map +0 -1
  94. /package/dist/{chunk-OTRZBTFQ.js.map → chunk-DWUVRWXD.js.map} +0 -0
  95. /package/dist/{chunk-RHTZAODZ.js.map → chunk-E5AD46HP.js.map} +0 -0
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  normalizeAgentTitleText
3
- } from "./chunk-GCBDIQDX.js";
3
+ } from "./chunk-MIJXEELH.js";
4
4
  import {
5
5
  translateInUiLanguage
6
- } from "./chunk-FSKGEGGX.js";
6
+ } from "./chunk-4E3QCW6L.js";
7
7
  import {
8
8
  resolveAgentGUIProviderCatalogIdentity
9
9
  } from "./chunk-KJQERFKX.js";
@@ -33,6 +33,8 @@ var AGENT_PROVIDER_LABEL = Object.fromEntries(
33
33
 
34
34
  // shared/agentConversationTitleProjection.ts
35
35
  var AGENT_GUI_UNRESOLVED_PROVIDER = "unknown";
36
+ var AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS = 120;
37
+ var AGENT_GUI_TRUNCATED_TITLE_SUFFIX = "...";
36
38
  function isAgentGUIProviderUnresolved(value) {
37
39
  return value === AGENT_GUI_UNRESOLVED_PROVIDER;
38
40
  }
@@ -65,7 +67,7 @@ function resolveAgentGUIProviderIdentity(input) {
65
67
  }
66
68
  return "unknown";
67
69
  }
68
- function resolveAgentGUIConversationTitle(title, provider) {
70
+ function resolveAgentGUIConversationTitle(title) {
69
71
  const normalizedTitle = stripAgentGUITitleTrailingPeriod(title?.trim() ?? "");
70
72
  if (normalizedTitle) {
71
73
  return {
@@ -73,23 +75,28 @@ function resolveAgentGUIConversationTitle(title, provider) {
73
75
  titleFallback: null
74
76
  };
75
77
  }
76
- if (provider === "unknown") {
77
- return {
78
- title: "",
79
- titleFallback: "generic-agent"
80
- };
81
- }
82
78
  return {
83
- title: providerLabel(provider),
84
- titleFallback: null
79
+ title: "",
80
+ titleFallback: "untitled-conversation"
85
81
  };
86
82
  }
87
- function resolveAgentGUIConversationDisplayTitle(input, fallbackAgentLabel) {
83
+ function deriveAgentGUIOptimisticConversationTitle(visiblePrompt) {
84
+ const normalizedTitle = normalizeAgentTitleText(visiblePrompt);
85
+ const codePoints = Array.from(normalizedTitle);
86
+ if (codePoints.length <= AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS) {
87
+ return normalizedTitle;
88
+ }
89
+ return `${codePoints.slice(
90
+ 0,
91
+ AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS - AGENT_GUI_TRUNCATED_TITLE_SUFFIX.length
92
+ ).join("").trimEnd()}${AGENT_GUI_TRUNCATED_TITLE_SUFFIX}`;
93
+ }
94
+ function resolveAgentGUIConversationDisplayTitle(input, untitledConversationLabel) {
88
95
  if (input.title) {
89
96
  return stripAgentGUITitleTrailingPeriod(input.title.trim());
90
97
  }
91
- if (input.titleFallback === "generic-agent") {
92
- return stripAgentGUITitleTrailingPeriod(fallbackAgentLabel);
98
+ if (input.titleFallback === "untitled-conversation") {
99
+ return stripAgentGUITitleTrailingPeriod(untitledConversationLabel);
93
100
  }
94
101
  return "";
95
102
  }
@@ -116,50 +123,6 @@ function resolveAgentGUIProviderDisplayLabel(provider, fallbackAgentLabel) {
116
123
  }
117
124
  return providerLabel(resolvedProvider);
118
125
  }
119
- function firstAgentGUIUserMessageTitle(messages) {
120
- const userMessage = [...messages].filter(
121
- (message) => messageRole(message) === "user" && messageText(message).length > 0
122
- ).sort(compareMessagesAscending)[0];
123
- return userMessage ? messageText(userMessage) : "";
124
- }
125
- function messageRole(message) {
126
- const role = message.role?.trim().toLowerCase();
127
- if (role === "user") {
128
- return "user";
129
- }
130
- if (role === "assistant" || role === "agent") {
131
- return "agent";
132
- }
133
- const kind = message.kind?.trim().toLowerCase() ?? "";
134
- if (kind === "message.user") {
135
- return "user";
136
- }
137
- if (kind === "message.assistant" || kind === "message.agent") {
138
- return "agent";
139
- }
140
- return null;
141
- }
142
- function messageText(message) {
143
- const payload = message.payload;
144
- const displayPrompt = typeof payload?.displayPrompt === "string" ? payload.displayPrompt : "";
145
- const text = typeof payload?.text === "string" ? payload.text : "";
146
- const content = typeof payload?.content === "string" ? payload.content : "";
147
- return normalizeAgentTitleText(displayPrompt || text || content);
148
- }
149
- function compareMessagesAscending(left, right) {
150
- const leftTime = left.occurredAtUnixMs ?? left.completedAtUnixMs ?? left.startedAtUnixMs ?? 0;
151
- const rightTime = right.occurredAtUnixMs ?? right.completedAtUnixMs ?? right.startedAtUnixMs ?? 0;
152
- const timeDiff = leftTime - rightTime;
153
- if (timeDiff !== 0) {
154
- return timeDiff;
155
- }
156
- const sequenceDiff = messageSequence(left) - messageSequence(right) || (left.messageId ?? "").localeCompare(right.messageId ?? "");
157
- return sequenceDiff;
158
- }
159
- function messageSequence(message) {
160
- const numericId = typeof message.id === "number" && Number.isFinite(message.id) ? message.id : 0;
161
- return message.version ?? numericId;
162
- }
163
126
  function stripAgentGUITitleTrailingPeriod(title) {
164
127
  return title.trimEnd().replace(/[.。]+$/u, "").trimEnd();
165
128
  }
@@ -172,7 +135,7 @@ function localizedAgentGUIUntitledTaskLabels() {
172
135
  (language) => compactTitleText(
173
136
  translateInUiLanguage(
174
137
  language,
175
- "agentHost.workspaceAgentsUntitledTask"
138
+ "agentHost.workspaceAgentsUntitledConversation"
176
139
  )
177
140
  )
178
141
  ).filter(Boolean)
@@ -205,6 +168,62 @@ function compactTitleText(value) {
205
168
  return value.trim().replace(/\s+/g, " ");
206
169
  }
207
170
 
171
+ // workbench/sessionTitle.ts
172
+ function resolveAgentGuiWorkbenchHeaderTitle({
173
+ agentName,
174
+ conversationTitle,
175
+ provider
176
+ }) {
177
+ return stripTitle(agentName) || stripTitle(resolveAgentGUIProviderDisplayLabel(provider, "")) || stripTitle(conversationTitle) || null;
178
+ }
179
+ function resolveAgentGuiWorkbenchSessionTitle({
180
+ agentSessionId,
181
+ fallbackTitle,
182
+ optimisticTitle,
183
+ session = null
184
+ }) {
185
+ const normalizedAgentSessionId = agentSessionId?.trim() ?? "";
186
+ if (!normalizedAgentSessionId) {
187
+ return { agentSessionId: null, source: "none", title: null };
188
+ }
189
+ const snapshotTitle = stripTitle(session?.title);
190
+ if (snapshotTitle) {
191
+ return {
192
+ agentSessionId: normalizedAgentSessionId,
193
+ source: "snapshot",
194
+ title: snapshotTitle
195
+ };
196
+ }
197
+ const projectedOptimisticTitle = stripTitle(optimisticTitle);
198
+ if (projectedOptimisticTitle) {
199
+ return {
200
+ agentSessionId: normalizedAgentSessionId,
201
+ source: "optimistic",
202
+ title: projectedOptimisticTitle
203
+ };
204
+ }
205
+ if (session) {
206
+ return {
207
+ agentSessionId: normalizedAgentSessionId,
208
+ source: "none",
209
+ title: null
210
+ };
211
+ }
212
+ const fallbackDisplayTitle = stripTitle(fallbackTitle);
213
+ return fallbackDisplayTitle ? {
214
+ agentSessionId: normalizedAgentSessionId,
215
+ source: "fallback",
216
+ title: fallbackDisplayTitle
217
+ } : {
218
+ agentSessionId: normalizedAgentSessionId,
219
+ source: "none",
220
+ title: null
221
+ };
222
+ }
223
+ function stripTitle(value) {
224
+ return value?.trim() ?? "";
225
+ }
226
+
208
227
  export {
209
228
  AGENT_PROVIDERS,
210
229
  AGENT_PROVIDER_LABEL,
@@ -212,9 +231,11 @@ export {
212
231
  normalizeAgentGUIProviderIdentity,
213
232
  resolveAgentGUIProviderIdentity,
214
233
  resolveAgentGUIConversationTitle,
234
+ deriveAgentGUIOptimisticConversationTitle,
215
235
  resolveAgentGUIConversationDisplayTitle,
216
236
  resolveAgentGUIExplicitConversationTitle,
217
237
  resolveAgentGUIProviderDisplayLabel,
218
- firstAgentGUIUserMessageTitle
238
+ resolveAgentGuiWorkbenchHeaderTitle,
239
+ resolveAgentGuiWorkbenchSessionTitle
219
240
  };
220
- //# sourceMappingURL=chunk-4ROALW3K.js.map
241
+ //# sourceMappingURL=chunk-KAV2WHTG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../contexts/settings/domain/agentSettings.providers.ts","../contexts/settings/domain/agentSettings.providerMeta.ts","../shared/agentConversationTitleProjection.ts","../workbench/sessionTitle.ts"],"sourcesContent":["export const AGENT_PROVIDERS = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n \"tutti-agent\",\n \"nexight\",\n \"opencode\",\n \"openclaw\",\n \"hermes\"\n] as const;\nexport const EXPERIMENTAL_AGENT_PROVIDERS = [] as const;\n\nexport type AgentProvider = (typeof AGENT_PROVIDERS)[number];\n\nexport function isValidProvider(value: unknown): value is AgentProvider {\n return (\n typeof value === \"string\" &&\n AGENT_PROVIDERS.includes(value as AgentProvider)\n );\n}\n\nexport function normalizeAgentProviderOrder(value: unknown): AgentProvider[] {\n if (!Array.isArray(value)) {\n return [...AGENT_PROVIDERS];\n }\n\n const normalized: AgentProvider[] = [];\n const seen = new Set<AgentProvider>();\n\n for (const item of value) {\n if (!isValidProvider(item)) {\n continue;\n }\n\n if (seen.has(item)) {\n continue;\n }\n\n seen.add(item);\n normalized.push(item);\n }\n\n for (const provider of AGENT_PROVIDERS) {\n if (seen.has(provider)) {\n continue;\n }\n\n seen.add(provider);\n normalized.push(provider);\n }\n\n return normalized;\n}\n","import { resolveAgentGUIProviderCatalogIdentity } from \"../../../providerIdentityCatalog.ts\";\nimport {\n AGENT_PROVIDERS,\n type AgentProvider\n} from \"./agentSettings.providers.ts\";\n\nexport const AGENT_PROVIDER_LABEL = Object.fromEntries(\n AGENT_PROVIDERS.map((provider) => {\n const identity = resolveAgentGUIProviderCatalogIdentity(provider);\n if (!identity) {\n throw new Error(`Missing provider identity for ${provider}`);\n }\n return [provider, identity.displayName];\n })\n) as Record<AgentProvider, string>;\n\nexport interface AgentProviderCapabilities {\n runtimeObservation: \"jsonl\" | \"provider-api\" | \"none\";\n experimental: boolean;\n}\n\nexport const AGENT_PROVIDER_CAPABILITIES: Record<\n AgentProvider,\n AgentProviderCapabilities\n> = {\n \"claude-code\": {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n codex: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n \"tutti-agent\": {\n runtimeObservation: \"provider-api\",\n experimental: false\n },\n cursor: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n nexight: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n opencode: {\n runtimeObservation: \"provider-api\",\n experimental: false\n },\n openclaw: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n hermes: {\n runtimeObservation: \"jsonl\",\n experimental: false\n }\n};\n","import { AGENT_PROVIDER_LABEL } from \"../contexts/settings/domain/agentSettings.providerMeta.ts\";\nimport { translateInUiLanguage } from \"../i18n/runtime.ts\";\nimport { resolveAgentGUIProviderCatalogIdentity } from \"../providerIdentityCatalog.ts\";\nimport type { AgentGUIProvider } from \"../types.ts\";\nimport type { WorkspaceAgentActivityTimelineItem } from \"./workspaceAgentTimelineTypes.ts\";\nimport { normalizeAgentTitleText } from \"./utils/agentTitleText.ts\";\n\nexport type AgentGUIResolvedProvider = AgentGUIProvider | \"unknown\";\nexport type AgentGUIConversationTitleFallback = \"untitled-conversation\" | null;\n\nconst AGENT_GUI_UNRESOLVED_PROVIDER: AgentGUIResolvedProvider = \"unknown\";\nconst AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS = 120;\nconst AGENT_GUI_TRUNCATED_TITLE_SUFFIX = \"...\";\n\nexport function isAgentGUIProviderUnresolved(\n value: AgentGUIResolvedProvider\n): value is \"unknown\" {\n return value === AGENT_GUI_UNRESOLVED_PROVIDER;\n}\n\nexport interface AgentGUIConversationTitleMessage {\n id?: number | string | null;\n messageId?: string | null;\n version?: number | null;\n role?: string | null;\n kind?: string | null;\n payload?: {\n content?: unknown;\n displayPrompt?: unknown;\n text?: unknown;\n } | null;\n occurredAtUnixMs?: number | null;\n completedAtUnixMs?: number | null;\n startedAtUnixMs?: number | null;\n}\n\nexport function normalizeAgentGUIProviderIdentity(\n provider: string | null | undefined\n): AgentGUIResolvedProvider {\n const normalized = provider?.trim().toLowerCase() ?? \"\";\n const catalogIdentity = resolveAgentGUIProviderCatalogIdentity(normalized);\n if (catalogIdentity) {\n return catalogIdentity.providerId as AgentGUIProvider;\n }\n if (!/^[a-z][a-z0-9._:-]{0,127}$/.test(normalized)) {\n return \"unknown\";\n }\n return normalized as AgentGUIProvider;\n}\n\nfunction providerLabel(provider: AgentGUIProvider): string {\n return (AGENT_PROVIDER_LABEL as Record<string, string>)[provider] ?? provider;\n}\n\nexport function resolveAgentGUIProviderIdentity(input: {\n sessionProvider?: string | null;\n workspaceSessionProvider?: string | null;\n conversationProvider?: string | null;\n timelineItems?: readonly WorkspaceAgentActivityTimelineItem[];\n}): AgentGUIResolvedProvider {\n const candidates = [\n input.sessionProvider,\n input.workspaceSessionProvider,\n input.conversationProvider,\n timelineProviderHint(input.timelineItems ?? [])\n ];\n for (const candidate of candidates) {\n const normalized = normalizeAgentGUIProviderIdentity(candidate);\n if (normalized !== \"unknown\") {\n return normalized;\n }\n }\n return \"unknown\";\n}\n\nexport function resolveAgentGUIConversationTitle(\n title: string | null | undefined\n): {\n title: string;\n titleFallback: AgentGUIConversationTitleFallback;\n} {\n const normalizedTitle = stripAgentGUITitleTrailingPeriod(title?.trim() ?? \"\");\n if (normalizedTitle) {\n return {\n title: normalizedTitle,\n titleFallback: null\n };\n }\n return {\n title: \"\",\n titleFallback: \"untitled-conversation\"\n };\n}\n\nexport function deriveAgentGUIOptimisticConversationTitle(\n visiblePrompt: string | null | undefined\n): string {\n const normalizedTitle = normalizeAgentTitleText(visiblePrompt);\n const codePoints = Array.from(normalizedTitle);\n if (codePoints.length <= AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS) {\n return normalizedTitle;\n }\n return `${codePoints\n .slice(\n 0,\n AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS -\n AGENT_GUI_TRUNCATED_TITLE_SUFFIX.length\n )\n .join(\"\")\n .trimEnd()}${AGENT_GUI_TRUNCATED_TITLE_SUFFIX}`;\n}\n\nexport function resolveAgentGUIConversationDisplayTitle(\n input: {\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n },\n untitledConversationLabel: string\n): string {\n if (input.title) {\n return stripAgentGUITitleTrailingPeriod(input.title.trim());\n }\n if (input.titleFallback === \"untitled-conversation\") {\n return stripAgentGUITitleTrailingPeriod(untitledConversationLabel);\n }\n return \"\";\n}\n\nexport function resolveAgentGUIDockConversationTitle(input: {\n provider: AgentGUIResolvedProvider;\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n}): string | null {\n return resolveAgentGUIExplicitConversationTitle(input);\n}\n\nexport function resolveAgentGUIExplicitConversationTitle(input: {\n provider: AgentGUIResolvedProvider;\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n}): string | null {\n if (input.titleFallback) {\n return null;\n }\n\n const title = stripAgentGUITitleTrailingPeriod(input.title.trim());\n if (!title) {\n return null;\n }\n if (isAgentGUIUntitledTaskTitle(title)) {\n return null;\n }\n\n if (input.provider !== \"unknown\" && title === providerLabel(input.provider)) {\n return null;\n }\n\n return title;\n}\n\nexport function resolveAgentGUIExplicitConversationTitleFromMessages(input: {\n messages: readonly AgentGUIConversationTitleMessage[];\n provider: AgentGUIResolvedProvider;\n title: string | null | undefined;\n}): string | null {\n const explicitTitle = resolveAgentGUIExplicitConversationTitle({\n provider: input.provider,\n title: input.title?.trim() ?? \"\"\n });\n if (explicitTitle) {\n return explicitTitle;\n }\n return resolveAgentGUIExplicitConversationTitle({\n provider: input.provider,\n title: firstAgentGUIUserMessageTitle(input.messages)\n });\n}\n\nexport function resolveAgentGUIProviderDisplayLabel(\n provider: string | null | undefined,\n fallbackAgentLabel: string\n): string {\n const resolvedProvider = normalizeAgentGUIProviderIdentity(provider);\n if (resolvedProvider === \"unknown\") {\n return fallbackAgentLabel;\n }\n return providerLabel(resolvedProvider);\n}\n\nexport function firstAgentGUIUserMessageTitle(\n messages: readonly AgentGUIConversationTitleMessage[]\n): string {\n const userMessage = [...messages]\n .filter(\n (message) =>\n messageRole(message) === \"user\" && messageText(message).length > 0\n )\n .sort(compareMessagesAscending)[0];\n return userMessage ? messageText(userMessage) : \"\";\n}\n\nfunction messageRole(\n message: AgentGUIConversationTitleMessage\n): \"user\" | \"agent\" | null {\n const role = message.role?.trim().toLowerCase();\n if (role === \"user\") {\n return \"user\";\n }\n if (role === \"assistant\" || role === \"agent\") {\n return \"agent\";\n }\n const kind = message.kind?.trim().toLowerCase() ?? \"\";\n if (kind === \"message.user\") {\n return \"user\";\n }\n if (kind === \"message.assistant\" || kind === \"message.agent\") {\n return \"agent\";\n }\n return null;\n}\n\nfunction messageText(message: AgentGUIConversationTitleMessage): string {\n const payload = message.payload;\n const displayPrompt =\n typeof payload?.displayPrompt === \"string\" ? payload.displayPrompt : \"\";\n const text = typeof payload?.text === \"string\" ? payload.text : \"\";\n const content = typeof payload?.content === \"string\" ? payload.content : \"\";\n return normalizeAgentTitleText(displayPrompt || text || content);\n}\n\nfunction compareMessagesAscending(\n left: AgentGUIConversationTitleMessage,\n right: AgentGUIConversationTitleMessage\n): number {\n const leftTime =\n left.occurredAtUnixMs ??\n left.completedAtUnixMs ??\n left.startedAtUnixMs ??\n 0;\n const rightTime =\n right.occurredAtUnixMs ??\n right.completedAtUnixMs ??\n right.startedAtUnixMs ??\n 0;\n const timeDiff = leftTime - rightTime;\n if (timeDiff !== 0) {\n return timeDiff;\n }\n const sequenceDiff =\n messageSequence(left) - messageSequence(right) ||\n (left.messageId ?? \"\").localeCompare(right.messageId ?? \"\");\n return sequenceDiff;\n}\n\nfunction messageSequence(message: AgentGUIConversationTitleMessage): number {\n const numericId =\n typeof message.id === \"number\" && Number.isFinite(message.id)\n ? message.id\n : 0;\n return message.version ?? numericId;\n}\n\nfunction stripAgentGUITitleTrailingPeriod(title: string): string {\n return title\n .trimEnd()\n .replace(/[.。]+$/u, \"\")\n .trimEnd();\n}\n\nfunction isAgentGUIUntitledTaskTitle(title: string): boolean {\n return localizedAgentGUIUntitledTaskLabels().has(compactTitleText(title));\n}\n\nfunction localizedAgentGUIUntitledTaskLabels(): Set<string> {\n return new Set(\n ([\"en\", \"zh-CN\"] as const)\n .map((language) =>\n compactTitleText(\n translateInUiLanguage(\n language,\n \"agentHost.workspaceAgentsUntitledConversation\"\n )\n )\n )\n .filter(Boolean)\n );\n}\n\nfunction timelineProviderHint(\n timelineItems: readonly WorkspaceAgentActivityTimelineItem[]\n): string | null {\n for (const item of timelineItems) {\n if (isUserTimelineItem(item)) {\n continue;\n }\n const normalized = normalizeAgentGUIProviderIdentity(item.actorId);\n if (normalized !== \"unknown\") {\n return normalized;\n }\n }\n return null;\n}\n\nfunction isUserTimelineItem(item: WorkspaceAgentActivityTimelineItem): boolean {\n const role = item.role?.trim().toLowerCase();\n if (role === \"user\") {\n return true;\n }\n const actorType = item.actorType.trim().toLowerCase();\n if (actorType === \"user\") {\n return true;\n }\n return item.itemType.trim().toLowerCase() === \"message.user\";\n}\n\nfunction compactTitleText(value: string): string {\n return value.trim().replace(/\\s+/g, \" \");\n}\n","import type { AgentActivitySession } from \"@tutti-os/agent-activity-core\";\nimport { resolveAgentGUIProviderDisplayLabel } from \"../shared/agentConversationTitleProjection.ts\";\n\nexport interface ResolveAgentGuiWorkbenchHeaderTitleInput {\n agentName?: string | null;\n conversationTitle?: string | null;\n provider?: string | null;\n}\n\nexport interface ResolveAgentGuiWorkbenchSessionTitleInput {\n agentSessionId?: string | null;\n fallbackTitle?: string | null;\n optimisticTitle?: string | null;\n session?: Pick<AgentActivitySession, \"title\"> | null;\n}\n\nexport interface AgentGuiWorkbenchSessionTitleResult {\n agentSessionId: string | null;\n source: \"snapshot\" | \"optimistic\" | \"fallback\" | \"none\";\n title: string | null;\n}\n\nexport function resolveAgentGuiWorkbenchHeaderTitle({\n agentName,\n conversationTitle,\n provider\n}: ResolveAgentGuiWorkbenchHeaderTitleInput): string | null {\n return (\n stripTitle(agentName) ||\n stripTitle(resolveAgentGUIProviderDisplayLabel(provider, \"\")) ||\n stripTitle(conversationTitle) ||\n null\n );\n}\n\nexport function resolveAgentGuiWorkbenchSessionTitle({\n agentSessionId,\n fallbackTitle,\n optimisticTitle,\n session = null\n}: ResolveAgentGuiWorkbenchSessionTitleInput): AgentGuiWorkbenchSessionTitleResult {\n const normalizedAgentSessionId = agentSessionId?.trim() ?? \"\";\n if (!normalizedAgentSessionId) {\n return { agentSessionId: null, source: \"none\", title: null };\n }\n\n const snapshotTitle = stripTitle(session?.title);\n if (snapshotTitle) {\n return {\n agentSessionId: normalizedAgentSessionId,\n source: \"snapshot\",\n title: snapshotTitle\n };\n }\n\n const projectedOptimisticTitle = stripTitle(optimisticTitle);\n if (projectedOptimisticTitle) {\n return {\n agentSessionId: normalizedAgentSessionId,\n source: \"optimistic\",\n title: projectedOptimisticTitle\n };\n }\n\n if (session) {\n return {\n agentSessionId: normalizedAgentSessionId,\n source: \"none\",\n title: null\n };\n }\n\n const fallbackDisplayTitle = stripTitle(fallbackTitle);\n return fallbackDisplayTitle\n ? {\n agentSessionId: normalizedAgentSessionId,\n source: \"fallback\",\n title: fallbackDisplayTitle\n }\n : {\n agentSessionId: normalizedAgentSessionId,\n source: \"none\",\n title: null\n };\n}\n\nfunction stripTitle(value: string | null | undefined): string {\n return value?.trim() ?? \"\";\n}\n"],"mappings":"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","names":[]}