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
6 changes: 6 additions & 0 deletions .planning/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ The plan aligns to:
72. [Phase 78 - Conversation Runtime Prompt Recall And Bounded Capture Adoption](https://github.com/mikehostetler/jido_code/blob/main/.planning/phase-78-conversation-runtime-prompt-recall-and-bounded-capture-adoption.md): wire prompt-context retrieval and explicit bounded capture into the real conversation runtime so each turn can reuse the right short-term memory without replaying raw transcript history.
73. [Phase 79 - Prompt Memory Lifecycle Hardening And Contributor Convergence](https://github.com/mikehostetler/jido_code/blob/main/.planning/phase-79-prompt-memory-lifecycle-hardening-and-contributor-convergence.md): harden provider behavior, retention and cleanup policy, verification defaults, and contributor guidance so prompt memory remains bounded, explainable, and clearly separate from provenance and durable repository memory.
74. [Phase 80 - Source Code Graph Save-Triggered Refresh Adoption](https://github.com/mikehostetler/jido_code/blob/main/.planning/phase-80-source-code-graph-save-triggered-refresh-adoption.md): add repository-scoped source-change observation and debounced refresh scheduling so the `source_code` graph updates after code saves from either a human editor or product-managed LLM write path.
75. [Phase 81 - CodingPod Refactorer API Exposure](https://github.com/mikehostetler/jido_code/blob/main/.planning/phase-81-coding-pod-refactorer-api-exposure.md): expose the existing lazy `Refactorer` specialist through a first-class `AgentWorkspace.refactor_work/3,4` API while preserving CodingPod isolation, task-board visibility, workflow provenance, and deterministic product-owned specialist routing.

Chronology note: Phase 55 now owns the previously landed `55.6.*` memory
ontology and governed-reference verification so the planning sequence once
Expand Down Expand Up @@ -164,6 +165,11 @@ top of the existing explicit analyze, load, refresh, status, query, and recovery
lifecycle. Repo-scoped monitoring owns source-change observation while
`AgentWorkspace` and `SourceCodeGraphPod` continue to own graph mutation.

CodingPod refactorer exposure note: Phase 81 closes the remaining gap between
the `CodingPod` topology and the public workspace API by specifying a
first-class `refactor_work/3,4` route to the existing lazy `Refactorer`
specialist.

## Shared Conventions
- Numbering:
- Phases: `N`
Expand Down
78 changes: 78 additions & 0 deletions .planning/phase-81-coding-pod-refactorer-api-exposure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Phase 81 - CodingPod Refactorer API Exposure

<!-- covers: architecture.agent_os_integration.coding_agents -->
<!-- covers: architecture.agent_os_integration.eager_and_lazy_agent_activation -->
<!-- covers: architecture.agent_os_integration.pod_contains_multiple_agents -->

Back to index: [README](https://github.com/mikehostetler/jido_code/blob/main/.planning/README.md)

## Relevant Shared APIs / Interfaces
- `lib/jido_code/agent_workspace.ex`
- `lib/jido_code/pods/coding_pod.ex`
- `lib/jido_code/agents/refactorer.ex`
- `lib/jido_code/agent_workspace/specialist_runner.ex`
- `lib/jido_code/agent_workspace/runtime_specialist_runner.ex`
- `lib/jido_code/agent_workspace/deterministic_specialist_runner.ex`
- `docs/developer/04-coding-pod-and-specialist-workflows.md`
- `docs/developer/05-specialist-prompts-context-and-tool-execution.md`

## Relevant Assumptions / Defaults
- `Refactorer` is already part of the `CodingPod` topology as a lazy specialist.
- `AgentWorkspace` is the product-owned boundary for specialist routing; callers should not address pod internals directly.
- Refactoring work must preserve behavior and should follow the same bounded context, workflow provenance, task-board artifact, and pod metadata patterns as plan, execute, review, and explain.
- Refactorer exposure should not change `full_workflow/3,4` by default. Full workflow remains plan -> execute -> review unless a later phase explicitly adopts a refactor stage.

[x] 81 Phase 81 - CodingPod Refactorer API Exposure
Expose the existing `CodingPod` refactorer specialist through a first-class product API so behavior-preserving refactoring can use the same runtime, provenance, and context boundaries as other specialist work.

[x] 81.1 Section - Workspace Refactor Entry Point
Add the missing product-owned API surface for invoking the lazy refactorer specialist without leaking pod internals.

[x] 81.1.1 Task - Add `AgentWorkspace.refactor_work/3,4`
Route refactoring requests through the existing per-work-item `CodingPod` lifecycle and specialist runner pattern.

[x] 81.1.1.1 Subtask - Resolve workspace path, LLM selection, kernel, and coding pod exactly like `plan_work/4`, `execute_work/4`, `review_work/4`, and `explain_work/4`.
[x] 81.1.1.2 Subtask - Build refactor instructions through the shared `agent_instruction/4` path with semantic and memory context included when available.
[x] 81.1.1.3 Subtask - Ensure the `:refactorer` node lazily starts through `ensure_coding_specialist/3`.
[x] 81.1.1.4 Subtask - Return a bounded result map with refactoring output, original instruction, semantic context, memory context, workflow provenance summary, and LLM selection summary.

[x] 81.1.2 Task - Persist refactor-stage pod metadata and task-board state
Keep refactorer runs visible and recoverable using the same product-owned runtime bookkeeping as other CodingPod specialists.

[x] 81.1.2.1 Subtask - Persist a `:refactoring` stage result with `last_refactor` metadata on the coding pod.
[x] 81.1.2.2 Subtask - Ensure task-board stage events and artifacts are written by the shared specialist-run wrapper.
[x] 81.1.2.3 Subtask - Preserve workflow provenance capture for refactorer runs without exposing specialist-local internals to callers.

[x] 81.2 Section - Product Routing And Documentation
Make refactorer exposure understandable to contributors and safe for future conversation or workflow adoption.

[x] 81.2.1 Task - Update developer guidance for refactorer API exposure
Align the CodingPod and prompt-context guides with the new refactorer entrypoint.

[x] 81.2.1.1 Subtask - Update the CodingPod guide so `refactor_work/3,4` is listed with plan, execute, review, and explain.
[x] 81.2.1.2 Subtask - Update the prompt-context guide so refactorer runs are included in the workspace-prepared specialist request list.
[x] 81.2.1.3 Subtask - Document that `full_workflow/3,4` remains plan -> execute -> review unless explicitly changed later.

[x] 81.2.2 Task - Keep specialist selection deterministic
Preserve product-owned dispatch when refactorer work is later adopted by conversations or workflows.

[x] 81.2.2.1 Subtask - Keep callers on `AgentWorkspace.refactor_work/3,4` rather than direct pod or agent calls.
[x] 81.2.2.2 Subtask - Ensure any future conversation routing maps explicit refactor intent to the refactorer deterministically.
[x] 81.2.2.3 Subtask - Keep refactorer unavailable or degraded states typed and product-facing.

[x] 81.3 Section - Verification
Prove the refactorer is exposed through the same bounded runtime contract as the other CodingPod specialists.

[x] 81.3.1 Task - Add focused workspace coverage
Verify `refactor_work/3,4` starts the refactorer lazily and records bounded runtime state.

[x] 81.3.1.1 Subtask - Add coverage proving `AgentWorkspace.refactor_work/4` ensures kernel, coding pod, and `:refactorer` node before running.
[x] 81.3.1.2 Subtask - Add coverage proving returned refactor results include instruction, semantic context, memory context, workflow provenance, and LLM selection summary.
[x] 81.3.1.3 Subtask - Add coverage proving pod metadata records `last_refactor` without disturbing existing `last_plan`, `last_changes`, `last_review`, or `last_explanation` metadata.

[x] 81.3.2 Task - Add integration coverage
Verify refactorer exposure fits the existing CodingPod isolation and lifecycle model.

[x] 81.3.2.1 Subtask - Add an integration test proving different work items invoke isolated refactorer specialists in separate CodingPods.
[x] 81.3.2.2 Subtask - Add coverage proving completed work-item pod teardown ends refactorer context along with other specialist context.
[x] 81.3.2.3 Subtask - Run the relevant CodingPod, AgentWorkspace, and conversation-runtime suites after implementation.
27 changes: 20 additions & 7 deletions docs/developer/04-coding-pod-and-specialist-workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ It wraps each run with:
- success or failure events
- workflow provenance capture
- pod metadata persistence such as `last_plan`, `last_changes`,
`last_review`, and `last_explanation`
`last_review`, `last_refactor`, and `last_explanation`

## Important Nuance: Specialist Context Is Per Specialist

Expand Down Expand Up @@ -131,12 +131,26 @@ forward the planner's output as a new prompt into the coder and reviewer.
Instead, each stage gets the requested instruction and the current repo state,
plus any explicit semantic or memory context passed in through options.

## Refactorer Nuance
## Refactorer API

The pod topology includes a `refactorer`, but the main public workspace API
does not currently expose a dedicated `refactor_work/...` entrypoint. The node
exists in the pod contract even though it is not surfaced like plan, execute,
review, and explain.
The pod topology includes a lazy `refactorer`, exposed through
`AgentWorkspace.refactor_work/3,4`.

Use the workspace entrypoint rather than direct pod or specialist calls. It:

- routes through the existing per-work-item `CodingPod`
- lazily ensures the `refactorer` node
- preserves the shared specialist wrapper for task-board state, artifacts,
workflow provenance, semantic context, memory context, and pod metadata

`full_workflow/3,4` still remains plan -> code -> review. Refactoring is an
explicit stage until a later phase changes default workflow orchestration.

Conversation routing does not currently infer a dedicated refactor workflow.
If conversation or workflow surfaces adopt refactorer dispatch later, they
should map explicit refactor intent to `AgentWorkspace.refactor_work/3,4` and
return typed product-facing unavailable or degraded states when the refactorer
cannot run.

## Pod Teardown

Expand All @@ -152,4 +166,3 @@ So the work-item boundary is also the practical lifetime boundary.

Continue with
[`05-specialist-prompts-context-and-tool-execution.md`](https://github.com/mikehostetler/jido_code/blob/main/docs/developer/05-specialist-prompts-context-and-tool-execution.md).

Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This distinction is the most important thing to keep straight.

```mermaid
flowchart TD
A["AgentWorkspace.plan/execute/review/explain"]
A["AgentWorkspace.plan/execute/review/refactor/explain"]
B["Build semantic context and memory context"]
C["Build user instruction text"]
D["Build tool_context map"]
Expand All @@ -50,8 +50,8 @@ flowchart TD

## What The Workspace Adds Before Calling The Specialist

For `plan_work`, `execute_work`, `review_work`, and `explain_work`,
`AgentWorkspace` prepares three important inputs:
For `plan_work`, `execute_work`, `review_work`, `refactor_work`, and
`explain_work`, `AgentWorkspace` prepares three important inputs:

1. a user instruction string
2. a `tool_context` map
Expand Down Expand Up @@ -242,6 +242,10 @@ The workspace does not automatically feed the planner's result text into the
coder and reviewer as a new explicit prompt. The stages are orchestrated
sequentially, but prompt chaining is not the main contract.

`full_workflow/3,4` remains plan -> code -> review. `refactor_work/3,4` is an
explicit workspace entrypoint, not a default stage in full workflow
orchestration.

### Relatedness Is Not Semantic Today

If you send two unrelated prompts to the same specialist on the same work item,
Expand Down
5 changes: 5 additions & 0 deletions docs/developer/12-user-request-to-llm-message-path.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ That value is still visible as the request later in
For words like `fix`, `change`, `edit`, or `patch`, it usually infers
`:execute`.

The `refactorer` specialist is exposed through `AgentWorkspace.refactor_work/3,4`,
but conversation workflow inference does not currently choose a dedicated
`:refactor` workflow. Conversation adoption should be explicit if it is added
later.

This matters because it decides:

- whether the turn needs governed work attachment
Expand Down
89 changes: 87 additions & 2 deletions lib/jido_code/agent_workspace.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ defmodule JidoCode.AgentWorkspace do

## Work Execution

Functions for planning, executing, and reviewing work through agents.
Functions for planning, executing, refactoring, reviewing, and explaining
work through agents.
"""

alias JidoCode.AgentOS.Manager
alias JidoCode.Agents.{Coder, Explainer, Planner, RepoMonitor, Reviewer}
alias JidoCode.Agents.{Coder, Explainer, Planner, Refactorer, RepoMonitor, Reviewer}
alias JidoCode.Control.Actor
alias JidoCode.Conversations
alias JidoCode.Conversations.Driver, as: ConversationDriver
Expand Down Expand Up @@ -565,6 +566,70 @@ defmodule JidoCode.AgentWorkspace do
end
end

@doc """
Refactors work by routing to the refactorer agent.

Sends a behavior-preserving refactor request to the refactorer agent within
the WorkItem's CodingPod and returns the result.

## Examples

iex> AgentWorkspace.refactor_work("repo-123", "work-item-1", "Extract shared login validation")
{:ok, %{refactoring: "..."}}

"""
@spec refactor_work(managed_repo_id(), work_item_id(), String.t()) :: {:ok, map()} | {:error, term()}
def refactor_work(managed_repo_id, work_item_id, instruction) do
refactor_work(managed_repo_id, work_item_id, instruction, [])
end

@spec refactor_work(managed_repo_id(), work_item_id(), String.t(), keyword()) ::
{:ok, map()} | {:error, term()}
def refactor_work(managed_repo_id, work_item_id, instruction, opts) when is_list(opts) do
with {:ok, workspace_path} <-
resolve_workspace_path(managed_repo_id, work_item_id, Keyword.get(opts, :workspace_path)),
{:ok, opts} <- put_llm_selection(managed_repo_id, opts),
{:ok, _kernel_name} <- ensure_kernel(managed_repo_id),
{:ok, _} <- ensure_coding_pod(managed_repo_id, work_item_id, workspace_path),
{:ok, provenance_context} <-
workflow_provenance_context(
managed_repo_id,
work_item_id,
workspace_path,
:refactor,
instruction,
opts
),
{:ok, semantic_context} <- workflow_semantic_context(managed_repo_id, :refactor, opts),
{:ok, memory_context} <- workflow_memory_context(:refactor, opts),
{:ok, refactorer_pid} <- ensure_coding_specialist(managed_repo_id, work_item_id, :refactorer),
{:ok, response} <-
run_specialist(
Refactorer,
refactorer_pid,
agent_instruction(:refactor, instruction, semantic_context, memory_context),
managed_repo_id,
work_item_id,
workspace_path,
semantic_context,
memory_context,
provenance_context,
Keyword.put(opts, :work_item_id, work_item_id)
) do
result = %{
refactoring: normalize_specialist_result(response),
instruction: instruction,
semantic_context: semantic_context,
memory_context: memory_context,
workflow_provenance: provenance_summary(provenance_context),
llm_selection: llm_selection_summary(opts)
}

persist_coding_pod_result(managed_repo_id, work_item_id, :refactoring, %{last_refactor: result})
{:ok, result}
end
end

@doc """
Explains work with an optional explicit semantic source-graph context.
"""
Expand Down Expand Up @@ -1566,6 +1631,7 @@ defmodule JidoCode.AgentWorkspace do
defp specialist_stage(Planner), do: :planning
defp specialist_stage(Coder), do: :coding
defp specialist_stage(Reviewer), do: :reviewing
defp specialist_stage(Refactorer), do: :refactoring
defp specialist_stage(Explainer), do: :explaining
defp specialist_stage(_other), do: :working

Expand Down Expand Up @@ -1741,6 +1807,7 @@ defmodule JidoCode.AgentWorkspace do
defp task_board_artifact_type(:planning), do: "plan"
defp task_board_artifact_type(:coding), do: "draft"
defp task_board_artifact_type(:reviewing), do: "review"
defp task_board_artifact_type(:refactoring), do: "refactor"
defp task_board_artifact_type(:explaining), do: "explanation"
defp task_board_artifact_type(_other), do: "artifact"

Expand Down Expand Up @@ -2190,6 +2257,24 @@ defmodule JidoCode.AgentWorkspace do
)
end

defp specialist_artifact_capture(:refactoring, provenance_context, agent_run_id, content, started_at, ended_at) do
CaptureEnvelope.patch(
session_id: provenance_context.session_id,
actor_id: provenance_context.actor_id,
workflow: provenance_context.workflow,
work_item_id: provenance_context.work_item_id,
agent_run_id: agent_run_id,
content: stringify_artifact_content(content),
started_at: started_at,
ended_at: ended_at,
model: provenance_model_name(provenance_context),
revision: provenance_context.revision,
governed_references: provenance_context.governed_references,
related_resources: provenance_context.related_resources,
metadata: provenance_metadata(provenance_context)
)
end

defp specialist_artifact_capture(:reviewing, provenance_context, agent_run_id, content, started_at, ended_at) do
CaptureEnvelope.review(
session_id: provenance_context.session_id,
Expand Down
Loading
Loading