@tutti-os/agent-gui 0.0.214 → 0.0.216
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/README.md +3 -5
- package/dist/{AgentRichTextReadonly-TASIMIK4.js → AgentRichTextReadonly-IPPNAAWG.js} +6 -6
- package/dist/agent-conversation/index.d.ts +3 -5
- package/dist/agent-conversation/index.js +8 -8
- package/dist/agent-gui.d.ts +2 -9
- package/dist/agent-gui.js +15 -15
- package/dist/agent-message-center/index.d.ts +2 -3
- package/dist/agent-message-center/index.js +7 -7
- package/dist/{agentGuiNodeTypes-BMcpfKTn.d.ts → agentGuiNodeTypes-DW7T--Y8.d.ts} +1 -1
- package/dist/app/renderer/agentactivity.css +68 -34
- package/dist/{chunk-ISC67YBJ.js → chunk-6A6OVD66.js} +4 -4
- package/dist/{chunk-AD2RTSMS.js → chunk-AOK22J62.js} +2 -2
- package/dist/{chunk-2HYADTQP.js → chunk-B4TM2HYJ.js} +2 -2
- package/dist/{chunk-G2QO6HPB.js → chunk-DLN33TPF.js} +23 -9
- package/dist/chunk-DLN33TPF.js.map +1 -0
- package/dist/{chunk-XERDRMSF.js → chunk-DTP2OMCE.js} +4 -4
- package/dist/{chunk-7SSORDQY.js → chunk-EZRQMJTX.js} +8 -14
- package/dist/chunk-EZRQMJTX.js.map +1 -0
- package/dist/{chunk-RLFO3NJV.js → chunk-KJA3HHUJ.js} +529 -809
- package/dist/chunk-KJA3HHUJ.js.map +1 -0
- package/dist/chunk-LQMIEH4C.js +100 -0
- package/dist/chunk-LQMIEH4C.js.map +1 -0
- package/dist/{chunk-ZNHMWCO4.js → chunk-MOCBHFJ2.js} +5 -74
- package/dist/chunk-MOCBHFJ2.js.map +1 -0
- package/dist/{chunk-QVLEP54U.js → chunk-P2RIZAK5.js} +3 -3
- package/dist/chunk-P2RIZAK5.js.map +1 -0
- package/dist/{chunk-YBIT37P5.js → chunk-QFYOJMEQ.js} +2 -2
- package/dist/{chunk-BYHNJQYH.js → chunk-UERICUWM.js} +2 -2
- package/dist/{chunk-L4E2Y52A.js → chunk-VMPPZO5C.js} +5 -44
- package/dist/chunk-VMPPZO5C.js.map +1 -0
- package/dist/{chunk-FEUU4YMY.js → chunk-YY5WM3OE.js} +5707 -5727
- package/dist/chunk-YY5WM3OE.js.map +1 -0
- package/dist/{chunk-LQKLBDBK.js → chunk-Z5UJC4Q3.js} +43 -15
- package/dist/chunk-Z5UJC4Q3.js.map +1 -0
- package/dist/context-mention-palette/index.js +7 -7
- package/dist/{contribution-DfeuQHH6.d.ts → contribution-D4lcOjSU.d.ts} +2 -14
- package/dist/i18n/index.d.ts +2 -2
- package/dist/i18n/index.js +2 -2
- package/dist/index.d.ts +80 -80
- package/dist/index.js +15 -15
- package/dist/mention-search.js +5 -5
- package/dist/workbench/contribution.d.ts +1 -1
- package/dist/workbench/contribution.js +3 -5
- package/dist/workbench/index.d.ts +2 -2
- package/dist/workbench/index.js +3 -5
- package/dist/workbench/sessionTitle.js +2 -2
- package/dist/{workspaceLinkActions-COfr61YO.d.ts → workspaceLinkActions-CzsbvGmC.d.ts} +78 -71
- package/package.json +14 -14
- package/dist/chunk-7SSORDQY.js.map +0 -1
- package/dist/chunk-FEUU4YMY.js.map +0 -1
- package/dist/chunk-G2QO6HPB.js.map +0 -1
- package/dist/chunk-L4E2Y52A.js.map +0 -1
- package/dist/chunk-LQKLBDBK.js.map +0 -1
- package/dist/chunk-QVLEP54U.js.map +0 -1
- package/dist/chunk-RLFO3NJV.js.map +0 -1
- package/dist/chunk-ZNHMWCO4.js.map +0 -1
- package/dist/chunk-ZVYUTXQJ.js +0 -43
- package/dist/chunk-ZVYUTXQJ.js.map +0 -1
- /package/dist/{AgentRichTextReadonly-TASIMIK4.js.map → AgentRichTextReadonly-IPPNAAWG.js.map} +0 -0
- /package/dist/{chunk-ISC67YBJ.js.map → chunk-6A6OVD66.js.map} +0 -0
- /package/dist/{chunk-AD2RTSMS.js.map → chunk-AOK22J62.js.map} +0 -0
- /package/dist/{chunk-2HYADTQP.js.map → chunk-B4TM2HYJ.js.map} +0 -0
- /package/dist/{chunk-XERDRMSF.js.map → chunk-DTP2OMCE.js.map} +0 -0
- /package/dist/{chunk-YBIT37P5.js.map → chunk-QFYOJMEQ.js.map} +0 -0
- /package/dist/{chunk-BYHNJQYH.js.map → chunk-UERICUWM.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
translate
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UERICUWM.js";
|
|
4
4
|
import {
|
|
5
5
|
agentGUIProviderIdentityDisplayName,
|
|
6
6
|
resolveMigratedAgentGUIProviderIdentity
|
|
@@ -213,4 +213,4 @@ export {
|
|
|
213
213
|
getOptionalAgentHostApi,
|
|
214
214
|
workspaceAgentProviderLabel
|
|
215
215
|
};
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-QFYOJMEQ.js.map
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
setCurrentAgentGuiI18nRuntime,
|
|
7
7
|
translate,
|
|
8
8
|
translateInUiLanguage
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-P2RIZAK5.js";
|
|
10
10
|
|
|
11
11
|
// i18n/index.ts
|
|
12
12
|
import React, {
|
|
@@ -68,4 +68,4 @@ export {
|
|
|
68
68
|
AgentGuiI18nProvider,
|
|
69
69
|
useTranslation
|
|
70
70
|
};
|
|
71
|
-
//# sourceMappingURL=chunk-
|
|
71
|
+
//# sourceMappingURL=chunk-UERICUWM.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
translateInUiLanguage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-P2RIZAK5.js";
|
|
4
4
|
import {
|
|
5
5
|
normalizeAgentTitleText
|
|
6
6
|
} from "./chunk-MIJXEELH.js";
|
|
@@ -100,14 +100,14 @@ function deriveAgentGUIOptimisticConversationTitle(visiblePrompt) {
|
|
|
100
100
|
}
|
|
101
101
|
function resolveAgentGUIConversationTitleDisplayPrompt(input) {
|
|
102
102
|
const prompt = resolveAgentGUIConversationTitlePrompt(input);
|
|
103
|
-
if (!prompt ||
|
|
103
|
+
if (!prompt || extractRichTextMentionsFromContent(prompt).length === 0 && extractRichTextLinksFromContent(prompt).length === 0 || !agentGUITitleMatchesDerivedPrompt(
|
|
104
104
|
input.title,
|
|
105
105
|
prompt,
|
|
106
106
|
input.allowEmptyTitle
|
|
107
107
|
)) {
|
|
108
108
|
return null;
|
|
109
109
|
}
|
|
110
|
-
return prompt;
|
|
110
|
+
return normalizeAgentTitleText(prompt);
|
|
111
111
|
}
|
|
112
112
|
function resolveAgentGUIConversationBrowserFreeTitle(input) {
|
|
113
113
|
const prompt = resolveAgentGUIConversationTitlePrompt(input);
|
|
@@ -121,48 +121,9 @@ function resolveAgentGUIConversationBrowserFreeTitle(input) {
|
|
|
121
121
|
const presentationPrompt = removeAgentGUIBrowserElementMentions(prompt);
|
|
122
122
|
return presentationPrompt === prompt ? input.title : deriveAgentGUIOptimisticConversationTitle(presentationPrompt);
|
|
123
123
|
}
|
|
124
|
-
function resolveAgentGUIConversationTitleLeadingMentionKind(
|
|
125
|
-
const firstMention = extractRichTextMentionsFromContent(displayPrompt)[0];
|
|
126
|
-
const mentionKind = firstMention ? agentGUIConversationTitleMentionKind(firstMention) : null;
|
|
127
|
-
if (isAgentGUIConversationTitleIconMentionKind(mentionKind)) {
|
|
128
|
-
return mentionKind;
|
|
129
|
-
}
|
|
130
|
-
if (firstMention) return null;
|
|
131
|
-
return extractRichTextLinksFromContent(displayPrompt).length > 0 ? "file" : null;
|
|
132
|
-
}
|
|
133
|
-
function isAgentGUIConversationTitleIconMentionKind(kind) {
|
|
134
|
-
return kind === "file" || kind === "task";
|
|
135
|
-
}
|
|
136
|
-
function agentGUIConversationTitleMentionKind(mention) {
|
|
137
|
-
if (mention.providerId === "agent-session" || mention.providerId === "session") {
|
|
138
|
-
return "session";
|
|
139
|
-
}
|
|
140
|
-
if (mention.providerId === "workspace-issue" || mention.providerId === "issue" || mention.providerId === "task") {
|
|
141
|
-
return "task";
|
|
142
|
-
}
|
|
143
|
-
if (mention.providerId === "workspace-app") return "app";
|
|
144
|
-
if (mention.providerId === "agent-target") return "agent";
|
|
145
|
-
if (mention.providerId === "workspace-reference") {
|
|
146
|
-
return mention.scope?.source === "task" ? "task" : mention.scope?.source === "app" ? "app" : null;
|
|
147
|
-
}
|
|
124
|
+
function resolveAgentGUIConversationTitleLeadingMentionKind(_displayPrompt) {
|
|
148
125
|
return null;
|
|
149
126
|
}
|
|
150
|
-
function isAgentGUIConversationTitleDisplayPromptEligible(displayPrompt) {
|
|
151
|
-
const mentions = extractRichTextMentionsFromContent(displayPrompt);
|
|
152
|
-
if (mentions.some(
|
|
153
|
-
(mention) => {
|
|
154
|
-
if (mention.providerId === "browser-element") {
|
|
155
|
-
return false;
|
|
156
|
-
}
|
|
157
|
-
return !isAgentGUIConversationTitleIconMentionKind(
|
|
158
|
-
agentGUIConversationTitleMentionKind(mention)
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
)) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
return mentions.length > 0 || extractRichTextLinksFromContent(displayPrompt).length > 0;
|
|
165
|
-
}
|
|
166
127
|
function resolveAgentGUIConversationTitlePrompt(input) {
|
|
167
128
|
const activationPrompt = input.activation?.mode === "new" && isPendingActivationViable(input.activation) ? agentGUIActivationPromptText(
|
|
168
129
|
input.activation.content,
|
|
@@ -374,4 +335,4 @@ export {
|
|
|
374
335
|
resolveAgentGuiWorkbenchHeaderTitle,
|
|
375
336
|
resolveAgentGuiWorkbenchSessionTitle
|
|
376
337
|
};
|
|
377
|
-
//# sourceMappingURL=chunk-
|
|
338
|
+
//# sourceMappingURL=chunk-VMPPZO5C.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] 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};\n","import { AGENT_PROVIDER_LABEL } from \"../contexts/settings/domain/agentSettings.providerMeta.ts\";\nimport {\n isPendingActivationViable,\n type PendingActivationStatus,\n type AgentActivityMessage,\n type AgentPromptContentBlock\n} from \"@tutti-os/agent-activity-core\";\nimport {\n extractRichTextLinksFromContent,\n extractRichTextMentionsFromContent,\n removeRichTextMentionFromContent\n} from \"@tutti-os/ui-rich-text/core\";\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;\nexport type AgentGUIConversationTitleLeadingMentionKind =\n | \"agent\"\n | \"app\"\n | \"file\"\n | \"session\"\n | \"task\";\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 resolveAgentGUIConversationTitleDisplayPrompt(input: {\n activation?: {\n content: readonly AgentPromptContentBlock[];\n displayPrompt?: string;\n mode: \"existing\" | \"new\";\n status: PendingActivationStatus;\n } | null;\n allowEmptyTitle?: boolean;\n firstUserDisplayPrompt?: string | null;\n messages?: readonly AgentActivityMessage[];\n title: string | null;\n}): string | null {\n const prompt = resolveAgentGUIConversationTitlePrompt(input);\n if (\n !prompt ||\n (extractRichTextMentionsFromContent(prompt).length === 0 &&\n extractRichTextLinksFromContent(prompt).length === 0) ||\n !agentGUITitleMatchesDerivedPrompt(\n input.title,\n prompt,\n input.allowEmptyTitle\n )\n ) {\n return null;\n }\n // Titles are presentation text, not an interactive rich-text surface. Keep\n // the mention label but discard its Markdown href before handing it to the\n // header/rail consumers so mention SVGs cannot leak into the chrome.\n return normalizeAgentTitleText(prompt);\n}\n\nexport function resolveAgentGUIConversationBrowserFreeTitle(input: {\n activation?: {\n content: readonly AgentPromptContentBlock[];\n displayPrompt?: string;\n mode: \"existing\" | \"new\";\n status: PendingActivationStatus;\n } | null;\n allowEmptyTitle?: boolean;\n firstUserDisplayPrompt?: string | null;\n messages?: readonly AgentActivityMessage[];\n title: string | null;\n}): string | null {\n const prompt = resolveAgentGUIConversationTitlePrompt(input);\n if (\n !prompt ||\n !agentGUITitleMatchesDerivedPrompt(\n input.title,\n prompt,\n input.allowEmptyTitle\n )\n ) {\n return input.title;\n }\n const presentationPrompt = removeAgentGUIBrowserElementMentions(prompt);\n return presentationPrompt === prompt\n ? input.title\n : deriveAgentGUIOptimisticConversationTitle(presentationPrompt);\n}\n\nexport function resolveAgentGUIConversationTitleLeadingMentionKind(\n _displayPrompt: string | null | undefined\n): AgentGUIConversationTitleLeadingMentionKind | null {\n return null;\n}\n\nfunction resolveAgentGUIConversationTitlePrompt(input: {\n activation?: {\n content: readonly AgentPromptContentBlock[];\n displayPrompt?: string;\n mode: \"existing\" | \"new\";\n status: PendingActivationStatus;\n } | null;\n firstUserDisplayPrompt?: string | null;\n messages?: readonly AgentActivityMessage[];\n}): string {\n const activationPrompt =\n input.activation?.mode === \"new\" &&\n isPendingActivationViable(input.activation)\n ? agentGUIActivationPromptText(\n input.activation.content,\n input.activation.displayPrompt ?? null\n )\n : \"\";\n return (\n activationPrompt ||\n input.firstUserDisplayPrompt?.trim() ||\n resolveAgentGUIFirstUserMessageDisplayPrompt(input.messages ?? [])\n );\n}\n\nfunction removeAgentGUIBrowserElementMentions(prompt: string): string {\n return extractRichTextMentionsFromContent(prompt)\n .filter((mention) => mention.providerId === \"browser-element\")\n .reduce(\n (content, mention) => removeRichTextMentionFromContent(content, mention),\n prompt\n );\n}\n\nexport function resolveAgentGUIFirstUserMessageDisplayPrompt(\n messages: readonly AgentActivityMessage[]\n): string {\n const message = messages.find(\n (candidate) =>\n candidate.role.trim().toLowerCase() === \"user\" &&\n candidate.kind.trim().toLowerCase() === \"text\"\n );\n if (!message) {\n return \"\";\n }\n return (\n agentGUIStringValue(message.payload.displayPrompt) ||\n agentGUIPromptTextFromUnknownContent(message.payload.content) ||\n agentGUIStringValue(message.payload.text) ||\n agentGUIStringValue(message.payload.content)\n );\n}\n\nfunction agentGUIPromptTextFromUnknownContent(content: unknown): string {\n if (!Array.isArray(content)) {\n return \"\";\n }\n return content\n .flatMap((value) => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return [];\n }\n const block = value as Record<string, unknown>;\n return block.type === \"text\" && typeof block.text === \"string\"\n ? [block.text.trim()]\n : [];\n })\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction agentGUIActivationPromptText(\n content: readonly AgentPromptContentBlock[],\n displayPrompt: string | null\n): string {\n const display = displayPrompt?.trim() ?? \"\";\n if (display) {\n return display;\n }\n return content\n .filter((block) => block.type === \"text\")\n .map((block) => block.text?.trim() ?? \"\")\n .filter(Boolean)\n .join(\"\\n\");\n}\n\nfunction agentGUITitleMatchesDerivedPrompt(\n title: string | null,\n prompt: string,\n allowEmptyTitle = false\n): boolean {\n const canonicalTitle = title?.trim() ?? \"\";\n if (!canonicalTitle) {\n return allowEmptyTitle;\n }\n const derivedTitle = normalizeAgentTitleText(prompt);\n if (canonicalTitle === derivedTitle) {\n return true;\n }\n const runes = Array.from(derivedTitle);\n const truncatedDerivedTitle =\n runes.length > AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS\n ? `${runes\n .slice(\n 0,\n AGENT_GUI_MAX_OPTIMISTIC_TITLE_CODE_POINTS -\n AGENT_GUI_TRUNCATED_TITLE_SUFFIX.length\n )\n .join(\"\")\n .trim()}${AGENT_GUI_TRUNCATED_TITLE_SUFFIX}`\n : derivedTitle;\n return canonicalTitle === truncatedDerivedTitle;\n}\n\nfunction agentGUIStringValue(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\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":";;;;;;;;;;;AAAO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACFO,IAAM,uBAAuB,OAAO;AAAA,EACzC,gBAAgB,IAAI,CAAC,aAAa;AAChC,UAAM,WAAW,uCAAuC,QAAQ;AAChE,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,MAAM,iCAAiC,QAAQ,EAAE;AAAA,IAC7D;AACA,WAAO,CAAC,UAAU,SAAS,WAAW;AAAA,EACxC,CAAC;AACH;;;ACbA;AAAA,EACE;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAgBP,IAAM,gCAA0D;AAChE,IAAM,6CAA6C;AACnD,IAAM,mCAAmC;AAElC,SAAS,6BACd,OACoB;AACpB,SAAO,UAAU;AACnB;AAkBO,SAAS,kCACd,UAC0B;AAC1B,QAAM,aAAa,UAAU,KAAK,EAAE,YAAY,KAAK;AACrD,QAAM,kBAAkB,uCAAuC,UAAU;AACzE,MAAI,iBAAiB;AACnB,WAAO,gBAAgB;AAAA,EACzB;AACA,MAAI,CAAC,6BAA6B,KAAK,UAAU,GAAG;AAClD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,cAAc,UAAoC;AACzD,SAAQ,qBAAgD,QAAQ,KAAK;AACvE;AAEO,SAAS,gCAAgC,OAKnB;AAC3B,QAAM,aAAa;AAAA,IACjB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,qBAAqB,MAAM,iBAAiB,CAAC,CAAC;AAAA,EAChD;AACA,aAAW,aAAa,YAAY;AAClC,UAAM,aAAa,kCAAkC,SAAS;AAC9D,QAAI,eAAe,WAAW;AAC5B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iCACd,OAIA;AACA,QAAM,kBAAkB,iCAAiC,OAAO,KAAK,KAAK,EAAE;AAC5E,MAAI,iBAAiB;AACnB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,eAAe;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,eAAe;AAAA,EACjB;AACF;AAEO,SAAS,0CACd,eACQ;AACR,QAAM,kBAAkB,wBAAwB,aAAa;AAC7D,QAAM,aAAa,MAAM,KAAK,eAAe;AAC7C,MAAI,WAAW,UAAU,4CAA4C;AACnE,WAAO;AAAA,EACT;AACA,SAAO,GAAG,WACP;AAAA,IACC;AAAA,IACA,6CACE,iCAAiC;AAAA,EACrC,EACC,KAAK,EAAE,EACP,QAAQ,CAAC,GAAG,gCAAgC;AACjD;AAEO,SAAS,8CAA8C,OAW5C;AAChB,QAAM,SAAS,uCAAuC,KAAK;AAC3D,MACE,CAAC,UACA,mCAAmC,MAAM,EAAE,WAAW,KACrD,gCAAgC,MAAM,EAAE,WAAW,KACrD,CAAC;AAAA,IACC,MAAM;AAAA,IACN;AAAA,IACA,MAAM;AAAA,EACR,GACA;AACA,WAAO;AAAA,EACT;AAIA,SAAO,wBAAwB,MAAM;AACvC;AAEO,SAAS,4CAA4C,OAW1C;AAChB,QAAM,SAAS,uCAAuC,KAAK;AAC3D,MACE,CAAC,UACD,CAAC;AAAA,IACC,MAAM;AAAA,IACN;AAAA,IACA,MAAM;AAAA,EACR,GACA;AACA,WAAO,MAAM;AAAA,EACf;AACA,QAAM,qBAAqB,qCAAqC,MAAM;AACtE,SAAO,uBAAuB,SAC1B,MAAM,QACN,0CAA0C,kBAAkB;AAClE;AAEO,SAAS,mDACd,gBACoD;AACpD,SAAO;AACT;AAEA,SAAS,uCAAuC,OASrC;AACT,QAAM,mBACJ,MAAM,YAAY,SAAS,SAC3B,0BAA0B,MAAM,UAAU,IACtC;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,MAAM,WAAW,iBAAiB;AAAA,EACpC,IACA;AACN,SACE,oBACA,MAAM,wBAAwB,KAAK,KACnC,6CAA6C,MAAM,YAAY,CAAC,CAAC;AAErE;AAEA,SAAS,qCAAqC,QAAwB;AACpE,SAAO,mCAAmC,MAAM,EAC7C,OAAO,CAAC,YAAY,QAAQ,eAAe,iBAAiB,EAC5D;AAAA,IACC,CAAC,SAAS,YAAY,iCAAiC,SAAS,OAAO;AAAA,IACvE;AAAA,EACF;AACJ;AAEO,SAAS,6CACd,UACQ;AACR,QAAM,UAAU,SAAS;AAAA,IACvB,CAAC,cACC,UAAU,KAAK,KAAK,EAAE,YAAY,MAAM,UACxC,UAAU,KAAK,KAAK,EAAE,YAAY,MAAM;AAAA,EAC5C;AACA,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,SACE,oBAAoB,QAAQ,QAAQ,aAAa,KACjD,qCAAqC,QAAQ,QAAQ,OAAO,KAC5D,oBAAoB,QAAQ,QAAQ,IAAI,KACxC,oBAAoB,QAAQ,QAAQ,OAAO;AAE/C;AAEA,SAAS,qCAAqC,SAA0B;AACtE,MAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,WAAO;AAAA,EACT;AACA,SAAO,QACJ,QAAQ,CAAC,UAAU;AAClB,QAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,aAAO,CAAC;AAAA,IACV;AACA,UAAM,QAAQ;AACd,WAAO,MAAM,SAAS,UAAU,OAAO,MAAM,SAAS,WAClD,CAAC,MAAM,KAAK,KAAK,CAAC,IAClB,CAAC;AAAA,EACP,CAAC,EACA,OAAO,OAAO,EACd,KAAK,IAAI;AACd;AAEA,SAAS,6BACP,SACA,eACQ;AACR,QAAM,UAAU,eAAe,KAAK,KAAK;AACzC,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AACA,SAAO,QACJ,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,EACvC,IAAI,CAAC,UAAU,MAAM,MAAM,KAAK,KAAK,EAAE,EACvC,OAAO,OAAO,EACd,KAAK,IAAI;AACd;AAEA,SAAS,kCACP,OACA,QACA,kBAAkB,OACT;AACT,QAAM,iBAAiB,OAAO,KAAK,KAAK;AACxC,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AACA,QAAM,eAAe,wBAAwB,MAAM;AACnD,MAAI,mBAAmB,cAAc;AACnC,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,KAAK,YAAY;AACrC,QAAM,wBACJ,MAAM,SAAS,6CACX,GAAG,MACA;AAAA,IACC;AAAA,IACA,6CACE,iCAAiC;AAAA,EACrC,EACC,KAAK,EAAE,EACP,KAAK,CAAC,GAAG,gCAAgC,KAC5C;AACN,SAAO,mBAAmB;AAC5B;AAEA,SAAS,oBAAoB,OAAwB;AACnD,SAAO,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AACpD;AAEO,SAAS,wCACd,OAIA,2BACQ;AACR,MAAI,MAAM,OAAO;AACf,WAAO,iCAAiC,MAAM,MAAM,KAAK,CAAC;AAAA,EAC5D;AACA,MAAI,MAAM,kBAAkB,yBAAyB;AACnD,WAAO,iCAAiC,yBAAyB;AAAA,EACnE;AACA,SAAO;AACT;AAUO,SAAS,yCAAyC,OAIvC;AAChB,MAAI,MAAM,eAAe;AACvB,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ,iCAAiC,MAAM,MAAM,KAAK,CAAC;AACjE,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,MAAI,4BAA4B,KAAK,GAAG;AACtC,WAAO;AAAA,EACT;AAEA,MAAI,MAAM,aAAa,aAAa,UAAU,cAAc,MAAM,QAAQ,GAAG;AAC3E,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAoBO,SAAS,oCACd,UACA,oBACQ;AACR,QAAM,mBAAmB,kCAAkC,QAAQ;AACnE,MAAI,qBAAqB,WAAW;AAClC,WAAO;AAAA,EACT;AACA,SAAO,cAAc,gBAAgB;AACvC;AA2EA,SAAS,iCAAiC,OAAuB;AAC/D,SAAO,MACJ,QAAQ,EACR,QAAQ,WAAW,EAAE,EACrB,QAAQ;AACb;AAEA,SAAS,4BAA4B,OAAwB;AAC3D,SAAO,oCAAoC,EAAE,IAAI,iBAAiB,KAAK,CAAC;AAC1E;AAEA,SAAS,sCAAmD;AAC1D,SAAO,IAAI;AAAA,IACR,CAAC,MAAM,OAAO,EACZ;AAAA,MAAI,CAAC,aACJ;AAAA,QACE;AAAA,UACE;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,EACC,OAAO,OAAO;AAAA,EACnB;AACF;AAEA,SAAS,qBACP,eACe;AACf,aAAW,QAAQ,eAAe;AAChC,QAAI,mBAAmB,IAAI,GAAG;AAC5B;AAAA,IACF;AACA,UAAM,aAAa,kCAAkC,KAAK,OAAO;AACjE,QAAI,eAAe,WAAW;AAC5B,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAmD;AAC7E,QAAM,OAAO,KAAK,MAAM,KAAK,EAAE,YAAY;AAC3C,MAAI,SAAS,QAAQ;AACnB,WAAO;AAAA,EACT;AACA,QAAM,YAAY,KAAK,UAAU,KAAK,EAAE,YAAY;AACpD,MAAI,cAAc,QAAQ;AACxB,WAAO;AAAA,EACT;AACA,SAAO,KAAK,SAAS,KAAK,EAAE,YAAY,MAAM;AAChD;AAEA,SAAS,iBAAiB,OAAuB;AAC/C,SAAO,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AACzC;;;AChfO,SAAS,oCAAoC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF,GAA4D;AAC1D,SACE,WAAW,SAAS,KACpB,WAAW,oCAAoC,UAAU,EAAE,CAAC,KAC5D,WAAW,iBAAiB,KAC5B;AAEJ;AAEO,SAAS,qCAAqC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AACZ,GAAmF;AACjF,QAAM,2BAA2B,gBAAgB,KAAK,KAAK;AAC3D,MAAI,CAAC,0BAA0B;AAC7B,WAAO,EAAE,gBAAgB,MAAM,QAAQ,QAAQ,OAAO,KAAK;AAAA,EAC7D;AAEA,QAAM,gBAAgB,WAAW,SAAS,KAAK;AAC/C,MAAI,eAAe;AACjB,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,2BAA2B,WAAW,eAAe;AAC3D,MAAI,0BAA0B;AAC5B,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,SAAS;AACX,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,uBAAuB,WAAW,aAAa;AACrD,SAAO,uBACH;AAAA,IACE,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,OAAO;AAAA,EACT,IACA;AAAA,IACE,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACN;AAEA,SAAS,WAAW,OAA0C;AAC5D,SAAO,OAAO,KAAK,KAAK;AAC1B;","names":[]}
|