@plurnk/plurnk-service 0.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/LICENSE +21 -0
- package/README.md +54 -0
- package/SPEC.md +1045 -0
- package/bin/plurnk-service.js +111 -0
- package/dist/core/ChannelWrite.d.ts +40 -0
- package/dist/core/ChannelWrite.d.ts.map +1 -0
- package/dist/core/ChannelWrite.js +49 -0
- package/dist/core/ChannelWrite.js.map +1 -0
- package/dist/core/Db.d.ts +14 -0
- package/dist/core/Db.d.ts.map +1 -0
- package/dist/core/Db.js +7 -0
- package/dist/core/Db.js.map +1 -0
- package/dist/core/Engine.d.ts +107 -0
- package/dist/core/Engine.d.ts.map +1 -0
- package/dist/core/Engine.js +937 -0
- package/dist/core/Engine.js.map +1 -0
- package/dist/core/EnvFlags.d.ts +10 -0
- package/dist/core/EnvFlags.d.ts.map +1 -0
- package/dist/core/EnvFlags.js +82 -0
- package/dist/core/EnvFlags.js.map +1 -0
- package/dist/core/Migrator.d.ts +19 -0
- package/dist/core/Migrator.d.ts.map +1 -0
- package/dist/core/Migrator.js +55 -0
- package/dist/core/Migrator.js.map +1 -0
- package/dist/core/PluginLoader.d.ts +14 -0
- package/dist/core/PluginLoader.d.ts.map +1 -0
- package/dist/core/PluginLoader.js +100 -0
- package/dist/core/PluginLoader.js.map +1 -0
- package/dist/core/ProviderRegistry.d.ts +42 -0
- package/dist/core/ProviderRegistry.d.ts.map +1 -0
- package/dist/core/ProviderRegistry.js +72 -0
- package/dist/core/ProviderRegistry.js.map +1 -0
- package/dist/core/SchemeRegistry.d.ts +13 -0
- package/dist/core/SchemeRegistry.d.ts.map +1 -0
- package/dist/core/SchemeRegistry.js +50 -0
- package/dist/core/SchemeRegistry.js.map +1 -0
- package/dist/core/scheme-types.d.ts +37 -0
- package/dist/core/scheme-types.d.ts.map +1 -0
- package/dist/core/scheme-types.js +9 -0
- package/dist/core/scheme-types.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/Mock.d.ts +43 -0
- package/dist/providers/Mock.d.ts.map +1 -0
- package/dist/providers/Mock.js +36 -0
- package/dist/providers/Mock.js.map +1 -0
- package/dist/schemes/Exec.d.ts +5 -0
- package/dist/schemes/Exec.d.ts.map +1 -0
- package/dist/schemes/Exec.js +20 -0
- package/dist/schemes/Exec.js.map +1 -0
- package/dist/schemes/File.d.ts +35 -0
- package/dist/schemes/File.d.ts.map +1 -0
- package/dist/schemes/File.js +149 -0
- package/dist/schemes/File.js.map +1 -0
- package/dist/schemes/Known.d.ts +19 -0
- package/dist/schemes/Known.d.ts.map +1 -0
- package/dist/schemes/Known.js +44 -0
- package/dist/schemes/Known.js.map +1 -0
- package/dist/schemes/Log.d.ts +13 -0
- package/dist/schemes/Log.d.ts.map +1 -0
- package/dist/schemes/Log.js +38 -0
- package/dist/schemes/Log.js.map +1 -0
- package/dist/schemes/Plurnk.d.ts +5 -0
- package/dist/schemes/Plurnk.d.ts.map +1 -0
- package/dist/schemes/Plurnk.js +15 -0
- package/dist/schemes/Plurnk.js.map +1 -0
- package/dist/schemes/Skill.d.ts +19 -0
- package/dist/schemes/Skill.d.ts.map +1 -0
- package/dist/schemes/Skill.js +46 -0
- package/dist/schemes/Skill.js.map +1 -0
- package/dist/schemes/Unknown.d.ts +19 -0
- package/dist/schemes/Unknown.d.ts.map +1 -0
- package/dist/schemes/Unknown.js +44 -0
- package/dist/schemes/Unknown.js.map +1 -0
- package/dist/schemes/_entry-crud.d.ts +24 -0
- package/dist/schemes/_entry-crud.d.ts.map +1 -0
- package/dist/schemes/_entry-crud.js +56 -0
- package/dist/schemes/_entry-crud.js.map +1 -0
- package/dist/schemes/_entry-find.d.ts +10 -0
- package/dist/schemes/_entry-find.d.ts.map +1 -0
- package/dist/schemes/_entry-find.js +41 -0
- package/dist/schemes/_entry-find.js.map +1 -0
- package/dist/schemes/_entry-ops.d.ts +21 -0
- package/dist/schemes/_entry-ops.d.ts.map +1 -0
- package/dist/schemes/_entry-ops.js +146 -0
- package/dist/schemes/_entry-ops.js.map +1 -0
- package/dist/schemes/_entry-send.d.ts +8 -0
- package/dist/schemes/_entry-send.d.ts.map +1 -0
- package/dist/schemes/_entry-send.js +56 -0
- package/dist/schemes/_entry-send.js.map +1 -0
- package/dist/server/ClientConnection.d.ts +22 -0
- package/dist/server/ClientConnection.d.ts.map +1 -0
- package/dist/server/ClientConnection.js +120 -0
- package/dist/server/ClientConnection.js.map +1 -0
- package/dist/server/Daemon.d.ts +43 -0
- package/dist/server/Daemon.d.ts.map +1 -0
- package/dist/server/Daemon.js +252 -0
- package/dist/server/Daemon.js.map +1 -0
- package/dist/server/MethodRegistry.d.ts +56 -0
- package/dist/server/MethodRegistry.d.ts.map +1 -0
- package/dist/server/MethodRegistry.js +55 -0
- package/dist/server/MethodRegistry.js.map +1 -0
- package/dist/server/clientTurn.d.ts +3 -0
- package/dist/server/clientTurn.d.ts.map +1 -0
- package/dist/server/clientTurn.js +22 -0
- package/dist/server/clientTurn.js.map +1 -0
- package/dist/server/dsl.d.ts +47 -0
- package/dist/server/dsl.d.ts.map +1 -0
- package/dist/server/dsl.js +117 -0
- package/dist/server/dsl.js.map +1 -0
- package/dist/server/envelope.d.ts +44 -0
- package/dist/server/envelope.d.ts.map +1 -0
- package/dist/server/envelope.js +113 -0
- package/dist/server/envelope.js.map +1 -0
- package/dist/server/logEntry.d.ts +30 -0
- package/dist/server/logEntry.d.ts.map +1 -0
- package/dist/server/logEntry.js +43 -0
- package/dist/server/logEntry.js.map +1 -0
- package/dist/server/methods/_dispatchAsClient.d.ts +8 -0
- package/dist/server/methods/_dispatchAsClient.d.ts.map +1 -0
- package/dist/server/methods/_dispatchAsClient.js +31 -0
- package/dist/server/methods/_dispatchAsClient.js.map +1 -0
- package/dist/server/methods/discover.d.ts +3 -0
- package/dist/server/methods/discover.d.ts.map +1 -0
- package/dist/server/methods/discover.js +7 -0
- package/dist/server/methods/discover.js.map +1 -0
- package/dist/server/methods/entry_read.d.ts +3 -0
- package/dist/server/methods/entry_read.d.ts.map +1 -0
- package/dist/server/methods/entry_read.js +56 -0
- package/dist/server/methods/entry_read.js.map +1 -0
- package/dist/server/methods/log_read.d.ts +3 -0
- package/dist/server/methods/log_read.d.ts.map +1 -0
- package/dist/server/methods/log_read.js +39 -0
- package/dist/server/methods/log_read.js.map +1 -0
- package/dist/server/methods/loop_resolve.d.ts +3 -0
- package/dist/server/methods/loop_resolve.d.ts.map +1 -0
- package/dist/server/methods/loop_resolve.js +45 -0
- package/dist/server/methods/loop_resolve.js.map +1 -0
- package/dist/server/methods/loop_run.d.ts +3 -0
- package/dist/server/methods/loop_run.d.ts.map +1 -0
- package/dist/server/methods/loop_run.js +112 -0
- package/dist/server/methods/loop_run.js.map +1 -0
- package/dist/server/methods/op_copy.d.ts +3 -0
- package/dist/server/methods/op_copy.d.ts.map +1 -0
- package/dist/server/methods/op_copy.js +24 -0
- package/dist/server/methods/op_copy.js.map +1 -0
- package/dist/server/methods/op_dispatch.d.ts +3 -0
- package/dist/server/methods/op_dispatch.d.ts.map +1 -0
- package/dist/server/methods/op_dispatch.js +17 -0
- package/dist/server/methods/op_dispatch.js.map +1 -0
- package/dist/server/methods/op_edit.d.ts +3 -0
- package/dist/server/methods/op_edit.d.ts.map +1 -0
- package/dist/server/methods/op_edit.js +22 -0
- package/dist/server/methods/op_edit.js.map +1 -0
- package/dist/server/methods/op_exec.d.ts +3 -0
- package/dist/server/methods/op_exec.d.ts.map +1 -0
- package/dist/server/methods/op_exec.js +19 -0
- package/dist/server/methods/op_exec.js.map +1 -0
- package/dist/server/methods/op_find.d.ts +3 -0
- package/dist/server/methods/op_find.d.ts.map +1 -0
- package/dist/server/methods/op_find.js +22 -0
- package/dist/server/methods/op_find.js.map +1 -0
- package/dist/server/methods/op_hide.d.ts +3 -0
- package/dist/server/methods/op_hide.d.ts.map +1 -0
- package/dist/server/methods/op_hide.js +22 -0
- package/dist/server/methods/op_hide.js.map +1 -0
- package/dist/server/methods/op_move.d.ts +3 -0
- package/dist/server/methods/op_move.d.ts.map +1 -0
- package/dist/server/methods/op_move.js +22 -0
- package/dist/server/methods/op_move.js.map +1 -0
- package/dist/server/methods/op_parse.d.ts +3 -0
- package/dist/server/methods/op_parse.d.ts.map +1 -0
- package/dist/server/methods/op_parse.js +23 -0
- package/dist/server/methods/op_parse.js.map +1 -0
- package/dist/server/methods/op_read.d.ts +3 -0
- package/dist/server/methods/op_read.d.ts.map +1 -0
- package/dist/server/methods/op_read.js +22 -0
- package/dist/server/methods/op_read.js.map +1 -0
- package/dist/server/methods/op_send.d.ts +3 -0
- package/dist/server/methods/op_send.d.ts.map +1 -0
- package/dist/server/methods/op_send.js +21 -0
- package/dist/server/methods/op_send.js.map +1 -0
- package/dist/server/methods/op_show.d.ts +3 -0
- package/dist/server/methods/op_show.d.ts.map +1 -0
- package/dist/server/methods/op_show.js +22 -0
- package/dist/server/methods/op_show.js.map +1 -0
- package/dist/server/methods/ping.d.ts +3 -0
- package/dist/server/methods/ping.d.ts.map +1 -0
- package/dist/server/methods/ping.js +7 -0
- package/dist/server/methods/ping.js.map +1 -0
- package/dist/server/methods/providers_list.d.ts +3 -0
- package/dist/server/methods/providers_list.d.ts.map +1 -0
- package/dist/server/methods/providers_list.js +19 -0
- package/dist/server/methods/providers_list.js.map +1 -0
- package/dist/server/methods/session_attach.d.ts +3 -0
- package/dist/server/methods/session_attach.d.ts.map +1 -0
- package/dist/server/methods/session_attach.js +42 -0
- package/dist/server/methods/session_attach.js.map +1 -0
- package/dist/server/methods/session_create.d.ts +3 -0
- package/dist/server/methods/session_create.d.ts.map +1 -0
- package/dist/server/methods/session_create.js +53 -0
- package/dist/server/methods/session_create.js.map +1 -0
- package/dist/server/methods/session_list.d.ts +3 -0
- package/dist/server/methods/session_list.d.ts.map +1 -0
- package/dist/server/methods/session_list.js +8 -0
- package/dist/server/methods/session_list.js.map +1 -0
- package/dist/server/methods/session_runs.d.ts +3 -0
- package/dist/server/methods/session_runs.d.ts.map +1 -0
- package/dist/server/methods/session_runs.js +18 -0
- package/dist/server/methods/session_runs.js.map +1 -0
- package/dist/server/methods/session_set_persona.d.ts +3 -0
- package/dist/server/methods/session_set_persona.d.ts.map +1 -0
- package/dist/server/methods/session_set_persona.js +27 -0
- package/dist/server/methods/session_set_persona.js.map +1 -0
- package/dist/server/methods/session_set_root.d.ts +3 -0
- package/dist/server/methods/session_set_root.d.ts.map +1 -0
- package/dist/server/methods/session_set_root.js +33 -0
- package/dist/server/methods/session_set_root.js.map +1 -0
- package/dist/server/yolo.d.ts +4 -0
- package/dist/server/yolo.d.ts.map +1 -0
- package/dist/server/yolo.js +48 -0
- package/dist/server/yolo.js.map +1 -0
- package/migrations/001_sessions.sql +11 -0
- package/migrations/002_runs.sql +16 -0
- package/migrations/003_loops.sql +12 -0
- package/migrations/004_turns.sql +18 -0
- package/migrations/005_entries.sql +44 -0
- package/migrations/006_log_entries.sql +51 -0
- package/migrations/007_visibility.sql +10 -0
- package/migrations/008_schemes_providers.sql +25 -0
- package/migrations/009_cost_rollups.sql +44 -0
- package/migrations/010_subscriptions.sql +36 -0
- package/migrations/011_turn_call_metadata.sql +7 -0
- package/migrations/012_proposal_lifecycle.sql +22 -0
- package/migrations/013_log_entries_lifecycle_columns.sql +22 -0
- package/migrations/014_loop_flags.sql +9 -0
- package/migrations/015_sessions_project_root.sql +6 -0
- package/migrations/016_persona_columns.sql +11 -0
- package/package.json +66 -0
- package/persona.md +1 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Per-WebSocket-client JSON-RPC dispatch. One instance per connected client.
|
|
2
|
+
// Owns session attachment state, calls into the engine for auto-create on
|
|
3
|
+
// first requiresInit RPC, closes the client loop on disconnect.
|
|
4
|
+
//
|
|
5
|
+
// SPEC §13.2 (protocol), §13.7 (lifecycle), §13.8 (errors).
|
|
6
|
+
import { createClientEnvelope, closeClientLoop } from "./envelope.js";
|
|
7
|
+
// JSON-RPC 2.0 standard error codes (SPEC §13.8).
|
|
8
|
+
const ERR_PARSE = -32700;
|
|
9
|
+
const ERR_INVALID_REQUEST = -32600;
|
|
10
|
+
const ERR_METHOD_NOT_FOUND = -32601;
|
|
11
|
+
const ERR_INTERNAL = -32603;
|
|
12
|
+
// Plurnk-specific (SPEC §13.8).
|
|
13
|
+
const ERR_NOT_INITIALIZED = -32000;
|
|
14
|
+
export default class ClientConnection {
|
|
15
|
+
#ws;
|
|
16
|
+
#registry;
|
|
17
|
+
#db;
|
|
18
|
+
#engine;
|
|
19
|
+
#provider;
|
|
20
|
+
#broadcast;
|
|
21
|
+
#session = null;
|
|
22
|
+
constructor({ ws, registry, db, engine, provider, broadcast }) {
|
|
23
|
+
this.#ws = ws;
|
|
24
|
+
this.#registry = registry;
|
|
25
|
+
this.#db = db;
|
|
26
|
+
this.#engine = engine;
|
|
27
|
+
this.#provider = provider;
|
|
28
|
+
this.#broadcast = broadcast;
|
|
29
|
+
this.#ws.on("message", (data) => this.#handleMessage(data));
|
|
30
|
+
}
|
|
31
|
+
get session() {
|
|
32
|
+
return this.#session;
|
|
33
|
+
}
|
|
34
|
+
sendNotification(method, params) {
|
|
35
|
+
const notification = { jsonrpc: "2.0", method };
|
|
36
|
+
if (params !== undefined)
|
|
37
|
+
notification.params = params;
|
|
38
|
+
this.#send(notification);
|
|
39
|
+
}
|
|
40
|
+
close() {
|
|
41
|
+
if (this.#session !== null) {
|
|
42
|
+
void closeClientLoop(this.#db, this.#session.clientLoopId, 200);
|
|
43
|
+
this.#session = null;
|
|
44
|
+
}
|
|
45
|
+
if (this.#ws.readyState === 1)
|
|
46
|
+
this.#ws.terminate();
|
|
47
|
+
}
|
|
48
|
+
async #handleMessage(data) {
|
|
49
|
+
let id = null;
|
|
50
|
+
let request;
|
|
51
|
+
try {
|
|
52
|
+
const text = typeof data === "string" ? data : data.toString("utf8");
|
|
53
|
+
request = JSON.parse(text);
|
|
54
|
+
}
|
|
55
|
+
catch (_e) {
|
|
56
|
+
this.#sendError(null, ERR_PARSE, "parse error");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (request.jsonrpc !== "2.0" || typeof request.method !== "string") {
|
|
60
|
+
this.#sendError(request.id ?? null, ERR_INVALID_REQUEST, "invalid request");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
id = request.id ?? null;
|
|
64
|
+
const registration = this.#registry.getMethod(request.method);
|
|
65
|
+
if (registration === undefined) {
|
|
66
|
+
this.#sendError(id, ERR_METHOD_NOT_FOUND, `method '${request.method}' not found`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (registration.requiresInit && this.#session === null) {
|
|
70
|
+
try {
|
|
71
|
+
const envelope = await createClientEnvelope(this.#db, { prefix: "auto" });
|
|
72
|
+
this.#session = envelope;
|
|
73
|
+
this.#broadcast("all", this, "session/created", {
|
|
74
|
+
id: envelope.sessionId,
|
|
75
|
+
name: envelope.sessionName,
|
|
76
|
+
projectRoot: envelope.projectRoot,
|
|
77
|
+
persona: envelope.sessionPersona,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
catch (cause) {
|
|
81
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
82
|
+
this.#sendError(id, ERR_NOT_INITIALIZED, `auto-create envelope failed: ${message}`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const ctx = {
|
|
87
|
+
registry: this.#registry,
|
|
88
|
+
db: this.#db,
|
|
89
|
+
engine: this.#engine,
|
|
90
|
+
provider: this.#provider,
|
|
91
|
+
session: this.#session,
|
|
92
|
+
attachSession: (envelope) => {
|
|
93
|
+
if (this.#session !== null) {
|
|
94
|
+
throw new Error("connection already has a session attached");
|
|
95
|
+
}
|
|
96
|
+
this.#session = envelope;
|
|
97
|
+
},
|
|
98
|
+
notify: (target, method, params) => this.#broadcast(target, this, method, params),
|
|
99
|
+
};
|
|
100
|
+
try {
|
|
101
|
+
const result = await registration.handler(request.params ?? {}, ctx);
|
|
102
|
+
this.#send({ jsonrpc: "2.0", id, result });
|
|
103
|
+
}
|
|
104
|
+
catch (cause) {
|
|
105
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
106
|
+
this.#sendError(id, ERR_INTERNAL, message);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
#sendError(id, code, message, data) {
|
|
110
|
+
const response = { jsonrpc: "2.0", id, error: { code, message } };
|
|
111
|
+
if (data !== undefined && response.error !== undefined)
|
|
112
|
+
response.error.data = data;
|
|
113
|
+
this.#send(response);
|
|
114
|
+
}
|
|
115
|
+
#send(payload) {
|
|
116
|
+
if (this.#ws.readyState === 1)
|
|
117
|
+
this.#ws.send(JSON.stringify(payload));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=ClientConnection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClientConnection.js","sourceRoot":"","sources":["../../src/server/ClientConnection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { Db } from "../core/Db.ts";
|
|
2
|
+
import Engine from "../core/Engine.ts";
|
|
3
|
+
import SchemeRegistry from "../core/SchemeRegistry.ts";
|
|
4
|
+
import { Mimetypes } from "@plurnk/plurnk-mimetypes";
|
|
5
|
+
import MethodRegistry from "./MethodRegistry.ts";
|
|
6
|
+
import type { Provider } from "./MethodRegistry.ts";
|
|
7
|
+
export interface DaemonOptions {
|
|
8
|
+
host?: string;
|
|
9
|
+
port?: number;
|
|
10
|
+
}
|
|
11
|
+
export interface DaemonAddress {
|
|
12
|
+
host: string;
|
|
13
|
+
port: number;
|
|
14
|
+
}
|
|
15
|
+
export default class Daemon {
|
|
16
|
+
#private;
|
|
17
|
+
constructor({ db, schemes, mimetypes, provider, nodeModulesPath, }: {
|
|
18
|
+
db: Db;
|
|
19
|
+
schemes?: SchemeRegistry;
|
|
20
|
+
mimetypes?: Mimetypes;
|
|
21
|
+
provider?: Provider | null;
|
|
22
|
+
nodeModulesPath?: string;
|
|
23
|
+
});
|
|
24
|
+
get registry(): MethodRegistry;
|
|
25
|
+
get engine(): Engine;
|
|
26
|
+
get provider(): Provider | null;
|
|
27
|
+
get schemes(): SchemeRegistry;
|
|
28
|
+
get mimetypes(): Mimetypes;
|
|
29
|
+
start({ host, port }?: DaemonOptions): Promise<DaemonAddress>;
|
|
30
|
+
stop(): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Emit a stream/event notification scoped to the session containing the
|
|
33
|
+
* entry. ChannelWrite helpers (src/core/ChannelWrite.ts) invoke this when
|
|
34
|
+
* they update channel content or state. SPEC §13.6.
|
|
35
|
+
*/
|
|
36
|
+
notifyStreamEvent(sessionId: number, event: {
|
|
37
|
+
entryId: number;
|
|
38
|
+
channel: string;
|
|
39
|
+
state: string;
|
|
40
|
+
contentLength: number;
|
|
41
|
+
}): void;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=Daemon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Daemon.d.ts","sourceRoot":"","sources":["../../src/server/Daemon.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AAExC,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,cAAc,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,OAAO,cAAc,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAgB,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AA6BlE,MAAM,WAAW,aAAa;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,CAAC,OAAO,OAAO,MAAM;;gBAWX,EACR,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,GACpD,EAAE;QACC,EAAE,EAAE,EAAE,CAAC;QACP,OAAO,CAAC,EAAE,cAAc,CAAC;QACzB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;QAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B;IA2CD,IAAI,QAAQ,IAAI,cAAc,CAA2B;IACzD,IAAI,MAAM,IAAI,MAAM,CAAyB;IAC7C,IAAI,QAAQ,IAAI,QAAQ,GAAG,IAAI,CAA2B;IAC1D,IAAI,OAAO,IAAI,cAAc,CAA0B;IACvD,IAAI,SAAS,IAAI,SAAS,CAA4B;IAEhD,KAAK,CAAC,EAAE,IAAkB,EAAE,IAAW,EAAE,GAAE,aAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IA4BtF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAgF3B;;;;OAIG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAmDhI"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// Top-level daemon orchestrator. Owns the DB connection, engine, registries,
|
|
2
|
+
// the WebSocketServer, and the active client connections.
|
|
3
|
+
// SPEC §13.
|
|
4
|
+
import { WebSocketServer } from "ws";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import Engine from "../core/Engine.js";
|
|
7
|
+
import SchemeRegistry from "../core/SchemeRegistry.js";
|
|
8
|
+
import { Mimetypes } from "@plurnk/plurnk-mimetypes";
|
|
9
|
+
import { discoverPlugins, loadPlugin } from "../core/PluginLoader.js";
|
|
10
|
+
import MethodRegistry from "./MethodRegistry.js";
|
|
11
|
+
import ClientConnection from "./ClientConnection.js";
|
|
12
|
+
import { register as registerPing } from "./methods/ping.js";
|
|
13
|
+
import { register as registerDiscover } from "./methods/discover.js";
|
|
14
|
+
import { register as registerSessionCreate } from "./methods/session_create.js";
|
|
15
|
+
import { register as registerSessionList } from "./methods/session_list.js";
|
|
16
|
+
import { register as registerSessionAttach } from "./methods/session_attach.js";
|
|
17
|
+
import { register as registerSessionRuns } from "./methods/session_runs.js";
|
|
18
|
+
import { register as registerSessionSetRoot } from "./methods/session_set_root.js";
|
|
19
|
+
import { register as registerSessionSetPersona } from "./methods/session_set_persona.js";
|
|
20
|
+
import { register as registerOpEdit } from "./methods/op_edit.js";
|
|
21
|
+
import { register as registerOpRead } from "./methods/op_read.js";
|
|
22
|
+
import { register as registerOpFind } from "./methods/op_find.js";
|
|
23
|
+
import { register as registerOpShow } from "./methods/op_show.js";
|
|
24
|
+
import { register as registerOpHide } from "./methods/op_hide.js";
|
|
25
|
+
import { register as registerOpCopy } from "./methods/op_copy.js";
|
|
26
|
+
import { register as registerOpMove } from "./methods/op_move.js";
|
|
27
|
+
import { register as registerOpSend } from "./methods/op_send.js";
|
|
28
|
+
import { register as registerOpExec } from "./methods/op_exec.js";
|
|
29
|
+
import { register as registerOpDispatch } from "./methods/op_dispatch.js";
|
|
30
|
+
import { register as registerOpParse } from "./methods/op_parse.js";
|
|
31
|
+
import { register as registerLoopRun } from "./methods/loop_run.js";
|
|
32
|
+
import { register as registerEntryRead } from "./methods/entry_read.js";
|
|
33
|
+
import { register as registerLogRead } from "./methods/log_read.js";
|
|
34
|
+
import { register as registerProvidersList } from "./methods/providers_list.js";
|
|
35
|
+
import { register as registerLoopResolve } from "./methods/loop_resolve.js";
|
|
36
|
+
import { attachYolo } from "./yolo.js";
|
|
37
|
+
export default class Daemon {
|
|
38
|
+
#db;
|
|
39
|
+
#engine;
|
|
40
|
+
#schemes;
|
|
41
|
+
#mimetypes;
|
|
42
|
+
#provider;
|
|
43
|
+
#registry;
|
|
44
|
+
#nodeModulesPath;
|
|
45
|
+
#wss = null;
|
|
46
|
+
#connections = new Set();
|
|
47
|
+
constructor({ db, schemes, mimetypes, provider, nodeModulesPath, }) {
|
|
48
|
+
this.#db = db;
|
|
49
|
+
this.#schemes = schemes ?? new SchemeRegistry();
|
|
50
|
+
this.#provider = provider ?? null;
|
|
51
|
+
// Mimetypes owns discovery, detection, handler instantiation, and
|
|
52
|
+
// budget-truncated preview rendering. plurnk-service stays mimetype-
|
|
53
|
+
// illiterate — we just inject the tokenize function (sourced from the
|
|
54
|
+
// active provider's countTokens) and configure text/markdown as the
|
|
55
|
+
// default mimetype (LLM output is overwhelmingly markdown; the
|
|
56
|
+
// text-markdown handler is a hard dep so the default actually
|
|
57
|
+
// resolves at runtime).
|
|
58
|
+
this.#mimetypes = mimetypes ?? new Mimetypes({
|
|
59
|
+
tokenize: async (text) => this.#provider?.countTokens(text) ?? Math.ceil(text.length / 4),
|
|
60
|
+
defaultMimetype: "text/markdown",
|
|
61
|
+
});
|
|
62
|
+
this.#engine = new Engine({ db, schemes: this.#schemes, mimetypes: this.#mimetypes });
|
|
63
|
+
this.#nodeModulesPath = nodeModulesPath ?? resolve(process.cwd(), "node_modules");
|
|
64
|
+
this.#registry = new MethodRegistry();
|
|
65
|
+
this.#registerBuiltins();
|
|
66
|
+
this.#registerNotifications();
|
|
67
|
+
// Wire proposal-pending events to the loop/proposal WS notification.
|
|
68
|
+
// Sessionid scopes the broadcast to clients on the same session.
|
|
69
|
+
this.#engine.onProposalPending((event) => {
|
|
70
|
+
this.#broadcast({ sessionId: event.sessionId }, null, "loop/proposal", {
|
|
71
|
+
logEntryId: event.logEntryId,
|
|
72
|
+
loopId: event.loopId,
|
|
73
|
+
turnId: event.turnId,
|
|
74
|
+
op: event.op,
|
|
75
|
+
target: event.target,
|
|
76
|
+
body: event.body,
|
|
77
|
+
attrs: event.attrs,
|
|
78
|
+
// event.flags is carried for discoverability — a client in
|
|
79
|
+
// server-YOLO mode (event.flags.yolo=true) knows to skip
|
|
80
|
+
// rendering review UI because the entry will resolve in-
|
|
81
|
+
// process before any human can react.
|
|
82
|
+
flags: event.flags,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
// In-tree YOLO listener — auto-accepts proposals when the loop's
|
|
86
|
+
// persisted flags.yolo === true. Skips client roundtrip entirely.
|
|
87
|
+
attachYolo(this.#engine, this.#db);
|
|
88
|
+
}
|
|
89
|
+
get registry() { return this.#registry; }
|
|
90
|
+
get engine() { return this.#engine; }
|
|
91
|
+
get provider() { return this.#provider; }
|
|
92
|
+
get schemes() { return this.#schemes; }
|
|
93
|
+
get mimetypes() { return this.#mimetypes; }
|
|
94
|
+
async start({ host = "127.0.0.1", port = 3044 } = {}) {
|
|
95
|
+
if (this.#wss !== null)
|
|
96
|
+
throw new Error("daemon already started");
|
|
97
|
+
await this.#discoverAndLoadPlugins();
|
|
98
|
+
// Mimetypes owns its own discovery scan over @plurnk/plurnk-mimetypes-*
|
|
99
|
+
// packages; pre-warm it so first index render doesn't pay the cost.
|
|
100
|
+
await this.#mimetypes.ready();
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const wss = new WebSocketServer({ host, port });
|
|
103
|
+
wss.on("listening", () => {
|
|
104
|
+
this.#wss = wss;
|
|
105
|
+
wss.on("connection", (ws) => this.#onConnection(ws));
|
|
106
|
+
const addr = wss.address();
|
|
107
|
+
if (addr === null || typeof addr === "string") {
|
|
108
|
+
reject(new Error("WebSocketServer.address() returned unexpected value"));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
resolve({ host: addr.address, port: addr.port });
|
|
112
|
+
});
|
|
113
|
+
wss.on("error", (err) => {
|
|
114
|
+
if (this.#wss === null)
|
|
115
|
+
reject(err);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
async stop() {
|
|
120
|
+
if (this.#wss === null)
|
|
121
|
+
return;
|
|
122
|
+
for (const conn of this.#connections)
|
|
123
|
+
conn.close();
|
|
124
|
+
this.#connections.clear();
|
|
125
|
+
await new Promise((resolve, reject) => {
|
|
126
|
+
this.#wss?.close((err) => {
|
|
127
|
+
if (err !== undefined)
|
|
128
|
+
reject(err);
|
|
129
|
+
else
|
|
130
|
+
resolve();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
this.#wss = null;
|
|
134
|
+
}
|
|
135
|
+
#registerBuiltins() {
|
|
136
|
+
registerPing(this.#registry);
|
|
137
|
+
registerDiscover(this.#registry);
|
|
138
|
+
registerSessionCreate(this.#registry);
|
|
139
|
+
registerSessionList(this.#registry);
|
|
140
|
+
registerSessionAttach(this.#registry);
|
|
141
|
+
registerSessionRuns(this.#registry);
|
|
142
|
+
registerSessionSetRoot(this.#registry);
|
|
143
|
+
registerSessionSetPersona(this.#registry);
|
|
144
|
+
registerOpEdit(this.#registry);
|
|
145
|
+
registerOpRead(this.#registry);
|
|
146
|
+
registerOpFind(this.#registry);
|
|
147
|
+
registerOpShow(this.#registry);
|
|
148
|
+
registerOpHide(this.#registry);
|
|
149
|
+
registerOpCopy(this.#registry);
|
|
150
|
+
registerOpMove(this.#registry);
|
|
151
|
+
registerOpSend(this.#registry);
|
|
152
|
+
registerOpExec(this.#registry);
|
|
153
|
+
registerOpDispatch(this.#registry);
|
|
154
|
+
registerOpParse(this.#registry);
|
|
155
|
+
registerLoopRun(this.#registry);
|
|
156
|
+
registerLoopResolve(this.#registry);
|
|
157
|
+
registerEntryRead(this.#registry);
|
|
158
|
+
registerLogRead(this.#registry);
|
|
159
|
+
registerProvidersList(this.#registry);
|
|
160
|
+
}
|
|
161
|
+
#registerNotifications() {
|
|
162
|
+
this.#registry.registerNotification("log/entry", {
|
|
163
|
+
description: "A new log_entries row was written; scoped to the connection's attached session.",
|
|
164
|
+
params: { entry: "LogEntry — wire-shape log_entries row" },
|
|
165
|
+
});
|
|
166
|
+
this.#registry.registerNotification("loop/proposal", {
|
|
167
|
+
description: "A side-effecting action emitted a proposal (status=202, state='proposed'); dispatch is paused awaiting client resolution via loop.resolve. Scoped to the connection's attached session.",
|
|
168
|
+
params: {
|
|
169
|
+
logEntryId: "number — the log_entries.id awaiting resolution",
|
|
170
|
+
loopId: "number",
|
|
171
|
+
turnId: "number",
|
|
172
|
+
op: "string — the operation (EDIT, EXEC, etc.)",
|
|
173
|
+
target: "{scheme, pathname} — the resource being acted on",
|
|
174
|
+
body: "string — preview body (udiff for file edits, command summary for exec)",
|
|
175
|
+
attrs: "object — scheme-specific payload (patch, command args, etc.); opaque to engine",
|
|
176
|
+
flags: "{yolo, mode, noWeb, noInteraction, noProposals} — loop's persisted flags. flags.yolo=true means server-side YOLO is active and the engine will auto-accept in-process; clients can skip review UI for those entries.",
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
this.#registry.registerNotification("loop/terminated", {
|
|
180
|
+
description: "A loop has reached a terminal status; scoped to the connection's attached session.",
|
|
181
|
+
params: {
|
|
182
|
+
loopId: "number",
|
|
183
|
+
finalStatus: "number — terminal status code (200, 499, etc.)",
|
|
184
|
+
hitMaxTurns: "boolean",
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
this.#registry.registerNotification("stream/event", {
|
|
188
|
+
description: "A channel's content grew or its state transitioned. Scoped to the entry's session. Metadata-only; clients fetch new content via entry.read or op.read.",
|
|
189
|
+
params: {
|
|
190
|
+
entryId: "number — the entry whose channel changed",
|
|
191
|
+
channel: "string — the channel name",
|
|
192
|
+
state: "string — current state (static, active, closed, errored)",
|
|
193
|
+
contentLength: "number — current length of the channel's content",
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Emit a stream/event notification scoped to the session containing the
|
|
199
|
+
* entry. ChannelWrite helpers (src/core/ChannelWrite.ts) invoke this when
|
|
200
|
+
* they update channel content or state. SPEC §13.6.
|
|
201
|
+
*/
|
|
202
|
+
notifyStreamEvent(sessionId, event) {
|
|
203
|
+
this.#broadcast({ sessionId }, null, "stream/event", event);
|
|
204
|
+
}
|
|
205
|
+
#onConnection(ws) {
|
|
206
|
+
const conn = new ClientConnection({
|
|
207
|
+
ws,
|
|
208
|
+
registry: this.#registry,
|
|
209
|
+
db: this.#db,
|
|
210
|
+
engine: this.#engine,
|
|
211
|
+
provider: this.#provider,
|
|
212
|
+
broadcast: (target, from, method, params) => this.#broadcast(target, from, method, params),
|
|
213
|
+
});
|
|
214
|
+
this.#connections.add(conn);
|
|
215
|
+
ws.on("close", () => {
|
|
216
|
+
conn.close();
|
|
217
|
+
this.#connections.delete(conn);
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
async #discoverAndLoadPlugins() {
|
|
221
|
+
// Scheme discovery only. Providers are config-driven (wired via the
|
|
222
|
+
// bin script). Mimetypes self-discovers — Mimetypes.ready() in start()
|
|
223
|
+
// scans @plurnk/plurnk-mimetypes-* packages via the framework's own
|
|
224
|
+
// discover().
|
|
225
|
+
const plugins = await discoverPlugins(this.#nodeModulesPath);
|
|
226
|
+
for (const plugin of plugins) {
|
|
227
|
+
if (plugin.manifest.kind !== "scheme")
|
|
228
|
+
continue;
|
|
229
|
+
const instance = await loadPlugin(plugin);
|
|
230
|
+
this.#schemes.register(plugin.manifest.name, instance);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
#broadcast(target, from, method, params) {
|
|
234
|
+
if (target === "this") {
|
|
235
|
+
from?.sendNotification(method, params);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (target === "all") {
|
|
239
|
+
for (const conn of this.#connections) {
|
|
240
|
+
conn.sendNotification(method, params);
|
|
241
|
+
}
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
const sessionId = target.sessionId;
|
|
245
|
+
for (const conn of this.#connections) {
|
|
246
|
+
if (conn.session?.sessionId === sessionId) {
|
|
247
|
+
conn.sendNotification(method, params);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=Daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Daemon.js","sourceRoot":"","sources":["../../src/server/Daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type Engine from "../core/Engine.ts";
|
|
2
|
+
import type { Db } from "../core/Db.ts";
|
|
3
|
+
import type { Provider } from "../core/ProviderRegistry.ts";
|
|
4
|
+
import type { ClientEnvelope } from "./envelope.ts";
|
|
5
|
+
export type { Provider } from "../core/ProviderRegistry.ts";
|
|
6
|
+
export type NotifyTarget = "this" | "all" | {
|
|
7
|
+
sessionId: number;
|
|
8
|
+
};
|
|
9
|
+
export type MethodHandler = (params: unknown, ctx: HandlerContext) => Promise<unknown>;
|
|
10
|
+
export interface HandlerContext {
|
|
11
|
+
registry: MethodRegistry;
|
|
12
|
+
db: Db;
|
|
13
|
+
engine: Engine;
|
|
14
|
+
provider: Provider | null;
|
|
15
|
+
session: ClientEnvelope | null;
|
|
16
|
+
attachSession: (envelope: ClientEnvelope) => void;
|
|
17
|
+
notify: (target: NotifyTarget, method: string, params?: unknown) => void;
|
|
18
|
+
}
|
|
19
|
+
export interface MethodRegistration {
|
|
20
|
+
handler: MethodHandler;
|
|
21
|
+
description: string;
|
|
22
|
+
params?: Record<string, string>;
|
|
23
|
+
requiresInit?: boolean;
|
|
24
|
+
longRunning?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface NotificationRegistration {
|
|
27
|
+
description: string;
|
|
28
|
+
params?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
export interface MethodCatalogEntry {
|
|
31
|
+
description: string;
|
|
32
|
+
params: Record<string, string>;
|
|
33
|
+
requiresInit: boolean;
|
|
34
|
+
longRunning: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface NotificationCatalogEntry {
|
|
37
|
+
description: string;
|
|
38
|
+
params: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
export interface Catalog {
|
|
41
|
+
protocolVersion: string;
|
|
42
|
+
methods: Record<string, MethodCatalogEntry>;
|
|
43
|
+
notifications: Record<string, NotificationCatalogEntry>;
|
|
44
|
+
}
|
|
45
|
+
export default class MethodRegistry {
|
|
46
|
+
#private;
|
|
47
|
+
registerMethod(name: string, registration: MethodRegistration): void;
|
|
48
|
+
registerNotification(name: string, registration: NotificationRegistration): void;
|
|
49
|
+
getMethod(name: string): MethodRegistration | undefined;
|
|
50
|
+
hasMethod(name: string): boolean;
|
|
51
|
+
hasNotification(name: string): boolean;
|
|
52
|
+
listMethods(): string[];
|
|
53
|
+
listNotifications(): string[];
|
|
54
|
+
catalog(): Catalog;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=MethodRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MethodRegistry.d.ts","sourceRoot":"","sources":["../../src/server/MethodRegistry.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,YAAY,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAElE,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvF,MAAM,WAAW,cAAc;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,MAAM,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAC5E;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,OAAO;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CAC3D;AAID,MAAM,CAAC,OAAO,OAAO,cAAc;;IAI/B,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,GAAG,IAAI;IAOpE,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,wBAAwB,GAAG,IAAI;IAOhF,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIvD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIhC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAItC,WAAW,IAAI,MAAM,EAAE;IAIvB,iBAAiB,IAAI,MAAM,EAAE;IAI7B,OAAO,IAAI,OAAO;CAmBrB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Daemon's method + notification registry. Methods are JSON-RPC endpoints
|
|
2
|
+
// the daemon exposes; notifications are server-initiated events the daemon
|
|
3
|
+
// may emit. Both have metadata that surfaces via `discover` (SPEC §13.4).
|
|
4
|
+
const PROTOCOL_VERSION = "0.1.0";
|
|
5
|
+
export default class MethodRegistry {
|
|
6
|
+
#methods = new Map();
|
|
7
|
+
#notifications = new Map();
|
|
8
|
+
registerMethod(name, registration) {
|
|
9
|
+
if (this.#methods.has(name)) {
|
|
10
|
+
throw new Error(`method '${name}' is already registered`);
|
|
11
|
+
}
|
|
12
|
+
this.#methods.set(name, registration);
|
|
13
|
+
}
|
|
14
|
+
registerNotification(name, registration) {
|
|
15
|
+
if (this.#notifications.has(name)) {
|
|
16
|
+
throw new Error(`notification '${name}' is already registered`);
|
|
17
|
+
}
|
|
18
|
+
this.#notifications.set(name, registration);
|
|
19
|
+
}
|
|
20
|
+
getMethod(name) {
|
|
21
|
+
return this.#methods.get(name);
|
|
22
|
+
}
|
|
23
|
+
hasMethod(name) {
|
|
24
|
+
return this.#methods.has(name);
|
|
25
|
+
}
|
|
26
|
+
hasNotification(name) {
|
|
27
|
+
return this.#notifications.has(name);
|
|
28
|
+
}
|
|
29
|
+
listMethods() {
|
|
30
|
+
return [...this.#methods.keys()].toSorted();
|
|
31
|
+
}
|
|
32
|
+
listNotifications() {
|
|
33
|
+
return [...this.#notifications.keys()].toSorted();
|
|
34
|
+
}
|
|
35
|
+
catalog() {
|
|
36
|
+
const methods = {};
|
|
37
|
+
for (const [name, reg] of this.#methods.entries()) {
|
|
38
|
+
methods[name] = {
|
|
39
|
+
description: reg.description,
|
|
40
|
+
params: reg.params ?? {},
|
|
41
|
+
requiresInit: reg.requiresInit ?? false,
|
|
42
|
+
longRunning: reg.longRunning ?? false,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
const notifications = {};
|
|
46
|
+
for (const [name, reg] of this.#notifications.entries()) {
|
|
47
|
+
notifications[name] = {
|
|
48
|
+
description: reg.description,
|
|
49
|
+
params: reg.params ?? {},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return { protocolVersion: PROTOCOL_VERSION, methods, notifications };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=MethodRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MethodRegistry.js","sourceRoot":"","sources":["../../src/server/MethodRegistry.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAsD1E,MAAM,gBAAgB,GAAG,OAAO,CAAC;AAEjC,MAAM,CAAC,OAAO,OAAO,cAAc;IAC/B,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;IACjD,cAAc,GAAG,IAAI,GAAG,EAAoC,CAAC;IAE7D,cAAc,CAAC,IAAY,EAAE,YAAgC;QACzD,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,yBAAyB,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC1C,CAAC;IAED,oBAAoB,CAAC,IAAY,EAAE,YAAsC;QACrE,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,yBAAyB,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IAED,eAAe,CAAC,IAAY;QACxB,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAED,WAAW;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IAChD,CAAC;IAED,iBAAiB;QACb,OAAO,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;IAED,OAAO;QACH,MAAM,OAAO,GAAuC,EAAE,CAAC;QACvD,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;YAChD,OAAO,CAAC,IAAI,CAAC,GAAG;gBACZ,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;gBACxB,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,KAAK;gBACvC,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,KAAK;aACxC,CAAC;QACN,CAAC;QACD,MAAM,aAAa,GAA6C,EAAE,CAAC;QACnE,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC;YACtD,aAAa,CAAC,IAAI,CAAC,GAAG;gBAClB,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,MAAM,EAAE,GAAG,CAAC,MAAM,IAAI,EAAE;aAC3B,CAAC;QACN,CAAC;QACD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IACzE,CAAC;CACJ"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientTurn.d.ts","sourceRoot":"","sources":["../../src/server/clientTurn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,eAAe,CAAC;AAUpD,eAAO,MAAM,gBAAgB,GAAU,IAAI,EAAE,EAAE,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAQ7E,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Helper for creating a turn inside a connection's client loop. Each
|
|
2
|
+
// client-origin RPC dispatch (op.*) creates one such turn with a synthetic
|
|
3
|
+
// packet matching the same shape as model turns but with empty content.
|
|
4
|
+
const CLIENT_TURN_PACKET = JSON.stringify({
|
|
5
|
+
tokens: 0,
|
|
6
|
+
system: { tokens: 0, system_definition: "", persona: "", index: [], log: [] },
|
|
7
|
+
user: { tokens: 0, prompt: "", telemetry: { budget: "", errors: [] }, system_requirements: "" },
|
|
8
|
+
assistant: { tokens: 0, content: "", ops: [], reasoning: null },
|
|
9
|
+
assistantRaw: null,
|
|
10
|
+
});
|
|
11
|
+
export const insertClientTurn = async (db, loopId) => {
|
|
12
|
+
const seqRow = await db.client_turn_next_sequence.get({ loop_id: loopId });
|
|
13
|
+
if (seqRow === undefined)
|
|
14
|
+
throw new Error("insertClientTurn: next-sequence query returned no row");
|
|
15
|
+
const row = await db.client_turn_insert.get({
|
|
16
|
+
loop_id: loopId, sequence: seqRow.next, packet: CLIENT_TURN_PACKET,
|
|
17
|
+
});
|
|
18
|
+
if (row === undefined)
|
|
19
|
+
throw new Error("insertClientTurn: insert returned no row");
|
|
20
|
+
return row.id;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=clientTurn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientTurn.js","sourceRoot":"","sources":["../../src/server/clientTurn.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,2EAA2E;AAC3E,wEAAwE;AAIxE,MAAM,kBAAkB,GAAG,IAAI,CAAC,SAAS,CAAC;IACtC,MAAM,EAAE,CAAC;IACT,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IAC7E,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE;IAC/F,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;IAC/D,YAAY,EAAE,IAAI;CACrB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,EAAM,EAAE,MAAc,EAAmB,EAAE;IAC9E,MAAM,MAAM,GAAG,MAAO,EAAE,CAAC,yBAAwC,CAAC,GAAG,CAAmB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7G,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IACnG,MAAM,GAAG,GAAG,MAAO,EAAE,CAAC,kBAAiC,CAAC,GAAG,CAAiB;QACxE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB;KACrE,CAAC,CAAC;IACH,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IACnF,OAAO,GAAG,CAAC,EAAE,CAAC;AAClB,CAAC,CAAC"}
|