Class: Insika::Commands::RunRefinement
- Inherits:
-
Object
- Object
- Insika::Commands::RunRefinement
- Defined in:
- lib/insika/commands/run_refinement.rb
Overview
Control command (RFC-0013 phase A): reads a window of the agent's real traffic and records a ranked failure REPORT. Synchronous — it only scans durable stores (no provider call, no fiber), so it answers with the Run and does not create a Task. It is the ONLY way a refinement run starts: the CLI, the Studio button and any external cron all dispatch this one command (§3.10 — there is no scheduler in the engine).
Payload:
agent (required) agent id
since ISO8601 — only turns from this instant on
last_sessions Integer — the N most recent conversations instead
full truthy — ignore the previous run and use the full window
max_findings Integer cap on the report
exclude_sessions [prefix] — session ids to drop (load tests, debug traffic)
Window resolution (first that applies): explicit payload -> INCREMENTAL (since
the previous run for this agent, unless full) -> the agent's configured
refinement.window -> the collector's default.
Phase A writes NOTHING to the agent, so it needs no opt-in: an absent
refinement config reads as report-only. Only propose/auto_apply (phase C)
require the operator to enable them explicitly.
Constant Summary collapse
- READ_ONLY_MODES =
%w[report propose auto_apply].freeze
Instance Method Summary collapse
- #call(command) ⇒ Object
-
#initialize(profiles:, refinement_store:, collector:, event_stream:) ⇒ RunRefinement
constructor
A new instance of RunRefinement.
Constructor Details
#initialize(profiles:, refinement_store:, collector:, event_stream:) ⇒ RunRefinement
Returns a new instance of RunRefinement.
32 33 34 35 36 37 |
# File 'lib/insika/commands/run_refinement.rb', line 32 def initialize(profiles:, refinement_store:, collector:, event_stream:) @profiles = ProfileSource.coerce(profiles) @refinement_store = refinement_store @collector = collector @event_stream = event_stream end |
Instance Method Details
#call(command) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/insika/commands/run_refinement.rb', line 39 def call(command) p = AgentPayload.symbolize(command.payload) agent = AgentPayload.presence(p[:agent]) raise Insika::ValidationError, "agent is required" if agent.nil? profile = @profiles[agent] || (raise Insika::NotFoundError, "agent '#{agent}' not configured") config = refinement_config(profile) validate_mode!(config) window = resolve_window(agent, p, config) run = @refinement_store.create(agent_id: agent, window: window) emit(:refinement_started, agent: agent, run_id: run.id, window: window) begin report = @collector.collect( agent_id: agent, max_findings: max_findings(p, config), exclude_sessions: exclude_sessions(p, config), **collect_args(window) ) done = @refinement_store.complete(run.id, findings: report.findings, excluded: report.excluded) emit(:refinement_report, agent: agent, run_id: run.id, status: done.status, findings: done.findings_count, sessions: report.sessions_seen, turns: report.turns_seen, excluded: report.excluded) done rescue StandardError => e @refinement_store.fail(run.id, error: e.) raise end end |