@@ -2,15 +2,18 @@ import type { ProgressAttributeDescriptor, ProgressRenderConfig } from "./tracin
22
33const hiddenAttributePrefixes = [ "http.request.header." , "http.response.header." ] ;
44
5- const hiddenInteractiveAttributeKeys = new Set ( [
5+ const hiddenAttributeKeys = new Set ( [
66 "concurrency" ,
77 "gen_ai.openai.request.response_format" ,
88 "gen_ai.openai.response.service_tier" ,
99 "gen_ai.operation.name" ,
1010 "gen_ai.response.id" ,
1111 "gen_ai.system" ,
12+ "http.request.method" ,
1213 "server.port" ,
14+ "toolChoice" ,
1315 "url.full" ,
16+ "url.scheme" ,
1417] ) ;
1518
1619const orderedInteractiveAttributeKeys = [
@@ -27,7 +30,6 @@ const orderedInteractiveAttributeKeys = [
2730 "staged_files" ,
2831 "unstaged_files" ,
2932 "file_count" ,
30- "http.request.method" ,
3133 "url.path" ,
3234 "http.response.status_code" ,
3335 "server.address" ,
@@ -43,13 +45,86 @@ const interactiveLabelByKey: Record<string, string> = {
4345 unstaged_files : "unstaged" ,
4446 "gen_ai.request.model" : "model" ,
4547 "gen_ai.response.model" : "model" ,
46- "http.request.method" : "method" ,
4748 "http.response.status_code" : "status" ,
4849 "server.address" : "server" ,
4950 "url.path" : "path" ,
5051} ;
5152
52- const toInteractiveDescriptors = (
53+ const friendlySpanNames : Record < string , string > = {
54+ "commit.prepare-request" : "Prepare commit" ,
55+ "commit.run" : "Run commit" ,
56+ "commit.resolve-provider" : "Resolve provider" ,
57+ "commit.load-project-config" : "Load project config" ,
58+ "commit.scan-changes" : "Scan changes" ,
59+ "commit.plan-groups" : "Plan commits" ,
60+ "commit.refresh-scopes" : "Refresh scopes" ,
61+ "commit.replan-groups" : "Replan commits" ,
62+ "commit.generate-message" : "Generate commit message" ,
63+ "commit.run-hooks" : "Run commit hooks" ,
64+ "commit.create" : "Create commit" ,
65+ "commit.load-previous" : "Load previous commit" ,
66+ "commit.generate-amend-message" : "Generate amended message" ,
67+ "commit.amend" : "Amend commit" ,
68+ "init.run" : "Run init" ,
69+ "init.resolve-provider" : "Resolve provider" ,
70+ "init.initialize-repository" : "Initialize repository" ,
71+ "init.generate-gitignore" : "Generate .gitignore" ,
72+ "init.generate-scopes" : "Generate scopes" ,
73+ "init.write-default-hook" : "Write default hook" ,
74+ "init.write-hook" : "Write hook config" ,
75+ "init.write-project-config" : "Write project config" ,
76+ "config.resolve-provider" : "Resolve provider config" ,
77+ "config.resolve-field" : "Resolve config value" ,
78+ "hooks.execute" : "Run hook" ,
79+ "LanguageModel.generateText" : "Call model" ,
80+ } ;
81+
82+ const titleCase = ( value : string ) : string =>
83+ value
84+ . split ( / \s + / )
85+ . filter ( ( part ) => part . length > 0 )
86+ . map ( ( part ) => part [ 0 ] ?. toUpperCase ( ) + part . slice ( 1 ) )
87+ . join ( " " ) ;
88+
89+ const formatFriendlySpanName = ( name : string , attributes : ReadonlyMap < string , unknown > ) : string => {
90+ const friendly = friendlySpanNames [ name ] ;
91+ if ( friendly != null ) {
92+ if ( name === "hooks.execute" ) {
93+ const hookType = attributes . get ( "hook_type" ) ;
94+ return hookType === "conventional" ? "Validate conventional commit" : friendly ;
95+ }
96+ return friendly ;
97+ }
98+
99+ if ( name . startsWith ( "http.client" ) ) {
100+ const method = attributes . get ( "http.request.method" ) ;
101+ return typeof method === "string" && method . length > 0 ? `HTTP ${ method } ` : "HTTP request" ;
102+ }
103+
104+ return titleCase ( name . replace ( / [ . _ - ] + / g, " " ) ) ;
105+ } ;
106+
107+ const simplifyInteractiveLabel = ( key : string ) : string => {
108+ const mapped = interactiveLabelByKey [ key ] ;
109+ if ( mapped != null ) {
110+ return mapped ;
111+ }
112+ if ( key . startsWith ( "gen_ai.request." ) ) {
113+ return key . slice ( "gen_ai.request." . length ) ;
114+ }
115+ if ( key . startsWith ( "gen_ai.response." ) ) {
116+ return key . slice ( "gen_ai.response." . length ) ;
117+ }
118+ if ( key . startsWith ( "gen_ai.usage." ) ) {
119+ return key . slice ( "gen_ai.usage." . length ) ;
120+ }
121+ if ( key . startsWith ( "gen_ai." ) ) {
122+ return key . slice ( "gen_ai." . length ) ;
123+ }
124+ return key ;
125+ } ;
126+
127+ const toDescriptors = (
53128 attributes : ReadonlyMap < string , unknown > ,
54129) : Array < ProgressAttributeDescriptor > => {
55130 const descriptors : Array < ProgressAttributeDescriptor > = [ ] ;
@@ -58,7 +133,7 @@ const toInteractiveDescriptors = (
58133 const push = (
59134 key : string ,
60135 value : unknown ,
61- label = interactiveLabelByKey [ key ] ?? key ,
136+ label = simplifyInteractiveLabel ( key ) ,
62137 dedupeKey ?: string ,
63138 ) => {
64139 if ( value === undefined || value === null ) {
@@ -119,7 +194,7 @@ const toInteractiveDescriptors = (
119194 if ( used . has ( key ) || value === undefined || value === null ) {
120195 return false ;
121196 }
122- if ( hiddenInteractiveAttributeKeys . has ( key ) ) {
197+ if ( hiddenAttributeKeys . has ( key ) ) {
123198 return false ;
124199 }
125200 return hiddenAttributePrefixes . every ( ( prefix ) => ! key . startsWith ( prefix ) ) ;
@@ -135,10 +210,10 @@ const toInteractiveDescriptors = (
135210
136211export const gitAgentProgressRenderConfig : ProgressRenderConfig = {
137212 headerLabel : "Git agent" ,
138- formatAttributes ( { attributes } , { mode } ) {
139- if ( mode === "raw" ) {
140- return undefined ;
141- }
142- return toInteractiveDescriptors ( attributes ) ;
213+ formatSpanName ( name , { span } ) {
214+ return formatFriendlySpanName ( name , span . attributes ) ;
215+ } ,
216+ formatAttributes ( { attributes } ) {
217+ return toDescriptors ( attributes ) ;
143218 } ,
144219} ;
0 commit comments