|
1 | | -import { stripVersionSuffix } from '@sim/utils/string' |
| 1 | +import { stripVersionSuffix, truncate } from '@sim/utils/string' |
2 | 2 |
|
3 | 3 | /** |
4 | 4 | * Single source of truth for copilot tool-call display titles. |
@@ -115,6 +115,40 @@ function pathLeaf(path: string): string { |
115 | 115 | return decodePathSegment(leaf) |
116 | 116 | } |
117 | 117 |
|
| 118 | +/** Returns the final path segment without a file extension or virtual content suffix. */ |
| 119 | +function pathStem(path: string): string { |
| 120 | + const normalized = path.replace(/\/+$/, '').replace(/\/content$/, '') |
| 121 | + const leaf = pathLeaf(normalized) |
| 122 | + const extensionIndex = leaf.lastIndexOf('.') |
| 123 | + return extensionIndex > 0 ? leaf.slice(0, extensionIndex) : leaf |
| 124 | +} |
| 125 | + |
| 126 | +/** |
| 127 | + * Labels a docs corpus page as `<section>/<page>` (docs/workflows/blocks/agent.mdx |
| 128 | + * → `workflows/agent`); a top-level page is just its stem (docs/getting-started.mdx |
| 129 | + * → `getting-started`). Returns null when the path is not a docs page. |
| 130 | + */ |
| 131 | +export function docsPageLabel(path: string): string | null { |
| 132 | + const segments = path |
| 133 | + .split('/') |
| 134 | + .map((segment) => segment.trim()) |
| 135 | + .filter(Boolean) |
| 136 | + .map(decodePathSegment) |
| 137 | + if (segments[0] !== 'docs' || segments.length < 2) return null |
| 138 | + const leaf = pathStem(path) |
| 139 | + if (segments.length === 2) return leaf |
| 140 | + return `${segments[1]}/${leaf}` |
| 141 | +} |
| 142 | + |
| 143 | +function grepTitle(args: ToolArgs): string { |
| 144 | + const path = stringArg(args, 'path') |
| 145 | + const docsPage = docsPageLabel(path) |
| 146 | + if (docsPage) return `Skimming Docs Page: ${docsPage}` |
| 147 | + const target = pathStem(path) || 'Internal Knowledge Base' |
| 148 | + const pattern = truncate(stringArg(args, 'pattern').replace(/\s+/g, ' '), 60) |
| 149 | + return pattern ? `Searching ${target} for ${pattern}` : `Searching ${target}` |
| 150 | +} |
| 151 | + |
118 | 152 | function summarizeTargets(targets: string[], fallback: string): string { |
119 | 153 | const normalized = targets.map((target) => target.trim()).filter(Boolean) |
120 | 154 | if (normalized.length === 0) return fallback |
@@ -805,12 +839,10 @@ export function getToolDisplayTitle(name: string, args?: Record<string, unknown> |
805 | 839 | return target ? `Searching online for ${target}` : 'Searching online' |
806 | 840 | } |
807 | 841 | case 'grep': { |
808 | | - const target = firstStringArg(args, 'toolTitle', 'title') |
809 | | - return target ? `Searching for ${target}` : 'Searching' |
| 842 | + return grepTitle(args) |
810 | 843 | } |
811 | 844 | case 'glob': { |
812 | | - const target = firstStringArg(args, 'toolTitle', 'title') |
813 | | - return target ? `Finding ${target}` : 'Finding files' |
| 845 | + return 'Exploring Internal Knowledge Base' |
814 | 846 | } |
815 | 847 | case 'mv': { |
816 | 848 | const sources = stringArrayArg(args, 'sources') |
@@ -893,9 +925,9 @@ export function getToolDisplayTitle(name: string, args?: Record<string, unknown> |
893 | 925 | } |
894 | 926 | case 'web_fetch': { |
895 | 927 | const urls = stringArrayArg(args, 'urls') |
896 | | - if (urls.length === 1) return `Getting ${urls[0]}` |
897 | | - if (urls.length > 1) return `Getting ${urls.length} pages` |
898 | | - return 'Getting page contents' |
| 928 | + if (urls.length === 1) return `Fetching ${urls[0]}` |
| 929 | + if (urls.length > 1) return `Fetching ${urls.length} pages` |
| 930 | + return 'Fetching page contents' |
899 | 931 | } |
900 | 932 | case 'manage_custom_tool': { |
901 | 933 | const schema = args?.schema |
@@ -998,8 +1030,10 @@ const COMPLETED_VERB_REWRITES: Record<string, string> = { |
998 | 1030 | Editing: 'Edited', |
999 | 1031 | Enabling: 'Enabled', |
1000 | 1032 | Executing: 'Executed', |
| 1033 | + Exploring: 'Explored', |
1001 | 1034 | Extracting: 'Extracted', |
1002 | 1035 | Fading: 'Faded', |
| 1036 | + Fetching: 'Fetched', |
1003 | 1037 | Finding: 'Found', |
1004 | 1038 | Gathering: 'Gathered', |
1005 | 1039 | Generating: 'Generated', |
@@ -1035,6 +1069,7 @@ const COMPLETED_VERB_REWRITES: Record<string, string> = { |
1035 | 1069 | Selecting: 'Selected', |
1036 | 1070 | Setting: 'Set', |
1037 | 1071 | Sharing: 'Shared', |
| 1072 | + Skimming: 'Skimmed', |
1038 | 1073 | Stopping: 'Stopped', |
1039 | 1074 | Summarizing: 'Summarized', |
1040 | 1075 | Switching: 'Switched', |
|
0 commit comments