@shardworks/parlour-apparatus 0.1.101

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/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Sean Boots
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,195 @@
1
+ # `@shardworks/parlour-apparatus`
2
+
3
+ The Parlour manages multi-turn conversations within the guild. It provides the structure for two kinds of interaction: **consult** (a human talks to an anima) and **convene** (multiple animas hold a structured dialogue). The Parlour orchestrates turns — deciding *when* and *for whom* to call The Animator — while delegating session launch to The Animator and context composition to The Loom.
4
+
5
+ The Parlour sits downstream of both The Animator and The Loom in the dependency graph: `stacks <- animator <- parlour` and `loom <- parlour`.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ Add to your package's dependencies:
12
+
13
+ ```json
14
+ {
15
+ "@shardworks/parlour-apparatus": "workspace:*"
16
+ }
17
+ ```
18
+
19
+ The Parlour requires The Stacks, The Animator, and The Loom to be installed in the guild.
20
+
21
+ ---
22
+
23
+ ## API
24
+
25
+ The Parlour exposes a `ParlourApi` via its `provides` interface, retrieved at runtime:
26
+
27
+ ```typescript
28
+ import type { ParlourApi } from '@shardworks/parlour-apparatus';
29
+
30
+ const parlour = guild().apparatus<ParlourApi>('parlour');
31
+ ```
32
+
33
+ ### `create(request): Promise<CreateConversationResult>`
34
+
35
+ Create a new conversation. Sets up the conversation and participant records but does NOT take a first turn.
36
+
37
+ ```typescript
38
+ const { conversationId, participants } = await parlour.create({
39
+ kind: 'consult',
40
+ topic: 'Help me refactor the session layer',
41
+ turnLimit: 10,
42
+ cwd: '/workspace/shardworks',
43
+ participants: [
44
+ { kind: 'human', name: 'Sean' },
45
+ { kind: 'anima', name: 'Artificer' },
46
+ ],
47
+ });
48
+ ```
49
+
50
+ | Parameter | Type | Description |
51
+ |---|---|---|
52
+ | `kind` | `'consult' \| 'convene'` | Conversation kind |
53
+ | `topic` | `string` | Seed topic / initial prompt (optional) |
54
+ | `turnLimit` | `number` | Max anima turns before auto-conclude (optional) |
55
+ | `cwd` | `string` | Working directory — persists for the conversation's lifetime |
56
+ | `participants` | `ParticipantDeclaration[]` | Who is in the conversation |
57
+ | `eventId` | `string` | Triggering event id (optional, for clockworks) |
58
+
59
+ ### `takeTurn(request): Promise<TurnResult>`
60
+
61
+ Take a turn in a conversation. For anima participants, weaves context and calls The Animator. For human participants, records the message as context for the next anima turn.
62
+
63
+ ```typescript
64
+ // Human turn — records message, no session launched
65
+ await parlour.takeTurn({
66
+ conversationId,
67
+ participantId: humanId,
68
+ message: 'What about the error handling?',
69
+ });
70
+
71
+ // Anima turn — launches a session via The Animator
72
+ const result = await parlour.takeTurn({
73
+ conversationId,
74
+ participantId: animaId,
75
+ message: 'What about the error handling?', // or omit to use topic
76
+ });
77
+ // result.sessionResult contains the Animator's SessionResult
78
+ // result.turnNumber is the 1-indexed turn count
79
+ // result.conversationActive indicates if the conversation is still open
80
+ ```
81
+
82
+ ### `takeTurnStreaming(request): { chunks, result }`
83
+
84
+ Same as `takeTurn()`, but streams output chunks as the session produces them. Returns synchronously with `{ chunks, result }` — same pattern as The Animator.
85
+
86
+ ```typescript
87
+ const { chunks, result } = parlour.takeTurnStreaming({
88
+ conversationId,
89
+ participantId: animaId,
90
+ });
91
+
92
+ for await (const chunk of chunks) {
93
+ if (chunk.type === 'text') process.stdout.write(chunk.text);
94
+ if (chunk.type === 'turn_complete') console.log(`\nTurn ${chunk.turnNumber} done`);
95
+ }
96
+
97
+ const turnResult = await result;
98
+ ```
99
+
100
+ Chunk types include all `SessionChunk` types from The Animator, plus:
101
+ - `{ type: 'turn_complete', turnNumber, costUsd? }` — emitted after the session completes
102
+
103
+ ### `nextParticipant(conversationId): Promise<Participant | null>`
104
+
105
+ Get the next participant in line. For consult: always returns the anima. For convene: round-robin by insertion order. Returns `null` if the conversation is ended or the turn limit is reached.
106
+
107
+ ### `end(conversationId, reason?): Promise<void>`
108
+
109
+ End a conversation. Reason defaults to `'concluded'`. Idempotent — safe to call on already-ended conversations.
110
+
111
+ ### `list(options?): Promise<ConversationSummary[]>`
112
+
113
+ List conversations with optional filters by `status`, `kind`, and `limit`. Returns summaries ordered by `createdAt` descending.
114
+
115
+ ### `show(conversationId): Promise<ConversationDetail | null>`
116
+
117
+ Show full detail for a conversation including all turns, participant list, and aggregate cost.
118
+
119
+ ---
120
+
121
+ ## Configuration
122
+
123
+ No guild-level configuration is required. The Parlour reads its dependencies from the guild's apparatus registry at startup.
124
+
125
+ ---
126
+
127
+ ## Support Kit
128
+
129
+ The Parlour contributes two books and three tools to the guild:
130
+
131
+ ### Books
132
+
133
+ | Book | Indexes | Contents |
134
+ |---|---|---|
135
+ | `conversations` | `status`, `kind`, `createdAt` | Conversation documents with nested participant records |
136
+ | `turns` | `conversationId`, `turnNumber`, `participantId`, `participantKind` | Per-turn records linking conversations to Animator sessions |
137
+
138
+ ### Tools
139
+
140
+ | Tool | Permission | Description |
141
+ |---|---|---|
142
+ | `conversation-list` | `read` | List conversations with optional status/kind filters |
143
+ | `conversation-show` | `read` | Show full conversation detail including all turns |
144
+ | `conversation-end` | `write` | End an active conversation (concluded or abandoned) |
145
+
146
+ ---
147
+
148
+ ## Key Types
149
+
150
+ ```typescript
151
+ interface CreateConversationRequest {
152
+ kind: 'consult' | 'convene';
153
+ topic?: string;
154
+ turnLimit?: number;
155
+ participants: ParticipantDeclaration[];
156
+ cwd: string;
157
+ eventId?: string;
158
+ }
159
+
160
+ interface ParticipantDeclaration {
161
+ kind: 'anima' | 'human';
162
+ name: string;
163
+ }
164
+
165
+ interface TurnResult {
166
+ sessionResult: SessionResult | null; // null for human turns
167
+ turnNumber: number;
168
+ conversationActive: boolean;
169
+ }
170
+
171
+ interface ConversationSummary {
172
+ id: string;
173
+ status: 'active' | 'concluded' | 'abandoned';
174
+ kind: 'consult' | 'convene';
175
+ topic: string | null;
176
+ participants: Participant[];
177
+ turnCount: number;
178
+ totalCostUsd: number;
179
+ // ... timestamps, turnLimit
180
+ }
181
+ ```
182
+
183
+ See `src/types.ts` for the complete type definitions.
184
+
185
+ ---
186
+
187
+ ## Exports
188
+
189
+ The package exports all public types and the `createParlour()` factory:
190
+
191
+ ```typescript
192
+ import parlourPlugin, { createParlour, type ParlourApi } from '@shardworks/parlour-apparatus';
193
+ ```
194
+
195
+ The default export is a pre-built plugin instance, ready for guild installation.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @shardworks/parlour-apparatus — The Parlour.
3
+ *
4
+ * Multi-turn conversation management: creates conversations, registers
5
+ * participants, orchestrates turns (with streaming), enforces turn limits,
6
+ * and ends conversations. Delegates session launch to The Animator and
7
+ * context composition to The Loom.
8
+ *
9
+ * See: docs/architecture/apparatus/parlour.md
10
+ */
11
+ export { type ParlourApi, type ConversationDoc, type TurnDoc, type ParticipantRecord, type Participant, type CreateConversationRequest, type CreateConversationResult, type ParticipantDeclaration, type TakeTurnRequest, type TurnResult, type ConversationChunk, type ConversationSummary, type ConversationDetail, type TurnSummary, type ListConversationsOptions, } from './types.ts';
12
+ export { createParlour } from './parlour.ts';
13
+ declare const _default: import("@shardworks/nexus-core").Plugin;
14
+ export default _default;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,EACL,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,wBAAwB,GAC9B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;;AAI7C,wBAA+B"}
package/dist/index.js ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @shardworks/parlour-apparatus — The Parlour.
3
+ *
4
+ * Multi-turn conversation management: creates conversations, registers
5
+ * participants, orchestrates turns (with streaming), enforces turn limits,
6
+ * and ends conversations. Delegates session launch to The Animator and
7
+ * context composition to The Loom.
8
+ *
9
+ * See: docs/architecture/apparatus/parlour.md
10
+ */
11
+ import { createParlour } from "./parlour.js";
12
+ // ── Parlour API ─────────────────────────────────────────────────────
13
+ export {} from "./types.js";
14
+ export { createParlour } from "./parlour.js";
15
+ // ── Default export: the apparatus plugin ──────────────────────────────
16
+ export default createParlour();
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,uEAAuE;AAEvE,OAAO,EAgBN,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,yEAAyE;AAEzE,eAAe,aAAa,EAAE,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The Parlour — multi-turn conversation management apparatus.
3
+ *
4
+ * Manages two kinds of conversation:
5
+ * - consult: a human talks to an anima
6
+ * - convene: multiple animas hold a structured dialogue
7
+ *
8
+ * The Parlour orchestrates turns — it decides when and for whom to call
9
+ * The Animator, and tracks conversation state in The Stacks. It does not
10
+ * launch sessions itself (delegates to The Animator) or assemble prompts
11
+ * (delegates to The Loom).
12
+ *
13
+ * See: docs/architecture/apparatus/parlour.md
14
+ */
15
+ import type { Plugin } from '@shardworks/nexus-core';
16
+ /**
17
+ * Create the Parlour apparatus plugin.
18
+ *
19
+ * Returns a Plugin with:
20
+ * - `requires: ['stacks', 'animator', 'loom']` — conversation orchestration
21
+ * - `provides: ParlourApi` — the conversation management API
22
+ * - `supportKit` — contributes `conversations` + `turns` books + management tools
23
+ */
24
+ export declare function createParlour(): Plugin;
25
+ //# sourceMappingURL=parlour.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parlour.d.ts","sourceRoot":"","sources":["../src/parlour.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,wBAAwB,CAAC;AAiMrE;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,MAAM,CA+etC"}