@302ai/media-studio-core 0.1.0-beta.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/LICENSE +190 -0
- package/README.md +213 -0
- package/dist/client/auth.d.ts +13 -0
- package/dist/client/auth.js +34 -0
- package/dist/client/chat.d.ts +14 -0
- package/dist/client/chat.js +89 -0
- package/dist/client/client.d.ts +20 -0
- package/dist/client/client.js +34 -0
- package/dist/client/session.d.ts +33 -0
- package/dist/client/session.js +91 -0
- package/dist/client/sessions.d.ts +54 -0
- package/dist/client/sessions.js +213 -0
- package/dist/client/types.d.ts +45 -0
- package/dist/client/types.js +9 -0
- package/dist/events.d.ts +90 -0
- package/dist/format/tool-formatter.d.ts +31 -0
- package/dist/format/tool-formatter.js +395 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +24 -0
- package/dist/media/media-result.d.ts +21 -0
- package/dist/media/media-result.js +134 -0
- package/dist/media.d.ts +16 -0
- package/dist/sessions/types.d.ts +375 -0
- package/dist/sessions/types.js +129 -0
- package/dist/stream/events.d.ts +90 -0
- package/dist/stream/events.js +54 -0
- package/dist/stream/stream.d.ts +58 -0
- package/dist/stream/stream.js +325 -0
- package/dist/transport/errors.d.ts +30 -0
- package/dist/transport/errors.js +47 -0
- package/dist/transport/types.d.ts +44 -0
- package/dist/transport/types.js +1 -0
- package/dist/transport/upstream.d.ts +8 -0
- package/dist/transport/upstream.js +63 -0
- package/package.json +52 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { nanoid } from "nanoid";
|
|
2
|
+
export class ChatSession {
|
|
3
|
+
sessionId;
|
|
4
|
+
chat;
|
|
5
|
+
messages;
|
|
6
|
+
isTurnActive = false;
|
|
7
|
+
constructor(chat, options = {}) {
|
|
8
|
+
this.chat = chat;
|
|
9
|
+
this.sessionId = options.sessionId ?? nanoid();
|
|
10
|
+
this.messages = options.initialMessages ? [...options.initialMessages] : [];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Whether a message turn is currently in-flight.
|
|
14
|
+
*/
|
|
15
|
+
get isBusy() {
|
|
16
|
+
return this.isTurnActive;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns a copy of the current in-memory conversation history.
|
|
20
|
+
*/
|
|
21
|
+
getMessages() {
|
|
22
|
+
return [...this.messages];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Clears accumulated turn history while preserving the session ID.
|
|
26
|
+
*/
|
|
27
|
+
clearHistory() {
|
|
28
|
+
if (this.isTurnActive) {
|
|
29
|
+
throw new Error("Cannot clear history while a turn is active.");
|
|
30
|
+
}
|
|
31
|
+
this.messages = [];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sends a user turn within this session.
|
|
35
|
+
*
|
|
36
|
+
* Automatically appends the user message to history, dispatches the full
|
|
37
|
+
* history to the model, and asynchronously appends the assistant's reply
|
|
38
|
+
* to history once the stream completes.
|
|
39
|
+
*
|
|
40
|
+
* Throws an error if another turn is already active on this session.
|
|
41
|
+
*/
|
|
42
|
+
async sendMessage(prompt, options) {
|
|
43
|
+
if (this.isTurnActive) {
|
|
44
|
+
throw new Error("Cannot send message: a turn is already active in this ChatSession.");
|
|
45
|
+
}
|
|
46
|
+
this.isTurnActive = true;
|
|
47
|
+
const userMessage = { role: "user", content: prompt };
|
|
48
|
+
const turnMessages = [...this.messages, userMessage];
|
|
49
|
+
this.messages.push(userMessage);
|
|
50
|
+
let stream;
|
|
51
|
+
try {
|
|
52
|
+
stream = await this.chat.stream({
|
|
53
|
+
sessionId: this.sessionId,
|
|
54
|
+
messages: turnMessages,
|
|
55
|
+
chatTaskId: options?.chatTaskId,
|
|
56
|
+
signal: options?.signal,
|
|
57
|
+
maxRetries: options?.maxRetries,
|
|
58
|
+
initialRetryDelayMs: options?.initialRetryDelayMs,
|
|
59
|
+
onFinalResponse: (finalResponse) => {
|
|
60
|
+
this.isTurnActive = false;
|
|
61
|
+
this.messages.push({
|
|
62
|
+
role: "assistant",
|
|
63
|
+
content: finalResponse.text,
|
|
64
|
+
});
|
|
65
|
+
options?.onFinalResponse?.(finalResponse);
|
|
66
|
+
},
|
|
67
|
+
onError: (err) => {
|
|
68
|
+
this.isTurnActive = false;
|
|
69
|
+
const idx = this.messages.lastIndexOf(userMessage);
|
|
70
|
+
if (idx !== -1 && this.messages[idx + 1]?.role !== "assistant") {
|
|
71
|
+
this.messages.splice(idx, 1);
|
|
72
|
+
}
|
|
73
|
+
options?.onError?.(err);
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
// Ensure turn is marked inactive once stream settles (e.g. clean completion, early break, or abort)
|
|
77
|
+
stream.settled.finally(() => {
|
|
78
|
+
this.isTurnActive = false;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
this.isTurnActive = false;
|
|
83
|
+
const idx = this.messages.lastIndexOf(userMessage);
|
|
84
|
+
if (idx !== -1) {
|
|
85
|
+
this.messages.splice(idx, 1);
|
|
86
|
+
}
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
return stream;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type ListSessionsQuery, type ListSessionsResponse, type PrewarmSessionReady, type SessionPrewarmOutcome, type SessionPrewarmStage, type SessionSource } from "../sessions/types.js";
|
|
2
|
+
export type SessionPrewarmOptions = {
|
|
3
|
+
sessionId: string;
|
|
4
|
+
source: SessionSource;
|
|
5
|
+
note?: string;
|
|
6
|
+
installUserSkills?: boolean;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
onStageChange?: (stage: SessionPrewarmStage) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Fired exactly once, when the first `session_ready` event arrives. That
|
|
11
|
+
* event is the upstream commit point: the session is durably persisted and
|
|
12
|
+
* the id is safe to store from this moment on.
|
|
13
|
+
*/
|
|
14
|
+
onSessionReady?: (session: PrewarmSessionReady) => void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Session management against the media-studio gateway: list, remove, and
|
|
18
|
+
* provision (prewarm) sessions.
|
|
19
|
+
*/
|
|
20
|
+
export declare class ClientSessions {
|
|
21
|
+
private readonly baseUrl;
|
|
22
|
+
private readonly apiKey;
|
|
23
|
+
private readonly customFetch;
|
|
24
|
+
constructor(baseUrl: string, apiKey: string, customFetch?: typeof fetch);
|
|
25
|
+
private authHeaders;
|
|
26
|
+
/**
|
|
27
|
+
* Lists sessions from the server (the single source of truth).
|
|
28
|
+
*
|
|
29
|
+
* @throws {ChatUpstreamError} on HTTP failure.
|
|
30
|
+
*/
|
|
31
|
+
list(query?: ListSessionsQuery): Promise<ListSessionsResponse>;
|
|
32
|
+
/**
|
|
33
|
+
* Deletes a session server-side. Destroys the upstream conversation memory;
|
|
34
|
+
* this is irreversible.
|
|
35
|
+
*
|
|
36
|
+
* @throws {ChatUpstreamError} on HTTP failure.
|
|
37
|
+
*/
|
|
38
|
+
remove(sessionId: string): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Provisions a session via the prewarm SSE endpoint — the same flow the
|
|
41
|
+
* web app uses. Streams stage events through `onStageChange` and resolves
|
|
42
|
+
* to a three-state outcome bounded by the `session_ready` commit point:
|
|
43
|
+
*
|
|
44
|
+
* - `ready` — full provisioning completed;
|
|
45
|
+
* - `fallback` — the session is persisted but sandbox/skills provisioning
|
|
46
|
+
* failed or the stream ended early; plain-text chat still works;
|
|
47
|
+
* - `failed` — the session was never persisted upstream.
|
|
48
|
+
*
|
|
49
|
+
* Never call this again with a fresh id after `onSessionReady` fired for an
|
|
50
|
+
* id — that creates orphan sessions.
|
|
51
|
+
*/
|
|
52
|
+
prewarm(options: SessionPrewarmOptions): Promise<SessionPrewarmOutcome>;
|
|
53
|
+
private consumePrewarmStream;
|
|
54
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { createParser } from "eventsource-parser";
|
|
2
|
+
import { DeleteSessionResponseSchema, ListSessionsResponseSchema, PrewarmDoneSchema, PrewarmErrorSchema, PrewarmSandboxReadySchema, PrewarmSessionReadySchema, PrewarmSkillsReadySchema, } from "../sessions/types.js";
|
|
3
|
+
import { ChatUpstreamError, extractUpstreamErrorMessage, } from "../transport/errors.js";
|
|
4
|
+
const PREWARM_TIMEOUT_MS = 60_000;
|
|
5
|
+
const MAX_NETWORK_RETRIES = 2;
|
|
6
|
+
const RETRY_BASE_DELAY_MS = 500;
|
|
7
|
+
function delay(durationMs) {
|
|
8
|
+
return new Promise((resolve) => {
|
|
9
|
+
setTimeout(resolve, durationMs);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Session management against the media-studio gateway: list, remove, and
|
|
14
|
+
* provision (prewarm) sessions.
|
|
15
|
+
*/
|
|
16
|
+
export class ClientSessions {
|
|
17
|
+
baseUrl;
|
|
18
|
+
apiKey;
|
|
19
|
+
customFetch;
|
|
20
|
+
constructor(baseUrl, apiKey, customFetch) {
|
|
21
|
+
this.baseUrl = baseUrl;
|
|
22
|
+
this.apiKey = apiKey;
|
|
23
|
+
this.customFetch = customFetch ?? fetch;
|
|
24
|
+
}
|
|
25
|
+
authHeaders() {
|
|
26
|
+
return { Authorization: `Bearer ${this.apiKey}` };
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Lists sessions from the server (the single source of truth).
|
|
30
|
+
*
|
|
31
|
+
* @throws {ChatUpstreamError} on HTTP failure.
|
|
32
|
+
*/
|
|
33
|
+
async list(query) {
|
|
34
|
+
const params = new URLSearchParams();
|
|
35
|
+
if (query?.limit !== undefined)
|
|
36
|
+
params.set("limit", String(query.limit));
|
|
37
|
+
if (query?.offset !== undefined) {
|
|
38
|
+
params.set("offset", String(query.offset));
|
|
39
|
+
}
|
|
40
|
+
if (query?.note !== undefined)
|
|
41
|
+
params.set("note", query.note);
|
|
42
|
+
const search = params.toString();
|
|
43
|
+
const url = `${this.baseUrl}/api/sessions${search ? `?${search}` : ""}`;
|
|
44
|
+
const response = await this.customFetch(url, {
|
|
45
|
+
method: "GET",
|
|
46
|
+
headers: this.authHeaders(),
|
|
47
|
+
});
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
const rawBody = await response.text();
|
|
50
|
+
const message = extractUpstreamErrorMessage(rawBody) ||
|
|
51
|
+
`Failed to fetch sessions with status ${response.status}`;
|
|
52
|
+
throw new ChatUpstreamError(message, response.status, rawBody);
|
|
53
|
+
}
|
|
54
|
+
const rawJson = await response.json();
|
|
55
|
+
return ListSessionsResponseSchema.parse(rawJson);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Deletes a session server-side. Destroys the upstream conversation memory;
|
|
59
|
+
* this is irreversible.
|
|
60
|
+
*
|
|
61
|
+
* @throws {ChatUpstreamError} on HTTP failure.
|
|
62
|
+
*/
|
|
63
|
+
async remove(sessionId) {
|
|
64
|
+
const url = `${this.baseUrl}/api/sessions?sessionId=${encodeURIComponent(sessionId)}`;
|
|
65
|
+
const response = await this.customFetch(url, {
|
|
66
|
+
method: "DELETE",
|
|
67
|
+
headers: this.authHeaders(),
|
|
68
|
+
});
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
const rawBody = await response.text();
|
|
71
|
+
const message = extractUpstreamErrorMessage(rawBody) ||
|
|
72
|
+
`Failed to delete session with status ${response.status}`;
|
|
73
|
+
throw new ChatUpstreamError(message, response.status, rawBody);
|
|
74
|
+
}
|
|
75
|
+
const rawJson = await response.json();
|
|
76
|
+
DeleteSessionResponseSchema.parse(rawJson);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Provisions a session via the prewarm SSE endpoint — the same flow the
|
|
80
|
+
* web app uses. Streams stage events through `onStageChange` and resolves
|
|
81
|
+
* to a three-state outcome bounded by the `session_ready` commit point:
|
|
82
|
+
*
|
|
83
|
+
* - `ready` — full provisioning completed;
|
|
84
|
+
* - `fallback` — the session is persisted but sandbox/skills provisioning
|
|
85
|
+
* failed or the stream ended early; plain-text chat still works;
|
|
86
|
+
* - `failed` — the session was never persisted upstream.
|
|
87
|
+
*
|
|
88
|
+
* Never call this again with a fresh id after `onSessionReady` fired for an
|
|
89
|
+
* id — that creates orphan sessions.
|
|
90
|
+
*/
|
|
91
|
+
async prewarm(options) {
|
|
92
|
+
const { onStageChange, onSessionReady } = options;
|
|
93
|
+
const timeoutController = new AbortController();
|
|
94
|
+
const timeout = setTimeout(() => timeoutController.abort(), PREWARM_TIMEOUT_MS);
|
|
95
|
+
const signal = options.signal
|
|
96
|
+
? AbortSignal.any([timeoutController.signal, options.signal])
|
|
97
|
+
: timeoutController.signal;
|
|
98
|
+
const state = { sessionReady: null, outcome: null };
|
|
99
|
+
onStageChange?.("creating");
|
|
100
|
+
try {
|
|
101
|
+
for (let attempt = 0; attempt <= MAX_NETWORK_RETRIES; attempt++) {
|
|
102
|
+
if (state.outcome || signal.aborted)
|
|
103
|
+
break;
|
|
104
|
+
if (attempt > 0)
|
|
105
|
+
await delay(attempt * RETRY_BASE_DELAY_MS);
|
|
106
|
+
try {
|
|
107
|
+
const response = await this.customFetch(`${this.baseUrl}/api/sessions/prewarm`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: {
|
|
110
|
+
...this.authHeaders(),
|
|
111
|
+
Accept: "text/event-stream",
|
|
112
|
+
"Content-Type": "application/json",
|
|
113
|
+
},
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
sessionId: options.sessionId,
|
|
116
|
+
source: options.source,
|
|
117
|
+
...(options.note !== undefined ? { note: options.note } : {}),
|
|
118
|
+
...(options.installUserSkills !== undefined
|
|
119
|
+
? { installUserSkills: options.installUserSkills }
|
|
120
|
+
: {}),
|
|
121
|
+
}),
|
|
122
|
+
signal,
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
// 4xx (except 429) is deterministic: no point retrying.
|
|
126
|
+
const retryable = response.status >= 500 || response.status === 429;
|
|
127
|
+
if (!retryable)
|
|
128
|
+
break;
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
await this.consumePrewarmStream(response, state, {
|
|
132
|
+
onStageChange,
|
|
133
|
+
onSessionReady,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
if (signal.aborted)
|
|
138
|
+
break;
|
|
139
|
+
// Network failure or mid-stream read/parse error: retry until the
|
|
140
|
+
// budget is exhausted, then fall back on the session_ready boundary.
|
|
141
|
+
}
|
|
142
|
+
if (state.outcome)
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
clearTimeout(timeout);
|
|
148
|
+
}
|
|
149
|
+
if (state.outcome)
|
|
150
|
+
return state.outcome;
|
|
151
|
+
return state.sessionReady
|
|
152
|
+
? { status: "fallback", session: state.sessionReady }
|
|
153
|
+
: { status: "failed" };
|
|
154
|
+
}
|
|
155
|
+
async consumePrewarmStream(response, state, callbacks) {
|
|
156
|
+
if (!response.body)
|
|
157
|
+
return;
|
|
158
|
+
const parser = createParser({
|
|
159
|
+
onEvent(message) {
|
|
160
|
+
if (!message.data || state.outcome)
|
|
161
|
+
return;
|
|
162
|
+
const data = JSON.parse(message.data);
|
|
163
|
+
switch (message.event) {
|
|
164
|
+
case "session_ready": {
|
|
165
|
+
const session = PrewarmSessionReadySchema.parse(data);
|
|
166
|
+
if (!state.sessionReady)
|
|
167
|
+
callbacks.onSessionReady?.(session);
|
|
168
|
+
state.sessionReady = session;
|
|
169
|
+
callbacks.onStageChange?.("sandbox");
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
case "sandbox_ready": {
|
|
173
|
+
PrewarmSandboxReadySchema.parse(data);
|
|
174
|
+
callbacks.onStageChange?.("skills");
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
case "skills_ready": {
|
|
178
|
+
PrewarmSkillsReadySchema.parse(data);
|
|
179
|
+
callbacks.onStageChange?.("finishing");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
case "done": {
|
|
183
|
+
PrewarmDoneSchema.parse(data);
|
|
184
|
+
state.outcome = state.sessionReady
|
|
185
|
+
? { status: "ready", session: state.sessionReady }
|
|
186
|
+
: { status: "failed" };
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
case "error": {
|
|
190
|
+
PrewarmErrorSchema.parse(data);
|
|
191
|
+
state.outcome = state.sessionReady
|
|
192
|
+
? { status: "fallback", session: state.sessionReady }
|
|
193
|
+
: { status: "failed" };
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
default:
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
const reader = response.body.getReader();
|
|
202
|
+
const decoder = new TextDecoder();
|
|
203
|
+
for (;;) {
|
|
204
|
+
const { done, value } = await reader.read();
|
|
205
|
+
if (done)
|
|
206
|
+
break;
|
|
207
|
+
parser.feed(decoder.decode(value, { stream: true }));
|
|
208
|
+
if (state.outcome)
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
parser.feed(decoder.decode());
|
|
212
|
+
}
|
|
213
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { ChatFinalResponse } from "../stream/stream.js";
|
|
3
|
+
import type { ChatUpstreamMessage } from "../transport/types.js";
|
|
4
|
+
export interface MediaStudioClientOptions {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl?: string | undefined;
|
|
7
|
+
locale?: string | undefined;
|
|
8
|
+
fetch?: typeof fetch | undefined;
|
|
9
|
+
}
|
|
10
|
+
export declare const MeResponseSchema: z.ZodObject<{
|
|
11
|
+
uid: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
12
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
13
|
+
email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
14
|
+
apiKeyMasked: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
15
|
+
exp: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
valid: z.ZodBoolean;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type MeResponse = z.infer<typeof MeResponseSchema>;
|
|
19
|
+
export interface QuickPromptOptions {
|
|
20
|
+
sessionId: string;
|
|
21
|
+
chatTaskId?: string | undefined;
|
|
22
|
+
signal?: AbortSignal | undefined;
|
|
23
|
+
maxRetries?: number | undefined;
|
|
24
|
+
initialRetryDelayMs?: number | undefined;
|
|
25
|
+
onFinalResponse?: ((res: ChatFinalResponse) => void) | undefined;
|
|
26
|
+
onError?: ((err: unknown) => void) | undefined;
|
|
27
|
+
}
|
|
28
|
+
export interface ChatTurnOptions {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
messages: ChatUpstreamMessage[];
|
|
31
|
+
chatTaskId?: string | undefined;
|
|
32
|
+
sinceSeq?: number | string | undefined;
|
|
33
|
+
modelParams?: unknown;
|
|
34
|
+
skillUrls?: string[] | undefined;
|
|
35
|
+
structuredOutput?: boolean | undefined;
|
|
36
|
+
signal?: AbortSignal | undefined;
|
|
37
|
+
maxRetries?: number | undefined;
|
|
38
|
+
initialRetryDelayMs?: number | undefined;
|
|
39
|
+
onFinalResponse?: ((res: ChatFinalResponse) => void) | undefined;
|
|
40
|
+
onError?: ((err: unknown) => void) | undefined;
|
|
41
|
+
}
|
|
42
|
+
export interface ChatSessionOptions {
|
|
43
|
+
sessionId?: string | undefined;
|
|
44
|
+
initialMessages?: ChatUpstreamMessage[] | undefined;
|
|
45
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const MeResponseSchema = z.object({
|
|
3
|
+
uid: z.string().nullable().optional(),
|
|
4
|
+
name: z.string().nullable().optional(),
|
|
5
|
+
email: z.string().nullable().optional(),
|
|
6
|
+
apiKeyMasked: z.string().nullable().optional(),
|
|
7
|
+
exp: z.number().optional(),
|
|
8
|
+
valid: z.boolean(),
|
|
9
|
+
});
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Text part delta in streaming turn. */
|
|
3
|
+
export declare const TextDeltaEventSchema: z.ZodObject<{
|
|
4
|
+
type: z.ZodLiteral<"text-delta">;
|
|
5
|
+
delta: z.ZodString;
|
|
6
|
+
id: z.ZodOptional<z.ZodString>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
/** Reasoning / thinking part delta in streaming turn. */
|
|
9
|
+
export declare const ReasoningDeltaEventSchema: z.ZodObject<{
|
|
10
|
+
type: z.ZodLiteral<"reasoning-delta">;
|
|
11
|
+
delta: z.ZodString;
|
|
12
|
+
id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
/** Tool invocation event emitted when assistant calls an external tool. */
|
|
15
|
+
export declare const ToolCallEventSchema: z.ZodObject<{
|
|
16
|
+
type: z.ZodLiteral<"tool-call">;
|
|
17
|
+
toolCallId: z.ZodString;
|
|
18
|
+
toolName: z.ZodString;
|
|
19
|
+
args: z.ZodOptional<z.ZodUnknown>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
/** Tool result response emitted after tool execution finishes. */
|
|
22
|
+
export declare const ToolResultEventSchema: z.ZodObject<{
|
|
23
|
+
type: z.ZodLiteral<"tool-result">;
|
|
24
|
+
toolCallId: z.ZodString;
|
|
25
|
+
result: z.ZodOptional<z.ZodUnknown>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
/** High-level media result event emitted when image/video generation completes. */
|
|
28
|
+
export declare const MediaResultEventSchema: z.ZodObject<{
|
|
29
|
+
type: z.ZodLiteral<"media-result">;
|
|
30
|
+
result: z.ZodObject<{
|
|
31
|
+
status: z.ZodOptional<z.ZodString>;
|
|
32
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
33
|
+
operation: z.ZodOptional<z.ZodString>;
|
|
34
|
+
modelUsed: z.ZodOptional<z.ZodString>;
|
|
35
|
+
taskId: z.ZodOptional<z.ZodString>;
|
|
36
|
+
resultUrl: z.ZodOptional<z.ZodString>;
|
|
37
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
/** Terminal finish event indicating turn completion. */
|
|
41
|
+
export declare const FinishEventSchema: z.ZodObject<{
|
|
42
|
+
type: z.ZodLiteral<"finish">;
|
|
43
|
+
finishReason: z.ZodOptional<z.ZodString>;
|
|
44
|
+
}, z.core.$strip>;
|
|
45
|
+
/** Stream error event. Supports either error or message string. */
|
|
46
|
+
export declare const StreamErrorEventSchema: z.ZodObject<{
|
|
47
|
+
type: z.ZodLiteral<"error">;
|
|
48
|
+
error: z.ZodOptional<z.ZodString>;
|
|
49
|
+
message: z.ZodOptional<z.ZodString>;
|
|
50
|
+
chatTaskId: z.ZodOptional<z.ZodString>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
/** Discriminated union of all possible streaming events yielded by ChatStream. */
|
|
53
|
+
export declare const ChatStreamEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
54
|
+
type: z.ZodLiteral<"text-delta">;
|
|
55
|
+
delta: z.ZodString;
|
|
56
|
+
id: z.ZodOptional<z.ZodString>;
|
|
57
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
58
|
+
type: z.ZodLiteral<"reasoning-delta">;
|
|
59
|
+
delta: z.ZodString;
|
|
60
|
+
id: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
62
|
+
type: z.ZodLiteral<"tool-call">;
|
|
63
|
+
toolCallId: z.ZodString;
|
|
64
|
+
toolName: z.ZodString;
|
|
65
|
+
args: z.ZodOptional<z.ZodUnknown>;
|
|
66
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
67
|
+
type: z.ZodLiteral<"tool-result">;
|
|
68
|
+
toolCallId: z.ZodString;
|
|
69
|
+
result: z.ZodOptional<z.ZodUnknown>;
|
|
70
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
71
|
+
type: z.ZodLiteral<"media-result">;
|
|
72
|
+
result: z.ZodObject<{
|
|
73
|
+
status: z.ZodOptional<z.ZodString>;
|
|
74
|
+
domain: z.ZodOptional<z.ZodString>;
|
|
75
|
+
operation: z.ZodOptional<z.ZodString>;
|
|
76
|
+
modelUsed: z.ZodOptional<z.ZodString>;
|
|
77
|
+
taskId: z.ZodOptional<z.ZodString>;
|
|
78
|
+
resultUrl: z.ZodOptional<z.ZodString>;
|
|
79
|
+
prompt: z.ZodOptional<z.ZodString>;
|
|
80
|
+
}, z.core.$strip>;
|
|
81
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
82
|
+
type: z.ZodLiteral<"finish">;
|
|
83
|
+
finishReason: z.ZodOptional<z.ZodString>;
|
|
84
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
85
|
+
type: z.ZodLiteral<"error">;
|
|
86
|
+
error: z.ZodOptional<z.ZodString>;
|
|
87
|
+
message: z.ZodOptional<z.ZodString>;
|
|
88
|
+
chatTaskId: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>], "type">;
|
|
90
|
+
export type ChatStreamEvent = z.infer<typeof ChatStreamEventSchema>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export type ToolCategory = "agent" | "create" | "model" | "search" | "file" | "bash" | "skill" | "other";
|
|
2
|
+
export interface FormattedToolMilestone {
|
|
3
|
+
rawName: string;
|
|
4
|
+
normalizedName: string;
|
|
5
|
+
category: ToolCategory;
|
|
6
|
+
milestoneLine: string;
|
|
7
|
+
actionLabel: string;
|
|
8
|
+
details: {
|
|
9
|
+
model?: string;
|
|
10
|
+
aspectRatio?: string;
|
|
11
|
+
duration?: string;
|
|
12
|
+
resolution?: string;
|
|
13
|
+
voice?: string;
|
|
14
|
+
operation?: string;
|
|
15
|
+
subagentType?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
target?: string;
|
|
18
|
+
query?: string;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 1:1 normalization parity with main project's `normalizeMcpToolName`.
|
|
23
|
+
* Strips `tool-` prefix, lowercases, resolves MCP namespaces (`mcp__server__name`),
|
|
24
|
+
* and trims trailing `output` suffix.
|
|
25
|
+
*/
|
|
26
|
+
export declare function normalizeMcpToolName(toolName: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Parses and formats a tool call into a structured milestone and dynamic action label.
|
|
29
|
+
* Fully aligned 1:1 with the main project's tool renderer hierarchy.
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatToolMilestone(toolName: string, args: unknown): FormattedToolMilestone;
|