@xsai/text 1.0.0-beta.5 → 1.0.0-beta.6
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/dist/index.d.ts +9 -4
- package/dist/index.js +41 -78
- package/dist/internal.d.ts +20 -3
- package/dist/internal.js +5 -1
- package/dist/{language-model-Dne8NRLD.d.ts → language-model-CAPBb-ti.d.ts} +8 -1
- package/dist/read-step-DXGjtk1d.js +50 -0
- package/package.json +2 -2
- package/dist/schema-Bny4Y6lV.js +0 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as StepEndDoneEvent, T as ToolCallPart, a as ToolResultPart, U as Usage, b as TextEvent, M as Message, L as LanguageModelOptions, c as LanguageModel, d as ToolExecuteOptions } from './language-model-
|
|
2
|
-
export { A as AssistantMessage, e as AssistantMessageContent, f as AudioPart, C as CombinedStandardSchema, g as Content, h as ContentEndEvent, i as ContentMap, j as ContentStartEvent, k as ContentType, D as DeveloperMessage, l as DeveloperMessageContent, E as ExecutableTool, F as FilePart, m as FinishReason, I as ImagePart, n as InferSchemaInput, o as InferSchemaOutput, J as JSONSchema7, p as JSONSchema7Definition, q as LanguageModelProviderOptions, r as MessageMap, s as MessageProviderMetadata, t as MessageType, P as PartProviderMetadata, u as ProviderPart, R as RawEvent, v as ReasoningDeltaEvent, w as ReasoningPart, x as ReasoningPartContent, y as RefusalDeltaEvent, z as RefusalPart, B as ResolvedSchema, G as StepEndEvent, H as StepEndFailEvent, K as StepStartEvent, N as StepStatus, O as SystemMessage, Q as SystemMessageContent, V as TextDeltaEvent, W as TextEventMap, X as TextEventType, Y as TextPart, Z as Tool, _ as ToolCallDeltaEvent, $ as ToolChoice, a0 as ToolOptions, a1 as ToolResultPartContent, a2 as UnresolvedSchema, a3 as UserMessage, a4 as UserMessageContent, a5 as
|
|
1
|
+
import { S as StepEndDoneEvent, T as ToolCallPart, a as ToolResultPart, U as Usage, b as TextEvent, M as Message, L as LanguageModelOptions, c as LanguageModel, d as ToolExecuteOptions } from './language-model-CAPBb-ti.js';
|
|
2
|
+
export { A as AssistantMessage, e as AssistantMessageContent, f as AudioPart, C as CombinedStandardSchema, g as Content, h as ContentEndEvent, i as ContentMap, j as ContentStartEvent, k as ContentType, D as DeveloperMessage, l as DeveloperMessageContent, E as ExecutableTool, F as FilePart, m as FinishReason, I as ImagePart, n as InferSchemaInput, o as InferSchemaOutput, J as JSONSchema7, p as JSONSchema7Definition, q as LanguageModelProviderOptions, r as MessageMap, s as MessageProviderMetadata, t as MessageType, P as PartProviderMetadata, u as ProviderPart, R as RawEvent, v as ReasoningDeltaEvent, w as ReasoningPart, x as ReasoningPartContent, y as RefusalDeltaEvent, z as RefusalPart, B as ResolvedSchema, G as StepEndEvent, H as StepEndFailEvent, K as StepStartEvent, N as StepStatus, O as SystemMessage, Q as SystemMessageContent, V as TextDeltaEvent, W as TextEventMap, X as TextEventType, Y as TextPart, Z as Tool, _ as ToolCallDeltaEvent, $ as ToolChoice, a0 as ToolOptions, a1 as ToolResultPartContent, a2 as UnresolvedSchema, a3 as UserMessage, a4 as UserMessageContent, a5 as formatIssues, a6 as resolveSchema, a7 as tool } from './language-model-CAPBb-ti.js';
|
|
3
3
|
import { Promisable } from '@xsai/shared';
|
|
4
4
|
export { HttpError, XSAIError, XSAIErrorCause, XSAIErrorCauseMap, XSAIErrorCode, XSAIErrorOptions } from '@xsai/shared';
|
|
5
5
|
|
|
@@ -40,8 +40,13 @@ declare const hasToolCall: (name?: string) => StopCondition;
|
|
|
40
40
|
/** @deprecated use `maxSteps` instead. */
|
|
41
41
|
declare const stepCountAtLeast: (count: number) => StopCondition;
|
|
42
42
|
|
|
43
|
+
interface ExecuteToolOptions extends Pick<LanguageModelOptions, 'signal' | 'tools'> {
|
|
44
|
+
postToolCall?: PostToolCall;
|
|
45
|
+
preToolCall?: PreToolCall;
|
|
46
|
+
}
|
|
43
47
|
type PostToolCall = (toolResult: ToolResultPart, options: ToolExecuteOptions) => Promisable<ToolResultPart | void>;
|
|
44
48
|
type PreToolCall = (toolCall: ToolCallPart, options: ToolExecuteOptions) => Promisable<ToolCallPart | ToolResultPart | void>;
|
|
49
|
+
declare const executeTool: (call: ToolCallPart, { postToolCall, preToolCall, signal, tools }: ExecuteToolOptions) => Promise<ToolResultPart>;
|
|
45
50
|
|
|
46
51
|
interface StreamTextOptions extends LanguageModelOptions {
|
|
47
52
|
postToolCall?: PostToolCall;
|
|
@@ -82,5 +87,5 @@ declare module '@xsai/shared' {
|
|
|
82
87
|
}
|
|
83
88
|
}
|
|
84
89
|
|
|
85
|
-
export { LanguageModel, LanguageModelOptions, Message, StepEndDoneEvent, TextEvent, TextEventTarget, ToolCallPart, ToolExecuteOptions, ToolResultPart, Usage, and, collect, generateText, hasToolCall, maxSteps, not, or, stepCountAtLeast, streamText, toCustomEvent, withEventTarget };
|
|
86
|
-
export type { CollectResult, PostToolCall, PreToolCall, PrepareStep, PrepareStepOptions, PrepareStepResult, StepResult, StopCondition, StopContext, StreamTextOptions };
|
|
90
|
+
export { LanguageModel, LanguageModelOptions, Message, StepEndDoneEvent, TextEvent, TextEventTarget, ToolCallPart, ToolExecuteOptions, ToolResultPart, Usage, and, collect, executeTool, generateText, hasToolCall, maxSteps, not, or, stepCountAtLeast, streamText, toCustomEvent, withEventTarget };
|
|
91
|
+
export type { CollectResult, ExecuteToolOptions, PostToolCall, PreToolCall, PrepareStep, PrepareStepOptions, PrepareStepResult, StepResult, StopCondition, StopContext, StreamTextOptions };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { XSAIError } from '@xsai/shared';
|
|
2
2
|
export { HttpError, XSAIError } from '@xsai/shared';
|
|
3
|
-
import { r as resolveSchema } from './
|
|
3
|
+
import { f as formatIssues, r as readStep, a as resolveSchema } from './read-step-DXGjtk1d.js';
|
|
4
4
|
|
|
5
5
|
const getText = (message) => typeof message.content === "string" ? message.content : message.content.filter((part) => part.type === "text").map((part) => part.text).join("");
|
|
6
6
|
const getToolCalls = (message) => typeof message.content === "string" ? [] : message.content.filter((part) => part.type === "tool-call");
|
|
@@ -80,7 +80,7 @@ const assertSameCallId = (source, next) => {
|
|
|
80
80
|
if (source !== next)
|
|
81
81
|
throw new Error(`Tool call hooks must preserve callId "${source}".`);
|
|
82
82
|
};
|
|
83
|
-
const
|
|
83
|
+
const attempt = async (call, signal, callback) => {
|
|
84
84
|
try {
|
|
85
85
|
return await callback();
|
|
86
86
|
} catch (error) {
|
|
@@ -88,85 +88,48 @@ const catchToolError = async (call, signal, callback) => {
|
|
|
88
88
|
return toolError(call, error instanceof Error ? error.message : String(error));
|
|
89
89
|
}
|
|
90
90
|
};
|
|
91
|
+
const parseInput = (args) => {
|
|
92
|
+
try {
|
|
93
|
+
return JSON.parse(args.trim() || "{}");
|
|
94
|
+
} catch {
|
|
95
|
+
throw new Error("Failed to parse tool input.");
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const runTool = async (call, tools, options) => {
|
|
99
|
+
const tool = tools?.find((candidate) => candidate.name === call.name);
|
|
100
|
+
if (tool == null) {
|
|
101
|
+
const available = tools?.map((candidate) => candidate.name).join(", ");
|
|
102
|
+
throw new Error(`Model tried to call unavailable tool "${call.name}", ${available == null || available === "" ? "No tools are available" : `Available tools: ${available}`}.`);
|
|
103
|
+
}
|
|
104
|
+
if (tool.execute == null)
|
|
105
|
+
throw new Error(`Tool "${call.name}" is not executable.`);
|
|
106
|
+
let input = parseInput(call.arguments);
|
|
107
|
+
if (tool.inputSchema.validate != null) {
|
|
108
|
+
const validation = await tool.inputSchema.validate(input);
|
|
109
|
+
if (validation.issues)
|
|
110
|
+
throw new Error(`Tool input validation failed for "${call.name}": ${formatIssues(validation.issues)}`);
|
|
111
|
+
input = validation.value;
|
|
112
|
+
}
|
|
113
|
+
return { callId: call.callId, output: await tool.execute(input, options), type: "tool-result" };
|
|
114
|
+
};
|
|
91
115
|
const executeTool = async (call, { postToolCall, preToolCall, signal, tools }) => {
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
if (
|
|
95
|
-
assertSameCallId(call.callId,
|
|
96
|
-
if (
|
|
97
|
-
return
|
|
98
|
-
call =
|
|
116
|
+
const options = { callId: call.callId, signal };
|
|
117
|
+
const prepared = await attempt(call, signal, async () => preToolCall?.(call, options));
|
|
118
|
+
if (prepared != null) {
|
|
119
|
+
assertSameCallId(call.callId, prepared.callId);
|
|
120
|
+
if (prepared.type === "tool-result")
|
|
121
|
+
return prepared;
|
|
122
|
+
call = prepared;
|
|
99
123
|
}
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return toolError(call, tool == null ? `Model tried to call unavailable tool "${call.name}", ${available == null || available === "" ? "No tools are available" : `Available tools: ${available}`}.` : `Tool "${call.name}" is not executable.`);
|
|
107
|
-
}
|
|
108
|
-
let toolInput;
|
|
109
|
-
try {
|
|
110
|
-
toolInput = JSON.parse(call.arguments.trim() || "{}");
|
|
111
|
-
} catch {
|
|
112
|
-
return toolError(call, "Failed to parse tool input.");
|
|
113
|
-
}
|
|
114
|
-
let validatedInput = toolInput;
|
|
115
|
-
if (executableTool.inputSchema.validate != null) {
|
|
116
|
-
const validation = await executableTool.inputSchema.validate(toolInput);
|
|
117
|
-
if (validation.issues)
|
|
118
|
-
return toolError(call, `Tool input validation failed for "${call.name}".`);
|
|
119
|
-
validatedInput = validation.value;
|
|
120
|
-
}
|
|
121
|
-
shouldPostToolCall = true;
|
|
122
|
-
return {
|
|
123
|
-
callId: call.callId,
|
|
124
|
-
output: await executableTool.execute(validatedInput, executeOptions),
|
|
125
|
-
type: "tool-result"
|
|
126
|
-
};
|
|
127
|
-
});
|
|
128
|
-
if (!shouldPostToolCall || postToolCall == null)
|
|
129
|
-
return toolResult;
|
|
130
|
-
const postToolCallResult = await catchToolError(call, signal, async () => postToolCall(toolResult, executeOptions));
|
|
131
|
-
if (postToolCallResult == null)
|
|
132
|
-
return toolResult;
|
|
133
|
-
assertSameCallId(toolResult.callId, postToolCallResult.callId);
|
|
134
|
-
return postToolCallResult;
|
|
124
|
+
const result = await attempt(call, signal, async () => runTool(call, tools, options));
|
|
125
|
+
const posted = await attempt(call, signal, async () => postToolCall?.(result, options));
|
|
126
|
+
if (posted == null)
|
|
127
|
+
return result;
|
|
128
|
+
assertSameCallId(result.callId, posted.callId);
|
|
129
|
+
return posted;
|
|
135
130
|
};
|
|
136
131
|
const executeTools = async ({ reason, toolCalls, ...options }) => reason === "length" ? toolCalls.map((call) => toolError(call, "The response reached the output token limit before the tool call was complete.")) : Promise.all(toolCalls.map(async (call) => executeTool(call, options)));
|
|
137
132
|
|
|
138
|
-
const readStep = async function* (stream, signal) {
|
|
139
|
-
const reader = stream.getReader();
|
|
140
|
-
let cancellation;
|
|
141
|
-
const abort = () => {
|
|
142
|
-
cancellation = reader.cancel(signal.reason);
|
|
143
|
-
void cancellation.catch(() => {
|
|
144
|
-
});
|
|
145
|
-
};
|
|
146
|
-
let stepEnd;
|
|
147
|
-
signal.addEventListener("abort", abort, { once: true });
|
|
148
|
-
try {
|
|
149
|
-
signal.throwIfAborted();
|
|
150
|
-
while (true) {
|
|
151
|
-
const { done, value: event } = await reader.read();
|
|
152
|
-
signal.throwIfAborted();
|
|
153
|
-
if (done)
|
|
154
|
-
break;
|
|
155
|
-
if (event.type === "step.end") {
|
|
156
|
-
if (stepEnd != null)
|
|
157
|
-
throw new XSAIError("protocol-error", "model stream produced more than one step.end event");
|
|
158
|
-
stepEnd = event;
|
|
159
|
-
}
|
|
160
|
-
yield event;
|
|
161
|
-
}
|
|
162
|
-
if (stepEnd == null)
|
|
163
|
-
throw new XSAIError("truncated-stream", "model stream ended without a step.end event");
|
|
164
|
-
return stepEnd;
|
|
165
|
-
} finally {
|
|
166
|
-
signal.removeEventListener("abort", abort);
|
|
167
|
-
await (cancellation ?? reader.cancel(signal.reason)).finally(() => reader.releaseLock());
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
133
|
const streamText = (model, { postToolCall, prepareStep, preToolCall, stopWhen: stopWhenOption, ...options }) => {
|
|
171
134
|
const stopWhen = stopWhenOption ?? maxSteps(10);
|
|
172
135
|
const input = [...Array.isArray(options.input) ? options.input : [{ content: options.input, role: "user" }]];
|
|
@@ -263,7 +226,7 @@ const tool = ((options) => {
|
|
|
263
226
|
if (outputSchema?.validate != null) {
|
|
264
227
|
const validation = await outputSchema.validate(result);
|
|
265
228
|
if (validation.issues)
|
|
266
|
-
throw new Error(`Tool output validation failed for "${options.name}"
|
|
229
|
+
throw new Error(`Tool output validation failed for "${options.name}": ${formatIssues(validation.issues)}`);
|
|
267
230
|
result = validation.value;
|
|
268
231
|
}
|
|
269
232
|
if (outputSchema)
|
|
@@ -275,4 +238,4 @@ const tool = ((options) => {
|
|
|
275
238
|
}
|
|
276
239
|
});
|
|
277
240
|
|
|
278
|
-
export { TextEventTarget, and, collect, generateText, hasToolCall, maxSteps, not, or, stepCountAtLeast, streamText, toCustomEvent, tool, withEventTarget };
|
|
241
|
+
export { TextEventTarget, and, collect, executeTool, generateText, hasToolCall, maxSteps, not, or, stepCountAtLeast, streamText, toCustomEvent, tool, withEventTarget };
|
package/dist/internal.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { StepStatus, FinishReason, AssistantMessage, AssistantMessageContent, PartProviderMetadata, Usage, TextEvent, LanguageModelOptions } from './index.js';
|
|
2
|
-
export { C as CombinedStandardSchema, n as InferSchemaInput, o as InferSchemaOutput, J as JSONSchema7, p as JSONSchema7Definition, B as ResolvedSchema, a2 as UnresolvedSchema, a5 as resolveSchema } from './language-model-
|
|
1
|
+
import { StepStatus, FinishReason, AssistantMessage, AssistantMessageContent, PartProviderMetadata, Usage, TextEvent, StepEndEvent, LanguageModelOptions } from './index.js';
|
|
2
|
+
export { C as CombinedStandardSchema, n as InferSchemaInput, o as InferSchemaOutput, J as JSONSchema7, p as JSONSchema7Definition, B as ResolvedSchema, a2 as UnresolvedSchema, a5 as formatIssues, a6 as resolveSchema } from './language-model-CAPBb-ti.js';
|
|
3
3
|
import { XSAIError, EventSourceMessage, SendRequestOptions, HttpOptions } from '@xsai/shared';
|
|
4
4
|
|
|
5
5
|
interface EventBuilder {
|
|
@@ -17,6 +17,7 @@ interface EventBuilder {
|
|
|
17
17
|
}
|
|
18
18
|
interface FinishMeta {
|
|
19
19
|
messageId?: string;
|
|
20
|
+
model?: string;
|
|
20
21
|
usage?: Usage;
|
|
21
22
|
}
|
|
22
23
|
interface PartDeltaExtra {
|
|
@@ -51,8 +52,24 @@ declare class EventSourceDataStream extends TransformStream<EventSourceMessage,
|
|
|
51
52
|
constructor();
|
|
52
53
|
}
|
|
53
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Reads a model stream until it ends or `signal` aborts. Unlike `for await` on the stream itself,
|
|
57
|
+
* an abort ends a pending read even if the model ignores its signal, and the model sees the reason.
|
|
58
|
+
* Not covered by semver.
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
declare const readEvents: (stream: ReadableStream<TextEvent>, signal: AbortSignal) => AsyncGenerator<TextEvent, void>;
|
|
63
|
+
/**
|
|
64
|
+
* Reads one model step and checks that it has exactly one `step.end`.
|
|
65
|
+
* Not covered by semver.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
declare const readStep: (stream: ReadableStream<TextEvent>, signal: AbortSignal) => AsyncGenerator<TextEvent, StepEndEvent>;
|
|
70
|
+
|
|
54
71
|
/** @internal */
|
|
55
72
|
declare const wireRequest: (options: SendRequestOptions, httpOptions: HttpOptions, modelOptions: LanguageModelOptions, eventStream: TransformStream<string, TextEvent>) => Promise<ReadableStream<TextEvent>>;
|
|
56
73
|
|
|
57
|
-
export { EventSourceDataStream, WireEventStream, eventBuilder, wireRequest };
|
|
74
|
+
export { EventSourceDataStream, WireEventStream, eventBuilder, readEvents, readStep, wireRequest };
|
|
58
75
|
export type { EventBuilder, FinishMeta, PartDeltaExtra, PartEndExtra, PartKey, PartStartInit };
|
package/dist/internal.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { XSAIError, sendRequest, EventSourceParserStream } from '@xsai/shared';
|
|
2
|
-
export { r as resolveSchema } from './
|
|
2
|
+
export { f as formatIssues, b as readEvents, r as readStep, a as resolveSchema } from './read-step-DXGjtk1d.js';
|
|
3
3
|
|
|
4
4
|
const emptyContent = (type, init) => {
|
|
5
5
|
switch (type) {
|
|
@@ -28,6 +28,7 @@ const eventBuilder = (emit, fail) => {
|
|
|
28
28
|
let terminalEmitted = false;
|
|
29
29
|
let messageId;
|
|
30
30
|
let terminal;
|
|
31
|
+
let model;
|
|
31
32
|
let usage;
|
|
32
33
|
const updateReasoning = (state, text) => {
|
|
33
34
|
if (text === "")
|
|
@@ -139,6 +140,7 @@ const eventBuilder = (emit, fail) => {
|
|
|
139
140
|
};
|
|
140
141
|
const common = {
|
|
141
142
|
message: message.id == null && messageId != null ? { ...message, id: messageId } : message,
|
|
143
|
+
model,
|
|
142
144
|
type: "step.end",
|
|
143
145
|
usage
|
|
144
146
|
};
|
|
@@ -186,6 +188,8 @@ const eventBuilder = (emit, fail) => {
|
|
|
186
188
|
meta: (meta) => {
|
|
187
189
|
if (meta.messageId != null)
|
|
188
190
|
messageId = meta.messageId;
|
|
191
|
+
if (meta.model != null)
|
|
192
|
+
model = meta.model;
|
|
189
193
|
if (meta.usage != null)
|
|
190
194
|
usage = meta.usage;
|
|
191
195
|
},
|
|
@@ -82,6 +82,7 @@ interface AssistantMessage {
|
|
|
82
82
|
type AssistantMessageContent = ProviderPart | ReasoningPart | RefusalPart | TextPart | ToolCallPart;
|
|
83
83
|
interface DeveloperMessage {
|
|
84
84
|
content: readonly DeveloperMessageContent[] | string;
|
|
85
|
+
providerMetadata?: MessageProviderMetadata;
|
|
85
86
|
role: 'developer';
|
|
86
87
|
}
|
|
87
88
|
type DeveloperMessageContent = TextPart;
|
|
@@ -95,6 +96,7 @@ interface MessageMap {
|
|
|
95
96
|
type MessageType = keyof MessageMap;
|
|
96
97
|
interface SystemMessage {
|
|
97
98
|
content: readonly SystemMessageContent[] | string;
|
|
99
|
+
providerMetadata?: MessageProviderMetadata;
|
|
98
100
|
role: 'system';
|
|
99
101
|
}
|
|
100
102
|
type SystemMessageContent = TextPart;
|
|
@@ -141,6 +143,8 @@ interface RefusalDeltaEvent {
|
|
|
141
143
|
interface StepEndDoneEvent {
|
|
142
144
|
error?: never;
|
|
143
145
|
message: AssistantMessage;
|
|
146
|
+
/** The model that the provider says answered, if it says. */
|
|
147
|
+
model?: string;
|
|
144
148
|
reason?: FinishReason;
|
|
145
149
|
status: Exclude<StepStatus, 'failed'>;
|
|
146
150
|
type: 'step.end';
|
|
@@ -151,6 +155,8 @@ type StepEndEvent = StepEndDoneEvent | StepEndFailEvent;
|
|
|
151
155
|
interface StepEndFailEvent {
|
|
152
156
|
error: XSAIError;
|
|
153
157
|
message: AssistantMessage;
|
|
158
|
+
/** The model that the provider says answered, if it says. */
|
|
159
|
+
model?: string;
|
|
154
160
|
reason?: never;
|
|
155
161
|
status: 'failed';
|
|
156
162
|
type: 'step.end';
|
|
@@ -481,6 +487,7 @@ interface ResolvedSchema<Input = unknown, Output = Input> {
|
|
|
481
487
|
validate?: StandardSchemaV1.Props<Input, Output>['validate'];
|
|
482
488
|
}
|
|
483
489
|
type UnresolvedSchema<Input = unknown, Output = Input> = CombinedStandardSchema<Input, Output> | JSONSchema7;
|
|
490
|
+
declare const formatIssues: (issues: readonly StandardSchemaV1.Issue[]) => string;
|
|
484
491
|
declare const resolveSchema: <Input = unknown, Output = Input>(schema: UnresolvedSchema<Input, Output>) => ResolvedSchema<Input, Output>;
|
|
485
492
|
|
|
486
493
|
interface ExecutableTool extends Tool {
|
|
@@ -532,5 +539,5 @@ type ToolChoice = 'auto' | 'none' | 'required' | {
|
|
|
532
539
|
name: string;
|
|
533
540
|
};
|
|
534
541
|
|
|
535
|
-
export {
|
|
542
|
+
export { formatIssues as a5, resolveSchema as a6, tool as a7 };
|
|
536
543
|
export type { ToolChoice as $, AssistantMessage as A, ResolvedSchema as B, CombinedStandardSchema as C, DeveloperMessage as D, ExecutableTool as E, FilePart as F, StepEndEvent as G, StepEndFailEvent as H, ImagePart as I, JSONSchema7 as J, StepStartEvent as K, LanguageModelOptions as L, Message as M, StepStatus as N, SystemMessage as O, PartProviderMetadata as P, SystemMessageContent as Q, RawEvent as R, StepEndDoneEvent as S, ToolCallPart as T, Usage as U, TextDeltaEvent as V, TextEventMap as W, TextEventType as X, TextPart as Y, Tool as Z, ToolCallDeltaEvent as _, ToolResultPart as a, ToolOptions as a0, ToolResultPartContent as a1, UnresolvedSchema as a2, UserMessage as a3, UserMessageContent as a4, TextEvent as b, LanguageModel as c, ToolExecuteOptions as d, AssistantMessageContent as e, AudioPart as f, Content as g, ContentEndEvent as h, ContentMap as i, ContentStartEvent as j, ContentType as k, DeveloperMessageContent as l, FinishReason as m, InferSchemaInput as n, InferSchemaOutput as o, JSONSchema7Definition as p, LanguageModelProviderOptions as q, MessageMap as r, MessageProviderMetadata as s, MessageType as t, ProviderPart as u, ReasoningDeltaEvent as v, ReasoningPart as w, ReasoningPartContent as x, RefusalDeltaEvent as y, RefusalPart as z };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { XSAIError } from '@xsai/shared';
|
|
2
|
+
|
|
3
|
+
const formatIssues = (issues) => issues.map(({ message, path }) => {
|
|
4
|
+
const location = path?.map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
|
|
5
|
+
return location == null || location === "" ? message : `${location}: ${message}`;
|
|
6
|
+
}).join("; ");
|
|
7
|
+
const resolveSchema = (schema) => "~standard" in schema ? {
|
|
8
|
+
schema: schema["~standard"].jsonSchema.input({ target: "draft-07" }),
|
|
9
|
+
validate: schema["~standard"].validate
|
|
10
|
+
} : { schema };
|
|
11
|
+
|
|
12
|
+
const readEvents = async function* (stream, signal) {
|
|
13
|
+
const reader = stream.getReader();
|
|
14
|
+
let cancellation;
|
|
15
|
+
const abort = () => {
|
|
16
|
+
cancellation = reader.cancel(signal.reason);
|
|
17
|
+
void cancellation.catch(() => {
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
21
|
+
try {
|
|
22
|
+
signal.throwIfAborted();
|
|
23
|
+
while (true) {
|
|
24
|
+
const { done, value } = await reader.read();
|
|
25
|
+
signal.throwIfAborted();
|
|
26
|
+
if (done)
|
|
27
|
+
return;
|
|
28
|
+
yield value;
|
|
29
|
+
}
|
|
30
|
+
} finally {
|
|
31
|
+
signal.removeEventListener("abort", abort);
|
|
32
|
+
await (cancellation ?? reader.cancel(signal.reason)).finally(() => reader.releaseLock());
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const readStep = async function* (stream, signal) {
|
|
36
|
+
let stepEnd;
|
|
37
|
+
for await (const event of readEvents(stream, signal)) {
|
|
38
|
+
if (event.type === "step.end") {
|
|
39
|
+
if (stepEnd != null)
|
|
40
|
+
throw new XSAIError("protocol-error", "model stream produced more than one step.end event");
|
|
41
|
+
stepEnd = event;
|
|
42
|
+
}
|
|
43
|
+
yield event;
|
|
44
|
+
}
|
|
45
|
+
if (stepEnd == null)
|
|
46
|
+
throw new XSAIError("truncated-stream", "model stream ended without a step.end event");
|
|
47
|
+
return stepEnd;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { resolveSchema as a, readEvents as b, formatIssues as f, readStep as r };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsai/text",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.6",
|
|
5
5
|
"description": "extra-small AI SDK: provider-agnostic text generation, streaming and tool calling.",
|
|
6
6
|
"author": "Moeru AI",
|
|
7
7
|
"license": "MIT",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"node": ">=26"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@xsai/shared": "1.0.0-beta.
|
|
44
|
+
"@xsai/shared": "1.0.0-beta.6"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@standard-schema/spec": "1.1.0",
|