@amalgm/chat 0.1.1 → 0.1.2
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/PURPOSE.md +9 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/relay/index.d.ts +65 -0
- package/dist/relay/index.d.ts.map +1 -0
- package/dist/relay/index.js +197 -0
- package/dist/relay/index.js.map +1 -0
- package/package.json +5 -1
package/PURPOSE.md
CHANGED
|
@@ -17,7 +17,7 @@ itself — independent of any particular host, harness, or UI. If it spawns a
|
|
|
17
17
|
process, opens a socket, or touches a disk, it is a host adapter behind a
|
|
18
18
|
port, not a law.
|
|
19
19
|
|
|
20
|
-
## The
|
|
20
|
+
## The eight jobs
|
|
21
21
|
|
|
22
22
|
1. **The event grammar.** One canonical vocabulary (`text.delta` …
|
|
23
23
|
`usage.final` … `done`) that every harness's native events are translated
|
|
@@ -49,6 +49,10 @@ port, not a law.
|
|
|
49
49
|
the ownership fork (amalgm billing → proxy meters via egress; byok /
|
|
50
50
|
provider_auth → local logging), and the cost rules (unknown cost is
|
|
51
51
|
null, never zero).
|
|
52
|
+
8. **Session-bound relays.** Amalgm-auth turns reach the billing proxy only
|
|
53
|
+
through a per-session egress token, and harness MCP traffic reaches only
|
|
54
|
+
servers frozen into that session's contract. Request paths never choose
|
|
55
|
+
an arbitrary credential or destination.
|
|
52
56
|
|
|
53
57
|
## Axioms
|
|
54
58
|
|
|
@@ -81,6 +85,10 @@ port, not a law.
|
|
|
81
85
|
10. **Amalgm dogfoods its own SDK.** The end state (spec §10): ChatView's
|
|
82
86
|
data layer imports nothing but `@amalgm/chat`; the engine host mounts
|
|
83
87
|
these laws instead of containing them.
|
|
88
|
+
11. **Relay authority comes from the frozen contract.** Egress replaces the
|
|
89
|
+
session token with the host's proxy credential and stamps usage identity;
|
|
90
|
+
MCP relay replaces caller auth with the selected frozen server headers.
|
|
91
|
+
Neither relay accepts an upstream URL from the request.
|
|
84
92
|
|
|
85
93
|
## Five surfaces
|
|
86
94
|
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* usage/ token algebra, turn finalization, ownership fork, catalog
|
|
13
13
|
* api/ thin fetch adapters over SDK services
|
|
14
14
|
* normalizers/ native harness events → the grammar (wave B)
|
|
15
|
+
* relay/ session-bound egress and MCP forwarding laws
|
|
15
16
|
*
|
|
16
17
|
* Hosts inject effects through the port types in `ports.ts` (axiom 7).
|
|
17
18
|
* Prefer the subpath exports (`@amalgm/chat/<module>`) — name collisions
|
|
@@ -25,5 +26,6 @@ export * as contract from './contract/index.js';
|
|
|
25
26
|
export * as warm from './warm/index.js';
|
|
26
27
|
export * as usage from './usage/index.js';
|
|
27
28
|
export * as api from './api/index.js';
|
|
29
|
+
export * as relay from './relay/index.js';
|
|
28
30
|
export type { ClockMsPort, ClockIsoPort, Sha256HexPort, RandomUuidPort } from './ports.js';
|
|
29
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* usage/ token algebra, turn finalization, ownership fork, catalog
|
|
13
13
|
* api/ thin fetch adapters over SDK services
|
|
14
14
|
* normalizers/ native harness events → the grammar (wave B)
|
|
15
|
+
* relay/ session-bound egress and MCP forwarding laws
|
|
15
16
|
*
|
|
16
17
|
* Hosts inject effects through the port types in `ports.ts` (axiom 7).
|
|
17
18
|
* Prefer the subpath exports (`@amalgm/chat/<module>`) — name collisions
|
|
@@ -25,4 +26,5 @@ export * as contract from './contract/index.js';
|
|
|
25
26
|
export * as warm from './warm/index.js';
|
|
26
27
|
export * as usage from './usage/index.js';
|
|
27
28
|
export * as api from './api/index.js';
|
|
29
|
+
export * as relay from './relay/index.js';
|
|
28
30
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-bound relay laws.
|
|
3
|
+
* Engine references:
|
|
4
|
+
* - runtime/scripts/chat-core/egress.js
|
|
5
|
+
* - runtime/scripts/chat-core/tooling/mcp-relay.js
|
|
6
|
+
* - runtime/scripts/chat-core/tooling/mcp-bundle.js
|
|
7
|
+
* - runtime/scripts/chat-core/server.js:115-133
|
|
8
|
+
*/
|
|
9
|
+
export interface RelayHeader {
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly value: string;
|
|
12
|
+
}
|
|
13
|
+
export interface RelayServer {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly type: 'http' | 'sse';
|
|
16
|
+
readonly url: string;
|
|
17
|
+
readonly headers: readonly RelayHeader[];
|
|
18
|
+
}
|
|
19
|
+
export interface ChatRelayContract {
|
|
20
|
+
readonly sessionId: string;
|
|
21
|
+
readonly userId?: string;
|
|
22
|
+
readonly computerId?: string;
|
|
23
|
+
readonly agentId?: string;
|
|
24
|
+
readonly harness?: string;
|
|
25
|
+
readonly authMethod: string;
|
|
26
|
+
readonly modelId?: string;
|
|
27
|
+
readonly usageModelId?: string;
|
|
28
|
+
readonly cwd?: string;
|
|
29
|
+
readonly usageOwner?: string;
|
|
30
|
+
readonly auth?: {
|
|
31
|
+
readonly tokenRef?: string | null;
|
|
32
|
+
};
|
|
33
|
+
readonly mcpServers?: readonly unknown[];
|
|
34
|
+
}
|
|
35
|
+
export interface ChatRelayTurn {
|
|
36
|
+
readonly turnId?: string;
|
|
37
|
+
readonly assistantMessageId?: string;
|
|
38
|
+
}
|
|
39
|
+
export type RelayFetchPort = (input: string, init: RequestInit) => Promise<Response>;
|
|
40
|
+
export interface ChatRelayApiOptions {
|
|
41
|
+
readonly contractForSession: (sessionId: string) => ChatRelayContract | null;
|
|
42
|
+
readonly turnForSession?: (sessionId: string) => ChatRelayTurn | null;
|
|
43
|
+
readonly proxyCredentials: () => Promise<{
|
|
44
|
+
readonly baseUrl: string;
|
|
45
|
+
readonly token: string;
|
|
46
|
+
}>;
|
|
47
|
+
readonly defaultMcpServer?: (contract: ChatRelayContract) => unknown;
|
|
48
|
+
readonly fetch: RelayFetchPort;
|
|
49
|
+
}
|
|
50
|
+
export declare function parseEgressPath(pathname: unknown): {
|
|
51
|
+
sessionId: string;
|
|
52
|
+
upstreamPath: string;
|
|
53
|
+
} | null;
|
|
54
|
+
export declare function parseMcpRelayPath(pathname: unknown): {
|
|
55
|
+
sessionId: string;
|
|
56
|
+
serverName: string;
|
|
57
|
+
} | null;
|
|
58
|
+
export declare function metadataHeaders(contract: ChatRelayContract, turn?: ChatRelayTurn | null): Record<string, string>;
|
|
59
|
+
export declare function safeMcpServerName(name: unknown): string;
|
|
60
|
+
export declare function headerArrayToRecord(headers: unknown): Record<string, string>;
|
|
61
|
+
export declare function normalizeMcpServer(server: unknown): RelayServer | null;
|
|
62
|
+
export declare function mcpServers(contract: ChatRelayContract, defaultServer?: unknown): RelayServer[];
|
|
63
|
+
export declare function findMcpRelayTarget(contract: ChatRelayContract, serverName: unknown, defaultServer?: unknown): RelayServer | null;
|
|
64
|
+
export declare function createChatRelayApi(options: ChatRelayApiOptions): (request: Request) => Promise<Response>;
|
|
65
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/relay/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-bound relay laws.
|
|
3
|
+
* Engine references:
|
|
4
|
+
* - runtime/scripts/chat-core/egress.js
|
|
5
|
+
* - runtime/scripts/chat-core/tooling/mcp-relay.js
|
|
6
|
+
* - runtime/scripts/chat-core/tooling/mcp-bundle.js
|
|
7
|
+
* - runtime/scripts/chat-core/server.js:115-133
|
|
8
|
+
*/
|
|
9
|
+
const MCP_HOP_HEADERS = new Set([
|
|
10
|
+
'connection',
|
|
11
|
+
'content-length',
|
|
12
|
+
'host',
|
|
13
|
+
'keep-alive',
|
|
14
|
+
'proxy-authenticate',
|
|
15
|
+
'proxy-authorization',
|
|
16
|
+
'te',
|
|
17
|
+
'trailer',
|
|
18
|
+
'transfer-encoding',
|
|
19
|
+
'upgrade',
|
|
20
|
+
]);
|
|
21
|
+
const EGRESS_DROP_REQUEST_HEADERS = new Set([
|
|
22
|
+
'host', 'authorization', 'x-api-key', 'connection', 'content-length', 'accept-encoding',
|
|
23
|
+
]);
|
|
24
|
+
const EGRESS_DROP_RESPONSE_HEADERS = new Set(['connection', 'content-encoding', 'transfer-encoding']);
|
|
25
|
+
export function parseEgressPath(pathname) {
|
|
26
|
+
const parts = String(pathname || '').split('/').filter(Boolean);
|
|
27
|
+
if (parts[0] !== 'egress' || !parts[1])
|
|
28
|
+
return null;
|
|
29
|
+
return { sessionId: decodeURIComponent(parts[1]), upstreamPath: `/${parts.slice(2).join('/')}` };
|
|
30
|
+
}
|
|
31
|
+
export function parseMcpRelayPath(pathname) {
|
|
32
|
+
const parts = String(pathname || '').split('/').filter(Boolean);
|
|
33
|
+
if (parts[0] !== 'mcp-relay' || !parts[1] || !parts[2])
|
|
34
|
+
return null;
|
|
35
|
+
return { sessionId: decodeURIComponent(parts[1]), serverName: decodeURIComponent(parts[2]) };
|
|
36
|
+
}
|
|
37
|
+
export function metadataHeaders(contract, turn = null) {
|
|
38
|
+
return {
|
|
39
|
+
'x-amalgm-session-id': contract.sessionId,
|
|
40
|
+
'x-amalgm-message-id': turn?.assistantMessageId || turn?.turnId || '',
|
|
41
|
+
'x-amalgm-turn-id': turn?.turnId || '',
|
|
42
|
+
'x-amalgm-agent-id': contract.agentId || '',
|
|
43
|
+
'x-amalgm-harness-id': contract.harness || '',
|
|
44
|
+
'x-amalgm-auth-method': contract.authMethod,
|
|
45
|
+
'x-amalgm-model-id': contract.usageModelId || contract.modelId || '',
|
|
46
|
+
'x-amalgm-cwd': contract.cwd || '',
|
|
47
|
+
'x-amalgm-usage-owner': contract.usageOwner || '',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function safeMcpServerName(name) {
|
|
51
|
+
return String(name || '')
|
|
52
|
+
.trim()
|
|
53
|
+
.replace(/[^A-Za-z0-9_.-]+/g, '_')
|
|
54
|
+
.replace(/^_+|_+$/g, '')
|
|
55
|
+
|| 'mcp';
|
|
56
|
+
}
|
|
57
|
+
export function headerArrayToRecord(headers) {
|
|
58
|
+
const out = {};
|
|
59
|
+
for (const header of Array.isArray(headers) ? headers : []) {
|
|
60
|
+
const value = header;
|
|
61
|
+
const name = String(value?.name || '').trim();
|
|
62
|
+
if (name)
|
|
63
|
+
out[name] = String(value?.value || '');
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
67
|
+
export function normalizeMcpServer(server) {
|
|
68
|
+
if (!server || typeof server !== 'object')
|
|
69
|
+
return null;
|
|
70
|
+
const input = server;
|
|
71
|
+
const name = safeMcpServerName(input.name);
|
|
72
|
+
const url = String(input.url || '').trim();
|
|
73
|
+
if (!name || !url)
|
|
74
|
+
return null;
|
|
75
|
+
const rawHeaders = Array.isArray(input.headers)
|
|
76
|
+
? input.headers
|
|
77
|
+
: Object.entries(input.headers && typeof input.headers === 'object' ? input.headers : {})
|
|
78
|
+
.filter(([headerName, value]) => headerName && value != null)
|
|
79
|
+
.map(([headerName, value]) => ({ name: headerName, value: String(value) }));
|
|
80
|
+
return {
|
|
81
|
+
name,
|
|
82
|
+
type: String(input.type || '').toLowerCase() === 'sse' ? 'sse' : 'http',
|
|
83
|
+
url,
|
|
84
|
+
headers: rawHeaders.map((header) => ({
|
|
85
|
+
name: String(header.name || ''),
|
|
86
|
+
value: String(header.value || ''),
|
|
87
|
+
})),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
export function mcpServers(contract, defaultServer) {
|
|
91
|
+
const byName = new Map();
|
|
92
|
+
const add = (server) => {
|
|
93
|
+
const normalized = normalizeMcpServer(server);
|
|
94
|
+
if (normalized)
|
|
95
|
+
byName.set(normalized.name, normalized);
|
|
96
|
+
};
|
|
97
|
+
if (defaultServer)
|
|
98
|
+
add(defaultServer);
|
|
99
|
+
for (const server of Array.isArray(contract.mcpServers) ? contract.mcpServers : [])
|
|
100
|
+
add(server);
|
|
101
|
+
return [...byName.values()];
|
|
102
|
+
}
|
|
103
|
+
export function findMcpRelayTarget(contract, serverName, defaultServer) {
|
|
104
|
+
const clean = safeMcpServerName(serverName);
|
|
105
|
+
return mcpServers(contract, defaultServer).find((server) => server.name === clean) || null;
|
|
106
|
+
}
|
|
107
|
+
export function createChatRelayApi(options) {
|
|
108
|
+
return async (request) => {
|
|
109
|
+
const url = new URL(request.url);
|
|
110
|
+
if (request.method === 'GET' && url.pathname === '/egress') {
|
|
111
|
+
return json(200, { service: 'egress', sessionBound: true, route: '/egress/:session/*' });
|
|
112
|
+
}
|
|
113
|
+
if (request.method === 'GET' && url.pathname === '/mcp-relay') {
|
|
114
|
+
return json(200, { service: 'mcp-relay', sessionBound: true, route: '/mcp-relay/:session/:server' });
|
|
115
|
+
}
|
|
116
|
+
const egress = parseEgressPath(url.pathname);
|
|
117
|
+
if (egress)
|
|
118
|
+
return forwardEgress(request, url, egress, options);
|
|
119
|
+
const relay = parseMcpRelayPath(url.pathname);
|
|
120
|
+
if (relay)
|
|
121
|
+
return forwardMcpRelay(request, url, relay, options);
|
|
122
|
+
return json(404, { error: 'Not found' });
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async function forwardEgress(request, url, route, options) {
|
|
126
|
+
const contract = options.contractForSession(route.sessionId);
|
|
127
|
+
if (!contract || contract.authMethod !== 'amalgm') {
|
|
128
|
+
return json(404, { error: 'No Amalgm egress session', sessionId: route.sessionId });
|
|
129
|
+
}
|
|
130
|
+
const authorization = request.headers.get('authorization') || '';
|
|
131
|
+
const bearer = authorization.replace(/^Bearer\s+/i, '').trim();
|
|
132
|
+
const provided = bearer || (request.headers.get('x-api-key') || '').trim();
|
|
133
|
+
if (!contract.auth?.tokenRef || provided !== contract.auth.tokenRef) {
|
|
134
|
+
return json(401, { error: 'Invalid egress token' });
|
|
135
|
+
}
|
|
136
|
+
const proxy = await options.proxyCredentials();
|
|
137
|
+
const headers = copyHeaders(request.headers, EGRESS_DROP_REQUEST_HEADERS);
|
|
138
|
+
Object.assign(headers, metadataHeaders(contract, options.turnForSession?.(route.sessionId) || null));
|
|
139
|
+
headers.Authorization = `Bearer ${proxy.token}`;
|
|
140
|
+
const body = await requestBody(request);
|
|
141
|
+
const response = await options.fetch(`${proxy.baseUrl.replace(/\/$/, '')}${route.upstreamPath}${url.search}`, { method: request.method, headers, ...(body ? { body } : {}) });
|
|
142
|
+
return copyResponse(response, EGRESS_DROP_RESPONSE_HEADERS);
|
|
143
|
+
}
|
|
144
|
+
async function forwardMcpRelay(request, url, route, options) {
|
|
145
|
+
const contract = options.contractForSession(route.sessionId);
|
|
146
|
+
if (!contract)
|
|
147
|
+
return json(404, { error: 'No MCP relay session', sessionId: route.sessionId });
|
|
148
|
+
const target = findMcpRelayTarget(contract, route.serverName, options.defaultMcpServer?.(contract));
|
|
149
|
+
if (!target)
|
|
150
|
+
return json(404, { error: 'Unknown MCP server', serverName: route.serverName });
|
|
151
|
+
const headers = copyHeaders(request.headers, new Set([...MCP_HOP_HEADERS, 'authorization']));
|
|
152
|
+
Object.assign(headers, headerArrayToRecord(target.headers), {
|
|
153
|
+
'x-amalgm-session-id': contract.sessionId,
|
|
154
|
+
'x-amalgm-user-id': contract.userId || '',
|
|
155
|
+
'x-amalgm-computer-id': contract.computerId || '',
|
|
156
|
+
});
|
|
157
|
+
for (const key of Object.keys(headers))
|
|
158
|
+
if (!headers[key])
|
|
159
|
+
delete headers[key];
|
|
160
|
+
const body = await requestBody(request);
|
|
161
|
+
const response = await options.fetch(`${target.url}${url.search}`, {
|
|
162
|
+
method: request.method,
|
|
163
|
+
headers,
|
|
164
|
+
...(body ? { body } : {}),
|
|
165
|
+
redirect: 'manual',
|
|
166
|
+
});
|
|
167
|
+
return copyResponse(response, MCP_HOP_HEADERS);
|
|
168
|
+
}
|
|
169
|
+
function copyHeaders(headers, drop) {
|
|
170
|
+
const out = {};
|
|
171
|
+
headers.forEach((value, name) => {
|
|
172
|
+
if (!drop.has(name.toLowerCase()))
|
|
173
|
+
out[name] = value;
|
|
174
|
+
});
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
async function requestBody(request) {
|
|
178
|
+
if (request.method === 'GET' || request.method === 'HEAD')
|
|
179
|
+
return undefined;
|
|
180
|
+
const body = await request.arrayBuffer();
|
|
181
|
+
return body.byteLength > 0 ? body : undefined;
|
|
182
|
+
}
|
|
183
|
+
function copyResponse(response, drop) {
|
|
184
|
+
const headers = new Headers();
|
|
185
|
+
response.headers.forEach((value, name) => {
|
|
186
|
+
if (!drop.has(name.toLowerCase()))
|
|
187
|
+
headers.set(name, value);
|
|
188
|
+
});
|
|
189
|
+
return new Response(response.body, { status: response.status, headers });
|
|
190
|
+
}
|
|
191
|
+
function json(status, body) {
|
|
192
|
+
return new Response(JSON.stringify(body), {
|
|
193
|
+
status,
|
|
194
|
+
headers: { 'content-type': 'application/json', 'cache-control': 'no-cache' },
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/relay/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amalgm/chat",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "The Amalgm chat SDK — the conversation pipeline's laws: turns, messages, streaming assembly, event normalization, and transcript truth, behind host-injected adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -51,6 +51,10 @@
|
|
|
51
51
|
"./api": {
|
|
52
52
|
"types": "./dist/api/index.d.ts",
|
|
53
53
|
"default": "./dist/api/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./relay": {
|
|
56
|
+
"types": "./dist/relay/index.d.ts",
|
|
57
|
+
"default": "./dist/relay/index.js"
|
|
54
58
|
}
|
|
55
59
|
},
|
|
56
60
|
"files": [
|