@ztimson/momentum 1.5.5 → 1.5.7

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/dist/ai.d.ts CHANGED
@@ -20,13 +20,25 @@ export type AiAgent = Meta & {
20
20
  /** Optional MCP whitelist */
21
21
  mcp?: string[] | null;
22
22
  };
23
+ /** Raw file payload sent to the server; text files carry plain text, everything else base64 */
24
+ export type AiFileUpload = {
25
+ name: string;
26
+ mime?: string;
27
+ content: string;
28
+ };
23
29
  export type AiMessage = {
24
30
  /** Message originator */
25
31
  role: 'assistant' | 'system' | 'user';
26
32
  /** Message content */
27
33
  content: string | any;
34
+ /** Attached files */
35
+ files?: AiFileUpload[];
28
36
  /** Timestamp */
29
37
  timestamp?: number;
38
+ /** Response time length */
39
+ duration?: number;
40
+ /** Tokens per second */
41
+ tps?: number;
30
42
  } | {
31
43
  /** Tool call */
32
44
  role: 'tool';
@@ -42,6 +54,27 @@ export type AiMessage = {
42
54
  error?: undefined | string;
43
55
  /** Timestamp */
44
56
  timestamp?: number;
57
+ /** Response time length */
58
+ duration?: number;
59
+ /** Tokens per second */
60
+ tps?: number;
61
+ };
62
+ /** A persisted chat thread */
63
+ export type AiConversation = Meta & {
64
+ /** Conversation ID */
65
+ _id: string;
66
+ /** Conversation name */
67
+ title: string;
68
+ /** Saved conversation */
69
+ pinned: boolean;
70
+ /** Estimated context size in tokens */
71
+ size: number;
72
+ /** Last response duration (ms) */
73
+ duration?: number;
74
+ /** Last response tokens/sec */
75
+ tps?: number;
76
+ /** Conversation messages */
77
+ history: AiMessage[];
45
78
  };
46
79
  /** Provider connection info */
47
80
  export type AiModel = {
@@ -87,6 +120,10 @@ export type AiOptions = {
87
120
  anonymous?: boolean;
88
121
  /** Which AI agent are you speaking to */
89
122
  agent?: string;
123
+ /** Existing conversation to append to; omit for a one-off, non-persisted question */
124
+ conversationId?: string;
125
+ /** Index of an existing message to edit/retry from; truncates history to this point before (re)asking. Resend the same text to retry, edited text to edit. */
126
+ messageIndex?: number;
90
127
  /** Additional context information to attach to message */
91
128
  context?: any;
92
129
  /** Attach files to message context */
@@ -133,6 +170,29 @@ export declare class Agents extends AssetController<AiAgent> {
133
170
  constructor(momentum: Momentum);
134
171
  }
135
172
  /** Manage and render templates */
173
+ export declare class Conversations extends AssetController<AiConversation> {
174
+ protected momentum: Momentum;
175
+ constructor(momentum: Momentum);
176
+ /** List all conversations; omit owner to list the current session's own */
177
+ list(owner?: string, reload?: boolean): Promise<AiConversation[]>;
178
+ /** Fetch a single conversation, including full history */
179
+ read(id: string, reload?: boolean): Promise<AiConversation>;
180
+ /** Create a new conversation; pass owner to create on behalf of another user */
181
+ create(value?: Partial<AiConversation>, owner?: string): Promise<AiConversation>;
182
+ /** Delete a conversation */
183
+ delete(id: string): Promise<number>;
184
+ /** Rename and/or pin a conversation */
185
+ rename(id: string, title: string): Promise<AiConversation>;
186
+ /** Pin/unpin a conversation */
187
+ pin(id: string, pinned?: boolean): Promise<AiConversation>;
188
+ /** Cancel any in-flight request for this conversation */
189
+ abort(id: string): Promise<void>;
190
+ /** Delete a message and everything that follows it from a conversation's history (no LLM call) */
191
+ deleteMessage(id: string, index: number): Promise<AiConversation>;
192
+ /** Fork a conversation's history up to `index` into a new conversation titled `Forked: <title>` */
193
+ fork(id: string, index: number): Promise<AiConversation>;
194
+ }
195
+ /** Manage and render templates */
136
196
  export declare class Skills extends AssetController<AiSkill> {
137
197
  protected momentum: Momentum;
138
198
  constructor(momentum: Momentum);
@@ -141,32 +201,22 @@ export declare class Skills extends AssetController<AiSkill> {
141
201
  export declare class Ai extends PathEventEmitter {
142
202
  protected momentum: Momentum;
143
203
  agents: Agents;
204
+ conversations: Conversations;
144
205
  skills: Skills;
145
206
  constructor(momentum: Momentum);
146
- /** Cancel current AI requests */
147
- abort(): Promise<void>;
148
207
  /**
149
208
  * Ask the AI assistant a question
150
209
  * @param {string} question Users question
151
- * @param {AiOptions & {stream: Function}} options context - Any hidden context information. stream - Receive response in chunks
210
+ * @param {AiOptions & {stream: Function}} options Pass a conversationId to persist/continue a thread; omit for a one-off.
211
+ * Pass messageIndex to edit (new text) or retry (same text) a prior exchange - history is truncated to that point first.
152
212
  * @return {Promise<string>} AI's response
153
213
  */
154
214
  ask(question: string, options?: AiOptions & {
155
215
  stream?: LLMStream;
156
216
  }): Promise<string>;
157
- /**
158
- * Clear AI assistant memory & context
159
- * @return {Promise<void>} Resolves once complete
160
- */
161
- clear(): Promise<void>;
162
- /**
163
- * Current chat history
164
- * @return {Promise<AiMessage[]>}
165
- */
166
- history(): Promise<AiMessage[]>;
167
217
  /**
168
218
  * Get model info
169
- * @return {AiInfo>} Model Info
219
+ * @return {Promise<{[name: string]: string}>} Model Info
170
220
  */
171
221
  tools(): Promise<{
172
222
  [name: string]: string;
package/dist/ai.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../src/ai.ts"],"names":[],"mappings":"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"}
package/dist/client.d.ts CHANGED
@@ -11,23 +11,12 @@ export type Platform = 'windows' | 'android' | 'ios' | 'mac' | 'linux' | 'unknow
11
11
  export type Theme = {
12
12
  background: string;
13
13
  backgroundContrast: string;
14
- surface: string;
15
- border: string;
16
- text: string;
17
- muted: string;
18
14
  primary: string;
19
15
  primaryContrast: string;
20
16
  accent: string;
21
17
  accentContrast: string;
22
- info: string;
23
- success: string;
24
- warn: string;
25
- danger: string;
26
- black: string;
27
- white: string;
28
18
  font: string;
29
- lighter: string;
30
- darker: string;
19
+ radius: string;
31
20
  };
32
21
  /** Handle device settings */
33
22
  export declare class Client extends PathEventEmitter {
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2050,6 +2050,24 @@
2050
2050
  };
2051
2051
  //#endregion
2052
2052
  //#region src/ai.ts
2053
+ var TEXT_FILE = /^text\/|\.(txt|md|csv|json|xml|ya?ml|html?|js|ts|py|log)$/i;
2054
+ async function toFileUpload(f) {
2055
+ if (TEXT_FILE.test(f.type) || TEXT_FILE.test(f.name)) return {
2056
+ name: f.name,
2057
+ mime: f.type,
2058
+ content: await f.text()
2059
+ };
2060
+ const dataUrl = await new Promise((res) => {
2061
+ const reader = new FileReader();
2062
+ reader.onload = () => res(reader.result);
2063
+ reader.readAsDataURL(f);
2064
+ });
2065
+ return {
2066
+ name: f.name,
2067
+ mime: f.type,
2068
+ content: dataUrl.split(",")[1]
2069
+ };
2070
+ }
2053
2071
  /** Manage and render templates */
2054
2072
  var Agents = class extends AssetController {
2055
2073
  momentum;
@@ -2063,6 +2081,103 @@
2063
2081
  }
2064
2082
  };
2065
2083
  /** Manage and render templates */
2084
+ var Conversations = class extends AssetController {
2085
+ momentum;
2086
+ constructor(momentum) {
2087
+ super(momentum, {
2088
+ module: "ai",
2089
+ path: "ai/conversations",
2090
+ key: "_id"
2091
+ });
2092
+ this.momentum = momentum;
2093
+ }
2094
+ /** List all conversations; omit owner to list the current session's own */
2095
+ list(owner, reload) {
2096
+ if (!owner) return super.all(reload);
2097
+ return this.momentum.api.request({ url: `api/${this.opts.path}/${owner}` }).then((resp) => {
2098
+ this.emit(PES`${this.opts.module}/${owner}:r`, resp);
2099
+ return resp;
2100
+ });
2101
+ }
2102
+ /** Fetch a single conversation, including full history */
2103
+ read(id, reload) {
2104
+ const cached = !reload ? this.cache.find({ _id: id }) : null;
2105
+ if (cached) return Promise.resolve(cached);
2106
+ return this.momentum.api.request({ url: `api/${this.opts.path}/${id}/history` }).then((resp) => {
2107
+ this.cache.add(resp);
2108
+ this.emit(PES`${this.opts.module}/${id}:r`, resp);
2109
+ return resp;
2110
+ });
2111
+ }
2112
+ /** Create a new conversation; pass owner to create on behalf of another user */
2113
+ create(value = {}, owner) {
2114
+ const url = owner ? `api/${this.opts.path}/${owner}` : `api/${this.opts.path}`;
2115
+ return this.momentum.api.request({
2116
+ url,
2117
+ method: "POST",
2118
+ body: { title: value.title }
2119
+ }).then((resp) => {
2120
+ this.cache.add(resp);
2121
+ this.emit(PES`${this.opts.module}/${resp._id}:c`, resp);
2122
+ return resp;
2123
+ });
2124
+ }
2125
+ /** Delete a conversation */
2126
+ async delete(id) {
2127
+ await this.momentum.api.request({
2128
+ url: `api/${this.opts.path}/${id}`,
2129
+ method: "DELETE"
2130
+ });
2131
+ this.cache.delete(id);
2132
+ this.emit(PES`${this.opts.module}/${id}:d`, id);
2133
+ return 1;
2134
+ }
2135
+ /** Rename and/or pin a conversation */
2136
+ rename(id, title) {
2137
+ return this.update({
2138
+ _id: id,
2139
+ title
2140
+ });
2141
+ }
2142
+ /** Pin/unpin a conversation */
2143
+ pin(id, pinned = true) {
2144
+ return this.update({
2145
+ _id: id,
2146
+ pinned
2147
+ });
2148
+ }
2149
+ /** Cancel any in-flight request for this conversation */
2150
+ abort(id) {
2151
+ return this.momentum.api.request({
2152
+ url: `api/${this.opts.path}/${id}/abort`,
2153
+ method: "POST"
2154
+ });
2155
+ }
2156
+ /** Delete a message and everything that follows it from a conversation's history (no LLM call) */
2157
+ deleteMessage(id, index) {
2158
+ return this.momentum.api.request({
2159
+ url: `api/${this.opts.path}/${id}/${index}`,
2160
+ method: "DELETE"
2161
+ }).then((resp) => {
2162
+ this.cache.add(resp);
2163
+ this.emit(PES`${this.opts.module}/${id}:u`, resp);
2164
+ return resp;
2165
+ });
2166
+ }
2167
+ /** Fork a conversation's history up to `index` into a new conversation titled `Forked: <title>` */
2168
+ fork(id, index) {
2169
+ return this.momentum.api.request({
2170
+ url: `api/${this.opts.path}/${id}/fork`,
2171
+ method: "POST",
2172
+ body: { index }
2173
+ }).then((resp) => {
2174
+ this.cache.add(resp);
2175
+ this.emit(PES`${this.opts.module}/${resp._id}:c`, resp);
2176
+ return resp;
2177
+ });
2178
+ }
2179
+ };
2180
+ /** Manage and render templates */
2066
2181
  var Skills = class extends AssetController {
2067
2182
  momentum;
2068
2183
  constructor(momentum) {
@@ -2078,49 +2193,41 @@
2078
2193
  var Ai = class extends PathEventEmitter {
2079
2194
  momentum;
2080
2195
  agents;
2196
+ conversations;
2081
2197
  skills;
2082
2198
  constructor(momentum) {
2083
2199
  super("ai");
2084
2200
  this.momentum = momentum;
2085
2201
  this.agents = new Agents(momentum);
2202
+ this.conversations = new Conversations(momentum);
2086
2203
  this.skills = new Skills(momentum);
2087
2204
  this.relayEvents(this.agents);
2205
+ this.relayEvents(this.conversations);
2088
2206
  this.relayEvents(this.skills);
2089
2207
  }
2090
- /** Cancel current AI requests */
2091
- abort() {
2092
- return this.momentum.api.request({
2093
- url: "/api/ai/abort",
2094
- method: "POST"
2095
- });
2096
- }
2097
2208
  /**
2098
2209
  * Ask the AI assistant a question
2099
2210
  * @param {string} question Users question
2100
- * @param {AiOptions & {stream: Function}} options context - Any hidden context information. stream - Receive response in chunks
2211
+ * @param {AiOptions & {stream: Function}} options Pass a conversationId to persist/continue a thread; omit for a one-off.
2212
+ * Pass messageIndex to edit (new text) or retry (same text) a prior exchange - history is truncated to that point first.
2101
2213
  * @return {Promise<string>} AI's response
2102
2214
  */
2103
2215
  async ask(question, options = {}) {
2104
2216
  if (!question) throw new Error("Cannot ask AI, missing question");
2105
- const files = (await Promise.all((options?.files || []).map((f) => new Promise((res) => {
2106
- const reader = new FileReader();
2107
- reader.onload = () => res([f.name, reader.result]);
2108
- reader.readAsDataURL(f);
2109
- })))).reduce((acc, f) => ({
2110
- ...acc,
2111
- [f[0]]: f[1]
2112
- }), {});
2217
+ const { stream, files: rawFiles, ...rest } = options;
2218
+ const files = await Promise.all((rawFiles || []).map(toFileUpload));
2113
2219
  const q = {
2114
- ...options,
2220
+ ...rest,
2115
2221
  question: question.trim(),
2116
- files: Object.keys(files).length ? files : void 0
2222
+ files: files.length ? files : void 0
2117
2223
  };
2118
- if (options.stream && this.momentum.socket?.connected) {
2224
+ if (!q.conversationId) delete q.conversationId;
2225
+ if (stream && this.momentum.socket?.connected) {
2119
2226
  let unsub = () => {};
2120
2227
  return new Promise((res) => {
2121
2228
  let buffer = "";
2122
2229
  unsub = this.momentum.socket?.on("llm", (event, chunk) => {
2123
- options.stream?.(chunk);
2230
+ stream(chunk);
2124
2231
  if (chunk.text) buffer += chunk.text;
2125
2232
  if (chunk.done) res(buffer);
2126
2233
  });
@@ -2136,28 +2243,8 @@
2136
2243
  });
2137
2244
  }
2138
2245
  /**
2139
- * Clear AI assistant memory & context
2140
- * @return {Promise<void>} Resolves once complete
2141
- */
2142
- clear() {
2143
- return this.momentum.api.request({
2144
- url: "api/ai",
2145
- method: "DELETE"
2146
- }).then(() => this.emit(PES`:d`, this.momentum.api.token));
2147
- }
2148
- /**
2149
- * Current chat history
2150
- * @return {Promise<AiMessage[]>}
2151
- */
2152
- history() {
2153
- return this.momentum.api.request({ url: "api/ai" }).then((resp) => {
2154
- this.emit(PES`:r`, resp);
2155
- return resp;
2156
- });
2157
- }
2158
- /**
2159
2246
  * Get model info
2160
- * @return {AiInfo>} Model Info
2247
+ * @return {Promise<{[name: string]: string}>} Model Info
2161
2248
  */
2162
2249
  tools() {
2163
2250
  return this.momentum.api.request({ url: "api/ai/tools" });
@@ -3381,36 +3468,16 @@
3381
3468
  const t = {
3382
3469
  background: setting?.background,
3383
3470
  backgroundContrast: contrast(setting?.background),
3384
- surface: setting?.darkMode ? "#2e2e2e" : "#ffffff",
3385
- border: setting?.darkMode ? "#374151" : "#E5E7EB",
3386
- text: setting?.darkMode ? "#ffffff" : "#000000",
3387
- muted: setting?.darkMode ? "#cccccc" : "#6c757d",
3388
3471
  primary: setting?.primary,
3389
3472
  primaryContrast: contrast(setting?.primary),
3390
3473
  accent: setting?.accent,
3391
3474
  accentContrast: contrast(setting?.accent),
3392
- info: "#6157cc",
3393
- success: "#65c147",
3394
- warn: "#d88750",
3395
- danger: "#bf4f4f",
3396
- black: "black",
3397
- white: "white",
3398
3475
  font: setting?.font,
3399
- lighter: setting?.darkMode ? "rgba(255, 255, 255, 0.1)" : "rgba(255, 255, 255, 0.05)",
3400
- darker: setting?.darkMode ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.05)"
3476
+ radius: "0.5rem"
3401
3477
  };
3402
3478
  if (!css) return t;
3403
- return `:root, :root .theme-${setting?.darkMode ? "dark" : "light"} {
3479
+ return `:root {
3404
3480
  ${Object.entries(t).map(([name, value]) => `--theme-${kebabCase(name)}: ${value} !important;`).join("\n")}
3405
- }
3406
-
3407
- :root .theme-${!setting?.darkMode ? "dark" : "light"} {
3408
- --theme-surface: ${!setting?.darkMode ? "#2e2e2e" : "#ffffff"} !important;
3409
- --theme-border: ${!setting?.darkMode ? "#374151" : "#E5E7EB"} !important;
3410
- --theme-text: ${!setting?.darkMode ? "#ffffff" : "#000000"} !important;
3411
- --theme-muted: ${!setting?.darkMode ? "#cccccc" : "#6c757d"} !important;
3412
- --theme-lighter: ${!setting?.darkMode ? "rgba(255, 255, 255, 0.1)" : "rgba(255, 255, 255, 0.05)"};
3413
- --theme-darker: ${!setting?.darkMode ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.05)"};
3414
3481
  }`;
3415
3482
  }
3416
3483
  /**
@@ -4952,7 +5019,7 @@ ${Object.entries(t).map(([name, value]) => `--theme-${kebabCase(name)}: ${value}
4952
5019
  };
4953
5020
  //#endregion
4954
5021
  //#region package.json
4955
- var version = "1.5.5";
5022
+ var version = "1.5.7";
4956
5023
  //#endregion
4957
5024
  //#region src/webRtc.ts
4958
5025
  var WebRtc = class extends PathEventEmitter {
@@ -5287,6 +5354,7 @@ ${Object.entries(t).map(([name, value]) => `--theme-${kebabCase(name)}: ${value}
5287
5354
  exports.Call = Call;
5288
5355
  exports.Captcha = Captcha;
5289
5356
  exports.Client = Client;
5357
+ exports.Conversations = Conversations;
5290
5358
  exports.Data = Data;
5291
5359
  exports.Discounts = Discounts;
5292
5360
  exports.Email = Email;
package/dist/index.mjs CHANGED
@@ -2046,6 +2046,24 @@ var Actions = class extends AssetController {
2046
2046
  };
2047
2047
  //#endregion
2048
2048
  //#region src/ai.ts
2049
+ var TEXT_FILE = /^text\/|\.(txt|md|csv|json|xml|ya?ml|html?|js|ts|py|log)$/i;
2050
+ async function toFileUpload(f) {
2051
+ if (TEXT_FILE.test(f.type) || TEXT_FILE.test(f.name)) return {
2052
+ name: f.name,
2053
+ mime: f.type,
2054
+ content: await f.text()
2055
+ };
2056
+ const dataUrl = await new Promise((res) => {
2057
+ const reader = new FileReader();
2058
+ reader.onload = () => res(reader.result);
2059
+ reader.readAsDataURL(f);
2060
+ });
2061
+ return {
2062
+ name: f.name,
2063
+ mime: f.type,
2064
+ content: dataUrl.split(",")[1]
2065
+ };
2066
+ }
2049
2067
  /** Manage and render templates */
2050
2068
  var Agents = class extends AssetController {
2051
2069
  momentum;
@@ -2059,6 +2077,103 @@ var Agents = class extends AssetController {
2059
2077
  }
2060
2078
  };
2061
2079
  /** Manage and render templates */
2080
+ var Conversations = class extends AssetController {
2081
+ momentum;
2082
+ constructor(momentum) {
2083
+ super(momentum, {
2084
+ module: "ai",
2085
+ path: "ai/conversations",
2086
+ key: "_id"
2087
+ });
2088
+ this.momentum = momentum;
2089
+ }
2090
+ /** List all conversations; omit owner to list the current session's own */
2091
+ list(owner, reload) {
2092
+ if (!owner) return super.all(reload);
2093
+ return this.momentum.api.request({ url: `api/${this.opts.path}/${owner}` }).then((resp) => {
2094
+ this.emit(PES`${this.opts.module}/${owner}:r`, resp);
2095
+ return resp;
2096
+ });
2097
+ }
2098
+ /** Fetch a single conversation, including full history */
2099
+ read(id, reload) {
2100
+ const cached = !reload ? this.cache.find({ _id: id }) : null;
2101
+ if (cached) return Promise.resolve(cached);
2102
+ return this.momentum.api.request({ url: `api/${this.opts.path}/${id}/history` }).then((resp) => {
2103
+ this.cache.add(resp);
2104
+ this.emit(PES`${this.opts.module}/${id}:r`, resp);
2105
+ return resp;
2106
+ });
2107
+ }
2108
+ /** Create a new conversation; pass owner to create on behalf of another user */
2109
+ create(value = {}, owner) {
2110
+ const url = owner ? `api/${this.opts.path}/${owner}` : `api/${this.opts.path}`;
2111
+ return this.momentum.api.request({
2112
+ url,
2113
+ method: "POST",
2114
+ body: { title: value.title }
2115
+ }).then((resp) => {
2116
+ this.cache.add(resp);
2117
+ this.emit(PES`${this.opts.module}/${resp._id}:c`, resp);
2118
+ return resp;
2119
+ });
2120
+ }
2121
+ /** Delete a conversation */
2122
+ async delete(id) {
2123
+ await this.momentum.api.request({
2124
+ url: `api/${this.opts.path}/${id}`,
2125
+ method: "DELETE"
2126
+ });
2127
+ this.cache.delete(id);
2128
+ this.emit(PES`${this.opts.module}/${id}:d`, id);
2129
+ return 1;
2130
+ }
2131
+ /** Rename and/or pin a conversation */
2132
+ rename(id, title) {
2133
+ return this.update({
2134
+ _id: id,
2135
+ title
2136
+ });
2137
+ }
2138
+ /** Pin/unpin a conversation */
2139
+ pin(id, pinned = true) {
2140
+ return this.update({
2141
+ _id: id,
2142
+ pinned
2143
+ });
2144
+ }
2145
+ /** Cancel any in-flight request for this conversation */
2146
+ abort(id) {
2147
+ return this.momentum.api.request({
2148
+ url: `api/${this.opts.path}/${id}/abort`,
2149
+ method: "POST"
2150
+ });
2151
+ }
2152
+ /** Delete a message and everything that follows it from a conversation's history (no LLM call) */
2153
+ deleteMessage(id, index) {
2154
+ return this.momentum.api.request({
2155
+ url: `api/${this.opts.path}/${id}/${index}`,
2156
+ method: "DELETE"
2157
+ }).then((resp) => {
2158
+ this.cache.add(resp);
2159
+ this.emit(PES`${this.opts.module}/${id}:u`, resp);
2160
+ return resp;
2161
+ });
2162
+ }
2163
+ /** Fork a conversation's history up to `index` into a new conversation titled `Forked: <title>` */
2164
+ fork(id, index) {
2165
+ return this.momentum.api.request({
2166
+ url: `api/${this.opts.path}/${id}/fork`,
2167
+ method: "POST",
2168
+ body: { index }
2169
+ }).then((resp) => {
2170
+ this.cache.add(resp);
2171
+ this.emit(PES`${this.opts.module}/${resp._id}:c`, resp);
2172
+ return resp;
2173
+ });
2174
+ }
2175
+ };
2176
+ /** Manage and render templates */
2062
2177
  var Skills = class extends AssetController {
2063
2178
  momentum;
2064
2179
  constructor(momentum) {
@@ -2074,49 +2189,41 @@ var Skills = class extends AssetController {
2074
2189
  var Ai = class extends PathEventEmitter {
2075
2190
  momentum;
2076
2191
  agents;
2192
+ conversations;
2077
2193
  skills;
2078
2194
  constructor(momentum) {
2079
2195
  super("ai");
2080
2196
  this.momentum = momentum;
2081
2197
  this.agents = new Agents(momentum);
2198
+ this.conversations = new Conversations(momentum);
2082
2199
  this.skills = new Skills(momentum);
2083
2200
  this.relayEvents(this.agents);
2201
+ this.relayEvents(this.conversations);
2084
2202
  this.relayEvents(this.skills);
2085
2203
  }
2086
- /** Cancel current AI requests */
2087
- abort() {
2088
- return this.momentum.api.request({
2089
- url: "/api/ai/abort",
2090
- method: "POST"
2091
- });
2092
- }
2093
2204
  /**
2094
2205
  * Ask the AI assistant a question
2095
2206
  * @param {string} question Users question
2096
- * @param {AiOptions & {stream: Function}} options context - Any hidden context information. stream - Receive response in chunks
2207
+ * @param {AiOptions & {stream: Function}} options Pass a conversationId to persist/continue a thread; omit for a one-off.
2208
+ * Pass messageIndex to edit (new text) or retry (same text) a prior exchange - history is truncated to that point first.
2097
2209
  * @return {Promise<string>} AI's response
2098
2210
  */
2099
2211
  async ask(question, options = {}) {
2100
2212
  if (!question) throw new Error("Cannot ask AI, missing question");
2101
- const files = (await Promise.all((options?.files || []).map((f) => new Promise((res) => {
2102
- const reader = new FileReader();
2103
- reader.onload = () => res([f.name, reader.result]);
2104
- reader.readAsDataURL(f);
2105
- })))).reduce((acc, f) => ({
2106
- ...acc,
2107
- [f[0]]: f[1]
2108
- }), {});
2213
+ const { stream, files: rawFiles, ...rest } = options;
2214
+ const files = await Promise.all((rawFiles || []).map(toFileUpload));
2109
2215
  const q = {
2110
- ...options,
2216
+ ...rest,
2111
2217
  question: question.trim(),
2112
- files: Object.keys(files).length ? files : void 0
2218
+ files: files.length ? files : void 0
2113
2219
  };
2114
- if (options.stream && this.momentum.socket?.connected) {
2220
+ if (!q.conversationId) delete q.conversationId;
2221
+ if (stream && this.momentum.socket?.connected) {
2115
2222
  let unsub = () => {};
2116
2223
  return new Promise((res) => {
2117
2224
  let buffer = "";
2118
2225
  unsub = this.momentum.socket?.on("llm", (event, chunk) => {
2119
- options.stream?.(chunk);
2226
+ stream(chunk);
2120
2227
  if (chunk.text) buffer += chunk.text;
2121
2228
  if (chunk.done) res(buffer);
2122
2229
  });
@@ -2132,28 +2239,8 @@ var Ai = class extends PathEventEmitter {
2132
2239
  });
2133
2240
  }
2134
2241
  /**
2135
- * Clear AI assistant memory & context
2136
- * @return {Promise<void>} Resolves once complete
2137
- */
2138
- clear() {
2139
- return this.momentum.api.request({
2140
- url: "api/ai",
2141
- method: "DELETE"
2142
- }).then(() => this.emit(PES`:d`, this.momentum.api.token));
2143
- }
2144
- /**
2145
- * Current chat history
2146
- * @return {Promise<AiMessage[]>}
2147
- */
2148
- history() {
2149
- return this.momentum.api.request({ url: "api/ai" }).then((resp) => {
2150
- this.emit(PES`:r`, resp);
2151
- return resp;
2152
- });
2153
- }
2154
- /**
2155
2242
  * Get model info
2156
- * @return {AiInfo>} Model Info
2243
+ * @return {Promise<{[name: string]: string}>} Model Info
2157
2244
  */
2158
2245
  tools() {
2159
2246
  return this.momentum.api.request({ url: "api/ai/tools" });
@@ -3377,36 +3464,16 @@ var Client = class Client extends PathEventEmitter {
3377
3464
  const t = {
3378
3465
  background: setting?.background,
3379
3466
  backgroundContrast: contrast(setting?.background),
3380
- surface: setting?.darkMode ? "#2e2e2e" : "#ffffff",
3381
- border: setting?.darkMode ? "#374151" : "#E5E7EB",
3382
- text: setting?.darkMode ? "#ffffff" : "#000000",
3383
- muted: setting?.darkMode ? "#cccccc" : "#6c757d",
3384
3467
  primary: setting?.primary,
3385
3468
  primaryContrast: contrast(setting?.primary),
3386
3469
  accent: setting?.accent,
3387
3470
  accentContrast: contrast(setting?.accent),
3388
- info: "#6157cc",
3389
- success: "#65c147",
3390
- warn: "#d88750",
3391
- danger: "#bf4f4f",
3392
- black: "black",
3393
- white: "white",
3394
3471
  font: setting?.font,
3395
- lighter: setting?.darkMode ? "rgba(255, 255, 255, 0.1)" : "rgba(255, 255, 255, 0.05)",
3396
- darker: setting?.darkMode ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.05)"
3472
+ radius: "0.5rem"
3397
3473
  };
3398
3474
  if (!css) return t;
3399
- return `:root, :root .theme-${setting?.darkMode ? "dark" : "light"} {
3475
+ return `:root {
3400
3476
  ${Object.entries(t).map(([name, value]) => `--theme-${kebabCase(name)}: ${value} !important;`).join("\n")}
3401
- }
3402
-
3403
- :root .theme-${!setting?.darkMode ? "dark" : "light"} {
3404
- --theme-surface: ${!setting?.darkMode ? "#2e2e2e" : "#ffffff"} !important;
3405
- --theme-border: ${!setting?.darkMode ? "#374151" : "#E5E7EB"} !important;
3406
- --theme-text: ${!setting?.darkMode ? "#ffffff" : "#000000"} !important;
3407
- --theme-muted: ${!setting?.darkMode ? "#cccccc" : "#6c757d"} !important;
3408
- --theme-lighter: ${!setting?.darkMode ? "rgba(255, 255, 255, 0.1)" : "rgba(255, 255, 255, 0.05)"};
3409
- --theme-darker: ${!setting?.darkMode ? "rgba(0, 0, 0, 0.1)" : "rgba(0, 0, 0, 0.05)"};
3410
3477
  }`;
3411
3478
  }
3412
3479
  /**
@@ -4948,7 +5015,7 @@ var Static = class extends Storage {
4948
5015
  };
4949
5016
  //#endregion
4950
5017
  //#region package.json
4951
- var version = "1.5.5";
5018
+ var version = "1.5.7";
4952
5019
  //#endregion
4953
5020
  //#region src/webRtc.ts
4954
5021
  var WebRtc = class extends PathEventEmitter {
@@ -5271,4 +5338,4 @@ var Momentum = class Momentum extends PathEventEmitter {
5271
5338
  }
5272
5339
  };
5273
5340
  //#endregion
5274
- export { ActionType, Actions, Agents, Ai, Analytics, Api, Audit, Auth, Blacklist, Call, Captcha, Client, Data, Discounts, Email, Forms, Groups, Logger, Momentum, Notifications, PE, PES, PathEvent, PathEventEmitter, Pdf, Permissions, Products, RateLimiter, Routes, Schemas, Settings, Skills, Sms, Socket, Static, Storage, Templates, Tokens, Totp, Transactions, Users, WebRtc, treeBuilder, validEvent };
5341
+ export { ActionType, Actions, Agents, Ai, Analytics, Api, Audit, Auth, Blacklist, Call, Captcha, Client, Conversations, Data, Discounts, Email, Forms, Groups, Logger, Momentum, Notifications, PE, PES, PathEvent, PathEventEmitter, Pdf, Permissions, Products, RateLimiter, Routes, Schemas, Settings, Skills, Sms, Socket, Static, Storage, Templates, Tokens, Totp, Transactions, Users, WebRtc, treeBuilder, validEvent };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ztimson/momentum",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "Client library for momentum",
5
5
  "keywords": [
6
6
  "Momentum"
@@ -33,7 +33,7 @@
33
33
  "postbuild": "npm run build:docs && node -e \"const fs=require('fs');fs.cpSync('dist/index.mjs','../server/public/momentum.mjs');fs.cpSync('dist/index.js','../server/public/momentum.js');fs.cpSync('dist/momentum.worker.mjs','../server/public/momentum.worker.mjs')\""
34
34
  },
35
35
  "dependencies": {
36
- "@ztimson/utils": "^0.30.2"
36
+ "@ztimson/utils": "^0.30.8"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^26.1.1",