@@ -5,23 +5,35 @@ import {
55 userTableDefinitions ,
66 userTableRows ,
77 workflow ,
8- workspaceFiles ,
8+ workspace ,
99} from '@sim/db/schema'
1010import { createLogger } from '@sim/logger'
1111import { and , count , eq , isNull } from 'drizzle-orm'
12+ import { listWorkspaceFiles } from '@/lib/uploads/contexts/workspace'
13+ import { getUsersWithPermissions } from '@/lib/workspaces/permissions/utils'
1214
1315const logger = createLogger ( 'WorkspaceContext' )
1416
1517/**
1618 * Generate WORKSPACE.md content from actual database state.
17- * This is injected into the system prompt — the LLM never writes it directly.
19+ * Auto-injected into the system prompt and served as a top-level VFS file.
20+ * The LLM never writes it directly.
1821 */
1922export async function generateWorkspaceContext (
2023 workspaceId : string ,
2124 userId : string
2225) : Promise < string > {
2326 try {
24- const [ workflows , kbs , tables , files , credentials ] = await Promise . all ( [
27+ const [ wsRow , members , workflows , kbs , tables , files , credentials ] = await Promise . all ( [
28+ db
29+ . select ( { id : workspace . id , name : workspace . name , ownerId : workspace . ownerId } )
30+ . from ( workspace )
31+ . where ( eq ( workspace . id , workspaceId ) )
32+ . limit ( 1 )
33+ . then ( ( rows ) => rows [ 0 ] ?? null ) ,
34+
35+ getUsersWithPermissions ( workspaceId ) ,
36+
2537 db
2638 . select ( {
2739 id : workflow . id ,
@@ -51,15 +63,7 @@ export async function generateWorkspaceContext(
5163 . from ( userTableDefinitions )
5264 . where ( eq ( userTableDefinitions . workspaceId , workspaceId ) ) ,
5365
54- db
55- . select ( {
56- id : workspaceFiles . id ,
57- originalName : workspaceFiles . originalName ,
58- contentType : workspaceFiles . contentType ,
59- size : workspaceFiles . size ,
60- } )
61- . from ( workspaceFiles )
62- . where ( eq ( workspaceFiles . workspaceId , workspaceId ) ) ,
66+ listWorkspaceFiles ( workspaceId ) ,
6367
6468 db
6569 . select ( {
@@ -72,6 +76,22 @@ export async function generateWorkspaceContext(
7276
7377 const sections : string [ ] = [ ]
7478
79+ // Workspace identity
80+ if ( wsRow ) {
81+ sections . push (
82+ `## Workspace\n- **Name**: ${ wsRow . name } \n- **ID**: ${ wsRow . id } \n- **Owner**: ${ wsRow . ownerId } `
83+ )
84+ }
85+
86+ // Members & permissions
87+ if ( members . length > 0 ) {
88+ const lines = members . map ( ( m ) => {
89+ const display = m . name ? `${ m . name } (${ m . email } )` : m . email
90+ return `- ${ display } — ${ m . permissionType } `
91+ } )
92+ sections . push ( `## Members\n${ lines . join ( '\n' ) } ` )
93+ }
94+
7595 // Workflows
7696 if ( workflows . length > 0 ) {
7797 const lines = workflows . map ( ( wf ) => {
@@ -83,9 +103,9 @@ export async function generateWorkspaceContext(
83103 if ( flags . length > 0 ) parts [ 0 ] += ` — ${ flags . join ( ', ' ) } `
84104 return parts . join ( '\n' )
85105 } )
86- sections . push ( `## Workflows\n${ lines . join ( '\n' ) } ` )
106+ sections . push ( `## Workflows ( ${ workflows . length } ) \n${ lines . join ( '\n' ) } ` )
87107 } else {
88- sections . push ( '## Workflows\n(none)' )
108+ sections . push ( '## Workflows (0) \n(none)' )
89109 }
90110
91111 // Knowledge Bases
@@ -95,9 +115,9 @@ export async function generateWorkspaceContext(
95115 if ( kb . description ) line += ` — ${ kb . description } `
96116 return line
97117 } )
98- sections . push ( `## Knowledge Bases\n${ lines . join ( '\n' ) } ` )
118+ sections . push ( `## Knowledge Bases ( ${ kbs . length } ) \n${ lines . join ( '\n' ) } ` )
99119 } else {
100- sections . push ( '## Knowledge Bases\n(none)' )
120+ sections . push ( '## Knowledge Bases (0) \n(none)' )
101121 }
102122
103123 // Tables (live row counts)
@@ -116,19 +136,17 @@ export async function generateWorkspaceContext(
116136 if ( t . description ) line += `, ${ t . description } `
117137 return line
118138 } )
119- sections . push ( `## Tables\n${ lines . join ( '\n' ) } ` )
139+ sections . push ( `## Tables ( ${ tables . length } ) \n${ lines . join ( '\n' ) } ` )
120140 } else {
121- sections . push ( '## Tables\n(none)' )
141+ sections . push ( '## Tables (0) \n(none)' )
122142 }
123143
124144 // Files
125145 if ( files . length > 0 ) {
126- const lines = files . map (
127- ( f ) => `- **${ f . originalName } ** (${ f . contentType } , ${ formatSize ( f . size ) } )`
128- )
129- sections . push ( `## Files\n${ lines . join ( '\n' ) } ` )
146+ const lines = files . map ( ( f ) => `- **${ f . name } ** (${ f . type } , ${ formatSize ( f . size ) } )` )
147+ sections . push ( `## Files (${ files . length } )\n${ lines . join ( '\n' ) } ` )
130148 } else {
131- sections . push ( '## Files\n(none)' )
149+ sections . push ( '## Files (0) \n(none)' )
132150 }
133151
134152 // Credentials
@@ -145,7 +163,7 @@ export async function generateWorkspaceContext(
145163 workspaceId,
146164 error : err instanceof Error ? err . message : String ( err ) ,
147165 } )
148- return '## Workflows\n(unavailable)\n\n## Knowledge Bases\n(unavailable)\n\n## Tables\n(unavailable)\n\n## Files\n(unavailable)\n\n## Credentials\n(unavailable)'
166+ return '## Workspace\n(unavailable)\n\n## Workflows\n(unavailable)\n\n## Knowledge Bases\n(unavailable)\n\n## Tables\n(unavailable)\n\n## Files\n(unavailable)\n\n## Credentials\n(unavailable)'
149167 }
150168}
151169
0 commit comments