@sparkelf/dsh-group-chat 0.0.0-stage → 0.2.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/README.md +90 -2
- package/cordis.patch.yml +3 -0
- package/lib/client.js +4856 -0
- package/lib/client.js.map +1 -0
- package/lib/index.d.ts +357 -0
- package/lib/index.js +10087 -0
- package/package.json +98 -4
package/README.md
CHANGED
|
@@ -1,3 +1,91 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
kind: package-readme
|
|
3
|
+
---
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
# @sparkelf/dsh-group-chat
|
|
6
|
+
|
|
7
|
+
Human-agent group chat for DataOps-managed DSH workspaces.
|
|
8
|
+
|
|
9
|
+
A room is a message bus shared by its members. Every member's workspace keeps its own
|
|
10
|
+
copy of every message, and each member's agent is a **local subscriber** that acts
|
|
11
|
+
only on its own instructions:
|
|
12
|
+
|
|
13
|
+
| Situation | What happens |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Any member posts anything | Broadcast to every member; each workspace appends it to the room's session, so each agent can read the whole conversation |
|
|
16
|
+
| A member mentions **themselves** | That member's own agent runs a turn |
|
|
17
|
+
| A member mentions someone else | Ordinary message — recorded and read, never executed |
|
|
18
|
+
| `@everyone`, or no mention | Ordinary message — no agent runs |
|
|
19
|
+
|
|
20
|
+
## Why the mention rule is this narrow
|
|
21
|
+
|
|
22
|
+
One rule decides every case: **a message runs an agent only when its sender
|
|
23
|
+
mentioned themselves.** Everything else is recorded and read, never executed.
|
|
24
|
+
|
|
25
|
+
That is a deliberate trade, and it is what makes the design safe and simple:
|
|
26
|
+
|
|
27
|
+
- **Nobody can drive someone else's agent.** A mention never reaches another
|
|
28
|
+
member's container, so it can never spend their model budget or reach their files.
|
|
29
|
+
- **No fan-out.** `@everyone` is an ordinary message, so it does not start N agent
|
|
30
|
+
runs.
|
|
31
|
+
- **Visibility is not gated, only execution.** Every message still enters every
|
|
32
|
+
agent's context, so an agent answering later has read the whole conversation.
|
|
33
|
+
|
|
34
|
+
The trade is that a room has no shared intelligence — only each member's own agent
|
|
35
|
+
plus a shared transcript. In exchange, no cross-container coordination protocol,
|
|
36
|
+
consensus algorithm, or distributed transaction is needed.
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
DataOps backend ← identity, global order, storage, routing
|
|
42
|
+
↑ POST (ack) ↓ pull (cursor)
|
|
43
|
+
workspace container ← one DSH per member
|
|
44
|
+
agent + session log
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
- **Uplink** is an awaited POST. The backend assigns the globally ordered id and
|
|
48
|
+
returns the finalized event; the event is appended locally **only after** that
|
|
49
|
+
acknowledgement, so a rejected message never enters the append-only log.
|
|
50
|
+
- **Downlink** is a cursor pull. The backend is the only cross-container
|
|
51
|
+
intersection point, so it is also the only authority on order; a cursor is the
|
|
52
|
+
entire synchronization state and survives a restart.
|
|
53
|
+
- **Idempotency** is `source.rpcId` — the identity DSH already mints for reconciling
|
|
54
|
+
optimistic and durable messages — enforced by a unique index, so a retried or
|
|
55
|
+
double-clicked send produces one message.
|
|
56
|
+
- **Only the turn's final `assistant/message` is published.** Intermediate steps,
|
|
57
|
+
file reads, and tool output never leave the member's own workspace.
|
|
58
|
+
|
|
59
|
+
## Configuration
|
|
60
|
+
|
|
61
|
+
The plugin reads the workspace identity DataOps already injects into the container.
|
|
62
|
+
It mints no credential of its own:
|
|
63
|
+
|
|
64
|
+
| Variable | Purpose |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `DATAOPS_AI_WORKSPACE_INTERNAL_TOKEN` | Credential the backend verifies |
|
|
67
|
+
| `DATAOPS_AI_WORKSPACE_USER_ID` | The account this workspace belongs to |
|
|
68
|
+
| `DATAOPS_AI_WORKSPACE_BACKEND_BASE_URL` | Backend origin |
|
|
69
|
+
| `DATAOPS_AI_WORKSPACE_MOUNT_PATH` | Workspace root, used as the room session's `cwd` |
|
|
70
|
+
|
|
71
|
+
**On any DSH where those are absent — a developer's own installation, for
|
|
72
|
+
instance — the plugin registers nothing at all:** no route, no listener, no timer.
|
|
73
|
+
Ordinary sessions are byte-identical with and without it installed. This is asserted
|
|
74
|
+
by a test whose context throws on every property read.
|
|
75
|
+
|
|
76
|
+
## Rooms and sessions
|
|
77
|
+
|
|
78
|
+
One room maps to one DSH session, named `group-room-<roomId>`. The binding lives in
|
|
79
|
+
the session id because `SessionHeader` carries no free-form metadata field. An
|
|
80
|
+
ordinary session never matches that prefix, which is the second half of how this
|
|
81
|
+
plugin stays out of the way.
|
|
82
|
+
|
|
83
|
+
## Known limits
|
|
84
|
+
|
|
85
|
+
- **Display names are not authentication.** The backend verifies *who* a caller is
|
|
86
|
+
(a workspace-scoped HMAC binds the credential to one account); it does not verify
|
|
87
|
+
what they type as their name.
|
|
88
|
+
- **A member's nickname is a snapshot.** It is copied at write time so a later
|
|
89
|
+
rename cannot rewrite history.
|
|
90
|
+
- **Offline members catch up by cursor.** A workspace that stays unreachable keeps a
|
|
91
|
+
gap in its local copy; the plugin does not fabricate a completeness marker for it.
|
package/cordis.patch.yml
ADDED