You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mothership: model-facing strings name only what exists on the CLI surface
The copilot back-derives fixes from the strings sim hands it, so a retired name
becomes a wrong instruction to the user (dev 2026-09-03: a save_upload mention
became "drag the photo into the files panel"). Every model-facing string audited
today now names the current surface:
- upload notice: a chat upload lives at uploads/<name> and is not a workspace
file; workflows import takes --workflow (there is no --file); a .zip is mounted
and unzipped in the sandbox rather than a files unzip path that does not resolve
- table import resolves uploads/<name> directly (includeChatUploads) instead of
pointing at the retired save_upload tool
- function-execute / generate-image: outputs get, files ls, files restore and
tables list replace read/grep/glob/restore_resource and Go VFS meta.json paths
- process-contents: browser/terminal pointers no longer name browser_* or a
terminal tool this surface does not have; docs fallback names docs search
- lint/deps usage strings use the plural workflows group
- integration credential error names credentials list
'File "payroll.xlsx" (application/octet-stream, 1 bytes) uploaded to workspace files.',
398
+
'File "payroll.xlsx" (application/octet-stream, 1 bytes) uploaded to this chat as "uploads/payroll.xlsx" (a chat upload: readable here, not listed under workspace files/).',
399
399
'Read it with: sim --output json files read "uploads/payroll.xlsx"',
400
400
'Pass the same path "uploads/payroll.xlsx" as inputs.files[].path to mount it in run_code or use it as a reference image in generate_image.',
'File "photo.png" (image/png, 10 bytes) uploaded to workspace files.',
440
+
'File "photo.png" (image/png, 10 bytes) uploaded to this chat as "uploads/photo.png" (a chat upload: readable here, not listed under workspace files/).',
441
441
'Read it with: sim --output json files read "uploads/photo.png"',
442
442
'Pass the same path "uploads/photo.png" as inputs.files[].path to mount it in run_code or use it as a reference image in generate_image.',
Copy file name to clipboardExpand all lines: apps/sim/lib/mothership/chat/payload.ts
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -338,8 +338,8 @@ export async function buildCopilotRequestPayload(
338
338
userMessageId
339
339
)
340
340
// Encode the read path per the percent-encoded VFS convention (matches
341
-
// files/ and the uploads glob output). The save_upload `fileName`
342
-
// arg stays the raw display name — the upload resolver accepts both.
341
+
// files/ and `files ls uploads` output); the resolver also accepts the raw
342
+
// display name.
343
343
letencodedUploadName=displayName
344
344
try{
345
345
encodedUploadName=encodeVfsSegment(displayName)
@@ -356,13 +356,13 @@ export async function buildCopilotRequestPayload(
356
356
]
357
357
}else{
358
358
lines=[
359
-
`File "${displayName}" (${mediaType}, ${f.size} bytes) uploaded to workspace files.`,
359
+
`File "${displayName}" (${mediaType}, ${f.size} bytes) uploaded to this chat as "uploads/${encodedUploadName}" (a chat upload: readable here, not listed under workspace files/).`,
360
360
`Read it with: sim --output json files read "uploads/${encodedUploadName}"`,
361
361
`Pass the same path "uploads/${encodedUploadName}" as inputs.files[].path to mount it in run_code or use it as a reference image in generate_image.`,
362
362
]
363
363
if(displayName.endsWith('.json')){
364
364
lines.push(
365
-
`If it is a workflow export, import it with: sim --output json workflows import --file "uploads/${encodedUploadName}"`
365
+
`If it is a workflow export: read it with files read, then import the JSON with: sim --output json workflows import --workflow '<the JSON>'`
Copy file name to clipboardExpand all lines: apps/sim/lib/mothership/chat/process-contents.ts
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -208,10 +208,10 @@ export async function processContextsServer(
208
208
type: 'browser_tab',
209
209
tag: ctx.label ? `@${ctx.label}` : '@Browser',
210
210
content:
211
-
'The user tagged the Browser resource as a whole, not a specific tab. Inspect the live tabs with browser_list_tabs and choose the relevant one from their request. If no browser tab is open yet, open or navigate one as needed.',
211
+
'The user tagged the Browser resource as a whole, not a specific tab. You cannot read or drive browser tabs here: ask which page they mean, and work from a URL or pasted content.',
212
212
}
213
213
}
214
-
constpointer=`The user pointed at an open browser tab: "${ctx.label}" (tabId ${ctx.tabId}). Act on THIS tab — switch to it with browser_switch_tab and read it with browser_snapshot rather than assuming which tab they meant.`
214
+
constpointer=`The user pointed at an open browser tab: "${ctx.label}" (tabId ${ctx.tabId}). You cannot read or drive browser tabs here: work from the tab's title and any URL or content the user shares rather than assuming what it shows.`
215
215
return{
216
216
type: 'browser_tab',
217
217
tag: ctx.label ? `@${ctx.label}` : '@',
@@ -229,7 +229,7 @@ export async function processContextsServer(
229
229
'The user tagged the Terminal resource as a whole, not a specific shell. Inspect the live terminals with the terminal list operation and choose the relevant one from their request. If no terminal is open yet, create one as needed.',
230
230
}
231
231
}
232
-
constpointer=`The user pointed at an open terminal: "${ctx.label}" (terminalId ${ctx.terminalId}). Act on THIS terminal — pass that terminalId to the terminal tool, and read its screen before assuming what is in it.`
232
+
constpointer=`The user pointed at an open terminal: "${ctx.label}" (terminalId ${ctx.terminalId}). You cannot read or drive terminals here: ask the user to paste the relevant output rather than assuming what is in it.`
233
233
return{
234
234
type: 'terminal_tab',
235
235
tag: ctx.label ? `@${ctx.label}` : '@',
@@ -343,7 +343,7 @@ export async function processContextsServer(
343
343
tag: ctx.label ? `@${ctx.label}` : '@',
344
344
content: JSON.stringify({
345
345
results: [],
346
-
note: 'Documentation search is temporarily unavailable. Do not infer that the docs lack this topic; retry search_docs or browse docs/** later.',
346
+
note: 'Documentation search is temporarily unavailable. Do not infer that the docs lack this topic; retry `docs search` later.',
return'uploads/ holds chat uploads addressed as "uploads/<name>" with no folders beneath it. Copy the exact "uploads/<name>" path from the upload notice.'
199
199
}
200
200
if(path.startsWith('internal/tool-results/')){
201
-
return'tool-result artifacts are stored by the copilot backend, not in workspace storage, so read and grep reach them but the sandbox cannot. This path is correct — searching for a different one will not find anything. Either read or grep the artifact and inline the values you need in code, or re-run the tool that produced it with an output path under files/ (run_function: outputs.files[].path, user_table: outputPath) and mount that files/... path.'
201
+
return'tool-result artifacts are stored by the copilot backend, not in workspace storage, so `outputs get` reaches them but the sandbox cannot. This path is correct — searching for a different one will not find anything. Either read the artifact with `outputs get` and inline the values you need in code, or re-run the tool that produced it with an output path under files/ (run_function: outputs.files[].path, user_table: outputPath) and mount that files/... path.'
202
202
}
203
203
if(path.startsWith('internal/')){
204
-
return'internal/ paths are served by the copilot backend, not from workspace storage, so read and grep reach them but the sandbox cannot. This path is correct — read or grep it and inline the values you need in code instead of mounting it.'
204
+
return'internal/ paths are served by the copilot backend, not from workspace storage, so the sandbox cannot mount them. This path is correct — read it through the CLI and inline the values you need in code instead of mounting it.'
205
205
}
206
206
if(path.startsWith('recently-deleted/')){
207
-
return'deleted resources are not mountable into the sandbox. Use restore_resource to restore it first, then mount the restored files/... path.'
207
+
return'deleted resources are not mountable into the sandbox. Restore it first (`files restore <fileId>`), then mount the restored files/... path.'
208
208
}
209
209
if(path.startsWith('tables/')){
210
210
return'tables are not mounted as files. Pass the table in inputs.tables instead and it is mounted as CSV.'
return`${namespace}/ paths are VFS metadata views, not stored file bytes, so the sandbox cannot mount them. This path is correct — read or grep it and inline the values you need in code.`
214
+
return`${namespace}/ paths are VFS metadata views, not stored file bytes, so the sandbox cannot mount them. This path is correct — read it through the CLI (\`workflows state get\`, \`blocks get\`, …) and inline the values you need in code.`
215
215
}
216
216
returnnull
217
217
}
@@ -301,7 +301,7 @@ async function resolveMountableWorkspaceFile(
301
301
thrownewError(`Cannot mount "${filePath}": ${unmountable}`)
302
302
}
303
303
thrownewError(
304
-
`Input file not found: "${filePath}". Pass the exact canonical VFS path copied from glob/read (e.g. "files/Reports/data.csv").`
304
+
`Input file not found: "${filePath}". Pass the exact path as \`files ls\` / \`files list\` prints it (e.g. "files/Reports/data.csv").`
305
305
)
306
306
}
307
307
@@ -374,7 +374,7 @@ export async function resolveInputFiles(
374
374
thrownewError(
375
375
unmountable
376
376
? `Cannot mount "${dirPath}": ${unmountable}`
377
-
: `Input directory not found: "${dirPath}". Pass a canonical workspace folder path copied from glob/read (e.g. "files/Reports").`
377
+
: `Input directory not found: "${dirPath}". Pass a workspace folder path as \`files ls\` prints it (e.g. "files/Reports").`
378
378
)
379
379
}
380
380
constmountRoot=
@@ -447,7 +447,7 @@ export async function resolveInputFiles(
`Reference image "${filePath}" was not found. Pass the exact canonical VFS path copied from glob/read (e.g. "files/photo.png"), or the "uploads/<name>" path from the upload notice.`
80
+
`Reference image "${filePath}" was not found. Pass the exact path as \`files ls\` prints it (e.g. "files/photo.png"), or the "uploads/<name>" path from the upload notice.`
`Cannot import "${reference}": chat uploads are not workspace files. Use save_upload to save it to a files/... path first, then pass that canonical path.`
156
+
'not_found',
157
+
`Cannot import "${reference}": no chat upload by that name in this workspace. Use the exact uploads/<name> path from the upload notice.`
156
158
)
157
159
}
158
160
thrownewOrchestrationError(
159
161
'not_found',
160
-
`File not found: "${reference}". Use glob("files/**") and read the canonical file path metadata to find workspace files.`
162
+
`File not found: "${reference}". Use \`files ls\` or \`files list --search <name>\` to find the path.`
0 commit comments