@theway-ai/sdk 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/dist/client.d.ts +138 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +390 -0
- package/dist/client.js.map +1 -0
- package/dist/generated/commands.d.ts +160 -0
- package/dist/generated/commands.d.ts.map +1 -0
- package/dist/generated/commands.js +449 -0
- package/dist/generated/commands.js.map +1 -0
- package/dist/generated/events.d.ts +144 -0
- package/dist/generated/events.d.ts.map +1 -0
- package/dist/generated/events.js +1044 -0
- package/dist/generated/events.js.map +1 -0
- package/dist/generated/extensions.d.ts +184 -0
- package/dist/generated/extensions.d.ts.map +1 -0
- package/dist/generated/extensions.js +1309 -0
- package/dist/generated/extensions.js.map +1 -0
- package/dist/generated/graph_engine.d.ts +373 -0
- package/dist/generated/graph_engine.d.ts.map +1 -0
- package/dist/generated/graph_engine.js +2422 -0
- package/dist/generated/graph_engine.js.map +1 -0
- package/dist/generated/health.d.ts +83 -0
- package/dist/generated/health.d.ts.map +1 -0
- package/dist/generated/health.js +179 -0
- package/dist/generated/health.js.map +1 -0
- package/dist/generated/session.d.ts +490 -0
- package/dist/generated/session.d.ts.map +1 -0
- package/dist/generated/session.js +3809 -0
- package/dist/generated/session.js.map +1 -0
- package/dist/generated/settings.d.ts +175 -0
- package/dist/generated/settings.d.ts.map +1 -0
- package/dist/generated/settings.js +304 -0
- package/dist/generated/settings.js.map +1 -0
- package/dist/generated/state.d.ts +291 -0
- package/dist/generated/state.d.ts.map +1 -0
- package/dist/generated/state.js +1382 -0
- package/dist/generated/state.js.map +1 -0
- package/dist/generated/tools.d.ts +413 -0
- package/dist/generated/tools.d.ts.map +1 -0
- package/dist/generated/tools.js +2487 -0
- package/dist/generated/tools.js.map +1 -0
- package/dist/health.d.ts +20 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +62 -0
- package/dist/health.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/package.json +46 -0
- package/proto/commands.proto +57 -0
- package/proto/events.proto +80 -0
- package/proto/extensions.proto +99 -0
- package/proto/graph_engine.proto +193 -0
- package/proto/health.proto +26 -0
- package/proto/session.proto +299 -0
- package/proto/settings.proto +73 -0
- package/proto/state.proto +129 -0
- package/proto/tools.proto +238 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// Graph engine domain: DAG/goal run state, subagent jobs, node output,
|
|
2
|
+
// control, checkpoint/restore, run enumeration, and the GraphEngineService
|
|
3
|
+
// RPC surface. Planning is agent-side; this surface observes and steers runs
|
|
4
|
+
// created by the dag_plan / goal tools.
|
|
5
|
+
|
|
6
|
+
syntax = "proto3";
|
|
7
|
+
package theway.grpc.v1;
|
|
8
|
+
|
|
9
|
+
import "commands.proto";
|
|
10
|
+
|
|
11
|
+
message DagRunSnapshot {
|
|
12
|
+
string id = 1;
|
|
13
|
+
string name = 2;
|
|
14
|
+
string status = 3; // running/completed/failed/cancelled
|
|
15
|
+
bool fail_fast = 4;
|
|
16
|
+
uint32 max_concurrency = 5;
|
|
17
|
+
string direction = 6; // TD/LR
|
|
18
|
+
int64 created_at = 7;
|
|
19
|
+
optional int64 completed_at = 8;
|
|
20
|
+
optional string error = 9;
|
|
21
|
+
repeated DagNodeSnapshot nodes = 10;
|
|
22
|
+
string kind = 11; // "dag" | "goal" — goal runs are single-node self-loops (condition-terminated)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
message DagNodeSnapshot {
|
|
26
|
+
string id = 1;
|
|
27
|
+
string agent = 2;
|
|
28
|
+
string status = 3; // pending/ready/running/succeeded/failed/skipped/cancelled
|
|
29
|
+
repeated string depends_on = 4;
|
|
30
|
+
optional string job_id = 5; // ↔ SubagentJobSnapshot.id
|
|
31
|
+
uint32 attempt = 6;
|
|
32
|
+
optional int64 started_at = 7;
|
|
33
|
+
optional int64 completed_at = 8;
|
|
34
|
+
optional string error = 9;
|
|
35
|
+
optional uint64 input_tokens = 10;
|
|
36
|
+
optional uint64 output_tokens = 11;
|
|
37
|
+
optional NodeResultSnapshot result = 12;
|
|
38
|
+
optional string output_tail = 13; // terminal output tail; full text via events/GetNodeOutput
|
|
39
|
+
optional string live_preview = 14; // live output while running
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
message NodeResultSnapshot {
|
|
43
|
+
bool success = 1;
|
|
44
|
+
optional string error = 2;
|
|
45
|
+
optional uint64 duration_ms = 3;
|
|
46
|
+
uint32 attempt = 4;
|
|
47
|
+
uint32 total_attempts = 5;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
message SubagentJobSnapshot {
|
|
51
|
+
string id = 1;
|
|
52
|
+
string agent = 2; // general / explorer / executor-coder / ...
|
|
53
|
+
string source = 3; // task | dag
|
|
54
|
+
optional string run_id = 4;
|
|
55
|
+
optional string node_id = 5;
|
|
56
|
+
string status = 6; // running/succeeded/failed/cancelled
|
|
57
|
+
optional int64 started_at = 7;
|
|
58
|
+
optional int64 completed_at = 8;
|
|
59
|
+
optional uint64 duration_ms = 9;
|
|
60
|
+
uint32 attempt = 10;
|
|
61
|
+
uint32 total_attempts = 11;
|
|
62
|
+
optional uint64 input_tokens = 12;
|
|
63
|
+
optional uint64 output_tokens = 13;
|
|
64
|
+
optional string error = 14;
|
|
65
|
+
optional string output_tail = 15;
|
|
66
|
+
optional string live_preview = 16;
|
|
67
|
+
// graph mode metrics:
|
|
68
|
+
optional double tps = 17; // output tokens/sec (sliding window)
|
|
69
|
+
optional double cps = 18; // output chars/sec
|
|
70
|
+
optional uint64 chars = 19; // cumulative output chars
|
|
71
|
+
optional uint64 tools_called = 20; // cumulative tool calls
|
|
72
|
+
optional uint32 turn = 21; // completed turns
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Full output of a DAG node, fetched on demand with an offset (P3).
|
|
76
|
+
message GetNodeOutputRequest {
|
|
77
|
+
string run_id = 1;
|
|
78
|
+
string node_id = 2;
|
|
79
|
+
uint64 offset = 3;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
message GetNodeOutputResponse {
|
|
83
|
+
string text = 1; // fragment from offset
|
|
84
|
+
uint64 offset = 2; // start offset of this fragment
|
|
85
|
+
uint64 total = 3; // full length
|
|
86
|
+
bool truncated = 4; // server buffer capped
|
|
87
|
+
// Full conversation transcript (user prompts + assistant turns with tool
|
|
88
|
+
// calls + tool results) as a JSON array of serde_json::Value — the same
|
|
89
|
+
// shape the registry keeps in memory and on disk. "" when unavailable
|
|
90
|
+
// (e.g. unknown node). Optional so older clients keep working.
|
|
91
|
+
optional string messages_json = 5;
|
|
92
|
+
bool messages_truncated = 6; // transcript buffer was capped (oldest dropped)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
enum GraphKind {
|
|
96
|
+
GRAPH_DAG = 0;
|
|
97
|
+
GRAPH_GOAL = 1;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
message GraphCancelRequest {
|
|
101
|
+
string run_id = 1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
message GraphRetryRequest {
|
|
105
|
+
string run_id = 1;
|
|
106
|
+
optional string node_id = 2; // omitted = all failed/cancelled nodes
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
message GraphRetryResponse {
|
|
110
|
+
repeated string reset_node_ids = 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
message GraphSkipRequest {
|
|
114
|
+
string run_id = 1;
|
|
115
|
+
string node_id = 2;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Turn-level control for a running DAG node's subagent.
|
|
119
|
+
message GraphNodeInterruptRequest {
|
|
120
|
+
string run_id = 1;
|
|
121
|
+
string node_id = 2;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
message GraphNodeSteerRequest {
|
|
125
|
+
string run_id = 1;
|
|
126
|
+
string node_id = 2;
|
|
127
|
+
string text = 3;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
message GraphSkipResponse {
|
|
131
|
+
bool skipped = 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Checkpoints are organized by session: a session owns its runs
|
|
135
|
+
// (DagRun.session_id), and `SessionState.dags` mounts the live graph status
|
|
136
|
+
// under that session. Checkpoint exports one run or the session's whole graph
|
|
137
|
+
// set as portable JSON snapshots; restore revives them back under the session.
|
|
138
|
+
message GraphCheckpointRequest {
|
|
139
|
+
// Owning session. Omitted = the session this connection belongs to.
|
|
140
|
+
optional string session_id = 1;
|
|
141
|
+
// Omitted = every running run of the session; set to export a single run.
|
|
142
|
+
optional string run_id = 2;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
message GraphCheckpointResponse {
|
|
146
|
+
string session_id = 1;
|
|
147
|
+
repeated GraphSnapshotEntry checkpoints = 2;
|
|
148
|
+
optional string error = 3;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
message GraphSnapshotEntry {
|
|
152
|
+
GraphKind kind = 1;
|
|
153
|
+
string run_id = 2;
|
|
154
|
+
string snapshot = 3; // JSON (PersistedRun shape: definition, node states, progress)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Restore: resume run(s) from GraphCheckpoint snapshots. Running runs are
|
|
158
|
+
// revived with their ready nodes re-scheduled, and re-attached to the session.
|
|
159
|
+
message GraphRestoreRequest {
|
|
160
|
+
string session_id = 1;
|
|
161
|
+
string snapshot = 2; // single GraphSnapshotEntry.snapshot (PersistedRun JSON)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
message GraphRestoreResponse {
|
|
165
|
+
string run_id = 1;
|
|
166
|
+
optional string error = 2;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
message GraphListRequest {
|
|
170
|
+
string session_id = 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
message GraphListResponse {
|
|
174
|
+
repeated DagRunSnapshot runs = 1;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
service GraphEngineService {
|
|
178
|
+
// Fetch a DAG node's full output from an offset (P3).
|
|
179
|
+
rpc GetNodeOutput(GetNodeOutputRequest) returns (GetNodeOutputResponse);
|
|
180
|
+
// Graph orchestration control (DAG + goal runs; planning is agent-side).
|
|
181
|
+
rpc GraphCancel(GraphCancelRequest) returns (CommandResult);
|
|
182
|
+
rpc GraphRetry(GraphRetryRequest) returns (GraphRetryResponse);
|
|
183
|
+
rpc GraphSkip(GraphSkipRequest) returns (GraphSkipResponse);
|
|
184
|
+
// Stop the node's in-flight turn (run ends unless steering was queued).
|
|
185
|
+
rpc GraphNodeInterrupt(GraphNodeInterruptRequest) returns (CommandResult);
|
|
186
|
+
// Queue a steering message injected at the node's next natural turn boundary.
|
|
187
|
+
rpc GraphNodeSteer(GraphNodeSteerRequest) returns (CommandResult);
|
|
188
|
+
// Checkpoint / restore (portable run snapshots for external persistence).
|
|
189
|
+
rpc GraphCheckpoint(GraphCheckpointRequest) returns (GraphCheckpointResponse);
|
|
190
|
+
rpc GraphRestore(GraphRestoreRequest) returns (GraphRestoreResponse);
|
|
191
|
+
// Enumerate one session's graph runs (DagRunSnapshot shape).
|
|
192
|
+
rpc GraphList(GraphListRequest) returns (GraphListResponse);
|
|
193
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Standard gRPC health checking protocol (grpc.health.v1), hand-written
|
|
2
|
+
// equivalent of grpc/grpc's health.proto. Served alongside theway.grpc.v1 so
|
|
3
|
+
// generic health probes (grpc_health_probe, load balancers, k8s-style checks)
|
|
4
|
+
// work without importing the domain proto. See docs/PROTOCOL.md.
|
|
5
|
+
|
|
6
|
+
syntax = "proto3";
|
|
7
|
+
package grpc.health.v1;
|
|
8
|
+
|
|
9
|
+
message HealthCheckRequest {
|
|
10
|
+
string service = 1;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
message HealthCheckResponse {
|
|
14
|
+
enum ServingStatus {
|
|
15
|
+
UNKNOWN = 0;
|
|
16
|
+
SERVING = 1;
|
|
17
|
+
NOT_SERVING = 2;
|
|
18
|
+
SERVICE_UNKNOWN = 3;
|
|
19
|
+
}
|
|
20
|
+
ServingStatus status = 1;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
service Health {
|
|
24
|
+
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
|
|
25
|
+
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
|
|
26
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// Session domain: the full session state plane (snapshot, sidebar, feed,
|
|
2
|
+
// model catalog, status), session resource messages
|
|
3
|
+
// (list/create/switch/rename/delete), and the SessionService RPC surface.
|
|
4
|
+
|
|
5
|
+
syntax = "proto3";
|
|
6
|
+
package theway.grpc.v1;
|
|
7
|
+
|
|
8
|
+
import "commands.proto";
|
|
9
|
+
import "extensions.proto";
|
|
10
|
+
import "graph_engine.proto";
|
|
11
|
+
|
|
12
|
+
// Full session state (the structured form of the former WireSnapshot JSON).
|
|
13
|
+
// Low-frequency, whole-replacement: GetState / stream snapshot frames.
|
|
14
|
+
message SessionState {
|
|
15
|
+
string session_id = 1;
|
|
16
|
+
string model = 2;
|
|
17
|
+
repeated ProviderGroup model_catalog = 3;
|
|
18
|
+
string cwd = 4;
|
|
19
|
+
bool busy = 5;
|
|
20
|
+
uint32 queued_count = 6;
|
|
21
|
+
optional TriggerPollStatus latest_trigger_poll = 7;
|
|
22
|
+
optional GoalSnapshot goal = 8;
|
|
23
|
+
optional ControlPlanePromptSnapshot control_plane_prompt = 9;
|
|
24
|
+
SidebarSnapshot sidebar = 10;
|
|
25
|
+
repeated FeedBlock feed_blocks = 11;
|
|
26
|
+
repeated string feed_lines = 12;
|
|
27
|
+
// graph mode (P1/P2 fill these):
|
|
28
|
+
repeated DagRunSnapshot dags = 13;
|
|
29
|
+
repeated SubagentJobSnapshot subagents = 14;
|
|
30
|
+
// TUI display settings pushed from the daemon (read from config.toml).
|
|
31
|
+
optional uint32 tui_max_feed_lines = 15;
|
|
32
|
+
// Token usage + context window for the live session.
|
|
33
|
+
optional ContextUsage context_usage = 16;
|
|
34
|
+
// Absolute index of feed_lines[0] in the full transcript (issue #35):
|
|
35
|
+
// stream snapshots carry only rows appended since the last publish; the
|
|
36
|
+
// initial get_state snapshot carries everything (base 0).
|
|
37
|
+
uint64 feed_lines_base = 17;
|
|
38
|
+
// Incremental gRPC snapshot frames require this many blocks to already be
|
|
39
|
+
// present on the consumer. Zero denotes a full replacement frame.
|
|
40
|
+
uint64 feed_blocks_base = 18;
|
|
41
|
+
// Appends/replacements since feed_blocks_base. Full frames leave this empty.
|
|
42
|
+
repeated FeedBlockPatch feed_block_patches = 19;
|
|
43
|
+
// Runtime-extension status is additive; older clients ignore this field.
|
|
44
|
+
ExtensionSnapshot extensions = 20;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
message FeedBlockPatch {
|
|
48
|
+
// index == consumer length appends; index < length replaces; index > length
|
|
49
|
+
// is a gap and requires a full GetState resync.
|
|
50
|
+
uint64 index = 1;
|
|
51
|
+
FeedBlock block = 2;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Token usage for the current/last turn, plus the model's context window size.
|
|
55
|
+
message ContextUsage {
|
|
56
|
+
uint64 input_tokens = 1;
|
|
57
|
+
uint64 output_tokens = 2;
|
|
58
|
+
uint64 cache_read_tokens = 3;
|
|
59
|
+
uint64 cache_write_tokens = 4;
|
|
60
|
+
uint64 total_tokens = 5;
|
|
61
|
+
uint32 context_window = 6;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
message ProviderGroup {
|
|
65
|
+
string provider = 1;
|
|
66
|
+
bool has_credential = 2;
|
|
67
|
+
repeated ModelEntry models = 3;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
message ModelEntry {
|
|
71
|
+
string id = 1;
|
|
72
|
+
string name = 2;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
message TriggerPollStatus {
|
|
76
|
+
string checked_at = 1;
|
|
77
|
+
string trace_id = 2;
|
|
78
|
+
string source_label = 3;
|
|
79
|
+
string event_label = 4;
|
|
80
|
+
string summary = 5;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
message GoalSnapshot {
|
|
84
|
+
string condition = 1;
|
|
85
|
+
string status = 2;
|
|
86
|
+
uint32 iterations = 3;
|
|
87
|
+
optional string last_reason = 4;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
message ControlPlanePromptSnapshot {
|
|
91
|
+
string tool_name = 1;
|
|
92
|
+
string label = 2;
|
|
93
|
+
string reason = 3;
|
|
94
|
+
string args_hash = 4;
|
|
95
|
+
string payload = 5;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
message SidebarSnapshot {
|
|
99
|
+
uint32 inbox_new = 1;
|
|
100
|
+
SkillsSnapshot skills = 2;
|
|
101
|
+
TriggersSnapshot triggers = 3;
|
|
102
|
+
CronSnapshot cron = 4;
|
|
103
|
+
McpSnapshot mcp = 5;
|
|
104
|
+
ToolsSnapshot tools = 6;
|
|
105
|
+
repeated string hooks = 7;
|
|
106
|
+
repeated string runtime = 8;
|
|
107
|
+
// Slash-prefixed file-command names (claude-code format, issue #37):
|
|
108
|
+
// discovered from .agents/commands + .claude/commands.
|
|
109
|
+
repeated string commands = 9;
|
|
110
|
+
// Daemon runtime revision, bumped by the `reload` agent tool; clients
|
|
111
|
+
// watch it to re-read local resources (e.g. ~/.theway/theme.toml).
|
|
112
|
+
uint64 runtime_revision = 10;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
message SkillsSnapshot {
|
|
116
|
+
uint32 total = 1;
|
|
117
|
+
uint32 enabled = 2;
|
|
118
|
+
uint32 disabled = 3;
|
|
119
|
+
uint32 builtin = 4;
|
|
120
|
+
uint32 user = 5;
|
|
121
|
+
uint32 project = 6;
|
|
122
|
+
repeated SkillSnapshot items = 7;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
message SkillSnapshot {
|
|
126
|
+
string name = 1;
|
|
127
|
+
string source = 2;
|
|
128
|
+
string file_path = 3;
|
|
129
|
+
bool enabled = 4;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
message TriggersSnapshot {
|
|
133
|
+
uint32 total = 1;
|
|
134
|
+
uint32 enabled = 2;
|
|
135
|
+
uint32 disabled = 3;
|
|
136
|
+
repeated TriggerRuleSnapshot rules = 4;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
message TriggerRuleSnapshot {
|
|
140
|
+
string id = 1;
|
|
141
|
+
string full_id = 2;
|
|
142
|
+
bool enabled = 3;
|
|
143
|
+
string mode = 4;
|
|
144
|
+
string condition = 5;
|
|
145
|
+
string action = 6;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
message CronSnapshot {
|
|
149
|
+
uint32 total = 1;
|
|
150
|
+
uint32 enabled = 2;
|
|
151
|
+
uint32 disabled = 3;
|
|
152
|
+
repeated CronJobSnapshot jobs = 4;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
message CronJobSnapshot {
|
|
156
|
+
string id = 1;
|
|
157
|
+
bool enabled = 2;
|
|
158
|
+
string schedule = 3;
|
|
159
|
+
string action = 4;
|
|
160
|
+
uint64 skipped_overlap_count = 5;
|
|
161
|
+
optional string last_error = 6;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
message McpSnapshot {
|
|
165
|
+
uint32 servers = 1;
|
|
166
|
+
uint32 tools = 2;
|
|
167
|
+
uint32 notification_hooks = 3;
|
|
168
|
+
repeated string server_names = 4;
|
|
169
|
+
repeated string tool_names = 5;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
message ToolsSnapshot {
|
|
173
|
+
uint32 total = 1;
|
|
174
|
+
repeated string names = 2;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// One renderable feed entry. oneof mirrors the serde tagged enum WireFeedBlock;
|
|
178
|
+
// JSON channels keep serde shape until the protojson migration.
|
|
179
|
+
message FeedBlock {
|
|
180
|
+
oneof kind {
|
|
181
|
+
UserBlock user = 1;
|
|
182
|
+
AssistantBlock assistant = 2;
|
|
183
|
+
ThinkingBlock thinking = 3;
|
|
184
|
+
ToolBlock tool = 4;
|
|
185
|
+
ToolResultBlock tool_result = 5;
|
|
186
|
+
PlainBlock plain = 6;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
message UserBlock {
|
|
191
|
+
string text = 1;
|
|
192
|
+
optional string timestamp = 2;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
message AssistantBlock {
|
|
196
|
+
string text = 1;
|
|
197
|
+
optional string timestamp = 2;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
message ThinkingBlock {
|
|
201
|
+
string text = 1;
|
|
202
|
+
optional string timestamp = 2;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
message ToolBlock {
|
|
206
|
+
string name = 1;
|
|
207
|
+
string args = 2;
|
|
208
|
+
optional string timestamp = 3;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
message ToolResultBlock {
|
|
212
|
+
repeated string lines = 1;
|
|
213
|
+
bool is_error = 2;
|
|
214
|
+
optional string timestamp = 3;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
message PlainBlock {
|
|
218
|
+
string text = 1;
|
|
219
|
+
string level = 2; // "output" | "system" | "error" | "note" (serde snake_case variant names)
|
|
220
|
+
optional string timestamp = 3;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
message SessionSummary {
|
|
224
|
+
string session_id = 1;
|
|
225
|
+
string name = 2;
|
|
226
|
+
string cwd = 3;
|
|
227
|
+
string model = 4;
|
|
228
|
+
string created_at = 5;
|
|
229
|
+
int64 last_activity_at = 6;
|
|
230
|
+
uint32 graph_count = 7;
|
|
231
|
+
uint32 active_graph_count = 8;
|
|
232
|
+
bool busy = 9;
|
|
233
|
+
optional string preview = 10;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
message ListSessionsResponse {
|
|
237
|
+
repeated SessionSummary sessions = 1;
|
|
238
|
+
string current_session_id = 2;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
message CreateSessionRequest {
|
|
242
|
+
optional string name = 1;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
message CreateSessionResponse {
|
|
246
|
+
SessionSummary session = 1;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
message SwitchSessionRequest {
|
|
250
|
+
string session_id = 1;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
message RenameSessionRequest {
|
|
254
|
+
string session_id = 1;
|
|
255
|
+
string name = 2;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
message DeleteSessionRequest {
|
|
259
|
+
string session_id = 1;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
message DeleteSessionResponse {
|
|
263
|
+
// Non-empty = deletion refused, these graphs are still running.
|
|
264
|
+
repeated string running_run_ids = 1;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Daemon path context (issue #68): home / base / work_dir are fixed at daemon
|
|
268
|
+
// startup; skills_dirs reflects the current skill search directories and is
|
|
269
|
+
// the only mutable part (see SetSkillDirs).
|
|
270
|
+
message PathContext {
|
|
271
|
+
string home = 1;
|
|
272
|
+
string base = 2;
|
|
273
|
+
string work_dir = 3;
|
|
274
|
+
repeated string skills_dirs = 4;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
message SetSkillDirsRequest {
|
|
278
|
+
repeated string dirs = 1;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
service SessionService {
|
|
282
|
+
// Full structured state (binary protobuf).
|
|
283
|
+
rpc GetState(Empty) returns (SessionState);
|
|
284
|
+
// Session resources: list (with current marker) / create / switch / rename /
|
|
285
|
+
// delete. DeleteSession reports the offending run ids when refused because
|
|
286
|
+
// the session still has running graphs.
|
|
287
|
+
rpc ListSessions(Empty) returns (ListSessionsResponse);
|
|
288
|
+
rpc CreateSession(CreateSessionRequest) returns (CreateSessionResponse);
|
|
289
|
+
rpc SwitchSession(SwitchSessionRequest) returns (CommandResult);
|
|
290
|
+
rpc RenameSession(RenameSessionRequest) returns (CommandResult);
|
|
291
|
+
rpc DeleteSession(DeleteSessionRequest) returns (DeleteSessionResponse);
|
|
292
|
+
// Daemon path context (issue #68): home/base/work_dir plus the current
|
|
293
|
+
// skill search directories.
|
|
294
|
+
rpc GetPathContext(Empty) returns (PathContext);
|
|
295
|
+
// Replace the extra skill directories dynamically; the command is queued
|
|
296
|
+
// into the event loop, which applies it authoritatively (hot-reload).
|
|
297
|
+
// `accepted` = the command was queued.
|
|
298
|
+
rpc SetSkillDirs(SetSkillDirsRequest) returns (CommandResult);
|
|
299
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Settings domain (issue #72): the daemon configuration surface. Controllers
|
|
2
|
+
// read the daemon's current configuration view (GetConfig) and push partial
|
|
3
|
+
// updates (SetConfig / Configure) that the serialized event loop applies
|
|
4
|
+
// authoritatively.
|
|
5
|
+
|
|
6
|
+
syntax = "proto3";
|
|
7
|
+
package theway.grpc.v1;
|
|
8
|
+
|
|
9
|
+
import "commands.proto";
|
|
10
|
+
|
|
11
|
+
// Daemon configuration snapshot / partial update (issue #72).
|
|
12
|
+
//
|
|
13
|
+
// Update semantics: a present `optional` field replaces the daemon's current
|
|
14
|
+
// value; an absent one keeps it. Non-empty repeated values replace lists.
|
|
15
|
+
// `clear_fields` explicitly clears optional or repeated fields, avoiding
|
|
16
|
+
// proto3's absent-vs-empty ambiguity. When a field is both cleared and set in
|
|
17
|
+
// one request, the set value wins.
|
|
18
|
+
//
|
|
19
|
+
// Covered areas: model selection (provider / model / base_url / thinking),
|
|
20
|
+
// skills (builtin_skills / skills_dirs), triggers (trigger_poll_secs), and
|
|
21
|
+
// TUI display (tui_max_feed_lines). Further config areas (relay,
|
|
22
|
+
// orchestrator, hooks, cron, ...) gain fields here in later phases; field
|
|
23
|
+
// numbers are append-only.
|
|
24
|
+
message DaemonConfig {
|
|
25
|
+
// ── model selection ──
|
|
26
|
+
optional string provider = 1;
|
|
27
|
+
optional string model = 2;
|
|
28
|
+
// Custom provider endpoint URL.
|
|
29
|
+
optional string base_url = 3;
|
|
30
|
+
// Extended-thinking toggle.
|
|
31
|
+
optional bool thinking = 4;
|
|
32
|
+
|
|
33
|
+
// ── skills ──
|
|
34
|
+
// Enabled builtin skill names.
|
|
35
|
+
repeated string builtin_skills = 5;
|
|
36
|
+
// Extra skill search directories (mirrors PathContext.skills_dirs).
|
|
37
|
+
repeated string skills_dirs = 6;
|
|
38
|
+
|
|
39
|
+
// ── triggers ──
|
|
40
|
+
optional uint32 trigger_poll_secs = 7;
|
|
41
|
+
|
|
42
|
+
// ── tui ──
|
|
43
|
+
optional uint32 tui_max_feed_lines = 8;
|
|
44
|
+
|
|
45
|
+
// ── controller tool endpoint (issue #77) ──
|
|
46
|
+
// Address of the controller's ToolService server (host:port). When set, the
|
|
47
|
+
// daemon forwards file/process operations to this endpoint instead of
|
|
48
|
+
// executing them locally.
|
|
49
|
+
optional string tool_service_addr = 9;
|
|
50
|
+
|
|
51
|
+
// ── controller storage endpoint (issue #85) ──
|
|
52
|
+
// Address of the controller's StorageService server (host:port). When set,
|
|
53
|
+
// the daemon uses controller-backed runtime storage (sessions, DAG runs,
|
|
54
|
+
// trigger rules, cron jobs) over RPC instead of local storage directly.
|
|
55
|
+
optional string storage_service_addr = 10;
|
|
56
|
+
|
|
57
|
+
// Field names to clear before applying values present in this message.
|
|
58
|
+
// Unknown names make the daemon reject the patch without partial changes.
|
|
59
|
+
repeated string clear_fields = 11;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
service SettingsService {
|
|
63
|
+
// Current daemon configuration view: only values successfully applied by
|
|
64
|
+
// the serialized daemon event loop. `clear_fields` is empty in snapshots.
|
|
65
|
+
rpc GetConfig(Empty) returns (DaemonConfig);
|
|
66
|
+
// Push a partial configuration update. The command is queued into the
|
|
67
|
+
// serialized event loop, which applies it authoritatively;
|
|
68
|
+
// `accepted` = the command was queued.
|
|
69
|
+
rpc SetConfig(DaemonConfig) returns (CommandResult);
|
|
70
|
+
// Same operation as SetConfig; kept as a distinct method name so the
|
|
71
|
+
// JSON-RPC / WS / MCP surfaces can align on a `configure` verb.
|
|
72
|
+
rpc Configure(DaemonConfig) returns (CommandResult);
|
|
73
|
+
}
|