lumiverse-spindle-types 0.4.24 → 0.4.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lumiverse-spindle-types",
3
- "version": "0.4.24",
3
+ "version": "0.4.26",
4
4
  "types": "./src/index.ts",
5
5
  "keywords": [
6
6
  "lumiverse",
package/src/api.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { SpindleManifest } from "./manifest";
2
+ import type { CouncilMemberContext } from "./council";
2
3
 
3
4
  // ─── DTO types for messages ──────────────────────────────────────────────
4
5
 
@@ -946,6 +947,42 @@ export interface MessageSwipedPayloadDTO {
946
947
  previousSwipeId?: number;
947
948
  }
948
949
 
950
+ /**
951
+ * Payload delivered to `spindle.on("TOOL_INVOCATION", ...)` handlers.
952
+ *
953
+ * Fires whenever an extension-registered tool is invoked by Lumiverse. Handlers
954
+ * must return a string (or promise thereof) with the tool's result — the host
955
+ * coerces `undefined` / `null` to an empty string.
956
+ *
957
+ * `councilMember` is populated when the invocation originates from a council
958
+ * execution cycle, providing the assigned member's identity, role, chance,
959
+ * avatar URL, and Lumia personality fields. It is `undefined` for all other
960
+ * invocation paths.
961
+ *
962
+ * `contextMessages` is populated when the invocation originates from a council
963
+ * execution cycle — carrying the structured chat context (system enrichment +
964
+ * chat history) that was assembled for this member. Extensions can inspect
965
+ * role boundaries directly instead of re-parsing the flattened `args.context`
966
+ * string. Multi-part message content is flattened to its text portion before
967
+ * being delivered. `undefined` for non-council invocation paths.
968
+ */
969
+ export interface ToolInvocationPayloadDTO {
970
+ /** The bare (unqualified) tool name, matching what was passed to `registerTool`. */
971
+ toolName: string;
972
+ /** Arguments delivered to the tool. Shape depends on the tool's JSON Schema. */
973
+ args: Record<string, unknown>;
974
+ /** Host-side correlation id for this invocation. */
975
+ requestId: string;
976
+ /** Council member snapshot when invoked via council — otherwise `undefined`. */
977
+ councilMember?: CouncilMemberContext;
978
+ /**
979
+ * Structured chat context for council invocations — preserves role
980
+ * boundaries lost by the flattened `args.context` string. `undefined` for
981
+ * non-council paths.
982
+ */
983
+ contextMessages?: LlmMessageDTO[];
984
+ }
985
+
949
986
  /**
950
987
  * Observer handle returned by `spindle.generate.observe()`.
951
988
  * Provides a high-level API for watching an in-flight generation on a
@@ -1301,6 +1338,22 @@ export type HostToWorker =
1301
1338
  requestId: string;
1302
1339
  toolName: string;
1303
1340
  args: Record<string, unknown>;
1341
+ /**
1342
+ * Populated when the invocation originates from a council execution
1343
+ * cycle — carries the assigned council member's identity, role, chance,
1344
+ * avatar URL, and Lumia personality fields so the extension can tailor
1345
+ * its tool pipeline to the member on whose behalf it is running.
1346
+ *
1347
+ * Undefined for non-council invocation paths.
1348
+ */
1349
+ councilMember?: CouncilMemberContext;
1350
+ /**
1351
+ * Structured chat context for council invocations — the same messages
1352
+ * that populated `args.context` (flattened string), but with role
1353
+ * boundaries preserved so extensions can re-render or filter them
1354
+ * without parsing. Undefined for non-council invocation paths.
1355
+ */
1356
+ contextMessages?: LlmMessageDTO[];
1304
1357
  }
1305
1358
  | { type: "shutdown" }
1306
1359
  | { type: "frontend_message"; payload: unknown; userId: string }
package/src/council.ts CHANGED
@@ -77,6 +77,47 @@ export interface CouncilSettings {
77
77
  toolsSettings: CouncilToolsSettings;
78
78
  }
79
79
 
