TraceMaker
C++ API of the engine
Loading...
Searching...
No Matches
session.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2#pragma once
3// A board session an agent can drive (design doc 19, milestone M18).
4//
5// The agent lists the open connections, asks the engine to route some nets with some hints, looks at the result, rips a net, goes back to an earlier
6// state and saves. The engine is what it was: copper comes only from the router (every segment and via passes the exact check), a call is a
7// transaction that is kept or not, hints are an advice file (doc 17) read by the same code, and the log of calls replays to the same bytes.
8//
9// One `Session::call` serves every transport (MCP and JSON lines, transport.hpp). It never throws: a refused call is {"error": {"code", "message"}}.
10#include <cstdint>
11#include <map>
12#include <memory>
13#include <optional>
14#include <string>
15#include <vector>
16
17#include <nlohmann/json.hpp>
18
19#include "core/events.hpp"
21#include "model/board.hpp"
22#include "model/rules.hpp"
23#include "route/router.hpp"
24
25namespace tmk::session {
26
28 std::string in; // the board; its project files supply the rules
29 std::string out; // where `save` writes; empty = `save` is refused
30 std::uint64_t seed = 1; // router seed of a `route` call that does not give one
31 long work_limit = 0; // search work of the whole session (expansions plus flood cells); 0 = none
32 int gpu_device = -1; // GPU for cost-to-go fields; -1 = CPU reference (same results)
33 int threads = 4; // portfolio threads of a `route` with several variants (the result does not depend on it)
34 std::string log; // JSON-lines log of the calls; empty = none
35 events::Sink* sink = nullptr; // the router's events (the viewer)
36};
37
38class Session {
39 public:
40 // Reads the board and its rules. Throws on an unreadable board.
41 explicit Session(SessionOptions opt);
42
43 // One tool call (doc 19 §4). Deterministic: the result depends on the board, the state, the arguments and the seed only.
44 nlohmann::json call(const std::string& tool, const nlohmann::json& args);
45
46 // The tools as MCP descriptors {name, description, inputSchema}, and the text the server sends as `instructions`.
47 static nlohmann::json tools();
48 static const char* instructions();
49
50 // Runs the calls of a log written by `SessionOptions::log` and stops at the first result or state digest that differs.
51 struct Replay {
52 bool ok = false;
53 int calls = 0;
54 std::string message;
55 };
56 Replay replay(const std::string& log_path);
57
58 int state() const { return cur_; }
59 // FNV-1a 64 of the current state's session copper in canonical order (a digest, not a cryptographic hash).
60 std::string state_digest() const;
61 const model::Board& base() const { return lb_.board; }
62 long work_used() const { return work_used_; }
63
64 private:
65 struct Copper {
66 std::vector<model::Track> tracks;
67 std::vector<model::Via> vias;
68 };
69 struct Reason {
70 std::string reason, why;
71 int rips = 0, fails = 0;
72 std::vector<std::string> blockers;
73 };
74 struct OpenConn {
75 std::string net, a, b; // a, b: REF.PIN ("zone" for a plane)
76 double length_mm = -1; // -1: the connection ends in a plane
77 int pad_a = -1, pad_b = -1;
78 };
79 struct State {
80 int id = 0, parent = -1;
81 std::string call;
82 Copper copper;
83 std::map<std::pair<std::string, std::string>, Reason> reasons; // of the last route that made or left this state
84 // Caches, filled on demand (a state never changes).
85 std::optional<std::vector<OpenConn>> open[2]; // planned without / with soft zones (plane connections)
86 std::optional<std::map<std::string, int>> errors[2]; // DRC errors by type, [0] on the stored fills, [1] with the zones refilled
87 int unconnected[2] = {-1, -1};
88 };
89 struct LastRoute {
90 std::shared_ptr<const model::Board> board;
91 route::RouteResult result;
92 int state = -1;
93 };
94
95 nlohmann::json dispatch(const std::string& tool, const nlohmann::json& args);
96 nlohmann::json board_info();
97 nlohmann::json open_connections(const nlohmann::json& args);
98 nlohmann::json route(const nlohmann::json& args);
99 nlohmann::json rip_net(const nlohmann::json& args);
100 nlohmann::json check(const nlohmann::json& args);
101 nlohmann::json stuck_report(const nlohmann::json& args);
102 nlohmann::json added_examples(State& s, const std::map<std::string, int>& added, bool refill);
103 nlohmann::json inspect_pad(const nlohmann::json& args);
104 nlohmann::json inspect_net(const nlohmann::json& args);
105 nlohmann::json history();
106 nlohmann::json undo();
107 nlohmann::json restore(const nlohmann::json& args);
108 nlohmann::json save(const nlohmann::json& args);
109
110 model::Board working(const Copper& c) const; // the board with the session copper added and locked
111 const std::vector<OpenConn>& open_of(State& s, bool soft_zones); // plans the state's open connections (cached)
112 const std::map<std::string, int>& errors_of(State& s, bool refill); // DRC errors by type (cached); refill = judged as kicad-cli --refill-zones
113 int add_state(State s);
114 std::string digest_of(const Copper& c) const;
115 nlohmann::json state_json(const State& s) const;
116
117 SessionOptions opt_;
118 io::LoadedBoard lb_;
119 model::DesignRules rules_;
120 std::string name_;
121 std::vector<State> states_;
122 int cur_ = 0;
123 long work_used_ = 0;
124 std::optional<LastRoute> last_;
125 int calls_ = 0;
126 bool soft_used_ = false; // a route with soft zones was kept: the DRC then judges the board with its zones refilled
127};
128
129} // namespace tmk::session
The board model (design doc 02 §3): every object TraceMaker reads from a .kicad_pcb,...
Reads .kicad_pcb files (KiCad 9 and 10 formats) into the board model, keeping the s-expression docume...
Session(SessionOptions opt)
Reads the board and its rules. Throws on an unreadable board.
const model::Board & base() const
Definition session.hpp:61
static const char * instructions()
int state() const
Definition session.hpp:58
long work_used() const
Definition session.hpp:62
nlohmann::json call(const std::string &tool, const nlohmann::json &args)
One tool call (doc 19 §4). Deterministic: the result depends on the board, the state,...
Replay replay(const std::string &log_path)
std::string state_digest() const
FNV-1a 64 of the current state's session copper in canonical order (a digest, not a cryptographic has...
static nlohmann::json tools()
The tools as MCP descriptors {name, description, inputSchema}, and the text the server sends as instr...
Event sink for live visualisation and replay (design doc 02 §7, protocol in docs/13-viewer-protocol....
TraceMaker's detailed router, version 1 (roadmap M4; design doc 05 §2, §5).
Design rules as KiCad defines them (design doc 08 §3–4): board minimums and net classes from the ....
std::uint64_t seed
router seed of a route call that does not give one
Definition session.hpp:30
int threads
portfolio threads of a route with several variants (the result does not depend on it)
Definition session.hpp:33
events::Sink * sink
the router's events (the viewer)
Definition session.hpp:35
std::string in
the board; its project files supply the rules
Definition session.hpp:28
std::string log
JSON-lines log of the calls; empty = none.
Definition session.hpp:34
long work_limit
search work of the whole session (expansions plus flood cells); 0 = none
Definition session.hpp:31
int gpu_device
GPU for cost-to-go fields; -1 = CPU reference (same results).
Definition session.hpp:32
std::string out
where save writes; empty = save is refused
Definition session.hpp:29
Runs the calls of a log written by SessionOptions::log and stops at the first result or state digest ...
Definition session.hpp:51