Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
328 changes: 316 additions & 12 deletions rbt/dashboard/v1/dashboard.proto
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ message Dashboard {
// whoever reads this to make of what they will.
repeated Servicer servicers = 6;

// Represents the version of the analysis that recorded
// `servicers`, `agents`, `unattributed_hazards` and `code_files`.
// A dashboard whose analysis records something new analyzes every
// file again rather than carrying forward what an earlier one
// recorded, which would never say it; see `CODE_ANALYSIS_VERSION`.
uint32 code_analysis_version = 16;

// Every agent found in the developer's application, sorted. One
// agent has a record per file whose analysis found it; see `Agent`.
repeated Agent agents = 17;

// Every hazard the analysis of the developer's application recorded
// that belongs to no agent, run, tool or method, sorted; see
// `UnattributedHazard`.
repeated UnattributedHazard unattributed_hazards = 18;

// Represents every file the walk of the application analyzed,
// keyed by its path, relative to the working directory for a file
// under it and absolute otherwise, as of the last write. A
Expand Down Expand Up @@ -119,6 +135,8 @@ message DashboardGetResponse {
map<string, rbt.v1alpha1.api.API> apis = 4;
map<string, string> api_digests = 5;
repeated Servicer servicers = 6;
repeated Agent agents = 16;
repeated UnattributedHazard unattributed_hazards = 17;
map<string, Generated> generated = 7;

// The worst reason over all the API files, and absent when
Expand Down Expand Up @@ -157,6 +175,9 @@ message DashboardUpdateApiResponse {}

message DashboardUpdateCodeRequest {
repeated Servicer servicers = 1;
uint32 code_analysis_version = 6;
repeated Agent agents = 7;
repeated UnattributedHazard unattributed_hazards = 8;
map<string, File> code_files = 2;
map<string, Generated> generated = 3;

Expand Down Expand Up @@ -518,12 +539,71 @@ message Servicer {
// makes.
repeated Call calls = 3;

// Represents every call the analysis could not resolve to a
// Reboot definition: possibly a helper that itself makes
// Reboot calls, to be followed by a future analysis, and
// possibly nothing of Reboot's. Spelled the way `ast.unparse`
// writes the callee, e.g. "self._transfer".
repeated string ambiguous = 4;
// Represents every agent the method's implementation runs,
// itself or through the functions it calls. What each agent is,
// is in `Agent`, which each of these names.
repeated Agent.Run runs = 4;

// One thing the method's implementation does, itself or through
// the functions it calls, that the analysis did not follow,
// recorded rather than guessed at or dropped, so the dashboard
// can show where what it draws may be incomplete.
message Hazard {
// A call the analysis could not resolve to a Reboot definition:
// one with no definition pyright can say, or one whose
// definition is no function, such as a stub's or a class's.
// Possibly a helper that itself makes Reboot calls, to be
// followed by a future analysis, and possibly nothing of
// Reboot's.
message AmbiguousCall {
// Represents what is called, spelled the way `ast.unparse`
// writes it, without the call's arguments, e.g.
// "self._transfer".
string callee = 1;
}

// A run of an agent the analysis could not resolve: the call's
// own definition proves an agent is run, but what it is run on
// is not an `Agent(...)` with a string literal `name=`, bound to
// a name at the top level of a module. E.g. an agent whose
// `name=` is computed or missing, one a factory builds or
// `Agent.wrap` adopts from one, an alias, a parameter, an
// element of a collection, one held on `self`, one constructed
// inside a function or where it is run, or a name bound to more
// than one thing. Nothing about the run is recorded, what it is
// given included.
message RunOnUnresolvedAgent {
// Represents what is called, spelled the way `ast.unparse`
// writes it: the receiver and the method, without the call's
// arguments, e.g. `make_agent().run`.
string callee = 1;
}

// An `override` of an agent the analysis could not resolve, the
// way it could not resolve a run's, e.g.
// `agents[0].override(model=...)`, which changes whatever runs
// inside it.
message OverrideOnUnresolvedAgent {
// Represents what is called, spelled the way `ast.unparse`
// writes it: the receiver and the method, without the call's
// arguments, e.g. `agents[0].override`.
string callee = 1;
}

// Represents the file the hazard is written in, spelled the way
// the developer would open it.
string filename = 1;

oneof hazard {
RunOnUnresolvedAgent run_on_unresolved_agent = 2;
OverrideOnUnresolvedAgent override_on_unresolved_agent = 3;
AmbiguousCall ambiguous_call = 4;
}
}

// Represents everything the method's implementation does that the
// analysis did not follow, in the order it met them.
repeated Hazard hazards = 5;
}

// The state type it services, spelled as the runtime names one,
Expand All @@ -534,17 +614,241 @@ message Servicer {
// open it, e.g. "backend/src/account_servicer.py".
string filename = 2;

// Represents the line its class is written on, counting from one.
uint32 line = 4;

// Represents the column its class starts at, counting from zero.
uint32 character = 5;

// Represents every method it defines, in the order they are
// written, which is the order somebody reading the file meets them.
repeated Method methods = 3;
}

// One agent the developer's application uses, as one file's analysis
// found it: a Reboot `Agent` constructed with a string literal `name=`
// and bound to a name at the top level of a module, which some method
// runs, or some function is decorated as a tool of.
//
// A record per file, because the analysis keys everything by the
// file it read, and an agent is met in more files than the one
// constructing it: a workflow runs it in one file, a tool is
// decorated on it in another. Every record says the same thing about
// the agent itself, since each is built from the construction the
// analysis resolved; what differs is the tools and the hazards each
// file contributed. Whoever reads these joins them on `name`, which
// the runtime requires to be unique.
message Agent {
// One thing about how an agent is constructed or given tools that
// the analysis did not follow, recorded rather than guessed at or
// dropped, so the dashboard can show where what it draws may be
// incomplete.
message Hazard {
// The agent is constructed with arguments that give it tools, or
// hide them, which are not followed. Each represents the value
// passed, spelled the way `ast.unparse` writes it, and is absent
// when it is not passed.
message ConstructedWith {
// `tools=`.
optional string tools = 1;

// `toolsets=`.
optional string toolsets = 2;

// `prepare_tools=`, which can hide any of its tools when it
// runs.
optional string prepare_tools = 3;
}

// A tool is registered on the agent by calling `tool` or
// `tool_plain` rather than decorating with it, e.g.
// `librarian.tool(lookup)`, which is not followed.
message ToolRegisteredByCall {
// Represents the call, its arguments included, spelled the way
// `ast.unparse` writes it.
string call = 1;
}

// The agent is overridden, with `agent.override(...)`, for
// whatever runs inside it, with arguments that change what it is
// or can reach, which are not followed. Each represents the value
// passed, spelled the way `ast.unparse` writes it, and is absent
// when it is not passed.
message Overridden {
// `tools=`, which reach the runs inside it.
optional string tools = 1;

// `name=`, which does not change the name the runs inside it
// are memoized under.
optional string name = 2;

// `model=`, which the runs inside it use instead of
// `Agent.model`.
optional string model = 3;

// `instructions=`, which the runs inside it are given instead of
// those in `Agent.system_prompt`.
optional string instructions = 4;
}

// Represents the file the hazard is written in, spelled the way
// the developer would open it.
string filename = 1;

oneof hazard {
ConstructedWith constructed_with = 2;
ToolRegisteredByCall tool_registered_by_call = 3;
Overridden overridden = 4;
}
}

// One run of an agent, made by a servicer method's implementation
// or by another agent's tool, through any of `Agent`'s entry points:
// `run`, `iter`, `run_stream` or `run_stream_events`. Which one says
// nothing about what the application does, so it is not recorded.
message Run {
// One thing a run is given on top of its agent that the analysis
// did not follow, recorded rather than guessed at or dropped.
message Hazard {
// The run is given arguments that change what its agent is or
// can reach. Each represents the value passed, spelled the way
// `ast.unparse` writes it, and is absent when it is not passed.
message RunArguments {
// `toolsets=`, which give the run tools.
optional string toolsets = 1;

// `model=`, which the run uses instead of `Agent.model`.
optional string model = 2;

// `instructions=`, which the run is given on top of those in
// `Agent.system_prompt`.
optional string instructions = 3;
}

// Represents the file the hazard is written in, spelled the way
// the developer would open it.
string filename = 1;

oneof hazard {
RunArguments run_arguments = 2;

// The run is written inside the `with` of an `override` of its
// agent, which changes what it is or can reach.
Agent.Hazard.Overridden overridden = 3;
}
}

// Represents the agent run, spelled as `Agent.name` spells it.
string agent = 1;

// Represents everything the run is given on top of its agent, by
// its own arguments or by an `override` it is written inside,
// that the analysis did not follow.
repeated Hazard hazards = 2;
}

// One tool an agent may call, and what analyzing its
// implementation found.
message Tool {
// One thing about how a tool is registered that the analysis did
// not follow, recorded rather than guessed at or dropped.
message Hazard {
// The tool is registered with `prepare=`, which can hide it
// when the agent runs.
message Prepared {
// Represents the value passed, spelled the way `ast.unparse`
// writes it.
string prepare = 1;
}

// Represents the file the hazard is written in, spelled the way
// the developer would open it.
string filename = 1;

oneof hazard {
Prepared prepared = 2;
}
}

// Represents the tool's name as the model is told it: the
// `name` given where it was registered, and the function's own
// name otherwise.
string name = 1;

// Represents what the model is told the tool does: the
// `description` given where it was registered, and the
// function's docstring otherwise. Absent when it has neither.
optional string description = 2;

// Represents every Reboot call and agent run the tool's
// implementation makes, and everything it does that the analysis
// did not follow, found exactly the way a servicer method's are.
repeated Servicer.Method.Call calls = 3;
repeated Run runs = 4;
repeated Servicer.Method.Hazard method_hazards = 5;

// Represents everything about how the tool is registered that the
// analysis did not follow.
repeated Hazard hazards = 6;
}

// Represents the agent's `name`, which the runtime requires and
// which is unique in an application, so it is what a run names and
// what records of one agent join on.
string name = 1;

// The file whose analysis found this record, spelled the way the
// developer would open it, e.g. "backend/src/librarian.py". What
// the records are keyed by, and not necessarily where the agent is
// constructed.
string filename = 2;

// Represents the model the agent is constructed with, e.g.
// "anthropic:claude-sonnet-4-6". Absent when it is not a literal
// the analysis can read.
optional string model = 3;

// Represents what the agent tells the model about itself: every
// literal string its `system_prompt` and its `instructions` are
// constructed with, in that order. A prompt computed rather than
// written down contributes nothing.
repeated string system_prompt = 4;

// Represents the agent's `description`, which is what another
// agent handing work to this one is told it does. Absent when it
// has none the analysis can read.
optional string description = 5;

// Represents every tool this file's analysis found the agent has,
// in the order it met them: each function decorated as one with
// `@agent.tool` or `@agent.tool_plain`, the one way of giving an
// agent a tool that can always be followed.
repeated Tool tools = 6;

// Represents everything about how the agent is constructed, given
// tools and overridden that the analysis did not follow. What a single run
// is given is on the run; see `Run.hazards`.
repeated Hazard hazards = 7;
}

// One thing the analysis did not follow that belongs to no agent, run,
// tool or method, recorded rather than dropped, for the file it is
// written in.
message UnattributedHazard {
// A tool is registered, decorated or by a call, on an agent that
// cannot be resolved, e.g. `@agents[0].tool`, so there is no agent
// to record it on.
message ToolOnUnresolvedAgent {
// Represents the registration, spelled the way `ast.unparse`
// writes it: the decorator without its arguments, e.g.
// `agents[0].tool`, or the whole call registering by calling,
// e.g. `agents[0].tool_plain(count)`.
string registration = 1;
}

// Represents the file the hazard is written in, spelled the way the
// developer would open it.
string filename = 1;

oneof hazard {
ToolOnUnresolvedAgent tool_on_unresolved_agent = 2;
}
}

// What analyzing one of the developer's files used: the digest
// of its bytes and what each of its imports observed. What a
// restarted dashboard reconstitutes its knowledge from, so that only
Expand Down
Loading
Loading