@copilotkitnext/agent 1.51.4-next.7 → 1.51.4
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/CHANGELOG.md +4 -0
- package/dist/index.js +36 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +36 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -4
- package/src/__tests__/basic-agent.test.ts +83 -27
- package/src/__tests__/config-tools-execution.test.ts +18 -5
- package/src/__tests__/property-overrides.test.ts +58 -19
- package/src/__tests__/state-tools.test.ts +63 -18
- package/src/__tests__/test-helpers.ts +21 -5
- package/src/__tests__/utils.test.ts +4 -2
- package/src/index.ts +132 -36
- package/tsup.config.ts +5 -5
package/src/index.ts
CHANGED
|
@@ -144,7 +144,10 @@ export type MCPClientConfig = MCPClientConfigHTTP | MCPClientConfigSSE;
|
|
|
144
144
|
* @param apiKey - Optional API key to use instead of environment variables
|
|
145
145
|
* @returns LanguageModel instance
|
|
146
146
|
*/
|
|
147
|
-
export function resolveModel(
|
|
147
|
+
export function resolveModel(
|
|
148
|
+
spec: ModelSpecifier,
|
|
149
|
+
apiKey?: string,
|
|
150
|
+
): LanguageModel {
|
|
148
151
|
// If already a LanguageModel instance, pass through
|
|
149
152
|
if (typeof spec !== "string") {
|
|
150
153
|
return spec;
|
|
@@ -205,14 +208,18 @@ export function resolveModel(spec: ModelSpecifier, apiKey?: string): LanguageMod
|
|
|
205
208
|
}
|
|
206
209
|
|
|
207
210
|
default:
|
|
208
|
-
throw new Error(
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Unknown provider "${provider}" in "${spec}". Supported: openai, anthropic, google (gemini).`,
|
|
213
|
+
);
|
|
209
214
|
}
|
|
210
215
|
}
|
|
211
216
|
|
|
212
217
|
/**
|
|
213
218
|
* Tool definition for BuiltInAgent
|
|
214
219
|
*/
|
|
215
|
-
export interface ToolDefinition<
|
|
220
|
+
export interface ToolDefinition<
|
|
221
|
+
TParameters extends z.ZodTypeAny = z.ZodTypeAny,
|
|
222
|
+
> {
|
|
216
223
|
name: string;
|
|
217
224
|
description: string;
|
|
218
225
|
parameters: TParameters;
|
|
@@ -243,7 +250,9 @@ export function defineTool<TParameters extends z.ZodTypeAny>(config: {
|
|
|
243
250
|
|
|
244
251
|
type AGUIUserMessage = Extract<Message, { role: "user" }>;
|
|
245
252
|
|
|
246
|
-
function flattenUserMessageContent(
|
|
253
|
+
function flattenUserMessageContent(
|
|
254
|
+
content?: AGUIUserMessage["content"],
|
|
255
|
+
): string {
|
|
247
256
|
if (!content) {
|
|
248
257
|
return "";
|
|
249
258
|
}
|
|
@@ -293,14 +302,19 @@ export function convertMessagesToVercelAISDKMessages(
|
|
|
293
302
|
content: message.content ?? "",
|
|
294
303
|
};
|
|
295
304
|
result.push(systemMsg);
|
|
296
|
-
} else if (
|
|
305
|
+
} else if (
|
|
306
|
+
message.role === "developer" &&
|
|
307
|
+
options.forwardDeveloperMessages
|
|
308
|
+
) {
|
|
297
309
|
const systemMsg: SystemModelMessage = {
|
|
298
310
|
role: "system",
|
|
299
311
|
content: message.content ?? "",
|
|
300
312
|
};
|
|
301
313
|
result.push(systemMsg);
|
|
302
314
|
} else if (message.role === "assistant") {
|
|
303
|
-
const parts: Array<TextPart | ToolCallPart> = message.content
|
|
315
|
+
const parts: Array<TextPart | ToolCallPart> = message.content
|
|
316
|
+
? [{ type: "text", text: message.content }]
|
|
317
|
+
: [];
|
|
304
318
|
|
|
305
319
|
for (const toolCall of message.toolCalls ?? []) {
|
|
306
320
|
const toolCallPart: ToolCallPart = {
|
|
@@ -372,7 +386,10 @@ interface JsonSchema {
|
|
|
372
386
|
/**
|
|
373
387
|
* Converts JSON Schema to Zod schema
|
|
374
388
|
*/
|
|
375
|
-
export function convertJsonSchemaToZodSchema(
|
|
389
|
+
export function convertJsonSchemaToZodSchema(
|
|
390
|
+
jsonSchema: JsonSchema,
|
|
391
|
+
required: boolean,
|
|
392
|
+
): z.ZodSchema {
|
|
376
393
|
// Handle empty schemas {} (no input required) - treat as empty object
|
|
377
394
|
if (!jsonSchema.type) {
|
|
378
395
|
return required ? z.object({}) : z.object({}).optional();
|
|
@@ -385,7 +402,10 @@ export function convertJsonSchemaToZodSchema(jsonSchema: JsonSchema, required: b
|
|
|
385
402
|
}
|
|
386
403
|
|
|
387
404
|
for (const [key, value] of Object.entries(jsonSchema.properties)) {
|
|
388
|
-
spec[key] = convertJsonSchemaToZodSchema(
|
|
405
|
+
spec[key] = convertJsonSchemaToZodSchema(
|
|
406
|
+
value,
|
|
407
|
+
jsonSchema.required ? jsonSchema.required.includes(key) : false,
|
|
408
|
+
);
|
|
389
409
|
}
|
|
390
410
|
let schema = z.object(spec).describe(jsonSchema.description ?? "");
|
|
391
411
|
return required ? schema : schema.optional();
|
|
@@ -420,11 +440,15 @@ function isJsonSchema(obj: unknown): obj is JsonSchema {
|
|
|
420
440
|
if (Object.keys(schema).length === 0) return true;
|
|
421
441
|
return (
|
|
422
442
|
typeof schema.type === "string" &&
|
|
423
|
-
["object", "string", "number", "integer", "boolean", "array"].includes(
|
|
443
|
+
["object", "string", "number", "integer", "boolean", "array"].includes(
|
|
444
|
+
schema.type,
|
|
445
|
+
)
|
|
424
446
|
);
|
|
425
447
|
}
|
|
426
448
|
|
|
427
|
-
export function convertToolsToVercelAITools(
|
|
449
|
+
export function convertToolsToVercelAITools(
|
|
450
|
+
tools: RunAgentInput["tools"],
|
|
451
|
+
): ToolSet {
|
|
428
452
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
429
453
|
const result: Record<string, any> = {};
|
|
430
454
|
|
|
@@ -445,7 +469,9 @@ export function convertToolsToVercelAITools(tools: RunAgentInput["tools"]): Tool
|
|
|
445
469
|
/**
|
|
446
470
|
* Converts ToolDefinition array to Vercel AI SDK ToolSet
|
|
447
471
|
*/
|
|
448
|
-
export function convertToolDefinitionsToVercelAITools(
|
|
472
|
+
export function convertToolDefinitionsToVercelAITools(
|
|
473
|
+
tools: ToolDefinition[],
|
|
474
|
+
): ToolSet {
|
|
449
475
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
450
476
|
const result: Record<string, any> = {};
|
|
451
477
|
|
|
@@ -587,7 +613,10 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
587
613
|
const hasState =
|
|
588
614
|
input.state !== undefined &&
|
|
589
615
|
input.state !== null &&
|
|
590
|
-
!(
|
|
616
|
+
!(
|
|
617
|
+
typeof input.state === "object" &&
|
|
618
|
+
Object.keys(input.state).length === 0
|
|
619
|
+
);
|
|
591
620
|
|
|
592
621
|
if (hasPrompt || hasContext || hasState) {
|
|
593
622
|
const parts: string[] = [];
|
|
@@ -632,7 +661,9 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
632
661
|
// Merge tools from input and config
|
|
633
662
|
let allTools: ToolSet = convertToolsToVercelAITools(input.tools);
|
|
634
663
|
if (this.config.tools && this.config.tools.length > 0) {
|
|
635
|
-
const configTools = convertToolDefinitionsToVercelAITools(
|
|
664
|
+
const configTools = convertToolDefinitionsToVercelAITools(
|
|
665
|
+
this.config.tools,
|
|
666
|
+
);
|
|
636
667
|
allTools = { ...allTools, ...configTools };
|
|
637
668
|
}
|
|
638
669
|
|
|
@@ -641,7 +672,9 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
641
672
|
messages,
|
|
642
673
|
tools: allTools,
|
|
643
674
|
toolChoice: this.config.toolChoice,
|
|
644
|
-
stopWhen: this.config.maxSteps
|
|
675
|
+
stopWhen: this.config.maxSteps
|
|
676
|
+
? stepCountIs(this.config.maxSteps)
|
|
677
|
+
: undefined,
|
|
645
678
|
maxOutputTokens: this.config.maxOutputTokens,
|
|
646
679
|
temperature: this.config.temperature,
|
|
647
680
|
topP: this.config.topP,
|
|
@@ -659,10 +692,16 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
659
692
|
|
|
660
693
|
// Check and apply each overridable property
|
|
661
694
|
if (props.model !== undefined && this.canOverride("model")) {
|
|
662
|
-
if (
|
|
695
|
+
if (
|
|
696
|
+
typeof props.model === "string" ||
|
|
697
|
+
typeof props.model === "object"
|
|
698
|
+
) {
|
|
663
699
|
// Accept any string or LanguageModel instance for model override
|
|
664
700
|
// Use the configured API key when resolving overridden models
|
|
665
|
-
streamTextParams.model = resolveModel(
|
|
701
|
+
streamTextParams.model = resolveModel(
|
|
702
|
+
props.model as string | LanguageModel,
|
|
703
|
+
this.config.apiKey,
|
|
704
|
+
);
|
|
666
705
|
}
|
|
667
706
|
}
|
|
668
707
|
if (props.toolChoice !== undefined && this.canOverride("toolChoice")) {
|
|
@@ -677,13 +716,21 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
677
716
|
"type" in toolChoice &&
|
|
678
717
|
toolChoice.type === "tool")
|
|
679
718
|
) {
|
|
680
|
-
streamTextParams.toolChoice = toolChoice as ToolChoice<
|
|
719
|
+
streamTextParams.toolChoice = toolChoice as ToolChoice<
|
|
720
|
+
Record<string, unknown>
|
|
721
|
+
>;
|
|
681
722
|
}
|
|
682
723
|
}
|
|
683
|
-
if (
|
|
724
|
+
if (
|
|
725
|
+
typeof props.maxOutputTokens === "number" &&
|
|
726
|
+
this.canOverride("maxOutputTokens")
|
|
727
|
+
) {
|
|
684
728
|
streamTextParams.maxOutputTokens = props.maxOutputTokens;
|
|
685
729
|
}
|
|
686
|
-
if (
|
|
730
|
+
if (
|
|
731
|
+
typeof props.temperature === "number" &&
|
|
732
|
+
this.canOverride("temperature")
|
|
733
|
+
) {
|
|
687
734
|
streamTextParams.temperature = props.temperature;
|
|
688
735
|
}
|
|
689
736
|
if (typeof props.topP === "number" && this.canOverride("topP")) {
|
|
@@ -692,22 +739,38 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
692
739
|
if (typeof props.topK === "number" && this.canOverride("topK")) {
|
|
693
740
|
streamTextParams.topK = props.topK;
|
|
694
741
|
}
|
|
695
|
-
if (
|
|
742
|
+
if (
|
|
743
|
+
typeof props.presencePenalty === "number" &&
|
|
744
|
+
this.canOverride("presencePenalty")
|
|
745
|
+
) {
|
|
696
746
|
streamTextParams.presencePenalty = props.presencePenalty;
|
|
697
747
|
}
|
|
698
|
-
if (
|
|
748
|
+
if (
|
|
749
|
+
typeof props.frequencyPenalty === "number" &&
|
|
750
|
+
this.canOverride("frequencyPenalty")
|
|
751
|
+
) {
|
|
699
752
|
streamTextParams.frequencyPenalty = props.frequencyPenalty;
|
|
700
753
|
}
|
|
701
|
-
if (
|
|
754
|
+
if (
|
|
755
|
+
Array.isArray(props.stopSequences) &&
|
|
756
|
+
this.canOverride("stopSequences")
|
|
757
|
+
) {
|
|
702
758
|
// Validate all elements are strings
|
|
703
|
-
if (
|
|
759
|
+
if (
|
|
760
|
+
props.stopSequences.every(
|
|
761
|
+
(item): item is string => typeof item === "string",
|
|
762
|
+
)
|
|
763
|
+
) {
|
|
704
764
|
streamTextParams.stopSequences = props.stopSequences;
|
|
705
765
|
}
|
|
706
766
|
}
|
|
707
767
|
if (typeof props.seed === "number" && this.canOverride("seed")) {
|
|
708
768
|
streamTextParams.seed = props.seed;
|
|
709
769
|
}
|
|
710
|
-
if (
|
|
770
|
+
if (
|
|
771
|
+
typeof props.maxRetries === "number" &&
|
|
772
|
+
this.canOverride("maxRetries")
|
|
773
|
+
) {
|
|
711
774
|
streamTextParams.maxRetries = props.maxRetries;
|
|
712
775
|
}
|
|
713
776
|
}
|
|
@@ -725,7 +788,8 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
725
788
|
streamTextParams.tools = {
|
|
726
789
|
...streamTextParams.tools,
|
|
727
790
|
AGUISendStateSnapshot: createVercelAISDKTool({
|
|
728
|
-
description:
|
|
791
|
+
description:
|
|
792
|
+
"Replace the entire application state with a new snapshot",
|
|
729
793
|
inputSchema: z.object({
|
|
730
794
|
snapshot: z.any().describe("The complete new state object"),
|
|
731
795
|
}),
|
|
@@ -734,13 +798,18 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
734
798
|
},
|
|
735
799
|
}),
|
|
736
800
|
AGUISendStateDelta: createVercelAISDKTool({
|
|
737
|
-
description:
|
|
801
|
+
description:
|
|
802
|
+
"Apply incremental updates to application state using JSON Patch operations",
|
|
738
803
|
inputSchema: z.object({
|
|
739
804
|
delta: z
|
|
740
805
|
.array(
|
|
741
806
|
z.object({
|
|
742
|
-
op: z
|
|
743
|
-
|
|
807
|
+
op: z
|
|
808
|
+
.enum(["add", "replace", "remove"])
|
|
809
|
+
.describe("The operation to perform"),
|
|
810
|
+
path: z
|
|
811
|
+
.string()
|
|
812
|
+
.describe("JSON Pointer path (e.g., '/foo/bar')"),
|
|
744
813
|
value: z
|
|
745
814
|
.any()
|
|
746
815
|
.optional()
|
|
@@ -764,9 +833,15 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
764
833
|
|
|
765
834
|
if (serverConfig.type === "http") {
|
|
766
835
|
const url = new URL(serverConfig.url);
|
|
767
|
-
transport = new StreamableHTTPClientTransport(
|
|
836
|
+
transport = new StreamableHTTPClientTransport(
|
|
837
|
+
url,
|
|
838
|
+
serverConfig.options,
|
|
839
|
+
);
|
|
768
840
|
} else if (serverConfig.type === "sse") {
|
|
769
|
-
transport = new SSEClientTransport(
|
|
841
|
+
transport = new SSEClientTransport(
|
|
842
|
+
new URL(serverConfig.url),
|
|
843
|
+
serverConfig.headers,
|
|
844
|
+
);
|
|
770
845
|
}
|
|
771
846
|
|
|
772
847
|
if (transport) {
|
|
@@ -775,13 +850,19 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
775
850
|
|
|
776
851
|
// Get tools from this MCP server and merge with existing tools
|
|
777
852
|
const mcpTools = await mcpClient.tools();
|
|
778
|
-
streamTextParams.tools = {
|
|
853
|
+
streamTextParams.tools = {
|
|
854
|
+
...streamTextParams.tools,
|
|
855
|
+
...mcpTools,
|
|
856
|
+
} as ToolSet;
|
|
779
857
|
}
|
|
780
858
|
}
|
|
781
859
|
}
|
|
782
860
|
|
|
783
861
|
// Call streamText and process the stream
|
|
784
|
-
const response = streamText({
|
|
862
|
+
const response = streamText({
|
|
863
|
+
...streamTextParams,
|
|
864
|
+
abortSignal: abortController.signal,
|
|
865
|
+
});
|
|
785
866
|
|
|
786
867
|
let messageId = randomUUID();
|
|
787
868
|
|
|
@@ -859,7 +940,10 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
859
940
|
// New text message starting - use the SDK-provided id
|
|
860
941
|
// Use randomUUID() if part.id is falsy or "0" to prevent message merging issues
|
|
861
942
|
const providedId = "id" in part ? part.id : undefined;
|
|
862
|
-
messageId =
|
|
943
|
+
messageId =
|
|
944
|
+
providedId && providedId !== "0"
|
|
945
|
+
? (providedId as typeof messageId)
|
|
946
|
+
: randomUUID();
|
|
863
947
|
break;
|
|
864
948
|
}
|
|
865
949
|
|
|
@@ -893,7 +977,11 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
893
977
|
subscriber.next(startEvent);
|
|
894
978
|
}
|
|
895
979
|
|
|
896
|
-
if (
|
|
980
|
+
if (
|
|
981
|
+
!state.hasArgsDelta &&
|
|
982
|
+
"input" in part &&
|
|
983
|
+
part.input !== undefined
|
|
984
|
+
) {
|
|
897
985
|
let serializedInput = "";
|
|
898
986
|
if (typeof part.input === "string") {
|
|
899
987
|
serializedInput = part.input;
|
|
@@ -933,14 +1021,22 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
933
1021
|
toolCallStates.delete(part.toolCallId);
|
|
934
1022
|
|
|
935
1023
|
// Check if this is a state update tool
|
|
936
|
-
if (
|
|
1024
|
+
if (
|
|
1025
|
+
toolName === "AGUISendStateSnapshot" &&
|
|
1026
|
+
toolResult &&
|
|
1027
|
+
typeof toolResult === "object"
|
|
1028
|
+
) {
|
|
937
1029
|
// Emit StateSnapshotEvent
|
|
938
1030
|
const stateSnapshotEvent: StateSnapshotEvent = {
|
|
939
1031
|
type: EventType.STATE_SNAPSHOT,
|
|
940
1032
|
snapshot: toolResult.snapshot,
|
|
941
1033
|
};
|
|
942
1034
|
subscriber.next(stateSnapshotEvent);
|
|
943
|
-
} else if (
|
|
1035
|
+
} else if (
|
|
1036
|
+
toolName === "AGUISendStateDelta" &&
|
|
1037
|
+
toolResult &&
|
|
1038
|
+
typeof toolResult === "object"
|
|
1039
|
+
) {
|
|
944
1040
|
// Emit StateDeltaEvent
|
|
945
1041
|
const stateDeltaEvent: StateDeltaEvent = {
|
|
946
1042
|
type: EventType.STATE_DELTA,
|
package/tsup.config.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
entry: [
|
|
5
|
-
format: [
|
|
4
|
+
entry: ["src/index.ts"],
|
|
5
|
+
format: ["cjs", "esm"],
|
|
6
6
|
dts: true,
|
|
7
7
|
sourcemap: true,
|
|
8
8
|
clean: true,
|
|
9
|
-
target:
|
|
10
|
-
outDir:
|
|
9
|
+
target: "es2022",
|
|
10
|
+
outDir: "dist",
|
|
11
11
|
});
|