@@ -27,6 +27,29 @@ class ReadFileTool extends StructuredTool {
2727 . describe ( "line number to end reading on (1-based index, inclusive)" ) ,
2828 } ) ;
2929
30+ /**
31+ * Check if a URI is a SAF URI
32+ */
33+ isSafUri ( uri ) {
34+ return uri . startsWith ( "content://" ) && uri . includes ( "/tree/" ) ;
35+ }
36+
37+ /**
38+ * Check if SAF URI already has the :: separator (complete format)
39+ */
40+ isCompleteSafUri ( uri ) {
41+ return this . isSafUri ( uri ) && uri . includes ( "::" ) ;
42+ }
43+
44+ /**
45+ * Construct SAF URI for file access
46+ */
47+ constructSafFileUri ( baseUri , filePath ) {
48+ // For incomplete SAF URIs (without ::), construct the full format
49+ // baseUri::primary:fullFilePath
50+ return `${ baseUri } ::primary:${ filePath } ` ;
51+ }
52+
3053 async _call ( { path, startLine, endLine } ) {
3154 try {
3255 // Split the path to get project name and file path
@@ -42,8 +65,25 @@ class ReadFileTool extends StructuredTool {
4265 return `Error: Project '${ projectName } ' not found in opened projects` ;
4366 }
4467
45- // Construct the full file URL
46- const fileUrl = project . url + "/" + filePath ;
68+ let fileUrl ;
69+
70+ // Check if this is a SAF URI
71+ if ( this . isSafUri ( project . url ) ) {
72+ if ( this . isCompleteSafUri ( project . url ) ) {
73+ // SAF URI already has :: separator, just append the file path normally
74+ // Handle both cases: with trailing slash or without
75+ const baseUrl = project . url . endsWith ( "/" )
76+ ? project . url
77+ : project . url + "/" ;
78+ fileUrl = baseUrl + filePath ;
79+ } else {
80+ // SAF URI without :: separator, use the special format
81+ fileUrl = this . constructSafFileUri ( project . url , path ) ;
82+ }
83+ } else {
84+ // For regular file URIs, use the normal path concatenation
85+ fileUrl = project . url + "/" + filePath ;
86+ }
4787
4888 // Read the file content
4989 const content = await fsOperation ( fileUrl ) . readFile ( "utf8" ) ;
0 commit comments