@rei-standard/amsg-shared 0.1.0-next.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 +253 -0
- package/dist/index.cjs +170 -0
- package/dist/index.d.cts +352 -0
- package/dist/index.d.ts +352 -0
- package/dist/index.mjs +150 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# @rei-standard/amsg-shared
|
|
2
|
+
|
|
3
|
+
Lowest layer of the ReiStandard Active Messaging ecosystem. Defines
|
|
4
|
+
the **three-axis push contract** that `amsg-instant`, `amsg-server`,
|
|
5
|
+
`amsg-sw`, and `amsg-client` all conform to.
|
|
6
|
+
|
|
7
|
+
Zero runtime deps. Does **not** depend on any other amsg package —
|
|
8
|
+
every other amsg sub-package depends on this one, never the reverse.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Three axes
|
|
13
|
+
|
|
14
|
+
A single push is described by three orthogonal axes:
|
|
15
|
+
|
|
16
|
+
| Axis | Field | Values | Defined by |
|
|
17
|
+
|----------------|-------------------|-------------------------------------------------------|--------------------|
|
|
18
|
+
| Dispatch | `messageType` | `instant` / `fixed` / `prompted` / `auto` | Package (fixed) |
|
|
19
|
+
| Business | `messageSubtype` | Any string | Caller (free-form) |
|
|
20
|
+
| Content | `messageKind` | `content` / `reasoning` / `tool_request` / `error` | Package (fixed) |
|
|
21
|
+
|
|
22
|
+
`messageType` answers **how this push was produced** (one-shot
|
|
23
|
+
`instant` worker, scheduled `fixed` ping, AI-`prompted` reply, fully
|
|
24
|
+
`auto`-generated cadence). `messageKind` answers **what it carries**.
|
|
25
|
+
The two are intentionally orthogonal: any `messageType` can carry any
|
|
26
|
+
`messageKind`.
|
|
27
|
+
|
|
28
|
+
There is also `source: 'instant' | 'scheduled'` — the **routing
|
|
29
|
+
origin** (`'instant'` for `amsg-instant`, `'scheduled'` for any
|
|
30
|
+
`amsg-server` output). `messageType: 'instant'` always pairs with
|
|
31
|
+
`source: 'instant'`; the other three `messageType`s always pair with
|
|
32
|
+
`source: 'scheduled'`.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Common fields (every push)
|
|
37
|
+
|
|
38
|
+
| Field | Type | Notes |
|
|
39
|
+
|------------------|-------------------|-----------------------------------------------------------------------------|
|
|
40
|
+
| `messageKind` | `MessageKind` | Discriminator. Literal type — TS narrows on it. |
|
|
41
|
+
| `messageType` | `MessageType` | Dispatch axis. |
|
|
42
|
+
| `source` | `'instant' \| 'scheduled'` | Routing origin. |
|
|
43
|
+
| `messageId` | `string` | Unique per push. Format owned by the producer. |
|
|
44
|
+
| `sessionId` | `string` | **Shared across all pushes from the same LLM round** (reasoning + content), and across all iterations of a single agentic-loop request. |
|
|
45
|
+
| `timestamp` | `string` (ISO 8601) | Producer-side wall clock. |
|
|
46
|
+
| `messageSubtype` | `string?` | Caller's business namespace. Defaults to `'chat'` at producers. |
|
|
47
|
+
| `metadata` | `object?` | **Caller passthrough.** Packages MUST NOT write here. |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Per-kind fields
|
|
52
|
+
|
|
53
|
+
### `ContentPush` — final user-facing content
|
|
54
|
+
|
|
55
|
+
| Field | Type | Notes |
|
|
56
|
+
|------------------|-------------|----------------------------------------------------------------|
|
|
57
|
+
| `messageKind` | `'content'` | Discriminator. |
|
|
58
|
+
| `message` | `string` | The sentence/segment to display. |
|
|
59
|
+
| `messageIndex` | `number?` | 1-based segment index within an N-split burst. Omit for singletons. |
|
|
60
|
+
| `totalMessages` | `number?` | Total segments in the burst. Omit for singletons. |
|
|
61
|
+
| `title` | `string?` | Notification title. |
|
|
62
|
+
| `contactName` | `string?` | Sender display name. |
|
|
63
|
+
| `avatarUrl` | `string \| null?` | Sender avatar URL (`https:` only — `data:` is rejected upstream). |
|
|
64
|
+
| `taskId` | `string \| null?` | Scheduled task ID (server only). |
|
|
65
|
+
|
|
66
|
+
### `ReasoningPush` — LLM meta-thinking
|
|
67
|
+
|
|
68
|
+
| Field | Type | Notes |
|
|
69
|
+
|--------------------|----------------|-------------------------------------------------------------|
|
|
70
|
+
| `messageKind` | `'reasoning'` | Discriminator. |
|
|
71
|
+
| `reasoningContent` | `string` | Lifted from `choices[0].message.reasoning_content`. |
|
|
72
|
+
| `title` | `string?` | |
|
|
73
|
+
| `contactName` | `string?` | |
|
|
74
|
+
| `avatarUrl` | `string \| null?` | |
|
|
75
|
+
|
|
76
|
+
**No `messageIndex` / `totalMessages`.** Reasoning is one push per
|
|
77
|
+
LLM round, never a split-burst. Those fields are absent at the type
|
|
78
|
+
level on purpose — making them optional would leave callers
|
|
79
|
+
wondering when they're set.
|
|
80
|
+
|
|
81
|
+
Emitted **before** the matching `ContentPush` burst when the LLM
|
|
82
|
+
response carried a non-empty `reasoning_content`.
|
|
83
|
+
|
|
84
|
+
### `ToolRequestPush` — tool invocation request
|
|
85
|
+
|
|
86
|
+
| Field | Type | Notes |
|
|
87
|
+
|---------------|------------------|-------------------------------------------------------------|
|
|
88
|
+
| `messageKind` | `'tool_request'` | Discriminator. |
|
|
89
|
+
| `toolCalls` | `Array<object>` | OpenAI `choices[0].message.tool_calls` shape, passthrough. |
|
|
90
|
+
| `title` | `string?` | |
|
|
91
|
+
| `contactName` | `string?` | |
|
|
92
|
+
| `message` | `string?` | Optional human-readable tag for the request. |
|
|
93
|
+
|
|
94
|
+
Emitted by an agentic-loop hook returning
|
|
95
|
+
`{ decision: 'tool-request', pushPayload }`. The client is expected
|
|
96
|
+
to execute the tool and resume via `/continue`.
|
|
97
|
+
|
|
98
|
+
### `ErrorPush` — producer-level error
|
|
99
|
+
|
|
100
|
+
| Field | Type | Notes |
|
|
101
|
+
|---------------|-----------|------------------------------------------------------------------------|
|
|
102
|
+
| `messageKind` | `'error'` | Discriminator. |
|
|
103
|
+
| `code` | `string` | Stable producer-defined code, e.g. `HOOK_THREW`, `LOOP_EXCEEDED`. |
|
|
104
|
+
| `message` | `string` | Human-readable description. |
|
|
105
|
+
| `iteration` | `number?` | Agentic-loop iteration when relevant. |
|
|
106
|
+
|
|
107
|
+
Replaces the legacy 0.7.0 `{ type: 'error', code: '...' }` envelope.
|
|
108
|
+
The legacy `type` field is **gone** — do not look for it on
|
|
109
|
+
`ErrorPush`.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Usage
|
|
114
|
+
|
|
115
|
+
### TypeScript / typed JavaScript
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import {
|
|
119
|
+
type AmsgPush,
|
|
120
|
+
type ContentPush,
|
|
121
|
+
type ReasoningPush,
|
|
122
|
+
isContentPush,
|
|
123
|
+
} from '@rei-standard/amsg-shared';
|
|
124
|
+
|
|
125
|
+
function dispatch(push: AmsgPush) {
|
|
126
|
+
switch (push.messageKind) {
|
|
127
|
+
case 'content':
|
|
128
|
+
// push narrowed to ContentPush — push.message is `string`
|
|
129
|
+
console.log(push.message);
|
|
130
|
+
break;
|
|
131
|
+
case 'reasoning':
|
|
132
|
+
// push narrowed to ReasoningPush — push.reasoningContent is `string`
|
|
133
|
+
console.log(push.reasoningContent);
|
|
134
|
+
break;
|
|
135
|
+
case 'tool_request':
|
|
136
|
+
// push.toolCalls is `Array<object>`
|
|
137
|
+
break;
|
|
138
|
+
case 'error':
|
|
139
|
+
console.error(push.code, push.message);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Builders
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
import {
|
|
149
|
+
buildContentPush,
|
|
150
|
+
buildReasoningPush,
|
|
151
|
+
buildToolRequestPush,
|
|
152
|
+
buildErrorPush,
|
|
153
|
+
} from '@rei-standard/amsg-shared';
|
|
154
|
+
|
|
155
|
+
// One sentence in an N-split burst
|
|
156
|
+
const content = buildContentPush({
|
|
157
|
+
messageType: 'instant',
|
|
158
|
+
source: 'instant',
|
|
159
|
+
messageId: `msg_${crypto.randomUUID()}_0`,
|
|
160
|
+
sessionId: 'sess_abc',
|
|
161
|
+
message: 'Hello!',
|
|
162
|
+
contactName: 'Rei',
|
|
163
|
+
messageIndex: 1,
|
|
164
|
+
totalMessages: 2,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Reasoning emitted before the content burst
|
|
168
|
+
const reasoning = buildReasoningPush({
|
|
169
|
+
messageType: 'instant',
|
|
170
|
+
source: 'instant',
|
|
171
|
+
messageId: `msg_${crypto.randomUUID()}_reasoning`,
|
|
172
|
+
sessionId: 'sess_abc', // SAME sessionId as the content above
|
|
173
|
+
reasoningContent: 'User greeted me; I should reply warmly.',
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Agentic-loop tool request
|
|
177
|
+
const toolReq = buildToolRequestPush({
|
|
178
|
+
messageType: 'instant',
|
|
179
|
+
source: 'instant',
|
|
180
|
+
messageId: `msg_${crypto.randomUUID()}_tool`,
|
|
181
|
+
sessionId: 'sess_abc',
|
|
182
|
+
toolCalls: [{ id: 'call_0', type: 'function', function: { name: 'get_weather', arguments: '{}' } }],
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
// Producer-level error
|
|
186
|
+
const error = buildErrorPush({
|
|
187
|
+
messageType: 'instant',
|
|
188
|
+
source: 'instant',
|
|
189
|
+
messageId: `msg_${crypto.randomUUID()}_err`,
|
|
190
|
+
sessionId: 'sess_abc',
|
|
191
|
+
code: 'HOOK_THREW',
|
|
192
|
+
message: 'onLLMOutput threw: ...',
|
|
193
|
+
iteration: 2,
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Type guards
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
import { isContentPush, isReasoningPush, isErrorPush } from '@rei-standard/amsg-shared';
|
|
201
|
+
|
|
202
|
+
if (isContentPush(push)) {
|
|
203
|
+
// push.message is `string`
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Constants
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
import { MESSAGE_KIND, MESSAGE_TYPE, PUSH_SOURCE } from '@rei-standard/amsg-shared';
|
|
213
|
+
|
|
214
|
+
MESSAGE_KIND.CONTENT; // 'content'
|
|
215
|
+
MESSAGE_KIND.REASONING; // 'reasoning'
|
|
216
|
+
MESSAGE_KIND.TOOL_REQUEST; // 'tool_request'
|
|
217
|
+
MESSAGE_KIND.ERROR; // 'error'
|
|
218
|
+
|
|
219
|
+
MESSAGE_TYPE.INSTANT; // 'instant'
|
|
220
|
+
MESSAGE_TYPE.FIXED; // 'fixed'
|
|
221
|
+
MESSAGE_TYPE.PROMPTED; // 'prompted'
|
|
222
|
+
MESSAGE_TYPE.AUTO; // 'auto'
|
|
223
|
+
|
|
224
|
+
PUSH_SOURCE.INSTANT; // 'instant'
|
|
225
|
+
PUSH_SOURCE.SCHEDULED; // 'scheduled'
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Invariants
|
|
231
|
+
|
|
232
|
+
1. **`messageKind` is a literal-type discriminator.** Producers must
|
|
233
|
+
set it via a builder (or to one of the literal values directly).
|
|
234
|
+
Never `string`-typed.
|
|
235
|
+
2. **`sessionId` is stable across a single LLM round.** A
|
|
236
|
+
`ReasoningPush` and the `ContentPush`(es) it precedes share the
|
|
237
|
+
same `sessionId`. Agentic-loop multi-iteration runs reuse the
|
|
238
|
+
same `sessionId` across iterations.
|
|
239
|
+
3. **`ReasoningPush` carries no `messageIndex` / `totalMessages`.**
|
|
240
|
+
Those fields belong to the content N-split burst.
|
|
241
|
+
4. **`metadata` is caller-owned.** Packages must add protocol-level
|
|
242
|
+
data as top-level fields, never inside `metadata`.
|
|
243
|
+
5. **`source` is the routing origin, not the dispatch type.**
|
|
244
|
+
`'instant'` ⇄ `amsg-instant`; `'scheduled'` ⇄ `amsg-server`.
|
|
245
|
+
|
|
246
|
+
See [§6 of `standards/active-messaging-api.md`](../../../standards/active-messaging-api.md)
|
|
247
|
+
for the wire-level contract.
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/index.js
|
|
20
|
+
var src_exports = {};
|
|
21
|
+
__export(src_exports, {
|
|
22
|
+
MESSAGE_KIND: () => MESSAGE_KIND,
|
|
23
|
+
MESSAGE_TYPE: () => MESSAGE_TYPE,
|
|
24
|
+
PUSH_SOURCE: () => PUSH_SOURCE,
|
|
25
|
+
buildContentPush: () => buildContentPush,
|
|
26
|
+
buildErrorPush: () => buildErrorPush,
|
|
27
|
+
buildReasoningPush: () => buildReasoningPush,
|
|
28
|
+
buildToolRequestPush: () => buildToolRequestPush,
|
|
29
|
+
isContentPush: () => isContentPush,
|
|
30
|
+
isErrorPush: () => isErrorPush,
|
|
31
|
+
isReasoningPush: () => isReasoningPush,
|
|
32
|
+
isToolRequestPush: () => isToolRequestPush
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(src_exports);
|
|
35
|
+
var MESSAGE_KIND = Object.freeze({
|
|
36
|
+
CONTENT: "content",
|
|
37
|
+
REASONING: "reasoning",
|
|
38
|
+
TOOL_REQUEST: "tool_request",
|
|
39
|
+
ERROR: "error"
|
|
40
|
+
});
|
|
41
|
+
var MESSAGE_TYPE = Object.freeze({
|
|
42
|
+
INSTANT: "instant",
|
|
43
|
+
FIXED: "fixed",
|
|
44
|
+
PROMPTED: "prompted",
|
|
45
|
+
AUTO: "auto"
|
|
46
|
+
});
|
|
47
|
+
var PUSH_SOURCE = Object.freeze({
|
|
48
|
+
INSTANT: "instant",
|
|
49
|
+
SCHEDULED: "scheduled"
|
|
50
|
+
});
|
|
51
|
+
function requireField(kind, field, value) {
|
|
52
|
+
if (value === void 0 || value === null || value === "") {
|
|
53
|
+
throw new Error(`[amsg-shared] ${kind}: '${field}' is required`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function buildContentPush(args) {
|
|
57
|
+
requireField("ContentPush", "messageType", args.messageType);
|
|
58
|
+
requireField("ContentPush", "source", args.source);
|
|
59
|
+
requireField("ContentPush", "messageId", args.messageId);
|
|
60
|
+
requireField("ContentPush", "sessionId", args.sessionId);
|
|
61
|
+
if (typeof args.message !== "string") {
|
|
62
|
+
throw new Error("[amsg-shared] ContentPush: 'message' must be a string");
|
|
63
|
+
}
|
|
64
|
+
const push = {
|
|
65
|
+
messageKind: "content",
|
|
66
|
+
messageType: args.messageType,
|
|
67
|
+
source: args.source,
|
|
68
|
+
messageId: args.messageId,
|
|
69
|
+
sessionId: args.sessionId,
|
|
70
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
71
|
+
message: args.message
|
|
72
|
+
};
|
|
73
|
+
if (args.title !== void 0) push.title = args.title;
|
|
74
|
+
if (args.contactName !== void 0) push.contactName = args.contactName;
|
|
75
|
+
if (args.avatarUrl !== void 0) push.avatarUrl = args.avatarUrl;
|
|
76
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
77
|
+
if (args.messageIndex !== void 0) push.messageIndex = args.messageIndex;
|
|
78
|
+
if (args.totalMessages !== void 0) push.totalMessages = args.totalMessages;
|
|
79
|
+
if (args.taskId !== void 0) push.taskId = args.taskId;
|
|
80
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
81
|
+
return push;
|
|
82
|
+
}
|
|
83
|
+
function buildReasoningPush(args) {
|
|
84
|
+
requireField("ReasoningPush", "messageType", args.messageType);
|
|
85
|
+
requireField("ReasoningPush", "source", args.source);
|
|
86
|
+
requireField("ReasoningPush", "messageId", args.messageId);
|
|
87
|
+
requireField("ReasoningPush", "sessionId", args.sessionId);
|
|
88
|
+
if (typeof args.reasoningContent !== "string" || !args.reasoningContent) {
|
|
89
|
+
throw new Error("[amsg-shared] ReasoningPush: 'reasoningContent' must be a non-empty string");
|
|
90
|
+
}
|
|
91
|
+
const push = {
|
|
92
|
+
messageKind: "reasoning",
|
|
93
|
+
messageType: args.messageType,
|
|
94
|
+
source: args.source,
|
|
95
|
+
messageId: args.messageId,
|
|
96
|
+
sessionId: args.sessionId,
|
|
97
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
98
|
+
reasoningContent: args.reasoningContent
|
|
99
|
+
};
|
|
100
|
+
if (args.title !== void 0) push.title = args.title;
|
|
101
|
+
if (args.contactName !== void 0) push.contactName = args.contactName;
|
|
102
|
+
if (args.avatarUrl !== void 0) push.avatarUrl = args.avatarUrl;
|
|
103
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
104
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
105
|
+
return push;
|
|
106
|
+
}
|
|
107
|
+
function buildToolRequestPush(args) {
|
|
108
|
+
requireField("ToolRequestPush", "messageType", args.messageType);
|
|
109
|
+
requireField("ToolRequestPush", "source", args.source);
|
|
110
|
+
requireField("ToolRequestPush", "messageId", args.messageId);
|
|
111
|
+
requireField("ToolRequestPush", "sessionId", args.sessionId);
|
|
112
|
+
if (!Array.isArray(args.toolCalls) || args.toolCalls.length === 0) {
|
|
113
|
+
throw new Error("[amsg-shared] ToolRequestPush: 'toolCalls' must be a non-empty array");
|
|
114
|
+
}
|
|
115
|
+
const push = {
|
|
116
|
+
messageKind: "tool_request",
|
|
117
|
+
messageType: args.messageType,
|
|
118
|
+
source: args.source,
|
|
119
|
+
messageId: args.messageId,
|
|
120
|
+
sessionId: args.sessionId,
|
|
121
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
122
|
+
toolCalls: args.toolCalls
|
|
123
|
+
};
|
|
124
|
+
if (args.title !== void 0) push.title = args.title;
|
|
125
|
+
if (args.contactName !== void 0) push.contactName = args.contactName;
|
|
126
|
+
if (args.message !== void 0) push.message = args.message;
|
|
127
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
128
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
129
|
+
return push;
|
|
130
|
+
}
|
|
131
|
+
function buildErrorPush(args) {
|
|
132
|
+
requireField("ErrorPush", "messageType", args.messageType);
|
|
133
|
+
requireField("ErrorPush", "source", args.source);
|
|
134
|
+
requireField("ErrorPush", "messageId", args.messageId);
|
|
135
|
+
requireField("ErrorPush", "sessionId", args.sessionId);
|
|
136
|
+
requireField("ErrorPush", "code", args.code);
|
|
137
|
+
if (typeof args.message !== "string") {
|
|
138
|
+
throw new Error("[amsg-shared] ErrorPush: 'message' must be a string");
|
|
139
|
+
}
|
|
140
|
+
const push = {
|
|
141
|
+
messageKind: "error",
|
|
142
|
+
messageType: args.messageType,
|
|
143
|
+
source: args.source,
|
|
144
|
+
messageId: args.messageId,
|
|
145
|
+
sessionId: args.sessionId,
|
|
146
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
147
|
+
code: args.code,
|
|
148
|
+
message: args.message
|
|
149
|
+
};
|
|
150
|
+
if (args.iteration !== void 0) push.iteration = args.iteration;
|
|
151
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
152
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
153
|
+
return push;
|
|
154
|
+
}
|
|
155
|
+
function isContentPush(value) {
|
|
156
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
157
|
+
value.messageKind === "content";
|
|
158
|
+
}
|
|
159
|
+
function isReasoningPush(value) {
|
|
160
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
161
|
+
value.messageKind === "reasoning";
|
|
162
|
+
}
|
|
163
|
+
function isToolRequestPush(value) {
|
|
164
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
165
|
+
value.messageKind === "tool_request";
|
|
166
|
+
}
|
|
167
|
+
function isErrorPush(value) {
|
|
168
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
169
|
+
value.messageKind === "error";
|
|
170
|
+
}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a {@link ContentPush}. Use this for legacy sentence-split
|
|
3
|
+
* bursts (set `messageIndex` 1-based + `totalMessages`) or for a
|
|
4
|
+
* single content push (omit both).
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} args
|
|
7
|
+
* @param {MessageType} args.messageType
|
|
8
|
+
* @param {PushSource} args.source
|
|
9
|
+
* @param {string} args.messageId
|
|
10
|
+
* @param {string} args.sessionId
|
|
11
|
+
* @param {string} args.message
|
|
12
|
+
* @param {string} [args.timestamp] - Defaults to `new Date().toISOString()`.
|
|
13
|
+
* @param {string} [args.title]
|
|
14
|
+
* @param {string} [args.contactName]
|
|
15
|
+
* @param {string | null} [args.avatarUrl]
|
|
16
|
+
* @param {string} [args.messageSubtype]
|
|
17
|
+
* @param {number} [args.messageIndex]
|
|
18
|
+
* @param {number} [args.totalMessages]
|
|
19
|
+
* @param {string | null} [args.taskId]
|
|
20
|
+
* @param {Object} [args.metadata]
|
|
21
|
+
* @returns {ContentPush}
|
|
22
|
+
*/
|
|
23
|
+
export function buildContentPush(args: {
|
|
24
|
+
messageType: MessageType;
|
|
25
|
+
source: PushSource;
|
|
26
|
+
messageId: string;
|
|
27
|
+
sessionId: string;
|
|
28
|
+
message: string;
|
|
29
|
+
timestamp?: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
contactName?: string;
|
|
32
|
+
avatarUrl?: string | null;
|
|
33
|
+
messageSubtype?: string;
|
|
34
|
+
messageIndex?: number;
|
|
35
|
+
totalMessages?: number;
|
|
36
|
+
taskId?: string | null;
|
|
37
|
+
metadata?: any;
|
|
38
|
+
}): ContentPush;
|
|
39
|
+
/**
|
|
40
|
+
* Build a {@link ReasoningPush}. Producers emit this **before** any
|
|
41
|
+
* matching `ContentPush` burst when the LLM response carried a non-
|
|
42
|
+
* empty `reasoning_content`.
|
|
43
|
+
*
|
|
44
|
+
* Does NOT take `messageIndex` / `totalMessages` — reasoning is one
|
|
45
|
+
* push per LLM round.
|
|
46
|
+
*
|
|
47
|
+
* @param {Object} args
|
|
48
|
+
* @param {MessageType} args.messageType
|
|
49
|
+
* @param {PushSource} args.source
|
|
50
|
+
* @param {string} args.messageId
|
|
51
|
+
* @param {string} args.sessionId
|
|
52
|
+
* @param {string} args.reasoningContent
|
|
53
|
+
* @param {string} [args.timestamp]
|
|
54
|
+
* @param {string} [args.title]
|
|
55
|
+
* @param {string} [args.contactName]
|
|
56
|
+
* @param {string | null} [args.avatarUrl]
|
|
57
|
+
* @param {string} [args.messageSubtype]
|
|
58
|
+
* @param {Object} [args.metadata]
|
|
59
|
+
* @returns {ReasoningPush}
|
|
60
|
+
*/
|
|
61
|
+
export function buildReasoningPush(args: {
|
|
62
|
+
messageType: MessageType;
|
|
63
|
+
source: PushSource;
|
|
64
|
+
messageId: string;
|
|
65
|
+
sessionId: string;
|
|
66
|
+
reasoningContent: string;
|
|
67
|
+
timestamp?: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
contactName?: string;
|
|
70
|
+
avatarUrl?: string | null;
|
|
71
|
+
messageSubtype?: string;
|
|
72
|
+
metadata?: any;
|
|
73
|
+
}): ReasoningPush;
|
|
74
|
+
/**
|
|
75
|
+
* Build a {@link ToolRequestPush}. Caller is expected to executed
|
|
76
|
+
* tools client-side and resume via `/continue` (see `amsg-instant`
|
|
77
|
+
* README §Agentic Loop).
|
|
78
|
+
*
|
|
79
|
+
* @param {Object} args
|
|
80
|
+
* @param {MessageType} args.messageType
|
|
81
|
+
* @param {PushSource} args.source
|
|
82
|
+
* @param {string} args.messageId
|
|
83
|
+
* @param {string} args.sessionId
|
|
84
|
+
* @param {Array<Object>} args.toolCalls
|
|
85
|
+
* @param {string} [args.timestamp]
|
|
86
|
+
* @param {string} [args.title]
|
|
87
|
+
* @param {string} [args.contactName]
|
|
88
|
+
* @param {string} [args.message]
|
|
89
|
+
* @param {string} [args.messageSubtype]
|
|
90
|
+
* @param {Object} [args.metadata]
|
|
91
|
+
* @returns {ToolRequestPush}
|
|
92
|
+
*/
|
|
93
|
+
export function buildToolRequestPush(args: {
|
|
94
|
+
messageType: MessageType;
|
|
95
|
+
source: PushSource;
|
|
96
|
+
messageId: string;
|
|
97
|
+
sessionId: string;
|
|
98
|
+
toolCalls: Array<any>;
|
|
99
|
+
timestamp?: string;
|
|
100
|
+
title?: string;
|
|
101
|
+
contactName?: string;
|
|
102
|
+
message?: string;
|
|
103
|
+
messageSubtype?: string;
|
|
104
|
+
metadata?: any;
|
|
105
|
+
}): ToolRequestPush;
|
|
106
|
+
/**
|
|
107
|
+
* Build an {@link ErrorPush}. Replaces the legacy
|
|
108
|
+
* `{ type: 'error', code: '...' }` envelope. The new shape carries
|
|
109
|
+
* the full common-fields set so the SW can route it through the
|
|
110
|
+
* same `messageKind` switch as the other three kinds.
|
|
111
|
+
*
|
|
112
|
+
* @param {Object} args
|
|
113
|
+
* @param {MessageType} args.messageType
|
|
114
|
+
* @param {PushSource} args.source
|
|
115
|
+
* @param {string} args.messageId
|
|
116
|
+
* @param {string} args.sessionId
|
|
117
|
+
* @param {string} args.code
|
|
118
|
+
* @param {string} args.message
|
|
119
|
+
* @param {string} [args.timestamp]
|
|
120
|
+
* @param {number} [args.iteration]
|
|
121
|
+
* @param {string} [args.messageSubtype]
|
|
122
|
+
* @param {Object} [args.metadata]
|
|
123
|
+
* @returns {ErrorPush}
|
|
124
|
+
*/
|
|
125
|
+
export function buildErrorPush(args: {
|
|
126
|
+
messageType: MessageType;
|
|
127
|
+
source: PushSource;
|
|
128
|
+
messageId: string;
|
|
129
|
+
sessionId: string;
|
|
130
|
+
code: string;
|
|
131
|
+
message: string;
|
|
132
|
+
timestamp?: string;
|
|
133
|
+
iteration?: number;
|
|
134
|
+
messageSubtype?: string;
|
|
135
|
+
metadata?: any;
|
|
136
|
+
}): ErrorPush;
|
|
137
|
+
/**
|
|
138
|
+
* Type guard: returns true if the argument is a {@link ContentPush}.
|
|
139
|
+
*
|
|
140
|
+
* @param {unknown} value
|
|
141
|
+
* @returns {value is ContentPush}
|
|
142
|
+
*/
|
|
143
|
+
export function isContentPush(value: unknown): value is ContentPush;
|
|
144
|
+
/**
|
|
145
|
+
* Type guard: returns true if the argument is a {@link ReasoningPush}.
|
|
146
|
+
*
|
|
147
|
+
* @param {unknown} value
|
|
148
|
+
* @returns {value is ReasoningPush}
|
|
149
|
+
*/
|
|
150
|
+
export function isReasoningPush(value: unknown): value is ReasoningPush;
|
|
151
|
+
/**
|
|
152
|
+
* Type guard: returns true if the argument is a {@link ToolRequestPush}.
|
|
153
|
+
*
|
|
154
|
+
* @param {unknown} value
|
|
155
|
+
* @returns {value is ToolRequestPush}
|
|
156
|
+
*/
|
|
157
|
+
export function isToolRequestPush(value: unknown): value is ToolRequestPush;
|
|
158
|
+
/**
|
|
159
|
+
* Type guard: returns true if the argument is an {@link ErrorPush}.
|
|
160
|
+
*
|
|
161
|
+
* @param {unknown} value
|
|
162
|
+
* @returns {value is ErrorPush}
|
|
163
|
+
*/
|
|
164
|
+
export function isErrorPush(value: unknown): value is ErrorPush;
|
|
165
|
+
/**
|
|
166
|
+
* @rei-standard/amsg-shared
|
|
167
|
+
*
|
|
168
|
+
* Lowest layer of the ReiStandard Active Messaging ecosystem.
|
|
169
|
+
* Defines the three-axis push contract that `amsg-instant`,
|
|
170
|
+
* `amsg-server`, `amsg-sw`, and `amsg-client` all conform to.
|
|
171
|
+
*
|
|
172
|
+
* Three orthogonal axes:
|
|
173
|
+
* 1. messageType — how the push was produced (instant / fixed / prompted / auto)
|
|
174
|
+
* 2. messageSubtype — caller's business classification (free-form string)
|
|
175
|
+
* 3. messageKind — what the push carries (content / reasoning / tool_request / error)
|
|
176
|
+
*
|
|
177
|
+
* Zero runtime dependencies. The package is ESM/CJS dual-published and
|
|
178
|
+
* intentionally has no `dependencies:` entry — every other amsg sub-
|
|
179
|
+
* package depends on it, never the reverse.
|
|
180
|
+
*
|
|
181
|
+
* Types are expressed via JSDoc `@typedef` unions with literal-type
|
|
182
|
+
* discriminators so TS consumers can narrow on `messageKind`:
|
|
183
|
+
*
|
|
184
|
+
* if (push.messageKind === 'reasoning') {
|
|
185
|
+
* // TS knows: push is ReasoningPush, push.reasoningContent is string
|
|
186
|
+
* }
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* What the push carries. Fixed enum — packages must not add values.
|
|
190
|
+
*
|
|
191
|
+
* @typedef {'content' | 'reasoning' | 'tool_request' | 'error'} MessageKind
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* How the push was produced. Fixed enum — packages must not add values.
|
|
195
|
+
*
|
|
196
|
+
* @typedef {'instant' | 'fixed' | 'prompted' | 'auto'} MessageType
|
|
197
|
+
*/
|
|
198
|
+
/**
|
|
199
|
+
* Which sub-package routed the push. Fixed enum — `'instant'` for
|
|
200
|
+
* `amsg-instant` (stateless one-shot), `'scheduled'` for any
|
|
201
|
+
* `amsg-server` output regardless of `messageType`. Packages must not
|
|
202
|
+
* add values.
|
|
203
|
+
*
|
|
204
|
+
* @typedef {'instant' | 'scheduled'} PushSource
|
|
205
|
+
*/
|
|
206
|
+
/**
|
|
207
|
+
* Runtime constant mirroring the {@link MessageKind} type. Useful for
|
|
208
|
+
* switch statements that need to enumerate every kind:
|
|
209
|
+
*
|
|
210
|
+
* for (const kind of Object.values(MESSAGE_KIND)) { ... }
|
|
211
|
+
*/
|
|
212
|
+
export const MESSAGE_KIND: Readonly<{
|
|
213
|
+
CONTENT: "content";
|
|
214
|
+
REASONING: "reasoning";
|
|
215
|
+
TOOL_REQUEST: "tool_request";
|
|
216
|
+
ERROR: "error";
|
|
217
|
+
}>;
|
|
218
|
+
/**
|
|
219
|
+
* Runtime constant mirroring the {@link MessageType} type.
|
|
220
|
+
*/
|
|
221
|
+
export const MESSAGE_TYPE: Readonly<{
|
|
222
|
+
INSTANT: "instant";
|
|
223
|
+
FIXED: "fixed";
|
|
224
|
+
PROMPTED: "prompted";
|
|
225
|
+
AUTO: "auto";
|
|
226
|
+
}>;
|
|
227
|
+
/**
|
|
228
|
+
* Runtime constant mirroring the {@link PushSource} type.
|
|
229
|
+
*/
|
|
230
|
+
export const PUSH_SOURCE: Readonly<{
|
|
231
|
+
INSTANT: "instant";
|
|
232
|
+
SCHEDULED: "scheduled";
|
|
233
|
+
}>;
|
|
234
|
+
/**
|
|
235
|
+
* Fields present on every push, regardless of kind. Discriminator
|
|
236
|
+
* fields (`messageKind`) and kind-specific fields live on the kind
|
|
237
|
+
* interfaces below.
|
|
238
|
+
*
|
|
239
|
+
* `metadata` is a passthrough namespace owned by the caller. Packages
|
|
240
|
+
* are forbidden from writing their own fields into `metadata` — any
|
|
241
|
+
* protocol-level data goes on top-level fields.
|
|
242
|
+
*/
|
|
243
|
+
export type AmsgPushCommon = {
|
|
244
|
+
/**
|
|
245
|
+
* - How the push was produced.
|
|
246
|
+
*/
|
|
247
|
+
messageType: MessageType;
|
|
248
|
+
/**
|
|
249
|
+
* - Which sub-package routed it.
|
|
250
|
+
*/
|
|
251
|
+
source: PushSource;
|
|
252
|
+
/**
|
|
253
|
+
* - Unique per push. Format owned by the producer.
|
|
254
|
+
*/
|
|
255
|
+
messageId: string;
|
|
256
|
+
/**
|
|
257
|
+
* - Shared across all pushes from one LLM round (reasoning + content) and across iterations of a single agentic-loop request.
|
|
258
|
+
*/
|
|
259
|
+
sessionId: string;
|
|
260
|
+
/**
|
|
261
|
+
* - ISO 8601 timestamp at producer.
|
|
262
|
+
*/
|
|
263
|
+
timestamp: string;
|
|
264
|
+
/**
|
|
265
|
+
* - Caller-defined business namespace. Defaults to 'chat' at producers.
|
|
266
|
+
*/
|
|
267
|
+
messageSubtype?: string;
|
|
268
|
+
/**
|
|
269
|
+
* - Caller passthrough. Packages MUST NOT write here.
|
|
270
|
+
*/
|
|
271
|
+
metadata?: any;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Final user-facing content. Sentence-split bursts of N use
|
|
275
|
+
* `messageIndex` (1-based) + `totalMessages` so the client can
|
|
276
|
+
* reassemble or animate.
|
|
277
|
+
*/
|
|
278
|
+
export type ContentPush = AmsgPushCommon & {
|
|
279
|
+
messageKind: "content";
|
|
280
|
+
message: string;
|
|
281
|
+
title?: string;
|
|
282
|
+
contactName?: string;
|
|
283
|
+
avatarUrl?: string | null;
|
|
284
|
+
messageIndex?: number;
|
|
285
|
+
totalMessages?: number;
|
|
286
|
+
taskId?: string | null;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* LLM "meta-thinking" — `choices[0].message.reasoning_content` lifted
|
|
290
|
+
* out of the upstream response into its own push. Emitted **before**
|
|
291
|
+
* the matching {@link ContentPush} burst when present and non-empty.
|
|
292
|
+
*
|
|
293
|
+
* Intentionally does NOT carry `messageIndex` / `totalMessages` —
|
|
294
|
+
* reasoning is a single push per LLM round, never a split-burst.
|
|
295
|
+
* That's why those fields are absent at the type level rather than
|
|
296
|
+
* `optional` (which would leave callers wondering when they're set).
|
|
297
|
+
*/
|
|
298
|
+
export type ReasoningPush = AmsgPushCommon & {
|
|
299
|
+
messageKind: "reasoning";
|
|
300
|
+
reasoningContent: string;
|
|
301
|
+
title?: string;
|
|
302
|
+
contactName?: string;
|
|
303
|
+
avatarUrl?: string | null;
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Tool invocation request emitted by an agentic-loop hook (`decision:
|
|
307
|
+
* 'tool-request'`). The client is expected to execute the tool and
|
|
308
|
+
* resume via the producer's `/continue` endpoint.
|
|
309
|
+
*
|
|
310
|
+
* `toolCalls` mirrors the OpenAI `choices[0].message.tool_calls`
|
|
311
|
+
* shape — left as `any`-equivalent so producers can passthrough
|
|
312
|
+
* whatever OpenAI-compatible upstream returned.
|
|
313
|
+
*/
|
|
314
|
+
export type ToolRequestPush = AmsgPushCommon & {
|
|
315
|
+
messageKind: "tool_request";
|
|
316
|
+
toolCalls: Array<any>;
|
|
317
|
+
title?: string;
|
|
318
|
+
contactName?: string;
|
|
319
|
+
message?: string;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Producer-level error. Replaces the legacy
|
|
323
|
+
* `{ type: 'error', code: '...' }` envelope. `code` is a stable
|
|
324
|
+
* string; `iteration` is the agentic-loop iteration number when
|
|
325
|
+
* relevant (0 / absent otherwise).
|
|
326
|
+
*/
|
|
327
|
+
export type ErrorPush = AmsgPushCommon & {
|
|
328
|
+
messageKind: "error";
|
|
329
|
+
code: string;
|
|
330
|
+
message: string;
|
|
331
|
+
iteration?: number;
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* Discriminated union of all pushes the SW can receive. TS consumers
|
|
335
|
+
* `switch` on `messageKind` and the compiler narrows automatically.
|
|
336
|
+
*/
|
|
337
|
+
export type AmsgPush = ContentPush | ReasoningPush | ToolRequestPush | ErrorPush;
|
|
338
|
+
/**
|
|
339
|
+
* What the push carries. Fixed enum — packages must not add values.
|
|
340
|
+
*/
|
|
341
|
+
export type MessageKind = "content" | "reasoning" | "tool_request" | "error";
|
|
342
|
+
/**
|
|
343
|
+
* How the push was produced. Fixed enum — packages must not add values.
|
|
344
|
+
*/
|
|
345
|
+
export type MessageType = "instant" | "fixed" | "prompted" | "auto";
|
|
346
|
+
/**
|
|
347
|
+
* Which sub-package routed the push. Fixed enum — `'instant'` for
|
|
348
|
+
* `amsg-instant` (stateless one-shot), `'scheduled'` for any
|
|
349
|
+
* `amsg-server` output regardless of `messageType`. Packages must not
|
|
350
|
+
* add values.
|
|
351
|
+
*/
|
|
352
|
+
export type PushSource = "instant" | "scheduled";
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a {@link ContentPush}. Use this for legacy sentence-split
|
|
3
|
+
* bursts (set `messageIndex` 1-based + `totalMessages`) or for a
|
|
4
|
+
* single content push (omit both).
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} args
|
|
7
|
+
* @param {MessageType} args.messageType
|
|
8
|
+
* @param {PushSource} args.source
|
|
9
|
+
* @param {string} args.messageId
|
|
10
|
+
* @param {string} args.sessionId
|
|
11
|
+
* @param {string} args.message
|
|
12
|
+
* @param {string} [args.timestamp] - Defaults to `new Date().toISOString()`.
|
|
13
|
+
* @param {string} [args.title]
|
|
14
|
+
* @param {string} [args.contactName]
|
|
15
|
+
* @param {string | null} [args.avatarUrl]
|
|
16
|
+
* @param {string} [args.messageSubtype]
|
|
17
|
+
* @param {number} [args.messageIndex]
|
|
18
|
+
* @param {number} [args.totalMessages]
|
|
19
|
+
* @param {string | null} [args.taskId]
|
|
20
|
+
* @param {Object} [args.metadata]
|
|
21
|
+
* @returns {ContentPush}
|
|
22
|
+
*/
|
|
23
|
+
export function buildContentPush(args: {
|
|
24
|
+
messageType: MessageType;
|
|
25
|
+
source: PushSource;
|
|
26
|
+
messageId: string;
|
|
27
|
+
sessionId: string;
|
|
28
|
+
message: string;
|
|
29
|
+
timestamp?: string;
|
|
30
|
+
title?: string;
|
|
31
|
+
contactName?: string;
|
|
32
|
+
avatarUrl?: string | null;
|
|
33
|
+
messageSubtype?: string;
|
|
34
|
+
messageIndex?: number;
|
|
35
|
+
totalMessages?: number;
|
|
36
|
+
taskId?: string | null;
|
|
37
|
+
metadata?: any;
|
|
38
|
+
}): ContentPush;
|
|
39
|
+
/**
|
|
40
|
+
* Build a {@link ReasoningPush}. Producers emit this **before** any
|
|
41
|
+
* matching `ContentPush` burst when the LLM response carried a non-
|
|
42
|
+
* empty `reasoning_content`.
|
|
43
|
+
*
|
|
44
|
+
* Does NOT take `messageIndex` / `totalMessages` — reasoning is one
|
|
45
|
+
* push per LLM round.
|
|
46
|
+
*
|
|
47
|
+
* @param {Object} args
|
|
48
|
+
* @param {MessageType} args.messageType
|
|
49
|
+
* @param {PushSource} args.source
|
|
50
|
+
* @param {string} args.messageId
|
|
51
|
+
* @param {string} args.sessionId
|
|
52
|
+
* @param {string} args.reasoningContent
|
|
53
|
+
* @param {string} [args.timestamp]
|
|
54
|
+
* @param {string} [args.title]
|
|
55
|
+
* @param {string} [args.contactName]
|
|
56
|
+
* @param {string | null} [args.avatarUrl]
|
|
57
|
+
* @param {string} [args.messageSubtype]
|
|
58
|
+
* @param {Object} [args.metadata]
|
|
59
|
+
* @returns {ReasoningPush}
|
|
60
|
+
*/
|
|
61
|
+
export function buildReasoningPush(args: {
|
|
62
|
+
messageType: MessageType;
|
|
63
|
+
source: PushSource;
|
|
64
|
+
messageId: string;
|
|
65
|
+
sessionId: string;
|
|
66
|
+
reasoningContent: string;
|
|
67
|
+
timestamp?: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
contactName?: string;
|
|
70
|
+
avatarUrl?: string | null;
|
|
71
|
+
messageSubtype?: string;
|
|
72
|
+
metadata?: any;
|
|
73
|
+
}): ReasoningPush;
|
|
74
|
+
/**
|
|
75
|
+
* Build a {@link ToolRequestPush}. Caller is expected to executed
|
|
76
|
+
* tools client-side and resume via `/continue` (see `amsg-instant`
|
|
77
|
+
* README §Agentic Loop).
|
|
78
|
+
*
|
|
79
|
+
* @param {Object} args
|
|
80
|
+
* @param {MessageType} args.messageType
|
|
81
|
+
* @param {PushSource} args.source
|
|
82
|
+
* @param {string} args.messageId
|
|
83
|
+
* @param {string} args.sessionId
|
|
84
|
+
* @param {Array<Object>} args.toolCalls
|
|
85
|
+
* @param {string} [args.timestamp]
|
|
86
|
+
* @param {string} [args.title]
|
|
87
|
+
* @param {string} [args.contactName]
|
|
88
|
+
* @param {string} [args.message]
|
|
89
|
+
* @param {string} [args.messageSubtype]
|
|
90
|
+
* @param {Object} [args.metadata]
|
|
91
|
+
* @returns {ToolRequestPush}
|
|
92
|
+
*/
|
|
93
|
+
export function buildToolRequestPush(args: {
|
|
94
|
+
messageType: MessageType;
|
|
95
|
+
source: PushSource;
|
|
96
|
+
messageId: string;
|
|
97
|
+
sessionId: string;
|
|
98
|
+
toolCalls: Array<any>;
|
|
99
|
+
timestamp?: string;
|
|
100
|
+
title?: string;
|
|
101
|
+
contactName?: string;
|
|
102
|
+
message?: string;
|
|
103
|
+
messageSubtype?: string;
|
|
104
|
+
metadata?: any;
|
|
105
|
+
}): ToolRequestPush;
|
|
106
|
+
/**
|
|
107
|
+
* Build an {@link ErrorPush}. Replaces the legacy
|
|
108
|
+
* `{ type: 'error', code: '...' }` envelope. The new shape carries
|
|
109
|
+
* the full common-fields set so the SW can route it through the
|
|
110
|
+
* same `messageKind` switch as the other three kinds.
|
|
111
|
+
*
|
|
112
|
+
* @param {Object} args
|
|
113
|
+
* @param {MessageType} args.messageType
|
|
114
|
+
* @param {PushSource} args.source
|
|
115
|
+
* @param {string} args.messageId
|
|
116
|
+
* @param {string} args.sessionId
|
|
117
|
+
* @param {string} args.code
|
|
118
|
+
* @param {string} args.message
|
|
119
|
+
* @param {string} [args.timestamp]
|
|
120
|
+
* @param {number} [args.iteration]
|
|
121
|
+
* @param {string} [args.messageSubtype]
|
|
122
|
+
* @param {Object} [args.metadata]
|
|
123
|
+
* @returns {ErrorPush}
|
|
124
|
+
*/
|
|
125
|
+
export function buildErrorPush(args: {
|
|
126
|
+
messageType: MessageType;
|
|
127
|
+
source: PushSource;
|
|
128
|
+
messageId: string;
|
|
129
|
+
sessionId: string;
|
|
130
|
+
code: string;
|
|
131
|
+
message: string;
|
|
132
|
+
timestamp?: string;
|
|
133
|
+
iteration?: number;
|
|
134
|
+
messageSubtype?: string;
|
|
135
|
+
metadata?: any;
|
|
136
|
+
}): ErrorPush;
|
|
137
|
+
/**
|
|
138
|
+
* Type guard: returns true if the argument is a {@link ContentPush}.
|
|
139
|
+
*
|
|
140
|
+
* @param {unknown} value
|
|
141
|
+
* @returns {value is ContentPush}
|
|
142
|
+
*/
|
|
143
|
+
export function isContentPush(value: unknown): value is ContentPush;
|
|
144
|
+
/**
|
|
145
|
+
* Type guard: returns true if the argument is a {@link ReasoningPush}.
|
|
146
|
+
*
|
|
147
|
+
* @param {unknown} value
|
|
148
|
+
* @returns {value is ReasoningPush}
|
|
149
|
+
*/
|
|
150
|
+
export function isReasoningPush(value: unknown): value is ReasoningPush;
|
|
151
|
+
/**
|
|
152
|
+
* Type guard: returns true if the argument is a {@link ToolRequestPush}.
|
|
153
|
+
*
|
|
154
|
+
* @param {unknown} value
|
|
155
|
+
* @returns {value is ToolRequestPush}
|
|
156
|
+
*/
|
|
157
|
+
export function isToolRequestPush(value: unknown): value is ToolRequestPush;
|
|
158
|
+
/**
|
|
159
|
+
* Type guard: returns true if the argument is an {@link ErrorPush}.
|
|
160
|
+
*
|
|
161
|
+
* @param {unknown} value
|
|
162
|
+
* @returns {value is ErrorPush}
|
|
163
|
+
*/
|
|
164
|
+
export function isErrorPush(value: unknown): value is ErrorPush;
|
|
165
|
+
/**
|
|
166
|
+
* @rei-standard/amsg-shared
|
|
167
|
+
*
|
|
168
|
+
* Lowest layer of the ReiStandard Active Messaging ecosystem.
|
|
169
|
+
* Defines the three-axis push contract that `amsg-instant`,
|
|
170
|
+
* `amsg-server`, `amsg-sw`, and `amsg-client` all conform to.
|
|
171
|
+
*
|
|
172
|
+
* Three orthogonal axes:
|
|
173
|
+
* 1. messageType — how the push was produced (instant / fixed / prompted / auto)
|
|
174
|
+
* 2. messageSubtype — caller's business classification (free-form string)
|
|
175
|
+
* 3. messageKind — what the push carries (content / reasoning / tool_request / error)
|
|
176
|
+
*
|
|
177
|
+
* Zero runtime dependencies. The package is ESM/CJS dual-published and
|
|
178
|
+
* intentionally has no `dependencies:` entry — every other amsg sub-
|
|
179
|
+
* package depends on it, never the reverse.
|
|
180
|
+
*
|
|
181
|
+
* Types are expressed via JSDoc `@typedef` unions with literal-type
|
|
182
|
+
* discriminators so TS consumers can narrow on `messageKind`:
|
|
183
|
+
*
|
|
184
|
+
* if (push.messageKind === 'reasoning') {
|
|
185
|
+
* // TS knows: push is ReasoningPush, push.reasoningContent is string
|
|
186
|
+
* }
|
|
187
|
+
*/
|
|
188
|
+
/**
|
|
189
|
+
* What the push carries. Fixed enum — packages must not add values.
|
|
190
|
+
*
|
|
191
|
+
* @typedef {'content' | 'reasoning' | 'tool_request' | 'error'} MessageKind
|
|
192
|
+
*/
|
|
193
|
+
/**
|
|
194
|
+
* How the push was produced. Fixed enum — packages must not add values.
|
|
195
|
+
*
|
|
196
|
+
* @typedef {'instant' | 'fixed' | 'prompted' | 'auto'} MessageType
|
|
197
|
+
*/
|
|
198
|
+
/**
|
|
199
|
+
* Which sub-package routed the push. Fixed enum — `'instant'` for
|
|
200
|
+
* `amsg-instant` (stateless one-shot), `'scheduled'` for any
|
|
201
|
+
* `amsg-server` output regardless of `messageType`. Packages must not
|
|
202
|
+
* add values.
|
|
203
|
+
*
|
|
204
|
+
* @typedef {'instant' | 'scheduled'} PushSource
|
|
205
|
+
*/
|
|
206
|
+
/**
|
|
207
|
+
* Runtime constant mirroring the {@link MessageKind} type. Useful for
|
|
208
|
+
* switch statements that need to enumerate every kind:
|
|
209
|
+
*
|
|
210
|
+
* for (const kind of Object.values(MESSAGE_KIND)) { ... }
|
|
211
|
+
*/
|
|
212
|
+
export const MESSAGE_KIND: Readonly<{
|
|
213
|
+
CONTENT: "content";
|
|
214
|
+
REASONING: "reasoning";
|
|
215
|
+
TOOL_REQUEST: "tool_request";
|
|
216
|
+
ERROR: "error";
|
|
217
|
+
}>;
|
|
218
|
+
/**
|
|
219
|
+
* Runtime constant mirroring the {@link MessageType} type.
|
|
220
|
+
*/
|
|
221
|
+
export const MESSAGE_TYPE: Readonly<{
|
|
222
|
+
INSTANT: "instant";
|
|
223
|
+
FIXED: "fixed";
|
|
224
|
+
PROMPTED: "prompted";
|
|
225
|
+
AUTO: "auto";
|
|
226
|
+
}>;
|
|
227
|
+
/**
|
|
228
|
+
* Runtime constant mirroring the {@link PushSource} type.
|
|
229
|
+
*/
|
|
230
|
+
export const PUSH_SOURCE: Readonly<{
|
|
231
|
+
INSTANT: "instant";
|
|
232
|
+
SCHEDULED: "scheduled";
|
|
233
|
+
}>;
|
|
234
|
+
/**
|
|
235
|
+
* Fields present on every push, regardless of kind. Discriminator
|
|
236
|
+
* fields (`messageKind`) and kind-specific fields live on the kind
|
|
237
|
+
* interfaces below.
|
|
238
|
+
*
|
|
239
|
+
* `metadata` is a passthrough namespace owned by the caller. Packages
|
|
240
|
+
* are forbidden from writing their own fields into `metadata` — any
|
|
241
|
+
* protocol-level data goes on top-level fields.
|
|
242
|
+
*/
|
|
243
|
+
export type AmsgPushCommon = {
|
|
244
|
+
/**
|
|
245
|
+
* - How the push was produced.
|
|
246
|
+
*/
|
|
247
|
+
messageType: MessageType;
|
|
248
|
+
/**
|
|
249
|
+
* - Which sub-package routed it.
|
|
250
|
+
*/
|
|
251
|
+
source: PushSource;
|
|
252
|
+
/**
|
|
253
|
+
* - Unique per push. Format owned by the producer.
|
|
254
|
+
*/
|
|
255
|
+
messageId: string;
|
|
256
|
+
/**
|
|
257
|
+
* - Shared across all pushes from one LLM round (reasoning + content) and across iterations of a single agentic-loop request.
|
|
258
|
+
*/
|
|
259
|
+
sessionId: string;
|
|
260
|
+
/**
|
|
261
|
+
* - ISO 8601 timestamp at producer.
|
|
262
|
+
*/
|
|
263
|
+
timestamp: string;
|
|
264
|
+
/**
|
|
265
|
+
* - Caller-defined business namespace. Defaults to 'chat' at producers.
|
|
266
|
+
*/
|
|
267
|
+
messageSubtype?: string;
|
|
268
|
+
/**
|
|
269
|
+
* - Caller passthrough. Packages MUST NOT write here.
|
|
270
|
+
*/
|
|
271
|
+
metadata?: any;
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* Final user-facing content. Sentence-split bursts of N use
|
|
275
|
+
* `messageIndex` (1-based) + `totalMessages` so the client can
|
|
276
|
+
* reassemble or animate.
|
|
277
|
+
*/
|
|
278
|
+
export type ContentPush = AmsgPushCommon & {
|
|
279
|
+
messageKind: "content";
|
|
280
|
+
message: string;
|
|
281
|
+
title?: string;
|
|
282
|
+
contactName?: string;
|
|
283
|
+
avatarUrl?: string | null;
|
|
284
|
+
messageIndex?: number;
|
|
285
|
+
totalMessages?: number;
|
|
286
|
+
taskId?: string | null;
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* LLM "meta-thinking" — `choices[0].message.reasoning_content` lifted
|
|
290
|
+
* out of the upstream response into its own push. Emitted **before**
|
|
291
|
+
* the matching {@link ContentPush} burst when present and non-empty.
|
|
292
|
+
*
|
|
293
|
+
* Intentionally does NOT carry `messageIndex` / `totalMessages` —
|
|
294
|
+
* reasoning is a single push per LLM round, never a split-burst.
|
|
295
|
+
* That's why those fields are absent at the type level rather than
|
|
296
|
+
* `optional` (which would leave callers wondering when they're set).
|
|
297
|
+
*/
|
|
298
|
+
export type ReasoningPush = AmsgPushCommon & {
|
|
299
|
+
messageKind: "reasoning";
|
|
300
|
+
reasoningContent: string;
|
|
301
|
+
title?: string;
|
|
302
|
+
contactName?: string;
|
|
303
|
+
avatarUrl?: string | null;
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Tool invocation request emitted by an agentic-loop hook (`decision:
|
|
307
|
+
* 'tool-request'`). The client is expected to execute the tool and
|
|
308
|
+
* resume via the producer's `/continue` endpoint.
|
|
309
|
+
*
|
|
310
|
+
* `toolCalls` mirrors the OpenAI `choices[0].message.tool_calls`
|
|
311
|
+
* shape — left as `any`-equivalent so producers can passthrough
|
|
312
|
+
* whatever OpenAI-compatible upstream returned.
|
|
313
|
+
*/
|
|
314
|
+
export type ToolRequestPush = AmsgPushCommon & {
|
|
315
|
+
messageKind: "tool_request";
|
|
316
|
+
toolCalls: Array<any>;
|
|
317
|
+
title?: string;
|
|
318
|
+
contactName?: string;
|
|
319
|
+
message?: string;
|
|
320
|
+
};
|
|
321
|
+
/**
|
|
322
|
+
* Producer-level error. Replaces the legacy
|
|
323
|
+
* `{ type: 'error', code: '...' }` envelope. `code` is a stable
|
|
324
|
+
* string; `iteration` is the agentic-loop iteration number when
|
|
325
|
+
* relevant (0 / absent otherwise).
|
|
326
|
+
*/
|
|
327
|
+
export type ErrorPush = AmsgPushCommon & {
|
|
328
|
+
messageKind: "error";
|
|
329
|
+
code: string;
|
|
330
|
+
message: string;
|
|
331
|
+
iteration?: number;
|
|
332
|
+
};
|
|
333
|
+
/**
|
|
334
|
+
* Discriminated union of all pushes the SW can receive. TS consumers
|
|
335
|
+
* `switch` on `messageKind` and the compiler narrows automatically.
|
|
336
|
+
*/
|
|
337
|
+
export type AmsgPush = ContentPush | ReasoningPush | ToolRequestPush | ErrorPush;
|
|
338
|
+
/**
|
|
339
|
+
* What the push carries. Fixed enum — packages must not add values.
|
|
340
|
+
*/
|
|
341
|
+
export type MessageKind = "content" | "reasoning" | "tool_request" | "error";
|
|
342
|
+
/**
|
|
343
|
+
* How the push was produced. Fixed enum — packages must not add values.
|
|
344
|
+
*/
|
|
345
|
+
export type MessageType = "instant" | "fixed" | "prompted" | "auto";
|
|
346
|
+
/**
|
|
347
|
+
* Which sub-package routed the push. Fixed enum — `'instant'` for
|
|
348
|
+
* `amsg-instant` (stateless one-shot), `'scheduled'` for any
|
|
349
|
+
* `amsg-server` output regardless of `messageType`. Packages must not
|
|
350
|
+
* add values.
|
|
351
|
+
*/
|
|
352
|
+
export type PushSource = "instant" | "scheduled";
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// src/index.js
|
|
2
|
+
var MESSAGE_KIND = Object.freeze({
|
|
3
|
+
CONTENT: "content",
|
|
4
|
+
REASONING: "reasoning",
|
|
5
|
+
TOOL_REQUEST: "tool_request",
|
|
6
|
+
ERROR: "error"
|
|
7
|
+
});
|
|
8
|
+
var MESSAGE_TYPE = Object.freeze({
|
|
9
|
+
INSTANT: "instant",
|
|
10
|
+
FIXED: "fixed",
|
|
11
|
+
PROMPTED: "prompted",
|
|
12
|
+
AUTO: "auto"
|
|
13
|
+
});
|
|
14
|
+
var PUSH_SOURCE = Object.freeze({
|
|
15
|
+
INSTANT: "instant",
|
|
16
|
+
SCHEDULED: "scheduled"
|
|
17
|
+
});
|
|
18
|
+
function requireField(kind, field, value) {
|
|
19
|
+
if (value === void 0 || value === null || value === "") {
|
|
20
|
+
throw new Error(`[amsg-shared] ${kind}: '${field}' is required`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function buildContentPush(args) {
|
|
24
|
+
requireField("ContentPush", "messageType", args.messageType);
|
|
25
|
+
requireField("ContentPush", "source", args.source);
|
|
26
|
+
requireField("ContentPush", "messageId", args.messageId);
|
|
27
|
+
requireField("ContentPush", "sessionId", args.sessionId);
|
|
28
|
+
if (typeof args.message !== "string") {
|
|
29
|
+
throw new Error("[amsg-shared] ContentPush: 'message' must be a string");
|
|
30
|
+
}
|
|
31
|
+
const push = {
|
|
32
|
+
messageKind: "content",
|
|
33
|
+
messageType: args.messageType,
|
|
34
|
+
source: args.source,
|
|
35
|
+
messageId: args.messageId,
|
|
36
|
+
sessionId: args.sessionId,
|
|
37
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
38
|
+
message: args.message
|
|
39
|
+
};
|
|
40
|
+
if (args.title !== void 0) push.title = args.title;
|
|
41
|
+
if (args.contactName !== void 0) push.contactName = args.contactName;
|
|
42
|
+
if (args.avatarUrl !== void 0) push.avatarUrl = args.avatarUrl;
|
|
43
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
44
|
+
if (args.messageIndex !== void 0) push.messageIndex = args.messageIndex;
|
|
45
|
+
if (args.totalMessages !== void 0) push.totalMessages = args.totalMessages;
|
|
46
|
+
if (args.taskId !== void 0) push.taskId = args.taskId;
|
|
47
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
48
|
+
return push;
|
|
49
|
+
}
|
|
50
|
+
function buildReasoningPush(args) {
|
|
51
|
+
requireField("ReasoningPush", "messageType", args.messageType);
|
|
52
|
+
requireField("ReasoningPush", "source", args.source);
|
|
53
|
+
requireField("ReasoningPush", "messageId", args.messageId);
|
|
54
|
+
requireField("ReasoningPush", "sessionId", args.sessionId);
|
|
55
|
+
if (typeof args.reasoningContent !== "string" || !args.reasoningContent) {
|
|
56
|
+
throw new Error("[amsg-shared] ReasoningPush: 'reasoningContent' must be a non-empty string");
|
|
57
|
+
}
|
|
58
|
+
const push = {
|
|
59
|
+
messageKind: "reasoning",
|
|
60
|
+
messageType: args.messageType,
|
|
61
|
+
source: args.source,
|
|
62
|
+
messageId: args.messageId,
|
|
63
|
+
sessionId: args.sessionId,
|
|
64
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
65
|
+
reasoningContent: args.reasoningContent
|
|
66
|
+
};
|
|
67
|
+
if (args.title !== void 0) push.title = args.title;
|
|
68
|
+
if (args.contactName !== void 0) push.contactName = args.contactName;
|
|
69
|
+
if (args.avatarUrl !== void 0) push.avatarUrl = args.avatarUrl;
|
|
70
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
71
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
72
|
+
return push;
|
|
73
|
+
}
|
|
74
|
+
function buildToolRequestPush(args) {
|
|
75
|
+
requireField("ToolRequestPush", "messageType", args.messageType);
|
|
76
|
+
requireField("ToolRequestPush", "source", args.source);
|
|
77
|
+
requireField("ToolRequestPush", "messageId", args.messageId);
|
|
78
|
+
requireField("ToolRequestPush", "sessionId", args.sessionId);
|
|
79
|
+
if (!Array.isArray(args.toolCalls) || args.toolCalls.length === 0) {
|
|
80
|
+
throw new Error("[amsg-shared] ToolRequestPush: 'toolCalls' must be a non-empty array");
|
|
81
|
+
}
|
|
82
|
+
const push = {
|
|
83
|
+
messageKind: "tool_request",
|
|
84
|
+
messageType: args.messageType,
|
|
85
|
+
source: args.source,
|
|
86
|
+
messageId: args.messageId,
|
|
87
|
+
sessionId: args.sessionId,
|
|
88
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
89
|
+
toolCalls: args.toolCalls
|
|
90
|
+
};
|
|
91
|
+
if (args.title !== void 0) push.title = args.title;
|
|
92
|
+
if (args.contactName !== void 0) push.contactName = args.contactName;
|
|
93
|
+
if (args.message !== void 0) push.message = args.message;
|
|
94
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
95
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
96
|
+
return push;
|
|
97
|
+
}
|
|
98
|
+
function buildErrorPush(args) {
|
|
99
|
+
requireField("ErrorPush", "messageType", args.messageType);
|
|
100
|
+
requireField("ErrorPush", "source", args.source);
|
|
101
|
+
requireField("ErrorPush", "messageId", args.messageId);
|
|
102
|
+
requireField("ErrorPush", "sessionId", args.sessionId);
|
|
103
|
+
requireField("ErrorPush", "code", args.code);
|
|
104
|
+
if (typeof args.message !== "string") {
|
|
105
|
+
throw new Error("[amsg-shared] ErrorPush: 'message' must be a string");
|
|
106
|
+
}
|
|
107
|
+
const push = {
|
|
108
|
+
messageKind: "error",
|
|
109
|
+
messageType: args.messageType,
|
|
110
|
+
source: args.source,
|
|
111
|
+
messageId: args.messageId,
|
|
112
|
+
sessionId: args.sessionId,
|
|
113
|
+
timestamp: args.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
|
|
114
|
+
code: args.code,
|
|
115
|
+
message: args.message
|
|
116
|
+
};
|
|
117
|
+
if (args.iteration !== void 0) push.iteration = args.iteration;
|
|
118
|
+
if (args.messageSubtype !== void 0) push.messageSubtype = args.messageSubtype;
|
|
119
|
+
if (args.metadata !== void 0) push.metadata = args.metadata;
|
|
120
|
+
return push;
|
|
121
|
+
}
|
|
122
|
+
function isContentPush(value) {
|
|
123
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
124
|
+
value.messageKind === "content";
|
|
125
|
+
}
|
|
126
|
+
function isReasoningPush(value) {
|
|
127
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
128
|
+
value.messageKind === "reasoning";
|
|
129
|
+
}
|
|
130
|
+
function isToolRequestPush(value) {
|
|
131
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
132
|
+
value.messageKind === "tool_request";
|
|
133
|
+
}
|
|
134
|
+
function isErrorPush(value) {
|
|
135
|
+
return !!value && typeof value === "object" && /** @type {{messageKind?: unknown}} */
|
|
136
|
+
value.messageKind === "error";
|
|
137
|
+
}
|
|
138
|
+
export {
|
|
139
|
+
MESSAGE_KIND,
|
|
140
|
+
MESSAGE_TYPE,
|
|
141
|
+
PUSH_SOURCE,
|
|
142
|
+
buildContentPush,
|
|
143
|
+
buildErrorPush,
|
|
144
|
+
buildReasoningPush,
|
|
145
|
+
buildToolRequestPush,
|
|
146
|
+
isContentPush,
|
|
147
|
+
isErrorPush,
|
|
148
|
+
isReasoningPush,
|
|
149
|
+
isToolRequestPush
|
|
150
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rei-standard/amsg-shared",
|
|
3
|
+
"version": "0.1.0-next.0",
|
|
4
|
+
"description": "ReiStandard Active Messaging shared types and push builders — the lowest layer (no deps on other amsg packages)",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/Tosd0/ReiStandard",
|
|
8
|
+
"directory": "packages/rei-standard-amsg/shared"
|
|
9
|
+
},
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.mjs",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.mjs",
|
|
23
|
+
"require": "./dist/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsup && tsc -p tsconfig.json && node -e \"require('fs').copyFileSync('dist/index.d.ts', 'dist/index.d.cts')\"",
|
|
31
|
+
"test": "node --test test/*.test.mjs"
|
|
32
|
+
},
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=20"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"tsup": "^8.0.0",
|
|
38
|
+
"typescript": "^5.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|