pub struct SomaContext {
pub project_dir: PathBuf,
pub kb: Box<dyn KnowledgeBase>,
/* private fields */
}Expand description
Server-side state for the Soma MCP server.
Fields§
§project_dir: PathBufProject directory (where user’s filter code lives).
kb: Box<dyn KnowledgeBase>Knowledge base for experiment tracking.
Implementations§
Source§impl SomaContext
impl SomaContext
Sourcepub fn new(project_dir: impl Into<PathBuf>) -> Self
pub fn new(project_dir: impl Into<PathBuf>) -> Self
Create a context with a persistent knowledge base when one is
available: SOMA_KB_PATH if set, else the project’s
.soma/experiments.jsonl when a .soma/ directory exists.
Falls back to the in-memory KB otherwise (records are lost on
server exit).
Sourcepub fn with_env_override(
project_dir: impl Into<PathBuf>,
env_override: Option<String>,
) -> Self
pub fn with_env_override( project_dir: impl Into<PathBuf>, env_override: Option<String>, ) -> Self
Deterministic constructor: env_override plays the role of the
SOMA_KB_PATH environment variable. Used by new() and by
tests, which must never depend on (or leak through) the real
process environment.
Sourcepub fn refresh_kb(&mut self)
pub fn refresh_kb(&mut self)
Pick up experiments another process appended since the last call. An MCP server outlives many training runs; without this it answers every question from the snapshot it loaded at startup.
Sourcepub fn kb_location(&self) -> Option<String>
pub fn kb_location(&self) -> Option<String>
Human-readable location of the journal, when it has one.
Sourcepub fn tracking_root(&self) -> PathBuf
pub fn tracking_root(&self) -> PathBuf
The tracking root this project’s runs live under (.soma).
Sourcepub fn list_filters(&self, params: &Value) -> ToolCallResult
pub fn list_filters(&self, params: &Value) -> ToolCallResult
list_filters: every .py/.rs file under path (default:
the project directory), recursing but skipping hidden
directories. Returns a JSON array of {"path": ...} objects.
Like every handler below, it takes the raw arguments object
from tools/call and reports a missing or bad argument as a
ToolCallResult::error — the model reads the message and can
retry, which a protocol-level error would not allow.
Sourcepub fn read_filter_source(&self, params: &Value) -> ToolCallResult
pub fn read_filter_source(&self, params: &Value) -> ToolCallResult
read_filter_source: the contents of file_path, resolved
against the project directory when relative.
Sourcepub fn write_filter_source(&self, params: &Value) -> ToolCallResult
pub fn write_filter_source(&self, params: &Value) -> ToolCallResult
write_filter_source: write content to file_path, creating
parent directories as needed. An existing file is copied to a
.bak sibling first — a model editing code deserves one level
of undo.
Sourcepub fn run_pipeline(&self, params: &Value) -> ToolCallResult
pub fn run_pipeline(&self, params: &Value) -> ToolCallResult
run_pipeline: build the graph the model described and run it.
The nodes name filters that live in the project — the same files
list_filters lists and read_filter_source reads — so the loop
a model works in is closed: read the code, write a variant, run
it, read the result out of the experiment pool.
Tracked by default, so the run lands in .soma/experiments.jsonl
with a lineage and kb_summarize_run can be pointed at it.
Sourcepub fn run_study(&self, params: &Value) -> ToolCallResult
pub fn run_study(&self, params: &Value) -> ToolCallResult
run_study: the same graph spec, searched.
The search space is not a second vocabulary — a node config value
written as {"__search__": {...}} becomes a dimension, and
graph.search_space() finds it. So the difference between running
a graph once and searching it is which values were marked.
Sourcepub fn record_experiment(&mut self, params: &Value) -> ToolCallResult
pub fn record_experiment(&mut self, params: &Value) -> ToolCallResult
record_experiment: append an experiment to the knowledge base.
id and name are required; hypothesis, research line,
pipeline summary, parent, notes, tags, metrics and params are
taken when present and silently skipped when absent or of the
wrong JSON type — a partial record beats no record.
Sourcepub fn query_knowledge_base(&self, params: &Value) -> ToolCallResult
pub fn query_knowledge_base(&self, params: &Value) -> ToolCallResult
query_knowledge_base: free-text search over recorded
experiments (query, plus max_results, default 10). Returns a
JSON array of experiment summaries — id, name, hypothesis, line,
metrics, tags — enough to decide which one to ask more about.
Sourcepub fn get_trajectory(&self, params: &Value) -> ToolCallResult
pub fn get_trajectory(&self, params: &Value) -> ToolCallResult
get_trajectory: the values of metric across the experiments
of research_line, in recording order — how the line has been
moving, as {experiment_id, value} pairs.
Sourcepub fn get_change_points(&self, params: &Value) -> ToolCallResult
pub fn get_change_points(&self, params: &Value) -> ToolCallResult
get_change_points: the experiments where metric jumped by
more than threshold (default 0.05) within research_line —
the moments worth reading closely, with before/after values and
a description of each.
Sourcepub fn list_research_lines(&self, _params: &Value) -> ToolCallResult
pub fn list_research_lines(&self, _params: &Value) -> ToolCallResult
list_research_lines: every research line in the pool, with its
trend, experiment count and best metric so far. Takes no
arguments.
Sourcepub fn promising_lines(&self, params: &Value) -> ToolCallResult
pub fn promising_lines(&self, params: &Value) -> ToolCallResult
promising_lines: the research lines with an improving trend,
or whose best result is on metric — where the next experiment
is most likely to pay off.
Sourcepub fn create_research_line(&mut self, params: &Value) -> ToolCallResult
pub fn create_research_line(&mut self, params: &Value) -> ToolCallResult
create_research_line: start a named line by recording a
<name>_init marker experiment carrying the description. Lines
have no existence of their own in the pool — they are the set of
experiments tagged with them, so creating one means recording
one.
Sourcepub fn generate_report(&self, params: &Value) -> ToolCallResult
pub fn generate_report(&self, params: &Value) -> ToolCallResult
generate_report: a Markdown report for research_line — the
experiment table, the trajectory of its first metric, the
significant changes, and the line’s trend. Markdown because the
consumer is a model (or a human pasted the output): structure
survives, no renderer needed.