diff --git a/lib/app/app_controller_desktop_thread_actions.dart b/lib/app/app_controller_desktop_thread_actions.dart index 22af0be9..578546e3 100644 --- a/lib/app/app_controller_desktop_thread_actions.dart +++ b/lib/app/app_controller_desktop_thread_actions.dart @@ -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); diff --git a/test/runtime/app_controller_thread_workspace_binding_test.dart b/test/runtime/app_controller_thread_workspace_binding_test.dart index 792d76ce..e180009b 100644 --- a/test/runtime/app_controller_thread_workspace_binding_test.dart +++ b/test/runtime/app_controller_thread_workspace_binding_test.dart @@ -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, diff --git a/test/runtime/assistant_execution_target_test.dart b/test/runtime/assistant_execution_target_test.dart index 7461223a..33dd3cb6 100644 --- a/test/runtime/assistant_execution_target_test.dart +++ b/test/runtime/assistant_execution_target_test.dart @@ -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));