pinomad 0.2.0 → 0.3.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.
@@ -0,0 +1,154 @@
1
+ // packages/protocol/src/settings.ts
2
+ var HOST_SETTING_KEY_SET = {
3
+ defaultModel: true,
4
+ defaultThinkingLevel: true,
5
+ steeringMode: true,
6
+ followUpMode: true
7
+ };
8
+ var HOST_SETTING_KEYS = Object.keys(HOST_SETTING_KEY_SET);
9
+ var THINKING_LEVEL_KEYS = { off: true, minimal: true, low: true, medium: true, high: true, xhigh: true, max: true };
10
+ var THINKING_LEVELS = Object.keys(THINKING_LEVEL_KEYS);
11
+ var isThinkingLevel = (value) => typeof value === "string" && Object.prototype.hasOwnProperty.call(THINKING_LEVEL_KEYS, value);
12
+ var isQueueMode = (value) => value === "all" || value === "one-at-a-time";
13
+
14
+ // packages/protocol/src/frames.ts
15
+ var HOST_STREAMS = { conversations: 0, index: 0, devices: 0, mcp: 0, models: 1, auth: 1, settings: 2, agents: 6 };
16
+ var HOST_STREAM_NAMES = Object.keys(HOST_STREAMS);
17
+ function hostStreams(hostMinor) {
18
+ return HOST_STREAM_NAMES.filter((name) => HOST_STREAMS[name] <= hostMinor);
19
+ }
20
+ var conversationStream = (id) => `conversation:${id}`;
21
+ var docStream = (kind, id) => `doc:${kind}:${id}`;
22
+ var UNAUTHORIZED_CLOSE_CODE = 4401;
23
+ var INVALID_FRAME_CLOSE_CODE = 4400;
24
+ var PROTOCOL = { major: 5, minor: 6 };
25
+ var CALL_SINCE = {
26
+ logout: 1,
27
+ updateSettings: 2,
28
+ listFolders: 3,
29
+ renameConversation: 4,
30
+ createAgent: 6,
31
+ updateAgent: 6,
32
+ deleteAgent: 6
33
+ };
34
+ function hostSupportsCall(hostMinor, method) {
35
+ return hostMinor >= (CALL_SINCE[method] ?? 0);
36
+ }
37
+ var FEATURE_SINCE = { images: 5 };
38
+ function hostSupportsFeature(hostMinor, feature) {
39
+ return hostMinor >= FEATURE_SINCE[feature];
40
+ }
41
+ function parseClientFrame(value) {
42
+ if (!record(value) || typeof value.type !== "string")
43
+ return { kind: "malformed" };
44
+ if (value.type === "subscribe" || value.type === "unsubscribe") {
45
+ const stream = value.stream;
46
+ if (typeof stream !== "string")
47
+ return { kind: "malformed" };
48
+ if (isStreamName(stream)) {
49
+ return { kind: "frame", frame: { type: value.type, stream } };
50
+ }
51
+ const prefix = stream.slice(0, stream.indexOf(":") === -1 ? undefined : stream.indexOf(":"));
52
+ if (STREAM_KINDS.has(prefix))
53
+ return { kind: "malformed" };
54
+ return { kind: "unsupportedStream", type: value.type, stream };
55
+ }
56
+ if (value.type !== "call")
57
+ return { kind: "unknownType" };
58
+ const { id, method, args } = value;
59
+ if (typeof id !== "number" || !Number.isSafeInteger(id) || !record(args) || typeof method !== "string") {
60
+ return { kind: "malformed" };
61
+ }
62
+ if (!isCallMethod(method))
63
+ return { kind: "unsupportedCall", id, method };
64
+ return validCallArgs(method, args) ? { kind: "frame", frame: { type: "call", id, method, args } } : { kind: "malformed" };
65
+ }
66
+ var STREAM_KINDS = new Set(["conversation", "doc", "tasks", ...HOST_STREAM_NAMES]);
67
+ function isStreamName(stream) {
68
+ return stream === "tasks" || HOST_STREAM_NAMES.includes(stream) || /^(?:conversation:|doc:.+:)[1-9]\d*$/.test(stream);
69
+ }
70
+ var isCallMethod = (method) => CALL_METHODS.includes(method);
71
+ var CALL_METHODS = [
72
+ "addProject",
73
+ "removeProject",
74
+ "listFolders",
75
+ "createConversation",
76
+ "archive",
77
+ "renameConversation",
78
+ "submit",
79
+ "abort",
80
+ "compact",
81
+ "setModel",
82
+ "setThinkingLevel",
83
+ "fork",
84
+ "answer",
85
+ "changes",
86
+ "createPairing",
87
+ "revokeDevice",
88
+ "logout",
89
+ "updateSettings",
90
+ "createAgent",
91
+ "updateAgent",
92
+ "deleteAgent"
93
+ ];
94
+ var SETTING_VALIDATORS = {
95
+ defaultModel: (value) => value === null || record(value) && nonempty(value.provider) && nonempty(value.modelId),
96
+ defaultThinkingLevel: (value) => value === null || isThinkingLevel(value),
97
+ steeringMode: (value) => value === null || isQueueMode(value),
98
+ followUpMode: (value) => value === null || isQueueMode(value)
99
+ };
100
+ function validCallArgs(method, args) {
101
+ const conversationId = () => typeof args.conversationId === "number" && Number.isSafeInteger(args.conversationId) && args.conversationId >= 1;
102
+ const images = () => args.images === undefined || Array.isArray(args.images) && args.images.every((image) => record(image) && typeof image.data === "string" && typeof image.mimeType === "string");
103
+ const role = () => record(args.role) && typeof args.role.name === "string" && typeof args.role.description === "string" && typeof args.role.prompt === "string" && (args.role.model === undefined || typeof args.role.model === "string") && (args.role.thinkingLevel === undefined || typeof args.role.thinkingLevel === "string");
104
+ switch (method) {
105
+ case "submit":
106
+ return conversationId() && typeof args.text === "string" && (args.whenBusy === "steer" || args.whenBusy === "followUp") && nonempty(args.requestId) && images();
107
+ case "abort":
108
+ return conversationId();
109
+ case "setThinkingLevel":
110
+ return conversationId() && nonempty(args.level);
111
+ case "compact":
112
+ return conversationId() && (args.instructions === undefined || typeof args.instructions === "string");
113
+ case "setModel":
114
+ return conversationId() && record(args.model) && nonempty(args.model.provider) && nonempty(args.model.modelId);
115
+ case "fork":
116
+ return conversationId() && typeof args.entryId === "string" && /^[1-9]\d*$/.test(args.entryId) && (args.removeTools === undefined || Array.isArray(args.removeTools) && args.removeTools.every(nonempty));
117
+ case "answer":
118
+ return conversationId() && nonempty(args.kind) && nonempty(args.requestId) && Array.isArray(args.answers) && args.answers.every((answer) => record(answer) && Array.isArray(answer.selected) && answer.selected.every((l) => typeof l === "string") && (answer.other === undefined || typeof answer.other === "string"));
119
+ case "changes":
120
+ return conversationId();
121
+ case "addProject":
122
+ case "removeProject":
123
+ return nonempty(args.path);
124
+ case "listFolders":
125
+ return args.path === undefined || nonempty(args.path);
126
+ case "createConversation":
127
+ return record(args.home) && (args.home.kind === "chat" || args.home.kind === "project" && nonempty(args.home.path)) && typeof args.text === "string" && (nonempty(args.text) || Array.isArray(args.images) && args.images.length > 0) && nonempty(args.requestId) && images() && (args.checkout === undefined || args.checkout === "worktree" || args.checkout === "project") && (args.model === undefined || record(args.model) && nonempty(args.model.provider) && nonempty(args.model.modelId)) && (args.thinkingLevel === undefined || nonempty(args.thinkingLevel));
128
+ case "archive":
129
+ return conversationId() && typeof args.archived === "boolean";
130
+ case "renameConversation":
131
+ return conversationId() && typeof args.title === "string";
132
+ case "createPairing":
133
+ return Object.keys(args).length === 0;
134
+ case "revokeDevice":
135
+ return nonempty(args.publicKey) && /^[A-Za-z0-9_-]+$/.test(args.publicKey);
136
+ case "logout":
137
+ return nonempty(args.providerId);
138
+ case "createAgent":
139
+ case "updateAgent":
140
+ return role();
141
+ case "deleteAgent":
142
+ return typeof args.name === "string";
143
+ case "updateSettings":
144
+ return record(args.patch) && Object.keys(args.patch).every((key) => HOST_SETTING_KEYS.includes(key)) && Object.entries(args.patch).every(([key, value]) => SETTING_VALIDATORS[key]?.(value) === true);
145
+ }
146
+ }
147
+ function record(value) {
148
+ return value !== null && typeof value === "object" && !Array.isArray(value);
149
+ }
150
+ function nonempty(value) {
151
+ return typeof value === "string" && value.length > 0;
152
+ }
153
+
154
+ export { HOST_SETTING_KEYS, THINKING_LEVELS, isThinkingLevel, isQueueMode, HOST_STREAM_NAMES, hostStreams, conversationStream, docStream, UNAUTHORIZED_CLOSE_CODE, INVALID_FRAME_CLOSE_CODE, PROTOCOL, hostSupportsCall, hostSupportsFeature, parseClientFrame };
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  main,
4
4
  restartService