80
+ // ---- Tool Invocation Context ----
81
+
82
+ /**
83
+ * Personality snapshot of the council member that triggered a tool invocation.
84
+ *
85
+ * Delivered to extension `TOOL_INVOCATION` handlers when an extension-provided
86
+ * council tool is executed as part of a council cycle. Allows extensions to
87
+ * personalise their tool pipeline with the assigned member's identity, role,
88
+ * and Lumia personality fields.
89
+ *
90
+ * This field is optional — it is only populated when the tool is invoked via
91
+ * the council execution path. Tools invoked outside council (e.g. future
92
+ * inline function calling) will not see this context.
93
+ */
94
+ export interface CouncilMemberContext {
95
+ /** Unique council member id (council settings row id). */
96
+ memberId: string;
97
+ /** Source Lumia item id this member is backed by. */
98
+ itemId: string;
99
+ /** Pack id the Lumia item lives in. */
100
+ packId: string;
101
+ /** Pack name the Lumia item lives in. */
102
+ packName: string;
103
+ /** Display name of the Lumia item (also used as the member name). */
104
+ name: string;
105
+ /** Freeform role description assigned by the user (e.g. "Plot Enforcer"). */
106
+ role: string;
107
+ /** Probability (0–100) that this member participates each generation. */
108
+ chance: number;
109
+ /** Relative URL to the member's avatar (e.g. `/api/v1/images/{id}`), or null. */
110
+ avatarUrl: string | null;
111
+ /** Lumia item "definition" field — physical/identity description. */
112
+ definition: string;
113
+ /** Lumia item "personality" field. */
114
+ personality: string;
115
+ /** Lumia item "behavior" field — behavioural patterns. */
116
+ behavior: string;
117
+ /** Gender identity marker (0=unspecified, 1=feminine, 2=masculine). */
118
+ genderIdentity: 0 | 1 | 2;
119
+ }
120
+
80
121
  // ---- Execution Results ----
81
122
 
82
123
  /** Result of a single tool invocation for a single member. */
package/src/index.ts CHANGED
@@ -71,6 +71,7 @@ export type {
71
71
  ChatMessageDTO,
72
72
  MessageSwipeAction,
73
73
  MessageSwipedPayloadDTO,
74
+ ToolInvocationPayloadDTO,
74
75
  WorkerToHost,
75
76
  HostToWorker,
76
77
  } from "./api";
@@ -114,6 +115,7 @@ export type { SpindleAPI } from "./spindle-api";
114
115
 
115
116
  export type {
116
117
  CouncilMember,
118
+ CouncilMemberContext,
117
119
  SidecarConfig,
118
120
  CouncilSidecarConfig,
119
121
  CouncilToolsSettings,
@@ -45,6 +45,7 @@ import type {
45
45
  GenerationStoppedPayloadDTO,
46
46
  GenerationObserver,
47
47
  MessageSwipedPayloadDTO,
48
+ ToolInvocationPayloadDTO,
48
49
  StreamChunkDTO,
49
50
  } from "./api";
50
51
 
@@ -64,6 +65,21 @@ export interface SpindleAPI {
64
65
  * `swipeId` identifies which slot the event concerns.
65
66
  */
66
67
  on(event: "MESSAGE_SWIPED", handler: (payload: MessageSwipedPayloadDTO, userId?: string) => void): () => void;
68
+ /**
69
+ * Receive invocations for tools registered via {@link SpindleAPI.registerTool}.
70
+ *
71
+ * The handler must return the tool's textual result (or a promise thereof).
72
+ * Undefined / null returns are coerced to an empty string by the host.
73
+ *
74
+ * When the invocation originates from a council execution cycle, the payload
75
+ * includes a `councilMember` snapshot describing the assigned member
76
+ * (identity, role, chance, avatar URL, and Lumia personality fields) so the
77
+ * extension can tailor its tool output to that member's voice.
78
+ */
79
+ on(
80
+ event: "TOOL_INVOCATION",
81
+ handler: (payload: ToolInvocationPayloadDTO) => string | Promise<string> | void | Promise<void>
82
+ ): () => void;
67
83
  /** Subscribe to a Lumiverse event. */
68
84
  on(event: string, handler: (payload: unknown, userId?: string) => void): () => void;
69
85