Docs

Daita agents / guide

Reviewed Learning

Turn completed runs into inactive learning candidates that a user can inspect, edit, accept, or reject.

#Candidate Review, Not Automatic Learning

Daita never silently turns a transcript into durable memory. Candidate review is a separate, bounded model request that proposes possible changes to memory, the user profile, semantics, or skills.

Proposals are stored as inactive candidates. They affect future runs only after explicit acceptance completes through the normal foreground agent loop and approval boundary.

#Review Recent Runs

Open the agent with a dedicated reviewer model and an explicit cost ceiling, then request a review:

python
from decimal import Decimal
from daita import Agent
 
agent = await Agent.open(
    "atlas",
    reviewer_model=reviewer_model,
    reviewer_profile=reviewer_profile,
    reviewer_max_estimated_cost_usd=Decimal("0.05"),
)
try:
    review = await agent.review_learning_candidates(
        max_estimated_cost_usd=Decimal("0.05"),
    )
    print(review.status, len(review.candidates))
finally:
    await agent.close()

The review path makes at most one tool-free model request and returns at most four proposals. It has independent token, time, and cost bounds. A missing reviewer configuration or required cost limit produces a review status rather than modifying knowledge.

The bundled terminal configures the reviewer route for you:

bash
daita memory review atlas --model openai:gpt-5.6-terra --cost-limit 0.05

#Inspect Candidates

python
from daita import LearningCandidateStatus
 
pending = await agent.list_learning_candidates(
    status=LearningCandidateStatus.AWAITING_REVIEW,
)
 
candidate = await agent.read_learning_candidate("candidate-id")

Candidate statuses are awaiting_review, accepted, rejected, and obsolete. Obsolescence is recalculated when referenced catalog or artifact state changes.

#Decide One Candidate at a Time

Accepting a candidate starts a fresh, attributable run:

python
result = await agent.accept_learning_candidate(
    "candidate-id",
    source_id="source-id",
)

The run uses the same write tools and approval handler as an ordinary request. There is no bulk-accept path.

Reject a proposal with a stable reason:

python
from daita import LearningCandidateRejectionReason
 
candidate = await agent.reject_learning_candidate(
    "candidate-id",
    LearningCandidateRejectionReason.NOT_DURABLE,
)

Available reasons include incorrect, not durable, not reusable, wrong scope, duplicate, sensitive, and user declined. Rejected records can be cleared later:

python
deleted_count = await agent.clear_rejected_learning_candidates()

Candidate content can also be edited with edit_learning_candidate() before a decision. Supply the content record that matches the candidate target.

#Terminal Workflow

bash
daita memory list-candidates atlas --status awaiting_review
daita memory show-candidate atlas candidate-id
daita memory edit-candidate atlas candidate-id
daita memory accept-candidate atlas candidate-id --model openai:gpt-5.6-terra
daita memory reject-candidate atlas candidate-id --reason not_durable
daita memory clear-rejected atlas

Review stamps prevent unchanged completed runs from being repeatedly reviewed. Clearing conversations also removes candidate records and review stamps, while leaving accepted knowledge intact.