ai 2.2.28 → 2.2.30

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.
@@ -13,6 +13,38 @@ interface FunctionCall {
13
13
  */
14
14
  name?: string;
15
15
  }
16
+ /**
17
+ * The tool calls generated by the model, such as function calls.
18
+ */
19
+ interface ToolCall {
20
+ id: string;
21
+ type: string;
22
+ function: {
23
+ name: string;
24
+ arguments: string;
25
+ };
26
+ }
27
+ /**
28
+ * Controls which (if any) function is called by the model.
29
+ * - none means the model will not call a function and instead generates a message.
30
+ * - auto means the model can pick between generating a message or calling a function.
31
+ * - Specifying a particular function via {"type: "function", "function": {"name": "my_function"}} forces the model to call that function.
32
+ * none is the default when no functions are present. auto is the default if functions are present.
33
+ */
34
+ type ToolChoice = 'none' | 'auto' | {
35
+ type: 'function';
36
+ function: {
37
+ name: string;
38
+ };
39
+ };
40
+ /**
41
+ * A list of tools the model may call. Currently, only functions are supported as a tool.
42
+ * Use this to provide a list of functions the model may generate JSON inputs for.
43
+ */
44
+ interface Tool {
45
+ type: 'function';
46
+ function: Function;
47
+ }
16
48
  interface Function {
17
49
  /**
18
50
  * The name of the function to be called. Must be a-z, A-Z, 0-9, or contain
@@ -41,10 +73,11 @@ type IdGenerator = () => string;
41
73
  */
42
74
  interface Message {
43
75
  id: string;
76
+ tool_call_id?: string;
44
77
  createdAt?: Date;
45
78
  content: string;
46
79
  ui?: string | JSX.Element | JSX.Element[] | null | undefined;
47
- role: 'system' | 'user' | 'assistant' | 'function' | 'data';
80
+ role: 'system' | 'user' | 'assistant' | 'function' | 'data' | 'tool';
48
81
  /**
49
82
  * If the message has a role of `function`, the `name` field is the name of the function.
50
83
  * Otherwise, the name field should not be set.
@@ -53,10 +86,15 @@ interface Message {
53
86
  /**
54
87
  * If the assistant role makes a function call, the `function_call` field
55
88
  * contains the function call name and arguments. Otherwise, the field should
56
- * not be set.
89
+ * not be set. (Deprecated and replaced by tool_calls.)
57
90
  */
58
91
  function_call?: string | FunctionCall;
59
92
  data?: JSONValue;
93
+ /**
94
+ * If the assistant role makes a tool call, the `tool_calls` field contains
95
+ * the tool call name and arguments. Otherwise, the field should not be set.
96
+ */
97
+ tool_calls?: string | ToolCall[];
60
98
  }
61
99
  type CreateMessage = Omit<Message, 'id'> & {
62
100
  id?: Message['id'];
@@ -67,12 +105,23 @@ type ChatRequest = {
67
105
  functions?: Array<Function>;
68
106
  function_call?: FunctionCall;
69
107
  data?: Record<string, string>;
108
+ tools?: Array<Tool>;
109
+ tool_choice?: ToolChoice;
70
110
  };
71
111
  type FunctionCallHandler = (chatMessages: Message[], functionCall: FunctionCall) => Promise<ChatRequest | void>;
112
+ type ToolCallHandler = (chatMessages: Message[], toolCalls: ToolCall[]) => Promise<ChatRequest | void>;
72
113
  type RequestOptions = {
73
114
  headers?: Record<string, string> | Headers;
74
115
  body?: object;
75
116
  };
117
+ type ChatRequestOptions = {
118
+ options?: RequestOptions;
119
+ functions?: Array<Function>;
120
+ function_call?: FunctionCall;
121
+ tools?: Array<Tool>;
122
+ tool_choice?: ToolChoice;
123
+ data?: Record<string, string>;
124
+ };
76
125
  type UseChatOptions = {
77
126
  /**
78
127
  * The API endpoint that accepts a `{ messages: Message[] }` object and returns
@@ -99,6 +148,12 @@ type UseChatOptions = {
99
148
  * automatically to the API and will be used to update the chat.
100
149
  */
101
150
  experimental_onFunctionCall?: FunctionCallHandler;
151
+ /**
152
+ * Callback function to be called when a tool call is received.
153
+ * If the function returns a `ChatRequest` object, the request will be sent
154
+ * automatically to the API and will be used to update the chat.
155
+ */
156
+ experimental_onToolCall?: ToolCallHandler;
102
157
  /**
103
158
  * Callback function to be called when the API response is received.
104
159
  */
@@ -217,13 +272,13 @@ type UseChatHelpers = {
217
272
  * @param message The message to append
218
273
  * @param options Additional options to pass to the API call
219
274
  */
220
- append: (message: Message | CreateMessage, options?: RequestOptions) => Promise<string | null | undefined>;
275
+ append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
221
276
  /**
222
277
  * Reload the last AI chat response for the given chat history. If the last
223
278
  * message isn't from the assistant, it will request the API to generate a
224
279
  * new response.
225
280
  */
226
- reload: (options?: RequestOptions) => Promise<string | null | undefined>;
281
+ reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
227
282
  /**
228
283
  * Abort the current request immediately, keep the generated tokens if any.
229
284
  */
@@ -238,8 +293,8 @@ type UseChatHelpers = {
238
293
  input: Accessor<string>;
239
294
  /** Signal setter to update the input value */
240
295
  setInput: Setter<string>;
241
- /** Form submission handler to automatically reset input and append a user message */
242
- handleSubmit: (e: any) => void;
296
+ /** Form submission handler to automatically reset input and append a user message */
297
+ handleSubmit: (e: any, chatRequestOptions?: ChatRequestOptions) => void;
243
298
  /** Whether the API request is in progress */
244
299
  isLoading: Accessor<boolean>;
245
300
  /** Additional data added on the server via StreamData */
@@ -126,6 +126,23 @@ var dataMessageStreamPart = {
126
126
  };
127
127
  }
128
128
  };
129
+ var toolCallStreamPart = {
130
+ code: "7",
131
+ name: "tool_calls",
132
+ parse: (value) => {
133
+ if (value == null || typeof value !== "object" || !("tool_calls" in value) || typeof value.tool_calls !== "object" || value.tool_calls == null || !Array.isArray(value.tool_calls) || value.tool_calls.some((tc) => {
134
+ tc == null || typeof tc !== "object" || !("id" in tc) || typeof tc.id !== "string" || !("type" in tc) || typeof tc.type !== "string" || !("function" in tc) || tc.function == null || typeof tc.function !== "object" || !("arguments" in tc.function) || typeof tc.function.name !== "string" || typeof tc.function.arguments !== "string";
135
+ })) {
136
+ throw new Error(
137
+ '"tool_calls" parts expect an object with a ToolCallPayload.'
138
+ );
139
+ }
140
+ return {
141
+ type: "tool_calls",
142
+ value
143
+ };
144
+ }
145
+ };
129
146
  var streamParts = [
130
147
  textStreamPart,
131
148
  functionCallStreamPart,
@@ -133,7 +150,8 @@ var streamParts = [
133
150
  errorStreamPart,
134
151
  assistantMessageStreamPart,
135
152
  assistantControlDataStreamPart,
136
- dataMessageStreamPart
153
+ dataMessageStreamPart,
154
+ toolCallStreamPart
137
155
  ];
138
156
  var streamPartsByCode = {
139
157
  [textStreamPart.code]: textStreamPart,
@@ -142,7 +160,8 @@ var streamPartsByCode = {
142
160
  [errorStreamPart.code]: errorStreamPart,
143
161
  [assistantMessageStreamPart.code]: assistantMessageStreamPart,
144
162
  [assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
145
- [dataMessageStreamPart.code]: dataMessageStreamPart
163
+ [dataMessageStreamPart.code]: dataMessageStreamPart,
164
+ [toolCallStreamPart.code]: toolCallStreamPart
146
165
  };
147
166
  var StreamStringPrefixes = {
148
167
  [textStreamPart.name]: textStreamPart.code,
@@ -151,7 +170,8 @@ var StreamStringPrefixes = {
151
170
  [errorStreamPart.name]: errorStreamPart.code,
152
171
  [assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
153
172
  [assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
154
- [dataMessageStreamPart.name]: dataMessageStreamPart.code
173
+ [dataMessageStreamPart.name]: dataMessageStreamPart.code,
174
+ [toolCallStreamPart.name]: toolCallStreamPart.code
155
175
  };
156
176
  var validCodes = streamParts.map((part) => part.code);
157
177
  var parseStreamPart = (line) => {
@@ -277,20 +297,35 @@ async function parseComplexResponse({
277
297
  };
278
298
  functionCallMessage = prefixMap["function_call"];
279
299
  }
300
+ let toolCallMessage = null;
301
+ if (type === "tool_calls") {
302
+ prefixMap["tool_calls"] = {
303
+ id: generateId(),
304
+ role: "assistant",
305
+ content: "",
306
+ tool_calls: value.tool_calls,
307
+ createdAt
308
+ };
309
+ toolCallMessage = prefixMap["tool_calls"];
310
+ }
280
311
  if (type === "data") {
281
312
  prefixMap["data"].push(...value);
282
313
  }
283
314
  const responseMessage = prefixMap["text"];
284
- const merged = [functionCallMessage, responseMessage].filter(
285
- Boolean
286
- );
315
+ const merged = [
316
+ functionCallMessage,
317
+ toolCallMessage,
318
+ responseMessage
319
+ ].filter(Boolean);
287
320
  update(merged, [...prefixMap["data"]]);
288
321
  }
289
322
  onFinish == null ? void 0 : onFinish(prefixMap);
290
323
  return {
291
- messages: [prefixMap.text, prefixMap.function_call].filter(
292
- Boolean
293
- ),
324
+ messages: [
325
+ prefixMap.text,
326
+ prefixMap.function_call,
327
+ prefixMap.tool_calls
328
+ ].filter(Boolean),
294
329
  data: prefixMap.data
295
330
  };
296
331
  }
@@ -376,6 +411,8 @@ async function callChatApi({
376
411
  streamedResponse += decode(value);
377
412
  if (streamedResponse.startsWith('{"function_call":')) {
378
413
  responseMessage["function_call"] = streamedResponse;
414
+ } else if (streamedResponse.startsWith('{"tool_calls":')) {
415
+ responseMessage["tool_calls"] = streamedResponse;
379
416
  } else {
380
417
  responseMessage["content"] = streamedResponse;
381
418
  }
@@ -390,6 +427,11 @@ async function callChatApi({
390
427
  responseMessage["function_call"] = parsedFunctionCall;
391
428
  appendMessage({ ...responseMessage });
392
429
  }
430
+ if (streamedResponse.startsWith('{"tool_calls":')) {
431
+ const parsedToolCalls = JSON.parse(streamedResponse).tool_calls;
432
+ responseMessage["tool_calls"] = parsedToolCalls;
433
+ appendMessage({ ...responseMessage });
434
+ }
393
435
  if (onFinish) {
394
436
  onFinish(responseMessage);
395
437
  }
@@ -401,6 +443,7 @@ async function callChatApi({
401
443
  async function processChatStream({
402
444
  getStreamedResponse,
403
445
  experimental_onFunctionCall,
446
+ experimental_onToolCall,
404
447
  updateChatRequest,
405
448
  getCurrentMessages
406
449
  }) {
@@ -409,12 +452,18 @@ async function processChatStream({
409
452
  if ("messages" in messagesAndDataOrJustMessage) {
410
453
  let hasFollowingResponse = false;
411
454
  for (const message of messagesAndDataOrJustMessage.messages) {
412
- if (message.function_call === void 0 || typeof message.function_call === "string") {
455
+ if ((message.function_call === void 0 || typeof message.function_call === "string") && (message.tool_calls === void 0 || typeof message.tool_calls === "string")) {
413
456
  continue;
414
457
  }
415
458
  hasFollowingResponse = true;
416
459
  if (experimental_onFunctionCall) {
417
460
  const functionCall = message.function_call;
461
+ if (typeof functionCall !== "object") {
462
+ console.warn(
463
+ "experimental_onFunctionCall should not be defined when using tools"
464
+ );
465
+ continue;
466
+ }
418
467
  const functionCallResponse = await experimental_onFunctionCall(
419
468
  getCurrentMessages(),
420
469
  functionCall
@@ -425,22 +474,83 @@ async function processChatStream({
425
474
  }
426
475
  updateChatRequest(functionCallResponse);
427
476
  }
477
+ if (experimental_onToolCall) {
478
+ const toolCalls = message.tool_calls;
479
+ if (!Array.isArray(toolCalls) || toolCalls.some((toolCall) => typeof toolCall !== "object")) {
480
+ console.warn(
481
+ "experimental_onToolCall should not be defined when using tools"
482
+ );
483
+ continue;
484
+ }
485
+ const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
486
+ if (toolCallResponse === void 0) {
487
+ hasFollowingResponse = false;
488
+ break;
489
+ }
490
+ updateChatRequest(toolCallResponse);
491
+ }
428
492
  }
429
493
  if (!hasFollowingResponse) {
430
494
  break;
431
495
  }
432
496
  } else {
497
+ let fixFunctionCallArguments2 = function(response) {
498
+ for (const message of response.messages) {
499
+ if (message.tool_calls !== void 0) {
500
+ for (const toolCall of message.tool_calls) {
501
+ if (typeof toolCall === "object") {
502
+ if (toolCall.function.arguments && typeof toolCall.function.arguments !== "string") {
503
+ toolCall.function.arguments = JSON.stringify(
504
+ toolCall.function.arguments
505
+ );
506
+ }
507
+ }
508
+ }
509
+ }
510
+ if (message.function_call !== void 0) {
511
+ if (typeof message.function_call === "object") {
512
+ if (message.function_call.arguments && typeof message.function_call.arguments !== "string") {
513
+ message.function_call.arguments = JSON.stringify(
514
+ message.function_call.arguments
515
+ );
516
+ }
517
+ }
518
+ }
519
+ }
520
+ };
521
+ var fixFunctionCallArguments = fixFunctionCallArguments2;
433
522
  const streamedResponseMessage = messagesAndDataOrJustMessage;
434
- if (streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") {
523
+ if ((streamedResponseMessage.function_call === void 0 || typeof streamedResponseMessage.function_call === "string") && (streamedResponseMessage.tool_calls === void 0 || typeof streamedResponseMessage.tool_calls === "string")) {
435
524
  break;
436
525
  }
437
526
  if (experimental_onFunctionCall) {
438
527
  const functionCall = streamedResponseMessage.function_call;
528
+ if (!(typeof functionCall === "object")) {
529
+ console.warn(
530
+ "experimental_onFunctionCall should not be defined when using tools"
531
+ );
532
+ continue;
533
+ }
439
534
  const functionCallResponse = await experimental_onFunctionCall(getCurrentMessages(), functionCall);
440
535
  if (functionCallResponse === void 0)
441
536
  break;
537
+ fixFunctionCallArguments2(functionCallResponse);
442
538
  updateChatRequest(functionCallResponse);
443
539
  }
540
+ if (experimental_onToolCall) {
541
+ const toolCalls = streamedResponseMessage.tool_calls;
542
+ if (!(typeof toolCalls === "object")) {
543
+ console.warn(
544
+ "experimental_onToolCall should not be defined when using functions"
545
+ );
546
+ continue;
547
+ }
548
+ const toolCallResponse = await experimental_onToolCall(getCurrentMessages(), toolCalls);
549
+ if (toolCallResponse === void 0)
550
+ break;
551
+ fixFunctionCallArguments2(toolCallResponse);
552
+ updateChatRequest(toolCallResponse);
553
+ }
444
554
  }
445
555
  }
446
556
  }
@@ -487,7 +597,7 @@ function useChat({
487
597
  );
488
598
  const [isLoading, setIsLoading] = (0, import_solid_js.createSignal)(false);
489
599
  let abortController = null;
490
- async function triggerRequest(messagesSnapshot, options) {
600
+ async function triggerRequest(messagesSnapshot, { options, data } = {}) {
491
601
  try {
492
602
  setError(void 0);
493
603
  setIsLoading(true);
@@ -499,7 +609,8 @@ function useChat({
499
609
  mutate(messagesSnapshot);
500
610
  let chatRequest = {
501
611
  messages: messagesSnapshot,
502
- options
612
+ options,
613
+ data
503
614
  };
504
615
  await processChatStream({
505
616
  getStreamedResponse: async () => {
@@ -518,6 +629,7 @@ function useChat({
518
629
  })
519
630
  ),
520
631
  body: {
632
+ data: chatRequest.data,
521
633
  ...body,
522
634
  ...options == null ? void 0 : options.body
523
635
  },
@@ -528,9 +640,9 @@ function useChat({
528
640
  abortController: () => abortController,
529
641
  credentials,
530
642
  onResponse,
531
- onUpdate(merged, data) {
643
+ onUpdate(merged, data2) {
532
644
  mutate([...chatRequest.messages, ...merged]);
533
- setStreamData([...existingData, ...data != null ? data : []]);
645
+ setStreamData([...existingData, ...data2 != null ? data2 : []]);
534
646
  },
535
647
  onFinish,
536
648
  appendMessage(message) {
@@ -594,16 +706,19 @@ function useChat({
594
706
  mutate(messages2);
595
707
  };
596
708
  const [input, setInput] = (0, import_solid_js.createSignal)(initialInput);
597
- const handleSubmit = (e) => {
709
+ const handleSubmit = (e, options = {}) => {
598
710
  e.preventDefault();
599
711
  const inputValue = input();
600
712
  if (!inputValue)
601
713
  return;
602
- append({
603
- content: inputValue,
604
- role: "user",
605
- createdAt: /* @__PURE__ */ new Date()
606
- });
714
+ append(
715
+ {
716
+ content: inputValue,
717
+ role: "user",
718
+ createdAt: /* @__PURE__ */ new Date()
719
+ },
720
+ options
721
+ );
607
722
  setInput("");
608
723
  };
609
724
  return {