@mercury-fw/channel-google-chat 0.1.3 → 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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @mercury-fw/channel-google-chat
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 521db42: Isolation between the people an agent talks to.
8
+
9
+ - The core keeps one identity per person, `<provider>:<id>`, so two providers issuing the same id are two people. Memory, the conversation archive, the tool log and pending confirmations are keyed on it.
10
+ - The wiki has a common area (`curated/`) everyone reads and an area per person (`users/<key>/`), which the model sees as `personal/`. Listing, reading and grepping reach the common area and the caller's own area, nothing else.
11
+ - Breaking: the model's `write_file` writes only under `personal/notes/`. The new `promote_note` tool copies one of the person's notes into `curated/`, and only once they confirm it with the token.
12
+ - A confirmation can only be confirmed by whoever staged it, in the same session. Its note is written once, in the person's area: a staged note no longer stays "pending" after it's resolved, for ids such as Google Chat's `users/<n>`.
13
+ - Breaking, `@mercury-fw/channel-types`: channel contract 3. `confirm` and `resolveConfirmation` take the caller's `Principal`, and so does every read getter except `manifest` and `health`. Channels written for contract 2 are refused.
14
+ - `@mercury-fw/confirm-engine`: the store's `stage`, `take` and `pending` take the owner's key.
15
+ - Breaking, `@mercury-fw/channel-http`: every read route returns only the caller's data. `/conversation?id=` takes one of the caller's `conversationId`s and `/conversations` lists them by `conversationId`. `/wiki/read` answers `404` outside what the caller can see, and `/memory/scroll` answers `400` for a collection that isn't kept per person.
16
+ - `@mercury-fw/channel-google-chat`: on channel contract 3.
17
+ - At startup, an instance's existing data moves to the new layout. Google Chat and terminal notes go into their areas, and Qdrant's ids go onto the new keys. Ids that don't say which provider they came from are left in place and logged.
18
+ - `mfw vault read` refuses a path outside the vault.
19
+ - The admin panel's wiki box edits the common area with the operator's tools (list, read, grep, `write_curated`), the same the nightly review uses.
20
+
21
+ ## 0.2.0
22
+
23
+ ### Minor Changes
24
+
25
+ - 8bed46b: - A turn carries a `Principal` (the person behind it and the provider that vouched for them) instead of the opaque `userId` and `wikiUserId`; the core derives every per-person id from it.
26
+ - Episodic memory follows the principal, not the channel: a session is captured whenever a provider vouched for the person. Google Chat keeps the ids it had; the terminal and the HTTP channel (until it authenticates its callers) send a principal nobody vouched for, so they stay out of episodic memory as before.
27
+ - The HTTP channel accepts a `conversationId` on `/turn` and `/confirm` only made of letters, digits, `-` and `_`, up to 128 characters once trimmed, and answers `400` otherwise: a client-chosen id can no longer reach another user's wiki notes, forge log lines or break the turn. An existing HTTP conversation whose id has other characters can still be read with `/conversation`, but not continued. `/conversation` keeps opening any session key `/conversations` lists, whatever channel it came from.
28
+ - The model's wiki read tools refuse a per-user id that isn't one path segment, as writes already did.
29
+ - `CHANNEL_API_VERSION` is 2: a channel written for version 1 is refused at load.
30
+ - The first-party channels declare their channel api version as a literal, so an older channel can't claim a newer contract it doesn't implement.
31
+
3
32
  ## 0.1.3
4
33
 
5
34
  ### Patch Changes
@@ -21,7 +21,7 @@
21
21
  */
22
22
  import { sendMessage, sendCard, updateCard, getOrCreateDmSpace, type ServiceAccountCredentials, type TokenSource } from "./google-chat-app-client.ts";
23
23
  import { type PubSubSubscription } from "./google-chat-pubsub-stream.ts";
24
- import { type Provider } from "@mercury-fw/channel-types";
24
+ import { type Provider, type Principal } from "@mercury-fw/channel-types";
25
25
  /**
26
26
  * Composite session key: space + sender. Deliberately does NOT include
27
27
  * `thread` — confirmed live (two consecutive messages in the same DM
@@ -69,7 +69,7 @@ export type GoogleChatProviderDeps = {
69
69
  * the channel's contact with confirmation — the store, vault and note-writer
70
70
  * stay in the core.
71
71
  */
72
- confirm: (token: string, sessionKey: string, userId: string) => Promise<string | null>;
72
+ confirm: (token: string, sessionKey: string, principal: Principal) => Promise<string | null>;
73
73
  /**
74
74
  * Handles a `CARD_CLICKED` event's action parameters. Defaults to resolving
75
75
  * the confirm button's token through `deps.confirm` (the same path a bare
package/dist/index.d.ts CHANGED
@@ -7,5 +7,5 @@
7
7
  * missing is a misconfiguration: `build()` throws and the loader skips this
8
8
  * channel fail-soft, leaving the rest of Mercury up.
9
9
  */
