@xsai/shared-chat 0.5.0-beta.2 → 0.5.0-beta.3

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 CHANGED
@@ -96,7 +96,7 @@ interface CompletionToolCall {
96
96
  }
97
97
  interface CompletionToolResult {
98
98
  args: Record<string, unknown>;
99
- result: ToolMessage['content'];
99
+ result: ToolExecuteResult;
100
100
  toolCallId: string;
101
101
  toolName: string;
102
102
  }
@@ -117,11 +117,16 @@ interface ToolExecuteOptions {
117
117
  }
118
118
  type ToolExecuteResult = object | string | unknown[];
119
119
 
120
- interface Usage {
120
+ interface ChatCompletionUsage {
121
121
  completion_tokens: number;
122
122
  prompt_tokens: number;
123
123
  total_tokens: number;
124
124
  }
125
+ interface Usage {
126
+ inputTokens: number;
127
+ outputTokens: number;
128
+ totalTokens: number;
129
+ }
125
130
 
126
131
  type CompletionStep<T extends boolean = false> = (T extends true ? {
127
132
  usage: Usage;
@@ -129,12 +134,10 @@ type CompletionStep<T extends boolean = false> = (T extends true ? {
129
134
  usage?: Usage;
130
135
  }) & {
131
136
  finishReason: FinishReason;
132
- stepType: CompletionStepType;
133
137
  text?: string;
134
138
  toolCalls: CompletionToolCall[];
135
139
  toolResults: CompletionToolResult[];
136
140
  };
137
- type CompletionStepType = 'continue' | 'done' | 'initial' | 'tool-result';
138
141
 
139
142
  type ToolChoice = AllowedTools | ToolChoiceMode | ToolChoiceTool;
140
143
  interface AllowedTools {
@@ -150,31 +153,24 @@ interface ToolChoiceTool {
150
153
  type: 'function';
151
154
  }
152
155
 
153
- type PrepareStep = (options: PrepareStepOptions) => PrepareStepResult | Promise<PrepareStepResult>;
154
- interface PrepareStepOptions {
155
- messages: Message[];
156
+ type PrepareStep<TInput = Message[], TToolChoice = ToolChoice> = (options: PrepareStepOptions<TInput>) => PrepareStepResult<TInput, TToolChoice> | Promise<PrepareStepResult<TInput, TToolChoice>>;
157
+ interface PrepareStepOptions<TInput = Message[]> {
158
+ input: TInput;
156
159
  model: string;
157
160
  stepNumber: number;
158
161
  steps: CompletionStep[];
159
162
  }
160
- interface PrepareStepResult {
161
- messages?: Message[];
163
+ interface PrepareStepResult<TInput = Message[], TToolChoice = ToolChoice> {
164
+ input?: TInput;
162
165
  model?: string;
163
- toolChoice?: ToolChoice;
166
+ toolChoice?: TToolChoice;
164
167
  }
165
168
 
166
- type StopCondition = (context: StopContext) => boolean;
167
- interface StopContext {
168
- messages: readonly Message[];
169
- step: StopStep;
170
- steps: readonly StopStep[];
171
- }
172
- interface StopStep {
173
- finishReason: FinishReason;
174
- text?: string;
175
- toolCalls: CompletionToolCall[];
176
- toolResults: CompletionToolResult[];
177
- usage?: Usage;
169
+ type StopCondition<Input = unknown> = (context: StopContext<Input>) => boolean;
170
+ interface StopContext<Input = unknown> {
171
+ input: readonly Input[];
172
+ step: CompletionStep;
173
+ steps: readonly CompletionStep[];
178
174
  }
179
175
 
180
176
  /** @see {@link https://platform.openai.com/docs/api-reference/chat/create} */
@@ -213,47 +209,45 @@ interface ChatOptions extends CommonRequestOptions {
213
209
  }
214
210
  declare const chat: <T extends WithUnknown<ChatOptions>>(options: T) => Promise<Response>;
215
211
 
216
- interface DetermineStepTypeOptions {
217
- finishReason: FinishReason;
218
- stepsLength: number;
219
- toolCallsLength: number;
220
- willContinue: boolean;
221
- }
222
- /** @internal */
223
- declare const determineStepType: ({ finishReason, stepsLength, toolCallsLength, willContinue }: DetermineStepTypeOptions) => CompletionStepType;
224
-
225
- interface ExecuteToolOptions {
212
+ interface ExecuteToolOptions<T = ToolMessage['content']> {
226
213
  abortSignal?: AbortSignal;
227
214
  messages: Message[];
228
215
  toolCall: ToolCall;
229
216
  tools?: Tool[];
217
+ wrapResult?: (result: ToolExecuteResult) => T;
230
218
  }
231
- interface ExecuteToolResult {
219
+ interface ExecuteToolResult<T = ToolMessage['content']> {
232
220
  completionToolCall: CompletionToolCall;
233
221
  completionToolResult: CompletionToolResult;
234
- message: ToolMessage;
222
+ result: T;
235
223
  }
236
- declare const executeTool: ({ abortSignal, messages, toolCall, tools }: ExecuteToolOptions) => Promise<ExecuteToolResult>;
224
+ declare const executeTool: <T = ToolMessage["content"]>({ abortSignal, messages, toolCall, tools, wrapResult }: ExecuteToolOptions<T>) => Promise<ExecuteToolResult<T>>;
237
225
 
238
- interface ResolvedStepOptions {
239
- messages: Message[];
226
+ interface ResolvePrepareStepOptions<TInput = Message[], TToolChoice = ToolChoice> {
227
+ input: TInput;
240
228
  model: string;
241
- toolChoice: ToolChoice | undefined;
242
- }
243
- interface ResolveStepOptionsOptions extends Pick<WithUnknown<ChatOptions>, 'messages' | 'model' | 'toolChoice'> {
244
- prepareStep?: PrepareStep;
229
+ prepareStep?: PrepareStep<TInput, TToolChoice>;
245
230
  stepNumber: number;
246
231
  steps: CompletionStep[];
232
+ toolChoice?: TToolChoice;
247
233
  }
248
- declare const resolveStepOptions: ({ messages, model, prepareStep, stepNumber, steps, toolChoice }: ResolveStepOptionsOptions) => Promise<ResolvedStepOptions>;
234
+ interface ResolvePrepareStepResult<TInput = Message[], TToolChoice = ToolChoice> {
235
+ input: TInput;
236
+ model: string;
237
+ toolChoice?: TToolChoice;
238
+ }
239
+ declare const resolvePrepareStep: <TInput, TToolChoice>({ input, model, prepareStep, stepNumber, steps, toolChoice }: ResolvePrepareStepOptions<TInput, TToolChoice>) => Promise<ResolvePrepareStepResult<TInput, TToolChoice>>;
249
240
 
250
- declare const and: (...conditions: StopCondition[]) => StopCondition;
251
- declare const or: (...conditions: StopCondition[]) => StopCondition;
252
- declare const not: (condition: StopCondition) => StopCondition;
241
+ declare const and: <Input = unknown>(...conditions: StopCondition<Input>[]) => StopCondition<Input>;
242
+ declare const or: <Input = unknown>(...conditions: StopCondition<Input>[]) => StopCondition<Input>;
243
+ declare const not: <Input = unknown>(condition: StopCondition<Input>) => StopCondition<Input>;
253
244
  declare const stepCountAtLeast: (count: number) => StopCondition;
254
245
  declare const hasToolCall: (name?: string) => StopCondition;
255
246
  /** @internal */
256
- declare const shouldStop: (stopWhen: StopCondition, context: StopContext) => boolean;
247
+ declare const shouldStop: <Input = unknown>(stopWhen: StopCondition<Input>, context: StopContext<Input>) => boolean;
248
+
249
+ declare const computeTotalUsage: (totalUsage: undefined | Usage, usage: Usage) => Usage;
250
+ declare const normalizeChatCompletionUsage: (usage: ChatCompletionUsage) => Usage;
257
251
 
258
- export { and, chat, determineStepType, executeTool, hasToolCall, not, or, resolveStepOptions, shouldStop, stepCountAtLeast };
259
- export type { AssistantMessage, AudioContentPart, ChatOptions, CommonContentPart, CompletionStep, CompletionStepType, CompletionToolCall, CompletionToolResult, DetermineStepTypeOptions, DeveloperMessage, ExecuteToolOptions, ExecuteToolResult, FileContentPart, FinishReason, ImageContentPart, Message, PrepareStep, PrepareStepOptions, PrepareStepResult, RefusalContentPart, ResolveStepOptionsOptions, ResolvedStepOptions, StopCondition, StopContext, StopStep, SystemMessage, TextContentPart, Tool, ToolCall, ToolChoice, ToolExecuteOptions, ToolExecuteResult, ToolMessage, Usage, UserMessage };
252
+ export { and, chat, computeTotalUsage, executeTool, hasToolCall, normalizeChatCompletionUsage, not, or, resolvePrepareStep, shouldStop, stepCountAtLeast };
253
+ export type { AssistantMessage, AudioContentPart, ChatCompletionUsage, ChatOptions, CommonContentPart, CompletionStep, CompletionToolCall, CompletionToolResult, DeveloperMessage, ExecuteToolOptions, ExecuteToolResult, FileContentPart, FinishReason, ImageContentPart, Message, PrepareStep, PrepareStepOptions, PrepareStepResult, RefusalContentPart, ResolvePrepareStepOptions, ResolvePrepareStepResult, StopCondition, StopContext, SystemMessage, TextContentPart, Tool, ToolCall, ToolChoice, ToolExecuteOptions, ToolExecuteResult, ToolMessage, Usage, UserMessage };
package/dist/index.js CHANGED
@@ -13,23 +13,11 @@ const chat = async (options) => (options.fetch ?? globalThis.fetch)(requestURL("
13
13
  signal: options.abortSignal
14
14
  }).then(responseCatch);
15
15
 
16
- const determineStepType = ({ finishReason, stepsLength, toolCallsLength, willContinue }) => {
17
- if (stepsLength === 0) {
18
- return "initial";
19
- } else if (willContinue) {
20
- if (toolCallsLength > 0 && ["tool-calls", "tool_calls"].includes(finishReason))
21
- return "tool-result";
22
- else if (!["error", "length"].includes(finishReason))
23
- return "continue";
24
- }
25
- return "done";
26
- };
27
-
28
- const wrapToolResult = (result) => {
16
+ const toToolMessageContent = (result) => {
29
17
  if (typeof result === "string")
30
18
  return result;
31
19
  if (Array.isArray(result)) {
32
- if (result.every((item) => !!(typeof item === "object" && "type" in item && ["file", "image_url", "input_audio", "text"].includes(item.type)))) {
20
+ if (result.every((item) => item !== null && typeof item === "object" && "type" in item && ["file", "image_url", "input_audio", "text"].includes(item.type))) {
33
21
  return result;
34
22
  }
35
23
  }
@@ -50,11 +38,11 @@ const parseToolInput = (toolName, input) => {
50
38
  };
51
39
  const runTool = async (tool, options) => {
52
40
  try {
53
- return wrapToolResult(await tool.execute(options.parsedArgs, {
41
+ return await tool.execute(options.parsedArgs, {
54
42
  abortSignal: options.abortSignal,
55
43
  messages: options.messages,
56
44
  toolCallId: options.toolCall.id
57
- }));
45
+ });
58
46
  } catch (cause) {
59
47
  if (isAbortError(cause, options.abortSignal))
60
48
  throw cause;
@@ -66,7 +54,7 @@ const runTool = async (tool, options) => {
66
54
  });
67
55
  }
68
56
  };
69
- const executeTool = async ({ abortSignal, messages, toolCall, tools }) => {
57
+ const executeTool = async ({ abortSignal, messages, toolCall, tools, wrapResult }) => {
70
58
  const toolName = toolCall.function.name;
71
59
  const toolArguments = toolCall.function.arguments;
72
60
  if (toolName == null) {
@@ -94,6 +82,7 @@ const executeTool = async ({ abortSignal, messages, toolCall, tools }) => {
94
82
  }
95
83
  const parsedArgs = parseToolInput(toolName, toolArguments);
96
84
  const result = await runTool(tool, { abortSignal, messages, parsedArgs, toolCall });
85
+ const wrappedResult = (wrapResult ?? toToolMessageContent)(result);
97
86
  const completionToolCall = {
98
87
  args: toolArguments,
99
88
  toolCallId: toolCall.id,
@@ -106,27 +95,22 @@ const executeTool = async ({ abortSignal, messages, toolCall, tools }) => {
106
95
  toolCallId: toolCall.id,
107
96
  toolName
108
97
  };
109
- const message = {
110
- content: result,
111
- role: "tool",
112
- tool_call_id: toolCall.id
113
- };
114
98
  return {
115
99
  completionToolCall,
116
100
  completionToolResult,
117
- message
101
+ result: wrappedResult
118
102
  };
119
103
  };
120
104
 
121
- const resolveStepOptions = async ({ messages, model, prepareStep, stepNumber, steps, toolChoice }) => {
105
+ const resolvePrepareStep = async ({ input, model, prepareStep, stepNumber, steps, toolChoice }) => {
122
106
  const prepared = prepareStep == null ? void 0 : await prepareStep({
123
- messages: structuredClone(messages),
107
+ input: structuredClone(input),
124
108
  model,
125
109
  stepNumber,
126
110
  steps: structuredClone(steps)
127
111
  });
128
112
  return {
129
- messages: prepared?.messages != null ? structuredClone(prepared.messages) : messages,
113
+ input: prepared?.input != null ? structuredClone(prepared.input) : input,
130
114
  model: prepared?.model ?? model,
131
115
  toolChoice: prepared?.toolChoice ?? toolChoice
132
116
  };
@@ -139,4 +123,15 @@ const stepCountAtLeast = (count) => ({ steps }) => steps.length >= count;
139
123
  const hasToolCall = (name) => ({ step }) => step.toolCalls.some((toolCall) => name == null || toolCall.toolName === name);
140
124
  const shouldStop = (stopWhen, context) => stopWhen(context);
141
125
 
142
- export { and, chat, determineStepType, executeTool, hasToolCall, not, or, resolveStepOptions, shouldStop, stepCountAtLeast };
126
+ const computeTotalUsage = (totalUsage, usage) => totalUsage == null ? usage : {
127
+ inputTokens: totalUsage.inputTokens + usage.inputTokens,
128
+ outputTokens: totalUsage.outputTokens + usage.outputTokens,
129
+ totalTokens: totalUsage.totalTokens + usage.totalTokens
130
+ };
131
+ const normalizeChatCompletionUsage = (usage) => ({
132
+ inputTokens: usage.prompt_tokens,
133
+ outputTokens: usage.completion_tokens,
134
+ totalTokens: usage.total_tokens
135
+ });
136
+
137
+ export { and, chat, computeTotalUsage, executeTool, hasToolCall, normalizeChatCompletionUsage, not, or, resolvePrepareStep, shouldStop, stepCountAtLeast };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xsai/shared-chat",
3
3
  "type": "module",
4
- "version": "0.5.0-beta.2",
4
+ "version": "0.5.0-beta.3",
5
5
  "description": "extra-small AI SDK.",
6
6
  "author": "Moeru AI",
7
7
  "license": "MIT",
@@ -29,7 +29,7 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@xsai/shared": "~0.5.0-beta.2"
32
+ "@xsai/shared": "0.5.0-beta.3"
33
33
  },
34
34
  "scripts": {
35
35
  "build": "pkgroll"