5
- } from "./chunk-d9q0dz8s.js";
6
- import"./chunk-rkfdsacq.js";
7
- import"./chunk-5h97zxag.js";
8
- import"./chunk-h35fermn.js";
5
+ } from "./chunk-t9y2wfk5.js";
6
+ import"./chunk-3tf23vjq.js";
7
+ import"./chunk-bggesvnj.js";
8
+ import"./chunk-c155p0t0.js";
9
9
  import"./chunk-cjfmfyjb.js";
10
10
  import"./chunk-df32avw6.js";
11
11
  export {
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  restartService,
4
4
  serviceManager
5
- } from "./chunk-d9q0dz8s.js";
5
+ } from "./chunk-t9y2wfk5.js";
6
6
  import {
7
7
  globalPrefixOf,
8
8
  packageDir,
9
9
  packagedVersion
10
- } from "./chunk-rkfdsacq.js";
11
- import"./chunk-5h97zxag.js";
12
- import"./chunk-h35fermn.js";
10
+ } from "./chunk-3tf23vjq.js";
11
+ import"./chunk-bggesvnj.js";
12
+ import"./chunk-c155p0t0.js";
13
13
  import"./chunk-cjfmfyjb.js";
14
14
  import"./chunk-df32avw6.js";
15
15
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  connectRemoteDurable
3
- } from "./chunk-5h97zxag.js";
4
- import"./chunk-h35fermn.js";
3
+ } from "./chunk-bggesvnj.js";
4
+ import"./chunk-c155p0t0.js";
5
5
  import {
6
6
  hostAddress
7
7
  } from "./chunk-cjfmfyjb.js";
@@ -2,10 +2,10 @@ import {
2
2
  commandHint,
3
3
  hostEntry,
4
4
  packagedVersion
5
- } from "./chunk-rkfdsacq.js";
5
+ } from "./chunk-3tf23vjq.js";
6
6
  import {
7
7
  connectRemoteDurable
8
- } from "./chunk-5h97zxag.js";
8
+ } from "./chunk-bggesvnj.js";
9
9
  import {
10
10
  DEFAULT_DATA_DIR,
11
11
  hostAddress