@matatbread/matbot-core 0.4.16 → 0.4.18

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/src/session.ts CHANGED
@@ -1,13 +1,14 @@
1
- import type { Session, Message } from './types.js';
1
+ import type { Session, SessionStatus, Message } from './types.js';
2
2
 
3
3
  // `createMessage` lives in plugin-api, where the hook registry can also reach it (core is downstream of
4
4
  // that package). Re-exported here so it stays where every consumer already imports it from.
5
5
  export { createMessage } from '@matatbread/matbot-plugin-api';
6
6
 
7
7
  export interface CreateSessionOpts {
8
- title?: string;
9
- parentSessionId?: string;
10
- branchPointMessageId?: string;
8
+ title?: string;
9
+ /** Defaults to `'active'`. `'archived'` creates it hidden: off the default session list from the
10
+ * start, rather than created visible and hidden by a second write. */
11
+ status?: SessionStatus;
11
12
  }
12
13
 
13
14
  export function createSession(opts: CreateSessionOpts = {}): Session {
@@ -15,10 +16,8 @@ export function createSession(opts: CreateSessionOpts = {}): Session {
15
16
  return {
16
17
  id: crypto.randomUUID(),
17
18
  version: crypto.randomUUID(),
18
- ...(opts.title !== undefined ? { title: opts.title } : {}),
19
- ...(opts.parentSessionId !== undefined ? { parentSessionId: opts.parentSessionId } : {}),
20
- ...(opts.branchPointMessageId !== undefined ? { branchPointMessageId: opts.branchPointMessageId } : {}),
21
- status: 'active',
19
+ ...(opts.title !== undefined ? { title: opts.title } : {}),
20
+ status: opts.status ?? 'active',
22
21
  messages: [],
23
22
  createdAt: now,
24
23
  updatedAt: now,
package/src/settings.ts CHANGED
@@ -148,7 +148,7 @@ export function makePluginSettings(rawStore: Store<SettingsDoc>, namespace: stri
148
148
  const doc = await getDoc();
149
149
  const data = mutate(doc?.data ?? {});
150
150
  if (data === undefined) return;
151
- const next: SettingsDoc = { id, version: Date.now().toString(), data };
151
+ const next: SettingsDoc = { id, version: crypto.randomUUID(), data };
152
152
  if (doc === null) { await store.set(id, next); return; }
153
153
  const r = await store.cas(id, doc.version, next);
154
154
  if (r.ok) return;
@@ -1,3 +1,4 @@
1
1
  export * from './query/index.js';
2
2
  export { CachingStorageBackend, type CachingOptions, type CacheNamespaceStats } from './caching-backend.js';
3
3
  export { mediumGuard } from './medium-guard.js';
4
+ export { MemoryStore } from './memory-store.js';
@@ -0,0 +1,34 @@
1
+ import type { Store, CASResult, StoreQuery, QueryResult } from '@matatbread/matbot-plugin-api';
2
+ import { executeQuery } from './query/index.js';
3
+
4
+ /** A `Store` held in a `Map`: nothing persists, nothing is announced, nothing outlives the instance. */
5
+ export class MemoryStore<T extends { id: string; version: string }> implements Store<T> {
6
+ private readonly items = new Map<string, T>();
7
+
8
+ async get(id: string): Promise<T | null> {
9
+ return this.items.get(id) ?? null;
10
+ }
11
+
12
+ async set(id: string, value: T): Promise<void> {
13
+ this.items.set(id, value);
14
+ }
15
+
16
+ async cas(id: string, expected: string, next: T): Promise<CASResult<T>> {
17
+ const current = this.items.get(id) ?? null;
18
+ if (current === null || current.version !== expected) return { ok: false, current };
19
+ this.items.set(id, next);
20
+ return { ok: true, doc: next };
21
+ }
22
+
23
+ async delete(id: string, expectedVersion?: string): Promise<boolean> {
24
+ if (expectedVersion !== undefined) {
25
+ const current = this.items.get(id);
26
+ if (current === undefined || current.version !== expectedVersion) return false;
27
+ }
28
+ return this.items.delete(id);
29
+ }
30
+
31
+ async query(q: StoreQuery): Promise<QueryResult<T>> {
32
+ return executeQuery([...this.items.values()], q);
33
+ }
34
+ }
@@ -5,6 +5,10 @@ interface TaggedContributor {
5
5
  pluginName?: string;
6
6
  }
7
7
 
8
+ /** The system prompt as sent: the parts joined, or null when there are none. */
9
+ export const joinSystemContext = (parts: readonly SystemContextPart[]): string | null =>
10
+ parts.length > 0 ? parts.map(p => p.text).join('\n\n') : null;
11
+
8
12
  export class SystemContextRegistryImpl implements SystemContextRegistry {
9
13
  private readonly _contributors: TaggedContributor[] = [];
10
14
 
@@ -32,9 +36,8 @@ export class SystemContextRegistryImpl implements SystemContextRegistry {
32
36
  }
33
37
 
34
38
  // The joined form is derived from the attributed one, so the prompt the model receives and the
35
- // breakdown `about_matbot` reports cannot drift: there is one traversal and one filter.
39
+ // breakdown `about_matbot` reports cannot drift: there is one traversal, one filter and one join.
36
40
  async build(ctx: { session: Session; signal: AbortSignal }): Promise<string | null> {
37
- const parts = await this.parts(ctx);
38
- return parts.length > 0 ? parts.map(p => p.text).join('\n\n') : null;
41
+ return joinSystemContext(await this.parts(ctx));
39
42
  }
40
43
  }
package/src/usage.ts CHANGED
@@ -12,12 +12,15 @@ export function addUsage(acc: Usage | undefined, next: Usage): Usage {
12
12
  const a = acc ?? { inputTokens: 0, outputTokens: 0 };
13
13
  const add = (x: number | undefined, y: number | undefined): number | undefined =>
14
14
  x === undefined && y === undefined ? undefined : (x ?? 0) + (y ?? 0);
15
+ const cacheReadTokens = add(a.cacheReadTokens, next.cacheReadTokens);
16
+ const cacheCreationTokens = add(a.cacheCreationTokens, next.cacheCreationTokens);
17
+ const reported = addReported(a.reported, next.reported);
15
18
  return {
16
19
  inputTokens: a.inputTokens + next.inputTokens,
17
20
  outputTokens: a.outputTokens + next.outputTokens,
18
- ...(((c) => c !== undefined ? { cacheReadTokens: c } : {}))(add(a.cacheReadTokens, next.cacheReadTokens)),
19
- ...(((c) => c !== undefined ? { cacheCreationTokens: c } : {}))(add(a.cacheCreationTokens, next.cacheCreationTokens)),
20
- ...(((r) => r !== undefined ? { reported: r } : {}))(addReported(a.reported, next.reported)),
21
+ ...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),
22
+ ...(cacheCreationTokens !== undefined ? { cacheCreationTokens } : {}),
23
+ ...(reported !== undefined ? { reported } : {}),
21
24
  };
22
25
  }
23
26