@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
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# @theway-ai/sdk
|
|
2
|
+
|
|
3
|
+
Typed TypeScript SDK for the **theway** gRPC daemon (`theway --grpc` loopback server).
|
|
4
|
+
Generated from the five domain protos
|
|
5
|
+
([`proto/commands.proto`](proto/commands.proto),
|
|
6
|
+
[`proto/session.proto`](proto/session.proto),
|
|
7
|
+
[`proto/graph_engine.proto`](proto/graph_engine.proto),
|
|
8
|
+
[`proto/events.proto`](proto/events.proto),
|
|
9
|
+
[`proto/settings.proto`](proto/settings.proto)) + [`proto/health.proto`](proto/health.proto)
|
|
10
|
+
via ts-proto + `@grpc/grpc-js` — **no runtime proto loading**, no path magic.
|
|
11
|
+
|
|
12
|
+
`ThewayGrpcClient` routes each RPC to its domain service — `CommandService`,
|
|
13
|
+
`SessionService`, `SettingsService`, `GraphEngineService`, and `EventService` — while
|
|
14
|
+
`HealthClient` covers the standard `grpc.health.v1.Health` service.
|
|
15
|
+
|
|
16
|
+
Published as a public package on the official npm registry (`https://registry.npmjs.org/`).
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
npm install @theway-ai/sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { ThewayGrpcClient, HealthClient } from '@theway-ai/sdk';
|
|
28
|
+
|
|
29
|
+
const client = new ThewayGrpcClient('http://127.0.0.1:34567');
|
|
30
|
+
|
|
31
|
+
// Full session state (typed SessionState)
|
|
32
|
+
const state = await client.getState();
|
|
33
|
+
|
|
34
|
+
// Commands — throw when the server replies accepted: false
|
|
35
|
+
await client.prompt('hello');
|
|
36
|
+
await client.setModelSpec('anthropic:claude-sonnet-4-5');
|
|
37
|
+
await client.abort();
|
|
38
|
+
await client.resolveControlPlane(true);
|
|
39
|
+
|
|
40
|
+
// Graph / session control
|
|
41
|
+
const { resetNodeIds } = await client.graphRetry('dag-1');
|
|
42
|
+
const sessions = await client.listSessions();
|
|
43
|
+
|
|
44
|
+
// Daemon settings (issue #72) — partial update: only set fields are applied
|
|
45
|
+
const config = await client.getConfig();
|
|
46
|
+
await client.setConfig({ triggerPollSecs: 30, skillsDirs: ['/extra/skills'] });
|
|
47
|
+
|
|
48
|
+
// Snapshot + event stream (StreamFrame oneof: payload.$case === 'snapshot' | 'event')
|
|
49
|
+
await client.streamEvents((frame) => {
|
|
50
|
+
if (frame.payload?.$case === 'snapshot') {
|
|
51
|
+
console.log(frame.payload.snapshot.feedLines?.length);
|
|
52
|
+
}
|
|
53
|
+
}, abortSignal);
|
|
54
|
+
|
|
55
|
+
// Standard gRPC health probe (grpc.health.v1)
|
|
56
|
+
const health = new HealthClient('127.0.0.1:34567');
|
|
57
|
+
const serving = await health.check('');
|
|
58
|
+
|
|
59
|
+
client.close();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Regenerating
|
|
63
|
+
|
|
64
|
+
`crates/theway-transport/proto/` at the repo root is the single source of truth; `proto/*.proto` in this package is a mirror and
|
|
65
|
+
`src/generated/` is regenerated from it. Sync and regenerate with:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
cd ../.. # repo root
|
|
69
|
+
make hooks # once per clone: enable the pre-commit hook
|
|
70
|
+
make sdk-sync # or: bash scripts/sdk-sync.sh
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The enabled pre-commit hook ([`.githooks/pre-commit`](../../.githooks/pre-commit)) runs the sync automatically
|
|
74
|
+
whenever `crates/theway-transport/proto/` changes and stages the regenerated files into the same commit, so the checked-in proto and
|
|
75
|
+
generated client never drift.
|
|
76
|
+
|
|
77
|
+
Manual generation without the Makefile:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
npm install
|
|
81
|
+
npm run gen # protoc (grpc-tools) + ts-proto → src/generated/
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Publishing
|
|
85
|
+
|
|
86
|
+
Publishing to the official npm registry is manual ([`scripts/sdk-publish.sh`](../../scripts/sdk-publish.sh)):
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
cd ../..
|
|
90
|
+
make sdk-publish BUMP=minor ISSUE="#62"
|
|
91
|
+
# 或: bash scripts/sdk-publish.sh minor "#62"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The script verifies the tree is clean and in sync, checks the active npm identity against the official
|
|
95
|
+
registry, bumps the version, publishes with public access, and commits the version bump. Run
|
|
96
|
+
`npm login --registry=https://registry.npmjs.org/` before invoking it; the account must satisfy npm's
|
|
97
|
+
two-factor authentication requirements for publishing.
|
|
98
|
+
|
|
99
|
+
## Versioning
|
|
100
|
+
|
|
101
|
+
The SDK version tracks the theway release that the proto contract was cut from
|
|
102
|
+
(theway v1.0.0 → SDK 1.0.0). Bump together with contract changes.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js';
|
|
2
|
+
import { type CommandResult, type Empty, type SendMessageRequest } from './generated/commands.js';
|
|
3
|
+
import { type StreamFrame } from './generated/events.js';
|
|
4
|
+
import { type DecideExtensionTrustRequest, type DecideExtensionTrustResponse, type ExtensionCommandOutcome, type ExtensionSnapshot, type InvokeExtensionCommandRequest, type ReloadExtensionsRequest, type ReloadExtensionsResponse } from './generated/extensions.js';
|
|
5
|
+
import { type GetNodeOutputRequest, type GetNodeOutputResponse, type GraphCheckpointRequest, type GraphCheckpointResponse, type GraphListResponse, type GraphRestoreResponse, type GraphRetryResponse, type GraphSkipResponse } from './generated/graph_engine.js';
|
|
6
|
+
import { type CreateSessionRequest, type CreateSessionResponse, type DeleteSessionRequest, type DeleteSessionResponse, type ListSessionsResponse, type RenameSessionRequest, type SessionState } from './generated/session.js';
|
|
7
|
+
import { type DaemonConfig } from './generated/settings.js';
|
|
8
|
+
import { type EditFileRequest, type EditFileResponse, type ExecCommandRequest, type FindRequest, type FindResponse, type GrepRequest, type GrepResponse, type ListDirRequest, type ListDirResponse, type MemoryForgetRequest, type MemoryForgetResponse, type MemoryListRequest, type MemoryListResponse, type MemoryReadRequest, type MemoryReadResponse, type MemorySaveRequest, type MemorySaveResponse, type ReadFileRequest, type ReadFileResponse, type SkillInstallRequest, type SkillInstallResponse, type WriteFileRequest, type WriteFileResponse } from './generated/tools.js';
|
|
9
|
+
import { type LoadCronJobsRequest, type LoadCronJobsResponse, type LoadDagRunsRequest, type LoadDagRunsResponse, type LoadTriggerRulesRequest, type LoadTriggerRulesResponse, type SaveCronJobsRequest, type SaveCronJobsResponse, type SaveDagRunRequest, type SaveDagRunResponse, type SaveTriggerRulesRequest, type SaveTriggerRulesResponse } from './generated/state.js';
|
|
10
|
+
/**
|
|
11
|
+
* Typed gRPC client for the `theway --grpc` loopback server
|
|
12
|
+
* (theway.grpc.v1.CommandService / SessionService / SettingsService /
|
|
13
|
+
* ExtensionService / ToolService / StorageService / GraphEngineService /
|
|
14
|
+
* EventService).
|
|
15
|
+
* Generated from the domain proto files
|
|
16
|
+
* and health.proto (ts-proto + @grpc/grpc-js) — no runtime proto loading.
|
|
17
|
+
*
|
|
18
|
+
* Command RPCs (SendMessage / SetModel / …) resolve the raw CommandResult;
|
|
19
|
+
* the convenience wrappers (`prompt`, `setModelSpec`, `abort`, …) throw when
|
|
20
|
+
* the server replies `accepted: false`, mirroring the caller-side contract of
|
|
21
|
+
* the JSON channels.
|
|
22
|
+
*/
|
|
23
|
+
export declare class ThewayGrpcClient {
|
|
24
|
+
#private;
|
|
25
|
+
constructor(baseUrl: string, credentials?: grpc.ChannelCredentials);
|
|
26
|
+
/** `GetState` — the latest full session state. */
|
|
27
|
+
getState(): Promise<SessionState>;
|
|
28
|
+
/** `GetNodeOutput` — a DAG node's output fragment from an offset. */
|
|
29
|
+
getNodeOutput(request: GetNodeOutputRequest): Promise<GetNodeOutputResponse>;
|
|
30
|
+
/** `SendMessage` — submit a user prompt (mode=QUEUE). */
|
|
31
|
+
prompt(text: string, images?: SendMessageRequest['images']): Promise<void>;
|
|
32
|
+
/** `SendMessage` — raw request (mode=INTERRUPT supported). */
|
|
33
|
+
sendMessage(request: SendMessageRequest): Promise<CommandResult>;
|
|
34
|
+
/** `SetModel` — switch model with a composed `provider:model` spec. */
|
|
35
|
+
setModelSpec(spec: string): Promise<void>;
|
|
36
|
+
/** `SetModel` with `provider` + `model` (composed into `provider:model`). */
|
|
37
|
+
setModel(provider: string, model: string): Promise<void>;
|
|
38
|
+
/** `Cancel` — stop the in-flight turn (same as local Ctrl-C). */
|
|
39
|
+
abort(): Promise<void>;
|
|
40
|
+
/** `Approve` — resolve the pending control-plane approval (approve / reject). */
|
|
41
|
+
resolveControlPlane(approve: boolean): Promise<void>;
|
|
42
|
+
/** Structured extension catalog, redacted diagnostics and contributions. */
|
|
43
|
+
getExtensions(): Promise<ExtensionSnapshot>;
|
|
44
|
+
/** Invoke a registered extension command in either interactive or headless mode. */
|
|
45
|
+
invokeExtensionCommand(request: InvokeExtensionCommandRequest): Promise<ExtensionCommandOutcome>;
|
|
46
|
+
/** Re-discover extensions; active work may return `status=pending`. */
|
|
47
|
+
reloadExtensions(request?: ReloadExtensionsRequest): Promise<ReloadExtensionsResponse>;
|
|
48
|
+
/** Persist a project or exact-package trust decision and request reload. */
|
|
49
|
+
decideExtensionTrust(request: DecideExtensionTrustRequest): Promise<DecideExtensionTrustResponse>;
|
|
50
|
+
/** `GraphCancel` — cancel a run. */
|
|
51
|
+
graphCancel(runId: string): Promise<void>;
|
|
52
|
+
/** `GraphRetry` — re-run failed/cancelled nodes (omitted nodeId = all). */
|
|
53
|
+
graphRetry(runId: string, nodeId?: string): Promise<GraphRetryResponse>;
|
|
54
|
+
/** `GraphSkip` — skip a node (counts as success for downstream). */
|
|
55
|
+
graphSkip(runId: string, nodeId: string): Promise<GraphSkipResponse>;
|
|
56
|
+
/** `GraphNodeInterrupt` — stop the node's in-flight turn. */
|
|
57
|
+
graphNodeInterrupt(runId: string, nodeId: string): Promise<void>;
|
|
58
|
+
/** `GraphNodeSteer` — queue a steering message at the node's next turn boundary. */
|
|
59
|
+
graphNodeSteer(runId: string, nodeId: string, text: string): Promise<void>;
|
|
60
|
+
/** `GraphCheckpoint` — export run snapshots as portable JSON. */
|
|
61
|
+
graphCheckpoint(request?: GraphCheckpointRequest): Promise<GraphCheckpointResponse>;
|
|
62
|
+
/** `GraphRestore` — revive a run from a GraphCheckpoint snapshot. */
|
|
63
|
+
graphRestore(sessionId: string, snapshot: string): Promise<GraphRestoreResponse>;
|
|
64
|
+
/** `GraphList` — enumerate one session's graph runs. */
|
|
65
|
+
graphList(sessionId: string): Promise<GraphListResponse>;
|
|
66
|
+
/** `ListSessions` — all sessions (live + archived) with the current one marked. */
|
|
67
|
+
listSessions(): Promise<ListSessionsResponse>;
|
|
68
|
+
/** `CreateSession` — create a session. */
|
|
69
|
+
createSession(name?: string): Promise<CreateSessionResponse>;
|
|
70
|
+
/** `SwitchSession` — switch the live session. */
|
|
71
|
+
switchSession(sessionId: string): Promise<void>;
|
|
72
|
+
/** `RenameSession` — rename a session. */
|
|
73
|
+
renameSession(sessionId: string, name: string): Promise<void>;
|
|
74
|
+
/** `DeleteSession` — delete a session (refused while graphs are running). */
|
|
75
|
+
deleteSession(sessionId: string): Promise<DeleteSessionResponse>;
|
|
76
|
+
/** `GetConfig` — the daemon's current configuration view. */
|
|
77
|
+
getConfig(): Promise<DaemonConfig>;
|
|
78
|
+
/**
|
|
79
|
+
* `SetConfig` — push a partial configuration update. Absent fields keep
|
|
80
|
+
* the daemon's current value (repeated fields default to empty = no-op).
|
|
81
|
+
*/
|
|
82
|
+
setConfig(config: Partial<DaemonConfig>): Promise<void>;
|
|
83
|
+
/** `Configure` — alias of `setConfig` (JSON-RPC / WS / MCP verb alignment). */
|
|
84
|
+
configure(config: Partial<DaemonConfig>): Promise<void>;
|
|
85
|
+
/** `ReadFile` — read a file with line pagination. */
|
|
86
|
+
toolRead(request: ReadFileRequest): Promise<ReadFileResponse>;
|
|
87
|
+
/** `WriteFile` — write a file. */
|
|
88
|
+
toolWrite(request: WriteFileRequest): Promise<WriteFileResponse>;
|
|
89
|
+
/** `EditFile` — search-and-replace edit. */
|
|
90
|
+
toolEdit(request: EditFileRequest): Promise<EditFileResponse>;
|
|
91
|
+
/** `ExecCommand` — streaming shell execution. */
|
|
92
|
+
toolExec(request: ExecCommandRequest): grpc.ClientReadableStream<import("./generated/tools.js").ExecOutputFrame>;
|
|
93
|
+
/** `ListDir` — list one directory level. */
|
|
94
|
+
toolListDir(request: ListDirRequest): Promise<ListDirResponse>;
|
|
95
|
+
/** `Grep` — regex content search. */
|
|
96
|
+
toolGrep(request: GrepRequest): Promise<GrepResponse>;
|
|
97
|
+
/** `Find` — filename-glob search. */
|
|
98
|
+
toolFind(request: FindRequest): Promise<FindResponse>;
|
|
99
|
+
/** `MemorySave` — save a memory entry. */
|
|
100
|
+
toolMemorySave(request: MemorySaveRequest): Promise<MemorySaveResponse>;
|
|
101
|
+
/** `MemoryList` — list memory entries. */
|
|
102
|
+
toolMemoryList(request: MemoryListRequest): Promise<MemoryListResponse>;
|
|
103
|
+
/** `MemoryRead` — read one memory entry. */
|
|
104
|
+
toolMemoryRead(request: MemoryReadRequest): Promise<MemoryReadResponse>;
|
|
105
|
+
/** `MemoryForget` — forget a memory entry. */
|
|
106
|
+
toolMemoryForget(request: MemoryForgetRequest): Promise<MemoryForgetResponse>;
|
|
107
|
+
/** `SkillInstall` — two-phase skill install. */
|
|
108
|
+
toolSkillInstall(request: SkillInstallRequest): Promise<SkillInstallResponse>;
|
|
109
|
+
/** `StorageService.ListSessions` — session list from external storage. */
|
|
110
|
+
stateListSessions(request: Empty): Promise<import('./generated/session.js').ListSessionsResponse>;
|
|
111
|
+
/** `StorageService.CreateSession` — create a session in external storage. */
|
|
112
|
+
stateCreateSession(request: CreateSessionRequest): Promise<CreateSessionResponse>;
|
|
113
|
+
/** `StorageService.RenameSession` — rename a session in external storage. */
|
|
114
|
+
stateRenameSession(request: RenameSessionRequest): Promise<CommandResult>;
|
|
115
|
+
/** `StorageService.DeleteSession` — delete a session in external storage. */
|
|
116
|
+
stateDeleteSession(request: DeleteSessionRequest): Promise<DeleteSessionResponse>;
|
|
117
|
+
/** `StorageService.SaveDagRun` — persist a DAG run. */
|
|
118
|
+
stateSaveDagRun(request: SaveDagRunRequest): Promise<SaveDagRunResponse>;
|
|
119
|
+
/** `StorageService.LoadDagRuns` — load persisted DAG runs. */
|
|
120
|
+
stateLoadDagRuns(request: LoadDagRunsRequest): Promise<LoadDagRunsResponse>;
|
|
121
|
+
/** `StorageService.SaveTriggerRules` — persist trigger rules. */
|
|
122
|
+
stateSaveTriggerRules(request: SaveTriggerRulesRequest): Promise<SaveTriggerRulesResponse>;
|
|
123
|
+
/** `StorageService.LoadTriggerRules` — load persisted trigger rules. */
|
|
124
|
+
stateLoadTriggerRules(request: LoadTriggerRulesRequest): Promise<LoadTriggerRulesResponse>;
|
|
125
|
+
/** `StorageService.SaveCronJobs` — persist cron jobs. */
|
|
126
|
+
stateSaveCronJobs(request: SaveCronJobsRequest): Promise<SaveCronJobsResponse>;
|
|
127
|
+
/** `StorageService.LoadCronJobs` — load persisted cron jobs. */
|
|
128
|
+
stateLoadCronJobs(request: LoadCronJobsRequest): Promise<LoadCronJobsResponse>;
|
|
129
|
+
/**
|
|
130
|
+
* `StreamEvents` — server-streaming snapshot/event frames. Every frame
|
|
131
|
+
* (snapshot and event) is delivered to `onFrame`. Resolves when the stream
|
|
132
|
+
* ends normally; rejects on transport errors or when the client is closed.
|
|
133
|
+
*/
|
|
134
|
+
streamEvents(onFrame: (frame: StreamFrame) => void, signal?: AbortSignal): Promise<void>;
|
|
135
|
+
/** Close the underlying channel; in-flight streams fail fast. */
|
|
136
|
+
close(): void;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js';
|
|
2
|
+
import { CommandServiceClient as CommandServiceClientCtor, MessageMode, } from './generated/commands.js';
|
|
3
|
+
import { EventServiceClient as EventServiceClientCtor, } from './generated/events.js';
|
|
4
|
+
import { ExtensionServiceClient as ExtensionServiceClientCtor, } from './generated/extensions.js';
|
|
5
|
+
import { GraphEngineServiceClient as GraphEngineServiceClientCtor, } from './generated/graph_engine.js';
|
|
6
|
+
import { SessionServiceClient as SessionServiceClientCtor, } from './generated/session.js';
|
|
7
|
+
import { SettingsServiceClient as SettingsServiceClientCtor, } from './generated/settings.js';
|
|
8
|
+
import { ToolServiceClient as ToolServiceClientCtor, } from './generated/tools.js';
|
|
9
|
+
import { StorageServiceClient as StorageServiceClientCtor, } from './generated/state.js';
|
|
10
|
+
// ── authority cleaning ──
|
|
11
|
+
const SCHEME_PREFIX = /^https?:\/\//;
|
|
12
|
+
const TRAILING_SLASHES = /\/+$/;
|
|
13
|
+
/**
|
|
14
|
+
* Typed gRPC client for the `theway --grpc` loopback server
|
|
15
|
+
* (theway.grpc.v1.CommandService / SessionService / SettingsService /
|
|
16
|
+
* ExtensionService / ToolService / StorageService / GraphEngineService /
|
|
17
|
+
* EventService).
|
|
18
|
+
* Generated from the domain proto files
|
|
19
|
+
* and health.proto (ts-proto + @grpc/grpc-js) — no runtime proto loading.
|
|
20
|
+
*
|
|
21
|
+
* Command RPCs (SendMessage / SetModel / …) resolve the raw CommandResult;
|
|
22
|
+
* the convenience wrappers (`prompt`, `setModelSpec`, `abort`, …) throw when
|
|
23
|
+
* the server replies `accepted: false`, mirroring the caller-side contract of
|
|
24
|
+
* the JSON channels.
|
|
25
|
+
*/
|
|
26
|
+
export class ThewayGrpcClient {
|
|
27
|
+
#session;
|
|
28
|
+
#command;
|
|
29
|
+
#extensions;
|
|
30
|
+
#graph;
|
|
31
|
+
#events;
|
|
32
|
+
#settings;
|
|
33
|
+
#tools;
|
|
34
|
+
#storage;
|
|
35
|
+
constructor(baseUrl, credentials = grpc.credentials.createInsecure()) {
|
|
36
|
+
const authority = baseUrl.replace(SCHEME_PREFIX, '').replace(TRAILING_SLASHES, '');
|
|
37
|
+
this.#session = new SessionServiceClientCtor(authority, credentials);
|
|
38
|
+
this.#command = new CommandServiceClientCtor(authority, credentials);
|
|
39
|
+
this.#extensions = new ExtensionServiceClientCtor(authority, credentials);
|
|
40
|
+
this.#graph = new GraphEngineServiceClientCtor(authority, credentials);
|
|
41
|
+
this.#events = new EventServiceClientCtor(authority, credentials);
|
|
42
|
+
this.#settings = new SettingsServiceClientCtor(authority, credentials);
|
|
43
|
+
this.#tools = new ToolServiceClientCtor(authority, credentials);
|
|
44
|
+
this.#storage = new StorageServiceClientCtor(authority, credentials);
|
|
45
|
+
}
|
|
46
|
+
// ── session state ──
|
|
47
|
+
/** `GetState` — the latest full session state. */
|
|
48
|
+
getState() {
|
|
49
|
+
return this.#call(this.#session.getState.bind(this.#session), 'GetState', {});
|
|
50
|
+
}
|
|
51
|
+
/** `GetNodeOutput` — a DAG node's output fragment from an offset. */
|
|
52
|
+
getNodeOutput(request) {
|
|
53
|
+
return this.#call(this.#graph.getNodeOutput.bind(this.#graph), 'GetNodeOutput', request);
|
|
54
|
+
}
|
|
55
|
+
// ── commands ──
|
|
56
|
+
/** `SendMessage` — submit a user prompt (mode=QUEUE). */
|
|
57
|
+
async prompt(text, images = []) {
|
|
58
|
+
const request = { text, images, mode: MessageMode.QUEUE };
|
|
59
|
+
const result = await this.sendMessage(request);
|
|
60
|
+
if (!result.accepted) {
|
|
61
|
+
throw new Error('theway grpc: SendMessage was not accepted by the server');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** `SendMessage` — raw request (mode=INTERRUPT supported). */
|
|
65
|
+
sendMessage(request) {
|
|
66
|
+
return this.#call(this.#command.sendMessage.bind(this.#command), 'SendMessage', request);
|
|
67
|
+
}
|
|
68
|
+
/** `SetModel` — switch model with a composed `provider:model` spec. */
|
|
69
|
+
async setModelSpec(spec) {
|
|
70
|
+
const request = { spec };
|
|
71
|
+
const result = await this.#call(this.#command.setModel.bind(this.#command), 'SetModel', request);
|
|
72
|
+
if (!result.accepted) {
|
|
73
|
+
throw new Error('theway grpc: SetModel was not accepted by the server');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/** `SetModel` with `provider` + `model` (composed into `provider:model`). */
|
|
77
|
+
setModel(provider, model) {
|
|
78
|
+
return this.setModelSpec(`${provider}:${model}`);
|
|
79
|
+
}
|
|
80
|
+
/** `Cancel` — stop the in-flight turn (same as local Ctrl-C). */
|
|
81
|
+
async abort() {
|
|
82
|
+
const result = await this.#call(this.#command.cancel.bind(this.#command), 'Cancel', {});
|
|
83
|
+
if (!result.accepted) {
|
|
84
|
+
throw new Error('theway grpc: Cancel was not accepted by the server');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** `Approve` — resolve the pending control-plane approval (approve / reject). */
|
|
88
|
+
async resolveControlPlane(approve) {
|
|
89
|
+
const request = { approve };
|
|
90
|
+
const result = await this.#call(this.#command.approve.bind(this.#command), 'Approve', request);
|
|
91
|
+
if (!result.accepted) {
|
|
92
|
+
throw new Error('theway grpc: Approve was not accepted by the server');
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// ── runtime extensions ──
|
|
96
|
+
/** Structured extension catalog, redacted diagnostics and contributions. */
|
|
97
|
+
getExtensions() {
|
|
98
|
+
return this.#call(this.#extensions.getExtensions.bind(this.#extensions), 'GetExtensions', {});
|
|
99
|
+
}
|
|
100
|
+
/** Invoke a registered extension command in either interactive or headless mode. */
|
|
101
|
+
invokeExtensionCommand(request) {
|
|
102
|
+
return this.#call(this.#extensions.invokeCommand.bind(this.#extensions), 'InvokeExtensionCommand', request);
|
|
103
|
+
}
|
|
104
|
+
/** Re-discover extensions; active work may return `status=pending`. */
|
|
105
|
+
reloadExtensions(request = { cancelActive: false }) {
|
|
106
|
+
return this.#call(this.#extensions.reload.bind(this.#extensions), 'ReloadExtensions', request);
|
|
107
|
+
}
|
|
108
|
+
/** Persist a project or exact-package trust decision and request reload. */
|
|
109
|
+
decideExtensionTrust(request) {
|
|
110
|
+
return this.#call(this.#extensions.decideTrust.bind(this.#extensions), 'DecideExtensionTrust', request);
|
|
111
|
+
}
|
|
112
|
+
// ── graph control (DAG + goal runs) ──
|
|
113
|
+
/** `GraphCancel` — cancel a run. */
|
|
114
|
+
async graphCancel(runId) {
|
|
115
|
+
const request = { runId };
|
|
116
|
+
const result = await this.#call(this.#graph.graphCancel.bind(this.#graph), 'GraphCancel', request);
|
|
117
|
+
if (!result.accepted) {
|
|
118
|
+
throw new Error('theway grpc: GraphCancel was not accepted by the server');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** `GraphRetry` — re-run failed/cancelled nodes (omitted nodeId = all). */
|
|
122
|
+
graphRetry(runId, nodeId) {
|
|
123
|
+
const request = { runId, nodeId };
|
|
124
|
+
return this.#call(this.#graph.graphRetry.bind(this.#graph), 'GraphRetry', request);
|
|
125
|
+
}
|
|
126
|
+
/** `GraphSkip` — skip a node (counts as success for downstream). */
|
|
127
|
+
graphSkip(runId, nodeId) {
|
|
128
|
+
const request = { runId, nodeId };
|
|
129
|
+
return this.#call(this.#graph.graphSkip.bind(this.#graph), 'GraphSkip', request);
|
|
130
|
+
}
|
|
131
|
+
/** `GraphNodeInterrupt` — stop the node's in-flight turn. */
|
|
132
|
+
async graphNodeInterrupt(runId, nodeId) {
|
|
133
|
+
const request = { runId, nodeId };
|
|
134
|
+
const result = await this.#call(this.#graph.graphNodeInterrupt.bind(this.#graph), 'GraphNodeInterrupt', request);
|
|
135
|
+
if (!result.accepted) {
|
|
136
|
+
throw new Error('theway grpc: GraphNodeInterrupt was not accepted by the server');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/** `GraphNodeSteer` — queue a steering message at the node's next turn boundary. */
|
|
140
|
+
async graphNodeSteer(runId, nodeId, text) {
|
|
141
|
+
const request = { runId, nodeId, text };
|
|
142
|
+
const result = await this.#call(this.#graph.graphNodeSteer.bind(this.#graph), 'GraphNodeSteer', request);
|
|
143
|
+
if (!result.accepted) {
|
|
144
|
+
throw new Error('theway grpc: GraphNodeSteer was not accepted by the server');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/** `GraphCheckpoint` — export run snapshots as portable JSON. */
|
|
148
|
+
graphCheckpoint(request = {}) {
|
|
149
|
+
return this.#call(this.#graph.graphCheckpoint.bind(this.#graph), 'GraphCheckpoint', request);
|
|
150
|
+
}
|
|
151
|
+
/** `GraphRestore` — revive a run from a GraphCheckpoint snapshot. */
|
|
152
|
+
graphRestore(sessionId, snapshot) {
|
|
153
|
+
const request = { sessionId, snapshot };
|
|
154
|
+
return this.#call(this.#graph.graphRestore.bind(this.#graph), 'GraphRestore', request);
|
|
155
|
+
}
|
|
156
|
+
/** `GraphList` — enumerate one session's graph runs. */
|
|
157
|
+
graphList(sessionId) {
|
|
158
|
+
const request = { sessionId };
|
|
159
|
+
return this.#call(this.#graph.graphList.bind(this.#graph), 'GraphList', request);
|
|
160
|
+
}
|
|
161
|
+
// ── session resources ──
|
|
162
|
+
/** `ListSessions` — all sessions (live + archived) with the current one marked. */
|
|
163
|
+
listSessions() {
|
|
164
|
+
return this.#call(this.#session.listSessions.bind(this.#session), 'ListSessions', {});
|
|
165
|
+
}
|
|
166
|
+
/** `CreateSession` — create a session. */
|
|
167
|
+
createSession(name) {
|
|
168
|
+
const request = { name };
|
|
169
|
+
return this.#call(this.#session.createSession.bind(this.#session), 'CreateSession', request);
|
|
170
|
+
}
|
|
171
|
+
/** `SwitchSession` — switch the live session. */
|
|
172
|
+
async switchSession(sessionId) {
|
|
173
|
+
const request = { sessionId };
|
|
174
|
+
const result = await this.#call(this.#session.switchSession.bind(this.#session), 'SwitchSession', request);
|
|
175
|
+
if (!result.accepted) {
|
|
176
|
+
throw new Error('theway grpc: SwitchSession was not accepted by the server');
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/** `RenameSession` — rename a session. */
|
|
180
|
+
async renameSession(sessionId, name) {
|
|
181
|
+
const request = { sessionId, name };
|
|
182
|
+
const result = await this.#call(this.#session.renameSession.bind(this.#session), 'RenameSession', request);
|
|
183
|
+
if (!result.accepted) {
|
|
184
|
+
throw new Error('theway grpc: RenameSession was not accepted by the server');
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/** `DeleteSession` — delete a session (refused while graphs are running). */
|
|
188
|
+
deleteSession(sessionId) {
|
|
189
|
+
const request = { sessionId };
|
|
190
|
+
return this.#call(this.#session.deleteSession.bind(this.#session), 'DeleteSession', request);
|
|
191
|
+
}
|
|
192
|
+
// ── settings / config ──
|
|
193
|
+
/** `GetConfig` — the daemon's current configuration view. */
|
|
194
|
+
getConfig() {
|
|
195
|
+
return this.#call(this.#settings.getConfig.bind(this.#settings), 'GetConfig', {});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* `SetConfig` — push a partial configuration update. Absent fields keep
|
|
199
|
+
* the daemon's current value (repeated fields default to empty = no-op).
|
|
200
|
+
*/
|
|
201
|
+
async setConfig(config) {
|
|
202
|
+
const result = await this.#call(this.#settings.setConfig.bind(this.#settings), 'SetConfig', fillDaemonConfig(config));
|
|
203
|
+
if (!result.accepted) {
|
|
204
|
+
throw new Error('theway grpc: SetConfig was not accepted by the server');
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/** `Configure` — alias of `setConfig` (JSON-RPC / WS / MCP verb alignment). */
|
|
208
|
+
async configure(config) {
|
|
209
|
+
const result = await this.#call(this.#settings.configure.bind(this.#settings), 'Configure', fillDaemonConfig(config));
|
|
210
|
+
if (!result.accepted) {
|
|
211
|
+
throw new Error('theway grpc: Configure was not accepted by the server');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
// ── tool operations ──
|
|
215
|
+
/** `ReadFile` — read a file with line pagination. */
|
|
216
|
+
toolRead(request) {
|
|
217
|
+
return this.#call(this.#tools.readFile.bind(this.#tools), 'ReadFile', request);
|
|
218
|
+
}
|
|
219
|
+
/** `WriteFile` — write a file. */
|
|
220
|
+
toolWrite(request) {
|
|
221
|
+
return this.#call(this.#tools.writeFile.bind(this.#tools), 'WriteFile', request);
|
|
222
|
+
}
|
|
223
|
+
/** `EditFile` — search-and-replace edit. */
|
|
224
|
+
toolEdit(request) {
|
|
225
|
+
return this.#call(this.#tools.editFile.bind(this.#tools), 'EditFile', request);
|
|
226
|
+
}
|
|
227
|
+
/** `ExecCommand` — streaming shell execution. */
|
|
228
|
+
toolExec(request) {
|
|
229
|
+
return this.#tools.execCommand(request);
|
|
230
|
+
}
|
|
231
|
+
/** `ListDir` — list one directory level. */
|
|
232
|
+
toolListDir(request) {
|
|
233
|
+
return this.#call(this.#tools.listDir.bind(this.#tools), 'ListDir', request);
|
|
234
|
+
}
|
|
235
|
+
/** `Grep` — regex content search. */
|
|
236
|
+
toolGrep(request) {
|
|
237
|
+
return this.#call(this.#tools.grep.bind(this.#tools), 'Grep', request);
|
|
238
|
+
}
|
|
239
|
+
/** `Find` — filename-glob search. */
|
|
240
|
+
toolFind(request) {
|
|
241
|
+
return this.#call(this.#tools.find.bind(this.#tools), 'Find', request);
|
|
242
|
+
}
|
|
243
|
+
/** `MemorySave` — save a memory entry. */
|
|
244
|
+
toolMemorySave(request) {
|
|
245
|
+
return this.#call(this.#tools.memorySave.bind(this.#tools), 'MemorySave', request);
|
|
246
|
+
}
|
|
247
|
+
/** `MemoryList` — list memory entries. */
|
|
248
|
+
toolMemoryList(request) {
|
|
249
|
+
return this.#call(this.#tools.memoryList.bind(this.#tools), 'MemoryList', request);
|
|
250
|
+
}
|
|
251
|
+
/** `MemoryRead` — read one memory entry. */
|
|
252
|
+
toolMemoryRead(request) {
|
|
253
|
+
return this.#call(this.#tools.memoryRead.bind(this.#tools), 'MemoryRead', request);
|
|
254
|
+
}
|
|
255
|
+
/** `MemoryForget` — forget a memory entry. */
|
|
256
|
+
toolMemoryForget(request) {
|
|
257
|
+
return this.#call(this.#tools.memoryForget.bind(this.#tools), 'MemoryForget', request);
|
|
258
|
+
}
|
|
259
|
+
/** `SkillInstall` — two-phase skill install. */
|
|
260
|
+
toolSkillInstall(request) {
|
|
261
|
+
return this.#call(this.#tools.skillInstall.bind(this.#tools), 'SkillInstall', request);
|
|
262
|
+
}
|
|
263
|
+
// ── runtime state storage ──
|
|
264
|
+
/** `StorageService.ListSessions` — session list from external storage. */
|
|
265
|
+
stateListSessions(request) {
|
|
266
|
+
return this.#call(this.#storage.listSessions.bind(this.#storage), 'ListSessions', request);
|
|
267
|
+
}
|
|
268
|
+
/** `StorageService.CreateSession` — create a session in external storage. */
|
|
269
|
+
stateCreateSession(request) {
|
|
270
|
+
return this.#call(this.#storage.createSession.bind(this.#storage), 'CreateSession', request);
|
|
271
|
+
}
|
|
272
|
+
/** `StorageService.RenameSession` — rename a session in external storage. */
|
|
273
|
+
stateRenameSession(request) {
|
|
274
|
+
return this.#call(this.#storage.renameSession.bind(this.#storage), 'RenameSession', request);
|
|
275
|
+
}
|
|
276
|
+
/** `StorageService.DeleteSession` — delete a session in external storage. */
|
|
277
|
+
stateDeleteSession(request) {
|
|
278
|
+
return this.#call(this.#storage.deleteSession.bind(this.#storage), 'DeleteSession', request);
|
|
279
|
+
}
|
|
280
|
+
/** `StorageService.SaveDagRun` — persist a DAG run. */
|
|
281
|
+
stateSaveDagRun(request) {
|
|
282
|
+
return this.#call(this.#storage.saveDagRun.bind(this.#storage), 'SaveDagRun', request);
|
|
283
|
+
}
|
|
284
|
+
/** `StorageService.LoadDagRuns` — load persisted DAG runs. */
|
|
285
|
+
stateLoadDagRuns(request) {
|
|
286
|
+
return this.#call(this.#storage.loadDagRuns.bind(this.#storage), 'LoadDagRuns', request);
|
|
287
|
+
}
|
|
288
|
+
/** `StorageService.SaveTriggerRules` — persist trigger rules. */
|
|
289
|
+
stateSaveTriggerRules(request) {
|
|
290
|
+
return this.#call(this.#storage.saveTriggerRules.bind(this.#storage), 'SaveTriggerRules', request);
|
|
291
|
+
}
|
|
292
|
+
/** `StorageService.LoadTriggerRules` — load persisted trigger rules. */
|
|
293
|
+
stateLoadTriggerRules(request) {
|
|
294
|
+
return this.#call(this.#storage.loadTriggerRules.bind(this.#storage), 'LoadTriggerRules', request);
|
|
295
|
+
}
|
|
296
|
+
/** `StorageService.SaveCronJobs` — persist cron jobs. */
|
|
297
|
+
stateSaveCronJobs(request) {
|
|
298
|
+
return this.#call(this.#storage.saveCronJobs.bind(this.#storage), 'SaveCronJobs', request);
|
|
299
|
+
}
|
|
300
|
+
/** `StorageService.LoadCronJobs` — load persisted cron jobs. */
|
|
301
|
+
stateLoadCronJobs(request) {
|
|
302
|
+
return this.#call(this.#storage.loadCronJobs.bind(this.#storage), 'LoadCronJobs', request);
|
|
303
|
+
}
|
|
304
|
+
// ── event stream ──
|
|
305
|
+
/**
|
|
306
|
+
* `StreamEvents` — server-streaming snapshot/event frames. Every frame
|
|
307
|
+
* (snapshot and event) is delivered to `onFrame`. Resolves when the stream
|
|
308
|
+
* ends normally; rejects on transport errors or when the client is closed.
|
|
309
|
+
*/
|
|
310
|
+
streamEvents(onFrame, signal) {
|
|
311
|
+
return new Promise((resolve, reject) => {
|
|
312
|
+
const forwardAbort = () => {
|
|
313
|
+
this.#closed = true;
|
|
314
|
+
// Cancel the stream by ending the call
|
|
315
|
+
};
|
|
316
|
+
signal?.addEventListener('abort', forwardAbort, { once: true });
|
|
317
|
+
const stream = this.#events.streamEvents.bind(this.#events)({});
|
|
318
|
+
stream.on('data', (frame) => {
|
|
319
|
+
try {
|
|
320
|
+
onFrame(frame);
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
signal?.removeEventListener('abort', forwardAbort);
|
|
324
|
+
stream.destroy();
|
|
325
|
+
reject(new Error(`theway grpc: StreamEvents handler threw: ${extractErrorMessage(err)}`, { cause: err }));
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
stream.on('end', () => {
|
|
329
|
+
signal?.removeEventListener('abort', forwardAbort);
|
|
330
|
+
resolve();
|
|
331
|
+
});
|
|
332
|
+
stream.on('error', (err) => {
|
|
333
|
+
signal?.removeEventListener('abort', forwardAbort);
|
|
334
|
+
if (this.#closed || signal?.aborted) {
|
|
335
|
+
reject(new Error('theway grpc: StreamEvents aborted by close()'));
|
|
336
|
+
}
|
|
337
|
+
else {
|
|
338
|
+
reject(this.#mapError('StreamEvents', err));
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
/** Close the underlying channel; in-flight streams fail fast. */
|
|
344
|
+
close() {
|
|
345
|
+
this.#closed = true;
|
|
346
|
+
this.#session.close();
|
|
347
|
+
this.#command.close();
|
|
348
|
+
this.#extensions.close();
|
|
349
|
+
this.#graph.close();
|
|
350
|
+
this.#events.close();
|
|
351
|
+
this.#settings.close();
|
|
352
|
+
this.#tools.close();
|
|
353
|
+
this.#storage.close();
|
|
354
|
+
}
|
|
355
|
+
// ── private helpers ──
|
|
356
|
+
#closed = false;
|
|
357
|
+
#call(invoke, method, request) {
|
|
358
|
+
return new Promise((resolve, reject) => {
|
|
359
|
+
invoke(request, (err, response) => {
|
|
360
|
+
if (err) {
|
|
361
|
+
reject(this.#mapError(method, err));
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
resolve(response);
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
#mapError(method, err) {
|
|
369
|
+
return new Error(`theway grpc: ${method} failed: ${err.message}`, { cause: err });
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function extractErrorMessage(err) {
|
|
373
|
+
if (err instanceof Error)
|
|
374
|
+
return err.message;
|
|
375
|
+
return String(err);
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Complete a partial `DaemonConfig` for the wire: ts-proto models proto3
|
|
379
|
+
* repeated fields as required arrays. Empty value arrays mean "keep" while
|
|
380
|
+
* `clearFields` carries explicit clear intent.
|
|
381
|
+
*/
|
|
382
|
+
function fillDaemonConfig(config) {
|
|
383
|
+
return {
|
|
384
|
+
...config,
|
|
385
|
+
builtinSkills: config.builtinSkills ?? [],
|
|
386
|
+
skillsDirs: config.skillsDirs ?? [],
|
|
387
|
+
clearFields: config.clearFields ?? [],
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=client.js.map
|