MCPcopy Index your code
hub / github.com/simstudioai/sim / maybeWriteOutputToFile

Function maybeWriteOutputToFile

apps/sim/lib/copilot/request/tools/files.ts:201–345  ·  view source on GitHub ↗
(
  toolName: string,
  params: Record<string, unknown> | undefined,
  result: ToolCallResult,
  context: ExecutionContext
)

Source from the content-addressed store, hash-verified

199}
200
201export async function maybeWriteOutputToFile(
202 toolName: string,
203 params: Record<string, unknown> | undefined,
204 result: ToolCallResult,
205 context: ExecutionContext
206): Promise<ToolCallResult> {
207 if (!result.success || !result.output) return result
208 if (!OUTPUT_PATH_TOOLS.has(toolName)) return result
209 if (!context.workspaceId || !context.userId) return result
210
211 const outputFiles = getOutputFileDeclarations(params).filter((file) => !file.sandboxPath)
212 if (outputFiles.length === 0) return result
213
214 const outputObject =
215 result.output && typeof result.output === 'object' && !Array.isArray(result.output)
216 ? (result.output as Record<string, unknown>)
217 : undefined
218 const resultObject =
219 outputObject?.result &&
220 typeof outputObject.result === 'object' &&
221 !Array.isArray(outputObject.result)
222 ? (outputObject.result as Record<string, unknown>)
223 : undefined
224 if (Array.isArray(resultObject?.files)) {
225 logger.warn('Skipping returned-value output write because sandbox export response is active', {
226 toolName,
227 outputCount: outputFiles.length,
228 })
229 return result
230 }
231
232 const denied = denyOutputWriteWithoutWritePermission(context)
233 if (denied) return denied
234
235 // Only span the actual write path (where we upload to storage). Fast
236 // no-op returns above don't need a span — they'd just pad the trace
237 // with empty work.
238 return withCopilotSpan(
239 TraceSpan.CopilotToolsWriteOutputFile,
240 {
241 [TraceAttr.ToolName]: toolName,
242 [TraceAttr.WorkspaceId]: context.workspaceId,
243 },
244 async (span) => {
245 try {
246 const writtenFiles = []
247 for (const outputFile of outputFiles) {
248 const fileName = normalizeOutputWorkspaceFileName(
249 outputFile.formatPath ?? outputFile.path
250 )
251 const format = resolveOutputFormat(fileName, outputFile.format)
252 const content = serializeOutputForFile(result.output, format)
253 const contentType = outputFile.mimeType || FORMAT_TO_CONTENT_TYPE[format]
254 const buffer = Buffer.from(content, 'utf-8')
255
256 if (context.abortSignal?.aborted) {
257 throw new Error('Request aborted before tool mutation could be applied')
258 }

Callers 2

files.test.tsFile · 0.90

Calls 11

withCopilotSpanFunction · 0.90
writeWorkspaceFileByPathFunction · 0.90
toErrorFunction · 0.90
resolveOutputFormatFunction · 0.85
serializeOutputForFileFunction · 0.85
infoMethod · 0.80
warnMethod · 0.65
pushMethod · 0.45

Tested by

no test coverage detected