Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions agent_core/core/impl/action/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@

nest_asyncio.apply()


def _to_pretty_json(value: Any) -> str:
"""Serialize a value to pretty-printed JSON for readable logs and event streams."""
try:
return json.dumps(value, indent=2, ensure_ascii=False, default=str)
except (TypeError, ValueError):
return str(value)


# Type aliases for hooks
OnActionStartHook = Callable[[str, Any, Dict, str, str], Any] # (run_id, action, inputs, parent_id, started_at) -> awaitable
OnActionEndHook = Callable[[str, Any, Dict, str, str, str], Any] # (run_id, action, outputs, status, parent_id, ended_at) -> awaitable
Expand Down Expand Up @@ -205,10 +214,11 @@ async def execute_action(
# Log to event stream
# Only pass session_id when is_running_task=True (task stream exists)
# When no task exists, use global stream by not passing task_id
pretty_input = _to_pretty_json(input_data)
self._log_event_stream(
is_gui_task=is_gui_task,
event_type="action_start",
event=f"Running action {action.name} with input: {input_data}.",
event=f"Running action {action.name} with input: {pretty_input}.",
display_message=f"Running {action.display_name}",
action_name=action.name,
session_id=session_id if is_running_task else None,
Expand Down Expand Up @@ -293,10 +303,11 @@ async def execute_action(
# Only pass session_id when is_running_task=True (task stream exists)
output_has_error = outputs and outputs.get("status") == "error"
display_status = "failed" if (status == "error" or output_has_error) else "completed"
pretty_output = _to_pretty_json(outputs)
self._log_event_stream(
is_gui_task=is_gui_task,
event_type="action_end",
event=f"Action {action.name} completed with output: {outputs}.",
event=f"Action {action.name} completed with output: {pretty_output}.",
display_message=f"{action.display_name} → {display_status}",
action_name=action.name,
session_id=session_id if is_running_task else None,
Expand Down
4 changes: 2 additions & 2 deletions agent_core/core/prompts/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,8 @@
* Default reads first 2000 lines - check has_more to know if more exists
* Use offset to skip to specific line numbers
* Use limit to control how many lines to read
- To find specific content in large files:
1. Use grep_files with keywords to locate relevant sections
- To find specific content in files:
1. Use grep_files with a regex pattern to locate relevant sections (use output_mode='content' for lines with line numbers, or 'files_with_matches' to discover files first)
2. Note the line numbers from grep results
3. Use read_file with appropriate offset to read that section
- DO NOT repeatedly read entire large files - use targeted reading with offset/limit
Expand Down
2 changes: 1 addition & 1 deletion agent_file_system/AGENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Efficient File Reading:

File Actions:
- read_file: General reading with pagination (offset/limit)
- grep_files: Search for keywords, returns matching chunks with line numbers
- grep_files: Search files/directories for regex patterns with three output modes: 'files_with_matches' (discover files), 'content' (matching lines with line numbers), 'count' (match counts). Supports glob/file_type filtering, before/after context lines, case_insensitive, and multiline.
- stream_read + stream_edit: Use together for file modifications

Avoid: Reading entire large files repeatedly - use grep + targeted offset/limit reads instead
Expand Down
Loading