Skip to content

fix: resolve agents by pid or name#2666

Closed
nikhil8182 wants to merge 1 commit into
Tracer-Cloud:mainfrom
nikhil8182:fix/agents-pid-name-resolution
Closed

fix: resolve agents by pid or name#2666
nikhil8182 wants to merge 1 commit into
Tracer-Cloud:mainfrom
nikhil8182:fix/agents-pid-name-resolution

Conversation

@nikhil8182
Copy link
Copy Markdown

Summary

  • add shared /agents target resolution for PID or registered agent name
  • update /agents kill and /agents trace to accept <pid|name>
  • reject ambiguous names with a clear list of candidate PIDs
  • update slash-completion copy and tests for name-based trace/kill flows

Test

  • uv run ruff check --fix app/cli/interactive_shell/command_registry/agents.py tests/cli/interactive_shell/test_agents_commands.py
  • uv run ruff format app/cli/interactive_shell/command_registry/agents.py tests/cli/interactive_shell/test_agents_commands.py
  • uv run pytest tests/cli/interactive_shell/test_agents_commands.py -q

Closes #1749

@github-actions
Copy link
Copy Markdown
Contributor

Greptile code review

This repo uses Greptile for automated review. Before merge, aim for Confidence Score: 5/5 with zero unresolved review threads — see CONTRIBUTING.md.

Run a review — add a PR comment with:

@greptile review

Give it ~5-10 minutes (sometimes longer) for results, then fix feedback and re-trigger until you reach Confidence Score: 5/5.

Optional: automate with the greploop skill.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 30, 2026

Greptile Summary

This PR adds name-based target resolution for /agents kill and /agents trace, letting users specify either a PID or a registered agent name. A new _resolve_agent_arg helper centralises the lookup logic, disambiguates ambiguous names with a clear error, and preserves existing PID-passthrough behaviour for numeric inputs.

  • _resolve_agent_arg is introduced to resolve a string argument against the AgentRegistry — numeric strings go through the PID path, non-numeric strings are matched against record.name, and ambiguous results (multiple agents sharing a name) raise a descriptive ValueError.
  • /agents kill and /agents trace are updated to call the new helper, removing duplicated int-parse logic and carrying the resolved (pid, record) pair through to terminal output and registry cleanup.
  • New tests cover name-based trace/kill, ambiguous-name rejection, and updated usage strings, but two test_unknown_name_rejected tests omit registry isolation and read from the real ~/.opensre/agents.jsonl.

Confidence Score: 3/5

The production code changes are straightforward and localized; the test suite has a reliability gap that could mask regressions on developer machines.

The _resolve_agent_arg logic is correct for typical inputs and the kill/trace wiring looks right. The concern is in the tests: two test_unknown_name_rejected cases skip registry isolation and call into the real ~/.opensre/agents.jsonl. If that file has entries named "abc" or "missing-agent", the error-path assertion fails silently — not a production break, but the safety net disappears on any machine with a populated registry.

Both test cases named test_unknown_name_rejected (in TestAgentsTrace and TestAgentsKill) need _isolate_registry added before they can be considered reliable.

Important Files Changed

Filename Overview
app/cli/interactive_shell/command_registry/agents.py Adds _resolve_agent_arg helper that dispatches on PID (numeric) or registered name; wires it into /agents kill and /agents trace. Logic is sound for the common case but positive-integer agent names are silently treated as PIDs and can never be resolved by name.
tests/cli/interactive_shell/test_agents_commands.py New tests cover name-based resolution, ambiguous-name rejection, and kill-by-name flows. Two test_unknown_name_rejected tests (trace + kill) omit _isolate_registry, making them read from the real ~/.opensre/agents.jsonl and potentially flaky in developer environments.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["User input: /agents kill|trace <arg>"] --> B["_resolve_agent_arg(arg, registry)"]
    B --> C{"int(arg) succeeds?"}
    C -- "Yes, pid > 0" --> D["return pid, registry.get(pid)"]
    C -- "Yes, pid <= 0" --> E["name scan: registry.list()"]
    C -- "No (ValueError)" --> E
    E --> F{"matches count"}
    F -- "== 1" --> G["return record.pid, record"]
    F -- "> 1" --> H["raise ValueError: ambiguous name"]
    F -- "== 0 AND pid is not None" --> I["return pid, None\n(negative/zero PID passthrough)"]
    F -- "== 0 AND pid is None" --> J["raise ValueError: unknown name"]
    D --> K["downstream: terminate / attach"]
    G --> K
    I --> K
    K --> L{"pid == os.getpid()?"}
    L -- "Yes" --> M["Error: refusing to kill self"]
    L -- "No" --> N["Execute operation"]
Loading

Reviews (1): Last reviewed commit: "fix: resolve agents by pid or name" | Re-trigger Greptile

Comment on lines +509 to 515
def test_unknown_name_rejected(self) -> None:
sess_obj = ReplSession()
console, buf = _capture()
assert dispatch_slash("/agents trace abc", sess_obj, console) is True
out = buf.getvalue().lower()
assert "invalid pid" in out
assert "invalid pid or unknown agent name" in out
assert sess_obj.history[-1]["ok"] is False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Missing registry isolation in test_unknown_name_rejected

Both TestAgentsTrace.test_unknown_name_rejected (line 509) and TestAgentsKill.test_unknown_name_rejected (line 699) call AgentRegistry() through the un-patched default constructor, which reads from ~/.opensre/agents.jsonl. If the developer's real registry contains an agent named "abc" or "missing-agent", _resolve_agent_arg will resolve it to a live PID instead of raising ValueError, the error message check ("invalid pid or unknown agent name") will fail, and the test turns into a false positive. Every other new test that exercises the name-resolution path calls _isolate_registry(monkeypatch, tmp_path / "agents.jsonl") before registering records — these two error-path tests should do the same.

Comment on lines +146 to +161
if pid is not None and pid > 0:
return pid, registry.get(pid)

matches = [record for record in registry.list() if record.name == text]
if len(matches) == 1:
record = matches[0]
return record.pid, record
if len(matches) > 1:
pids = ", ".join(str(record.pid) for record in sorted(matches, key=lambda r: r.pid))
raise ValueError(
f"ambiguous agent name {text!r}: {len(matches)} registered agents (pids: {pids})"
)

if pid is not None:
return pid, None
raise ValueError(f"invalid pid or unknown agent name: {text}")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Agents with purely-numeric names are silently unreachable by name

When text is a positive integer string (e.g. "1234"), the function returns on line 147 without ever checking the name index, so an agent registered as name="1234" can never be targeted by name — the argument is always treated as a raw PID. Conversely, an agent named "0" or "-5" can be targeted by name because those fall through to the registry.list() scan. This is noted in the docstring, but the asymmetry may surprise users who name their agents with numeric strings and receive no error — they just silently hit whichever process owns that PID.

@cerencamkiran
Copy link
Copy Markdown
Collaborator

Closing for now. Please wait to get assigned before opening a pr, and avoid opening multiple prs at the same time as a first-time contributor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[IMPROVEMENT] Unify /agents <subcommand> <pid|name> resolution

2 participants