fix: trim OpenClaw task prompt context

This commit is contained in:
Haitao Pan 2026-06-06 17:40:43 +08:00
parent 195827c67d
commit dd57b0320f
3 changed files with 31 additions and 66 deletions

View File

@ -865,24 +865,21 @@ extension AppControllerDesktopThreadActions on AppController {
final requestText = userPrompt.trim().isEmpty
? 'See attached.'
: userPrompt.trim();
final buffer = StringBuffer()
..writeln('TaskThread workspace context:')
..writeln('- sessionKey: $sessionKey')
..writeln('- localWorkspace: ${workingDirectory.trim()}');
final remoteHint = remoteWorkingDirectoryHint.trim();
final executionWorkspace =
executionWorkingDirectory?.trim().isNotEmpty == true
? executionWorkingDirectory!.trim()
: (remoteHint.isNotEmpty ? remoteHint : workingDirectory.trim());
if (remoteHint.isNotEmpty) {
buffer.writeln('- remoteWorkspaceHint: $remoteHint');
}
final resolvedWorkspace = executionWorkspace.isNotEmpty
: (remoteWorkingDirectoryHint.trim().isNotEmpty
? remoteWorkingDirectoryHint.trim()
: workingDirectory.trim());
final currentTaskWorkspace = executionWorkspace.isNotEmpty
? executionWorkspace
: target.isGateway
? r'$XWORKMATE_ARTIFACT_DIRECTORY'
: workingDirectory.trim();
buffer.writeln('- currentTaskWorkspace: $resolvedWorkspace');
: (target.isGateway
? r'$XWORKMATE_ARTIFACT_DIRECTORY'
: workingDirectory.trim());
final buffer = StringBuffer()
..writeln('TaskThread workspace context:')
..writeln('- sessionKey: $sessionKey')
..writeln('- currentTaskWorkspace: $currentTaskWorkspace');
final visibleTaskInputAttachments = taskInputAttachments
.where((item) => item.name.trim().isNotEmpty && item.key.isNotEmpty)
.toList(growable: false);
@ -894,48 +891,6 @@ extension AppControllerDesktopThreadActions on AppController {
);
}
}
buffer
..writeln()
..writeln('Workspace isolation rules:')
..writeln(
'1. Treat currentTaskWorkspace as the only writable workspace for this TaskThread execution.',
)
..writeln(
'2. Create, modify, and export task files inside currentTaskWorkspace or its task artifact scope.',
)
..writeln(
'3. Do not use arbitrary global directories, OpenClaw media cache, Downloads, Desktop, or /tmp as final deliverable locations.',
)
..writeln(
'4. If a tool creates output outside currentTaskWorkspace, copy or export the final deliverables into currentTaskWorkspace before claiming completion.',
)
..writeln(
'5. When reporting files, prefer paths inside currentTaskWorkspace or paths relative to currentTaskWorkspace.',
)
..writeln(
'6. The app syncs final artifacts from currentTaskWorkspace back into localWorkspace.',
)
..writeln(
'7. Files listed in taskInputAttachments already belong to this TaskThread; reuse them from the task context and do not ask the user to upload them again.',
)
..writeln();
if (target.isGateway) {
buffer
..writeln('XWorkmate task artifact contract:')
..writeln(
'- The remote runtime owns final-deliverable detection; do not rely on local task classification.',
)
..writeln(
'- If this request needs files, export the final deliverables through the current XWorkmate task artifact scope before final response.',
)
..writeln(
'- A textual download/path claim is not a deliverable unless the file has been exported into the current task artifact scope.',
)
..writeln(
'- Do not reuse artifacts from previous sessions, previous runs, or global OpenClaw workspaces.',
)
..writeln();
}
buffer
..writeln('User request:')
..write(requestText);

View File

@ -1451,7 +1451,6 @@ void main() {
'contains=XWorkmate Task Artifact\n'
'contains=Required extensions: pdf\n'
'contains=TaskThread workspace context:\n'
'contains=Workspace isolation rules:\n'
'```\n',
);
@ -1459,8 +1458,7 @@ void main() {
'%PDF-1.3\n'
'BT /F1 14 Tf (XWorkmate Task Artifact) Tj '
'(Required extensions: pdf) Tj '
'(TaskThread workspace context:) Tj '
'(Workspace isolation rules:) Tj ET',
'(TaskThread workspace context:) Tj ET',
);
final result = GoTaskServiceResult(
success: true,

View File

@ -1328,8 +1328,15 @@ void main() {
expect(request.resumeSession, isFalse);
expect(request.prompt, contains('TaskThread workspace context:'));
expect(request.prompt, contains('- sessionKey: unit-fixture-task-a'));
expect(request.prompt, contains(request.workingDirectory));
expect(request.prompt, contains(request.remoteWorkingDirectoryHint));
expect(
request.prompt,
contains('- currentTaskWorkspace: ${request.workingDirectory}'),
);
expect(request.prompt, isNot(contains('Workspace isolation rules:')));
expect(
request.prompt,
isNot(contains('XWorkmate task artifact contract:')),
);
expect(request.prompt, contains('User request:\nfirst turn'));
expect(
controller.chatMessages.map((message) => message.text),
@ -1439,13 +1446,10 @@ void main() {
artifactContract['currentTaskWorkspace'],
request.workingDirectory,
);
expect(request.prompt, isNot(contains('Required final artifact')));
expect(request.prompt, contains('XWorkmate task artifact contract:'));
expect(request.prompt, isNot(contains('Workspace isolation rules:')));
expect(
request.prompt,
contains(
'export the final deliverables through the current XWorkmate task artifact scope',
),
isNot(contains('XWorkmate task artifact contract:')),
);
expect(request.prompt, contains('最后 输出 PDF文件'));
},
@ -3122,6 +3126,14 @@ void main() {
queuedRequest.prompt,
contains('- sessionKey: queue-task-waiting'),
);
expect(
queuedRequest.prompt,
contains('- currentTaskWorkspace: ${queuedRequest.workingDirectory}'),
);
expect(
queuedRequest.prompt,
isNot(contains('Workspace isolation rules:')),
);
expect(queuedRequest.prompt, contains('User request:\nqueued prompt'));
expect(queuedRequest.resumeSession, isFalse);
expect(queuedRequest.inlineAttachments, hasLength(1));