@copilotkit/runtime 1.55.2-next.0 → 1.55.2-next.1
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 +7 -0
- package/dist/agent/converters/aisdk.cjs +215 -0
- package/dist/agent/converters/aisdk.cjs.map +1 -0
- package/dist/agent/converters/aisdk.d.cts +18 -0
- package/dist/agent/converters/aisdk.d.cts.map +1 -0
- package/dist/agent/converters/aisdk.d.mts +18 -0
- package/dist/agent/converters/aisdk.d.mts.map +1 -0
- package/dist/agent/converters/aisdk.mjs +214 -0
- package/dist/agent/converters/aisdk.mjs.map +1 -0
- package/dist/agent/converters/index.d.mts +3 -0
- package/dist/agent/converters/tanstack.cjs +180 -0
- package/dist/agent/converters/tanstack.cjs.map +1 -0
- package/dist/agent/converters/tanstack.d.cts +68 -0
- package/dist/agent/converters/tanstack.d.cts.map +1 -0
- package/dist/agent/converters/tanstack.d.mts +68 -0
- package/dist/agent/converters/tanstack.d.mts.map +1 -0
- package/dist/agent/converters/tanstack.mjs +178 -0
- package/dist/agent/converters/tanstack.mjs.map +1 -0
- package/dist/agent/index.cjs +111 -17
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +61 -4
- package/dist/agent/index.d.cts.map +1 -1
- package/dist/agent/index.d.mts +62 -4
- package/dist/agent/index.d.mts.map +1 -1
- package/dist/agent/index.mjs +111 -17
- package/dist/agent/index.mjs.map +1 -1
- package/dist/lib/integrations/nextjs/pages-router.cjs.map +1 -1
- package/dist/lib/integrations/nextjs/pages-router.d.cts.map +1 -1
- package/dist/lib/integrations/nextjs/pages-router.d.mts.map +1 -1
- package/dist/lib/integrations/nextjs/pages-router.mjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.cjs +4 -2
- package/dist/lib/runtime/copilot-runtime.cjs.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.cts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.d.mts.map +1 -1
- package/dist/lib/runtime/copilot-runtime.mjs +4 -2
- package/dist/lib/runtime/copilot-runtime.mjs.map +1 -1
- package/dist/lib/runtime/mcp-tools-utils.cjs +1 -1
- package/dist/lib/runtime/mcp-tools-utils.cjs.map +1 -1
- package/dist/lib/runtime/mcp-tools-utils.mjs +1 -1
- package/dist/lib/runtime/mcp-tools-utils.mjs.map +1 -1
- package/dist/package.cjs +1 -1
- package/dist/package.mjs +1 -1
- package/dist/service-adapters/anthropic/utils.cjs +1 -1
- package/dist/service-adapters/anthropic/utils.cjs.map +1 -1
- package/dist/service-adapters/anthropic/utils.mjs +1 -1
- package/dist/service-adapters/anthropic/utils.mjs.map +1 -1
- package/dist/service-adapters/openai/utils.cjs +1 -1
- package/dist/service-adapters/openai/utils.cjs.map +1 -1
- package/dist/service-adapters/openai/utils.mjs +1 -1
- package/dist/service-adapters/openai/utils.mjs.map +1 -1
- package/dist/v2/index.cjs +5 -0
- package/dist/v2/index.d.cts +4 -2
- package/dist/v2/index.d.mts +4 -2
- package/dist/v2/index.mjs +3 -1
- package/package.json +2 -2
- package/src/agent/__tests__/agent-test-helpers.ts +446 -0
- package/src/agent/__tests__/agent.test.ts +593 -0
- package/src/agent/__tests__/converter-aisdk.test.ts +692 -0
- package/src/agent/__tests__/converter-custom.test.ts +319 -0
- package/src/agent/__tests__/converter-tanstack-input.test.ts +211 -0
- package/src/agent/__tests__/converter-tanstack.test.ts +314 -0
- package/src/agent/__tests__/multimodal-tanstack.test.ts +284 -0
- package/src/agent/__tests__/test-helpers.ts +12 -8
- package/src/agent/converters/aisdk.ts +326 -0
- package/src/agent/converters/index.ts +7 -0
- package/src/agent/converters/tanstack.ts +286 -0
- package/src/agent/index.ts +245 -26
- package/src/lib/integrations/nextjs/pages-router.ts +1 -0
- package/src/lib/runtime/copilot-runtime.ts +21 -12
- package/src/lib/runtime/mcp-tools-utils.ts +1 -1
- package/src/service-adapters/anthropic/utils.ts +1 -1
- package/src/service-adapters/openai/utils.ts +1 -1
package/src/agent/index.ts
CHANGED
|
@@ -49,6 +49,8 @@ import { z } from "zod";
|
|
|
49
49
|
import type { StandardSchemaV1, InferSchemaOutput } from "@copilotkit/shared";
|
|
50
50
|
import { schemaToJsonSchema } from "@copilotkit/shared";
|
|
51
51
|
import { jsonSchema as aiJsonSchema } from "ai";
|
|
52
|
+
import { convertAISDKStream } from "./converters/aisdk";
|
|
53
|
+
import { convertTanStackStream } from "./converters/tanstack";
|
|
52
54
|
import {
|
|
53
55
|
StreamableHTTPClientTransport,
|
|
54
56
|
StreamableHTTPClientTransportOptions,
|
|
@@ -656,9 +658,66 @@ export function convertToolDefinitionsToVercelAITools(
|
|
|
656
658
|
}
|
|
657
659
|
|
|
658
660
|
/**
|
|
659
|
-
*
|
|
661
|
+
* Context passed to the user-supplied factory function in factory mode.
|
|
660
662
|
*/
|
|
661
|
-
export interface
|
|
663
|
+
export interface AgentFactoryContext {
|
|
664
|
+
input: RunAgentInput;
|
|
665
|
+
/**
|
|
666
|
+
* Prefer `abortSignal` for most use cases (AI SDK, fetch, custom backends).
|
|
667
|
+
* Provided for backends like TanStack AI that require the full AbortController.
|
|
668
|
+
* Do NOT call `.abort()` on this controller — use `abortRun()` on the agent instead.
|
|
669
|
+
*/
|
|
670
|
+
abortController: AbortController;
|
|
671
|
+
abortSignal: AbortSignal;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Factory config for AI SDK backend.
|
|
676
|
+
* The factory must return an object with a `fullStream` async iterable
|
|
677
|
+
* (compatible with the result of `streamText()` — only `fullStream` is consumed).
|
|
678
|
+
*/
|
|
679
|
+
export interface BuiltInAgentAISDKFactoryConfig {
|
|
680
|
+
type: "aisdk";
|
|
681
|
+
factory: (
|
|
682
|
+
ctx: AgentFactoryContext,
|
|
683
|
+
) =>
|
|
684
|
+
| { fullStream: AsyncIterable<unknown> }
|
|
685
|
+
| Promise<{ fullStream: AsyncIterable<unknown> }>;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Factory config for TanStack AI backend.
|
|
690
|
+
* The factory must return an async iterable of TanStack AI stream chunks.
|
|
691
|
+
*/
|
|
692
|
+
export interface BuiltInAgentTanStackFactoryConfig {
|
|
693
|
+
type: "tanstack";
|
|
694
|
+
factory: (
|
|
695
|
+
ctx: AgentFactoryContext,
|
|
696
|
+
) => AsyncIterable<unknown> | Promise<AsyncIterable<unknown>>;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
/**
|
|
700
|
+
* Factory config for a custom backend that directly yields AG-UI events.
|
|
701
|
+
*/
|
|
702
|
+
export interface BuiltInAgentCustomFactoryConfig {
|
|
703
|
+
type: "custom";
|
|
704
|
+
factory: (
|
|
705
|
+
ctx: AgentFactoryContext,
|
|
706
|
+
) => AsyncIterable<BaseEvent> | Promise<AsyncIterable<BaseEvent>>;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Union of all factory-mode configurations.
|
|
711
|
+
*/
|
|
712
|
+
export type BuiltInAgentFactoryConfig =
|
|
713
|
+
| BuiltInAgentAISDKFactoryConfig
|
|
714
|
+
| BuiltInAgentTanStackFactoryConfig
|
|
715
|
+
| BuiltInAgentCustomFactoryConfig;
|
|
716
|
+
|
|
717
|
+
/**
|
|
718
|
+
* Classic config — BuiltInAgent handles streamText, tools, MCP, state tools, prompt building.
|
|
719
|
+
*/
|
|
720
|
+
export interface BuiltInAgentClassicConfig {
|
|
662
721
|
/**
|
|
663
722
|
* The model to use
|
|
664
723
|
*/
|
|
@@ -760,6 +819,26 @@ export interface BuiltInAgentConfiguration {
|
|
|
760
819
|
providerOptions?: Record<string, any>;
|
|
761
820
|
}
|
|
762
821
|
|
|
822
|
+
/**
|
|
823
|
+
* Configuration for BuiltInAgent.
|
|
824
|
+
*
|
|
825
|
+
* Two modes:
|
|
826
|
+
* - **Classic** (model + params): BuiltInAgent handles everything — streamText, tools, MCP, state tools.
|
|
827
|
+
* - **Factory** (type + factory): You own the LLM call. BuiltInAgent handles lifecycle only.
|
|
828
|
+
*/
|
|
829
|
+
export type BuiltInAgentConfiguration =
|
|
830
|
+
| BuiltInAgentClassicConfig
|
|
831
|
+
| BuiltInAgentFactoryConfig;
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Type guard: returns true if this is a factory-mode config.
|
|
835
|
+
*/
|
|
836
|
+
function isFactoryConfig(
|
|
837
|
+
config: BuiltInAgentConfiguration,
|
|
838
|
+
): config is BuiltInAgentFactoryConfig {
|
|
839
|
+
return "factory" in config;
|
|
840
|
+
}
|
|
841
|
+
|
|
763
842
|
export class BuiltInAgent extends AbstractAgent {
|
|
764
843
|
private abortController?: AbortController;
|
|
765
844
|
|
|
@@ -771,10 +850,25 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
771
850
|
* Check if a property can be overridden by forwardedProps
|
|
772
851
|
*/
|
|
773
852
|
canOverride(property: OverridableProperty): boolean {
|
|
853
|
+
if (isFactoryConfig(this.config)) return false;
|
|
774
854
|
return this.config?.overridableProperties?.includes(property) ?? false;
|
|
775
855
|
}
|
|
776
856
|
|
|
777
857
|
run(input: RunAgentInput): Observable<BaseEvent> {
|
|
858
|
+
if (isFactoryConfig(this.config)) {
|
|
859
|
+
return this.runFactory(input, this.config);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
if (this.abortController) {
|
|
863
|
+
throw new Error(
|
|
864
|
+
"Agent is already running. Call abortRun() first or create a new instance.",
|
|
865
|
+
);
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
// Set synchronously before Observable creation to close TOCTOU window
|
|
869
|
+
this.abortController = new AbortController();
|
|
870
|
+
const abortController = this.abortController;
|
|
871
|
+
|
|
778
872
|
return new Observable<BaseEvent>((subscriber) => {
|
|
779
873
|
// Emit RUN_STARTED event
|
|
780
874
|
const startEvent: RunStartedEvent = {
|
|
@@ -980,8 +1074,6 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
980
1074
|
const mcpClients: Array<{ close: () => Promise<void> }> = [];
|
|
981
1075
|
|
|
982
1076
|
(async () => {
|
|
983
|
-
const abortController = new AbortController();
|
|
984
|
-
this.abortController = abortController;
|
|
985
1077
|
let terminalEventEmitted = false;
|
|
986
1078
|
let messageId = randomUUID();
|
|
987
1079
|
let reasoningMessageId = randomUUID();
|
|
@@ -1294,7 +1386,12 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
1294
1386
|
}
|
|
1295
1387
|
|
|
1296
1388
|
case "tool-result": {
|
|
1297
|
-
const toolResult =
|
|
1389
|
+
const toolResult =
|
|
1390
|
+
"output" in part
|
|
1391
|
+
? part.output
|
|
1392
|
+
: "result" in part
|
|
1393
|
+
? part.result
|
|
1394
|
+
: null;
|
|
1298
1395
|
const toolName = "toolName" in part ? part.toolName : "";
|
|
1299
1396
|
toolCallStates.delete(part.toolCallId);
|
|
1300
1397
|
|
|
@@ -1304,32 +1401,42 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
1304
1401
|
toolResult &&
|
|
1305
1402
|
typeof toolResult === "object"
|
|
1306
1403
|
) {
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1404
|
+
const snapshot = toolResult.snapshot;
|
|
1405
|
+
if (snapshot !== undefined) {
|
|
1406
|
+
const stateSnapshotEvent: StateSnapshotEvent = {
|
|
1407
|
+
type: EventType.STATE_SNAPSHOT,
|
|
1408
|
+
snapshot,
|
|
1409
|
+
};
|
|
1410
|
+
subscriber.next(stateSnapshotEvent);
|
|
1411
|
+
}
|
|
1313
1412
|
} else if (
|
|
1314
1413
|
toolName === "AGUISendStateDelta" &&
|
|
1315
1414
|
toolResult &&
|
|
1316
1415
|
typeof toolResult === "object"
|
|
1317
1416
|
) {
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1417
|
+
const delta = toolResult.delta;
|
|
1418
|
+
if (delta !== undefined) {
|
|
1419
|
+
const stateDeltaEvent: StateDeltaEvent = {
|
|
1420
|
+
type: EventType.STATE_DELTA,
|
|
1421
|
+
delta,
|
|
1422
|
+
};
|
|
1423
|
+
subscriber.next(stateDeltaEvent);
|
|
1424
|
+
}
|
|
1324
1425
|
}
|
|
1325
1426
|
|
|
1326
1427
|
// Always emit the tool result event for the LLM
|
|
1428
|
+
let serializedResult: string;
|
|
1429
|
+
try {
|
|
1430
|
+
serializedResult = JSON.stringify(toolResult);
|
|
1431
|
+
} catch {
|
|
1432
|
+
serializedResult = `[Unserializable tool result from ${toolName || part.toolCallId}]`;
|
|
1433
|
+
}
|
|
1327
1434
|
const resultEvent: ToolCallResultEvent = {
|
|
1328
1435
|
type: EventType.TOOL_CALL_RESULT,
|
|
1329
1436
|
role: "tool",
|
|
1330
1437
|
messageId: randomUUID(),
|
|
1331
1438
|
toolCallId: part.toolCallId,
|
|
1332
|
-
content:
|
|
1439
|
+
content: serializedResult,
|
|
1333
1440
|
};
|
|
1334
1441
|
subscriber.next(resultEvent);
|
|
1335
1442
|
break;
|
|
@@ -1354,15 +1461,29 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
1354
1461
|
if (abortController.signal.aborted) {
|
|
1355
1462
|
break;
|
|
1356
1463
|
}
|
|
1464
|
+
const err = part.error ?? part.message ?? part.cause;
|
|
1357
1465
|
const runErrorEvent: RunErrorEvent = {
|
|
1358
1466
|
type: EventType.RUN_ERROR,
|
|
1359
|
-
message:
|
|
1360
|
-
|
|
1467
|
+
message:
|
|
1468
|
+
err instanceof Error
|
|
1469
|
+
? err.message
|
|
1470
|
+
: typeof err === "string"
|
|
1471
|
+
? err
|
|
1472
|
+
: `AI SDK stream error: ${JSON.stringify(part)}`,
|
|
1473
|
+
threadId: input.threadId,
|
|
1474
|
+
runId: input.runId,
|
|
1475
|
+
} as RunErrorEvent;
|
|
1361
1476
|
subscriber.next(runErrorEvent);
|
|
1362
1477
|
terminalEventEmitted = true;
|
|
1363
1478
|
|
|
1364
1479
|
// Handle error
|
|
1365
|
-
subscriber.error(
|
|
1480
|
+
if (err instanceof Error) subscriber.error(err);
|
|
1481
|
+
else
|
|
1482
|
+
subscriber.error(
|
|
1483
|
+
new Error(
|
|
1484
|
+
typeof err === "string" ? err : `AI SDK stream error`,
|
|
1485
|
+
),
|
|
1486
|
+
);
|
|
1366
1487
|
break;
|
|
1367
1488
|
}
|
|
1368
1489
|
}
|
|
@@ -1392,8 +1513,10 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
1392
1513
|
} else {
|
|
1393
1514
|
const runErrorEvent: RunErrorEvent = {
|
|
1394
1515
|
type: EventType.RUN_ERROR,
|
|
1395
|
-
message: error
|
|
1396
|
-
|
|
1516
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1517
|
+
threadId: input.threadId,
|
|
1518
|
+
runId: input.runId,
|
|
1519
|
+
} as RunErrorEvent;
|
|
1397
1520
|
subscriber.next(runErrorEvent);
|
|
1398
1521
|
terminalEventEmitted = true;
|
|
1399
1522
|
subscriber.error(error);
|
|
@@ -1414,10 +1537,103 @@ export class BuiltInAgent extends AbstractAgent {
|
|
|
1414
1537
|
});
|
|
1415
1538
|
}
|
|
1416
1539
|
|
|
1540
|
+
private runFactory(
|
|
1541
|
+
input: RunAgentInput,
|
|
1542
|
+
config: BuiltInAgentFactoryConfig,
|
|
1543
|
+
): Observable<BaseEvent> {
|
|
1544
|
+
if (this.abortController) {
|
|
1545
|
+
throw new Error(
|
|
1546
|
+
"Agent is already running. Call abortRun() first or create a new instance.",
|
|
1547
|
+
);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
// Set synchronously before Observable creation to close TOCTOU window
|
|
1551
|
+
this.abortController = new AbortController();
|
|
1552
|
+
const controller = this.abortController;
|
|
1553
|
+
|
|
1554
|
+
return new Observable<BaseEvent>((subscriber) => {
|
|
1555
|
+
const startEvent: RunStartedEvent = {
|
|
1556
|
+
type: EventType.RUN_STARTED,
|
|
1557
|
+
threadId: input.threadId,
|
|
1558
|
+
runId: input.runId,
|
|
1559
|
+
};
|
|
1560
|
+
subscriber.next(startEvent);
|
|
1561
|
+
|
|
1562
|
+
const ctx: AgentFactoryContext = {
|
|
1563
|
+
input,
|
|
1564
|
+
abortController: controller,
|
|
1565
|
+
abortSignal: controller.signal,
|
|
1566
|
+
};
|
|
1567
|
+
|
|
1568
|
+
(async () => {
|
|
1569
|
+
try {
|
|
1570
|
+
let events: AsyncIterable<BaseEvent>;
|
|
1571
|
+
|
|
1572
|
+
switch (config.type) {
|
|
1573
|
+
case "aisdk": {
|
|
1574
|
+
const result = await config.factory(ctx);
|
|
1575
|
+
events = convertAISDKStream(result.fullStream, controller.signal);
|
|
1576
|
+
break;
|
|
1577
|
+
}
|
|
1578
|
+
case "tanstack": {
|
|
1579
|
+
const stream = await config.factory(ctx);
|
|
1580
|
+
events = convertTanStackStream(stream, controller.signal);
|
|
1581
|
+
break;
|
|
1582
|
+
}
|
|
1583
|
+
case "custom": {
|
|
1584
|
+
events = await config.factory(ctx);
|
|
1585
|
+
break;
|
|
1586
|
+
}
|
|
1587
|
+
default: {
|
|
1588
|
+
const _exhaustive: never = config;
|
|
1589
|
+
throw new Error(
|
|
1590
|
+
`Unknown agent config type: ${(_exhaustive as BuiltInAgentFactoryConfig).type}`,
|
|
1591
|
+
);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1595
|
+
for await (const event of events) {
|
|
1596
|
+
subscriber.next(event);
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
if (!controller.signal.aborted) {
|
|
1600
|
+
const finishedEvent: RunFinishedEvent = {
|
|
1601
|
+
type: EventType.RUN_FINISHED,
|
|
1602
|
+
threadId: input.threadId,
|
|
1603
|
+
runId: input.runId,
|
|
1604
|
+
};
|
|
1605
|
+
subscriber.next(finishedEvent);
|
|
1606
|
+
}
|
|
1607
|
+
subscriber.complete();
|
|
1608
|
+
} catch (error) {
|
|
1609
|
+
if (controller.signal.aborted) {
|
|
1610
|
+
subscriber.complete();
|
|
1611
|
+
} else {
|
|
1612
|
+
const runErrorEvent: RunErrorEvent = {
|
|
1613
|
+
type: EventType.RUN_ERROR,
|
|
1614
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1615
|
+
threadId: input.threadId,
|
|
1616
|
+
runId: input.runId,
|
|
1617
|
+
} as RunErrorEvent;
|
|
1618
|
+
subscriber.next(runErrorEvent);
|
|
1619
|
+
subscriber.error(error);
|
|
1620
|
+
}
|
|
1621
|
+
} finally {
|
|
1622
|
+
this.abortController = undefined;
|
|
1623
|
+
}
|
|
1624
|
+
})();
|
|
1625
|
+
|
|
1626
|
+
return () => {
|
|
1627
|
+
controller.abort();
|
|
1628
|
+
};
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1417
1632
|
clone() {
|
|
1418
1633
|
const cloned = new BuiltInAgent(this.config);
|
|
1419
|
-
//
|
|
1420
|
-
//
|
|
1634
|
+
// AbstractAgent.middlewares is private in @ag-ui/client — no public accessor exists.
|
|
1635
|
+
// This coupling is intentional: clone() must preserve middleware chains.
|
|
1636
|
+
// @ts-expect-error accessing private AbstractAgent.middlewares
|
|
1421
1637
|
cloned.middlewares = [...this.middlewares];
|
|
1422
1638
|
return cloned;
|
|
1423
1639
|
}
|
|
@@ -1437,4 +1653,7 @@ export class BasicAgent extends BuiltInAgent {
|
|
|
1437
1653
|
}
|
|
1438
1654
|
}
|
|
1439
1655
|
|
|
1440
|
-
|
|
1656
|
+
/** @deprecated Use BuiltInAgentClassicConfig instead */
|
|
1657
|
+
export type BasicAgentConfiguration = BuiltInAgentClassicConfig;
|
|
1658
|
+
|
|
1659
|
+
export * from "./converters";
|
|
@@ -13,6 +13,7 @@ export const config = {
|
|
|
13
13
|
// This import is needed to fix the type error
|
|
14
14
|
// Fix is currently in TypeScript 5.5 beta, waiting for stable version
|
|
15
15
|
// https://github.com/microsoft/TypeScript/issues/42873#issuecomment-2066874644
|
|
16
|
+
// oxlint-disable-next-line unicorn/require-module-specifiers, typescript/no-useless-empty-export
|
|
16
17
|
export type {} from "@whatwg-node/server";
|
|
17
18
|
|
|
18
19
|
export function copilotRuntimeNextJSPagesRouterEndpoint(
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
type MCPTool,
|
|
65
65
|
extractParametersFromSchema,
|
|
66
66
|
} from "./mcp-tools-utils";
|
|
67
|
-
import { BuiltInAgent, type
|
|
67
|
+
import { BuiltInAgent, type BuiltInAgentClassicConfig } from "../../agent";
|
|
68
68
|
// Define the function type alias here or import if defined elsewhere
|
|
69
69
|
type CreateMCPClientFunction = (
|
|
70
70
|
config: MCPEndpointConfig,
|
|
@@ -328,7 +328,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
328
328
|
params?: CopilotRuntimeConstructorParams<T>;
|
|
329
329
|
private observability?: CopilotObservabilityConfig;
|
|
330
330
|
// Cache MCP tools per endpoint to avoid re-fetching repeatedly
|
|
331
|
-
private mcpToolsCache: Map<string,
|
|
331
|
+
private mcpToolsCache: Map<string, BuiltInAgentClassicConfig["tools"]> =
|
|
332
332
|
new Map();
|
|
333
333
|
private runtimeArgs: CopilotRuntimeOptions;
|
|
334
334
|
private _instance: CopilotRuntimeVNext;
|
|
@@ -449,7 +449,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
449
449
|
// Receive this.params.action and turn it into the AbstractAgent tools
|
|
450
450
|
private getToolsFromActions(
|
|
451
451
|
actions: ActionsConfiguration<any>,
|
|
452
|
-
):
|
|
452
|
+
): BuiltInAgentClassicConfig["tools"] {
|
|
453
453
|
// Resolve actions to an array (handle function case)
|
|
454
454
|
const actionsArray =
|
|
455
455
|
typeof actions === "function"
|
|
@@ -472,7 +472,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
472
472
|
|
|
473
473
|
private assignToolsToAgents(
|
|
474
474
|
agents: Record<string, AbstractAgent>,
|
|
475
|
-
tools:
|
|
475
|
+
tools: BuiltInAgentClassicConfig["tools"],
|
|
476
476
|
): Record<string, AbstractAgent> {
|
|
477
477
|
if (!tools?.length) {
|
|
478
478
|
return agents;
|
|
@@ -481,12 +481,21 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
481
481
|
const enrichedAgents: Record<string, AbstractAgent> = { ...agents };
|
|
482
482
|
|
|
483
483
|
for (const [agentId, agent] of Object.entries(enrichedAgents)) {
|
|
484
|
-
const existingConfig = (Reflect.get(agent, "config") ??
|
|
485
|
-
|
|
486
|
-
|
|
484
|
+
const existingConfig = (Reflect.get(agent, "config") ?? {}) as Record<
|
|
485
|
+
string,
|
|
486
|
+
unknown
|
|
487
|
+
>;
|
|
487
488
|
|
|
488
|
-
|
|
489
|
-
|
|
489
|
+
// Skip factory-mode agents — they don't have a tools property
|
|
490
|
+
if ("factory" in existingConfig) {
|
|
491
|
+
continue;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const classicConfig = existingConfig as BuiltInAgentClassicConfig;
|
|
495
|
+
const existingTools = classicConfig.tools ?? [];
|
|
496
|
+
|
|
497
|
+
const updatedConfig: BuiltInAgentClassicConfig = {
|
|
498
|
+
...classicConfig,
|
|
490
499
|
tools: [...existingTools, ...tools],
|
|
491
500
|
};
|
|
492
501
|
|
|
@@ -657,7 +666,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
657
666
|
// Optionally accepts request-scoped properties to merge request-provided mcpServers
|
|
658
667
|
private async getToolsFromMCP(options?: {
|
|
659
668
|
properties?: Record<string, unknown>;
|
|
660
|
-
}): Promise<
|
|
669
|
+
}): Promise<BuiltInAgentClassicConfig["tools"]> {
|
|
661
670
|
const runtimeMcpServers = (this.params?.mcpServers ??
|
|
662
671
|
[]) as MCPEndpointConfig[];
|
|
663
672
|
const createMCPClient = this.params?.createMCPClient as
|
|
@@ -702,7 +711,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
702
711
|
return Array.from(byUrl.values());
|
|
703
712
|
})();
|
|
704
713
|
|
|
705
|
-
const allTools:
|
|
714
|
+
const allTools: BuiltInAgentClassicConfig["tools"] = [];
|
|
706
715
|
|
|
707
716
|
for (const config of effectiveEndpoints) {
|
|
708
717
|
const endpointUrl = config.endpoint;
|
|
@@ -717,7 +726,7 @@ export class CopilotRuntime<const T extends Parameter[] | [] = []> {
|
|
|
717
726
|
const client = await createMCPClient(config);
|
|
718
727
|
const toolsMap = await client.tools();
|
|
719
728
|
|
|
720
|
-
const toolDefs:
|
|
729
|
+
const toolDefs: BuiltInAgentClassicConfig["tools"] = Object.entries(
|
|
721
730
|
toolsMap,
|
|
722
731
|
).map(([toolName, tool]: [string, MCPTool]) => {
|
|
723
732
|
const params: Parameter[] = extractParametersFromSchema(tool);
|
|
@@ -32,7 +32,7 @@ export function limitMessagesToTokenCount(
|
|
|
32
32
|
|
|
33
33
|
let cutoff: boolean = false;
|
|
34
34
|
|
|
35
|
-
const reversedMessages = [...messages].
|
|
35
|
+
const reversedMessages = [...messages].toReversed();
|
|
36
36
|
for (const message of reversedMessages) {
|
|
37
37
|
if (message.role === "system") {
|
|
38
38
|
result.unshift(message);
|
|
@@ -40,7 +40,7 @@ export function limitMessagesToTokenCount(
|
|
|
40
40
|
|
|
41
41
|
let cutoff: boolean = false;
|
|
42
42
|
|
|
43
|
-
const reversedMessages = [...messages].
|
|
43
|
+
const reversedMessages = [...messages].toReversed();
|
|
44
44
|
for (const message of reversedMessages) {
|
|
45
45
|
if (["system", "developer"].includes(message.role)) {
|
|
46
46
|
result.unshift(message);
|