kernel/config/search.rs
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4// Copyright (c) 2026 2youg1 and the sprawling contributors
5
6//! Which outside service a run's `web_search` reaches: the shape only.
7//!
8//! What `Default` points at, how `selected` is found, what a file may not
9//! say and on which rungs it may say it are all `city`'s answers
10//! (`crates/city/spec/ConfigLayers.lean` §8-4c, city D25), so the default
11//! supplier's address is declared there once and has no copy here.
12//!
13//! Specified by `crates/kernel/spec/Config.lean` §8-22.
14
15use serde::{Deserialize, Serialize};
16
17use crate::event::record::ProviderAccount;
18use crate::tool::ServerLabel;
19
20/// One search service reached over MCP streamable HTTP.
21#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
22#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
23pub struct SearchSupplier {
24 /// The supplier's name, and the Connector label `web_search` carries.
25 pub id: ServerLabel,
26 /// The MCP HTTP address, judged like an `[[mcp]]` url (city D26).
27 pub url: String,
28 /// The name of the remote tool in this supplier's `tools/list`.
29 pub remote: String,
30 /// The remote parameter `web_search`'s `query` is handed to.
31 pub query_field: String,
32 /// The remote parameter `objective` is handed to; `None` when this
33 /// supplier takes no objective.
34 pub objective_field: Option<String>,
35 /// The remote parameter `num_results` is handed to; `None` when this
36 /// supplier takes no count.
37 pub count_field: Option<String>,
38 /// In priority order. An anonymous account is the row without a
39 /// reference; a key appears only as its vault reference.
40 pub accounts: Vec<ProviderAccount>,
41}
42
43/// What a layer says about web search. Three arms and no `enabled`
44/// switch, so each of the three intents has one spelling: the default
45/// supplier, this supplier, none. `Default` is a stated value, not an
46/// absence: a layer that states it covers a farther layer's `Custom`.
47#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
48#[serde(rename_all = "snake_case")]
49#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
50pub enum SearchConfiguration {
51 /// The supplier `city` declares as the default.
52 #[default]
53 Default,
54 /// Exactly the listed supplier whose id is `selected`; never another.
55 Custom {
56 selected: ServerLabel,
57 suppliers: Vec<SearchSupplier>,
58 },
59 /// No `web_search` under this layer.
60 Off,
61}