10
- import { type ChannelPlugin } from "@mercury-fw/channel-types";
10
+ import type { ChannelPlugin } from "@mercury-fw/channel-types";
11
11
  export declare const googleChatChannel: ChannelPlugin;
@@ -40,6 +40,7 @@ import {
40
40
  type Provider,
41
41
  type HandleTurn,
42
42
  type TurnSink,
43
+ type Principal,
43
44
  } from "@mercury-fw/channel-types";
44
45
 
45
46
  /**
@@ -257,7 +258,7 @@ export type GoogleChatProviderDeps = {
257
258
  * the channel's contact with confirmation — the store, vault and note-writer
258
259
  * stay in the core.
259
260
  */
260
- confirm: (token: string, sessionKey: string, userId: string) => Promise<string | null>;
261
+ confirm: (token: string, sessionKey: string, principal: Principal) => Promise<string | null>;
261
262
  /**
262
263
  * Handles a `CARD_CLICKED` event's action parameters. Defaults to resolving
263
264
  * the confirm button's token through `deps.confirm` (the same path a bare
@@ -315,7 +316,7 @@ export function createGoogleChatProvider(deps: GoogleChatProviderDeps): GoogleCh
315
316
  log(`[chat] card click with no token parameter`);
316
317
  return;
317
318
  }
318
- const reply = await deps.confirm(token, deriveSessionKey(space, sender), sender);
319
+ const reply = await deps.confirm(token, deriveSessionKey(space, sender), { id: sender, provider: "google-chat" });
319
320
  if (reply !== null) {
320
321
  log(`[chat:${space}] [out] ${reply}`);
321
322
  const sent = await sendMessageFn(space, reply, clientDeps);
@@ -478,7 +479,13 @@ export function createGoogleChatProvider(deps: GoogleChatProviderDeps): GoogleCh
478
479
  const sessionKey = deriveSessionKey(event.space, event.sender);
479
480
  const markedInput = event.senderDisplayName ? `[Da: ${event.senderDisplayName}]\n${event.text}` : event.text;
480
481
 
481
- const confirmReply = await deps.confirm(event.text, sessionKey, event.sender);
482
+ const principal: Principal = {
483
+ id: event.sender,
484
+ provider: "google-chat",
485
+ ...(event.senderDisplayName ? { displayName: event.senderDisplayName } : {}),
486
+ };
487
+
488
+ const confirmReply = await deps.confirm(event.text, sessionKey, principal);
482
489
  if (confirmReply !== null) {
483
490
  log(`[chat:${event.space}] [out] ${confirmReply}`);
484
491
  const sent = await sendMessageFn(event.space, confirmReply, clientDeps);
@@ -505,8 +512,7 @@ export function createGoogleChatProvider(deps: GoogleChatProviderDeps): GoogleCh
505
512
  multiUser: !event.isDirectMessage,
506
513
  text: markedInput,
507
514
  sessionKey,
508
- userId: event.sender,
509
- wikiUserId: encodeURIComponent(event.sender),
515
+ principal,
510
516
  logPrefix: `[chat:${event.space}:${event.sender}] `,
511
517
  },
512
518
  sink,
package/index.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * missing is a misconfiguration: `build()` throws and the loader skips this
8
8
  * channel fail-soft, leaving the rest of Mercury up.
9
9
  */
10
- import { CHANNEL_API_VERSION, type ChannelPlugin, type ChannelRuntimeContext } from "@mercury-fw/channel-types";
10
+ import type { ChannelPlugin, ChannelRuntimeContext } from "@mercury-fw/channel-types";
11
11
  import { createGoogleChatProvider } from "./google-chat-provider.ts";
12
12
 
13
13
  /** Reads a required env var, failing loudly (caught by the channel loader) instead of silently degrading. */
@@ -20,7 +20,9 @@ function require(env: ChannelRuntimeContext["env"], name: string): string {
20
20
  }
21
21
 
22
22
  export const googleChatChannel: ChannelPlugin = {
23
- apiVersion: CHANNEL_API_VERSION,
23
+ // The contract this channel is written for, as a literal: importing
24
+ // CHANNEL_API_VERSION would report whichever contract is installed.
25
+ apiVersion: 3,
24
26
  name: "google-chat",
25
27
  build: (ctx) => {
26
28
  // No subscription configured ⇒ this instance simply doesn't run Google Chat.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mercury-fw/channel-google-chat",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,10 +31,10 @@
31
31
  "@google-cloud/pubsub": "^5.3.1"
32
32
  },
33
33
  "peerDependencies": {
34
- "@mercury-fw/channel-types": ">=0.24.0 <1.0.0"
34
+ "@mercury-fw/channel-types": ">=0.36.0 <1.0.0"
35
35
  },
36
36
  "devDependencies": {
37
- "@mercury-fw/channel-types": "0.29.2",
37
+ "@mercury-fw/channel-types": "0.36.0",
38
38
  "@mercury-fw/typescript-config": "*",
39
39
  "@types/bun": "^1.4.2",
40
40
  "typescript": "^6.0.3"