@voltagent/ag-ui 0.1.0
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/LICENCE +21 -0
- package/dist/index.d.mts +94 -0
- package/dist/index.d.ts +94 -0
- package/dist/index.js +489 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +465 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +54 -0
package/LICENCE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 VoltAgent Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { AbstractAgent } from '@ag-ui/client';
|
|
2
|
+
import { RunAgentInput } from '@ag-ui/core';
|
|
3
|
+
import { Agent } from '@voltagent/core';
|
|
4
|
+
import { CopilotServiceAdapter } from '@copilotkit/runtime';
|
|
5
|
+
|
|
6
|
+
type VoltAgentAGUIConfig = {
|
|
7
|
+
agent: Agent;
|
|
8
|
+
/**
|
|
9
|
+
* Optional function to derive userId for VoltAgent memory/telemetry.
|
|
10
|
+
*/
|
|
11
|
+
deriveUserId?: (input: RunAgentInput) => string | undefined;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* VoltAgent adapter that speaks the AG-UI protocol.
|
|
15
|
+
* Mirrors the Mastra integration strategy: preserve AG-UI state in working memory
|
|
16
|
+
* and stream VoltAgent events as AG-UI BaseEvents.
|
|
17
|
+
*/
|
|
18
|
+
declare class VoltAgentAGUI extends AbstractAgent {
|
|
19
|
+
private readonly agent;
|
|
20
|
+
private readonly deriveUserId?;
|
|
21
|
+
constructor(config: VoltAgentAGUIConfig);
|
|
22
|
+
run(input: RunAgentInput): ReturnType<AbstractAgent["run"]>;
|
|
23
|
+
private buildStreamOptions;
|
|
24
|
+
private persistStateToWorkingMemory;
|
|
25
|
+
private readWorkingMemorySnapshot;
|
|
26
|
+
}
|
|
27
|
+
declare function createVoltAgentAGUI(config: VoltAgentAGUIConfig): VoltAgentAGUI;
|
|
28
|
+
|
|
29
|
+
type CopilotKitHandlerOptions = {
|
|
30
|
+
/**
|
|
31
|
+
* Static map of AG-UI agents. Use either this or `loadAgents`.
|
|
32
|
+
*/
|
|
33
|
+
agents?: Record<string, AbstractAgent>;
|
|
34
|
+
/**
|
|
35
|
+
* Lazy loader for AG-UI agents. If provided, it overrides `agents`.
|
|
36
|
+
*/
|
|
37
|
+
loadAgents?: () => Promise<Record<string, AbstractAgent>> | Record<string, AbstractAgent>;
|
|
38
|
+
/**
|
|
39
|
+
* Optional service adapter. Defaults to ExperimentalEmptyAdapter.
|
|
40
|
+
*/
|
|
41
|
+
serviceAdapter?: CopilotServiceAdapter;
|
|
42
|
+
/**
|
|
43
|
+
* Endpoint path used by CopilotKit clients. Defaults to "/copilotkit".
|
|
44
|
+
*/
|
|
45
|
+
endpoint?: string;
|
|
46
|
+
};
|
|
47
|
+
type RegisterCopilotKitRoutesOptions = {
|
|
48
|
+
/**
|
|
49
|
+
* Hono-style app instance with `all(path, handler)` support.
|
|
50
|
+
*/
|
|
51
|
+
app: {
|
|
52
|
+
all: (path: string, handler: (c: any) => any) => any;
|
|
53
|
+
post?: (path: string, handler: (c: any) => any) => any;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* VoltAgent agents to expose to CopilotKit. Will be wrapped lazily.
|
|
57
|
+
*/
|
|
58
|
+
agents?: Record<string, Agent>;
|
|
59
|
+
/**
|
|
60
|
+
* Optional resource IDs to pick from the global AgentRegistry if `agents` is not provided.
|
|
61
|
+
* If omitted and no agents are provided, all registered agents will be exposed.
|
|
62
|
+
*/
|
|
63
|
+
resourceIds?: string[];
|
|
64
|
+
/**
|
|
65
|
+
* Path to mount CopilotKit endpoint. Defaults to "/copilotkit".
|
|
66
|
+
*/
|
|
67
|
+
path?: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Create a framework-agnostic fetch handler for CopilotKit that serves VoltAgent-backed AG-UI agents.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { createCopilotKitHandler } from "@voltagent/ag-ui";
|
|
75
|
+
* import { createVoltAgentAGUI } from "@voltagent/ag-ui";
|
|
76
|
+
* import { agent } from "./agent"; // VoltAgent instance
|
|
77
|
+
*
|
|
78
|
+
* const handler = createCopilotKitHandler({
|
|
79
|
+
* agents: { assistant: createVoltAgentAGUI({ agent }) },
|
|
80
|
+
* endpoint: "/api/copilotkit",
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* export default {
|
|
84
|
+
* fetch: handler,
|
|
85
|
+
* };
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function createCopilotKitHandler(options: CopilotKitHandlerOptions): (req: Request) => Promise<Response>;
|
|
89
|
+
/**
|
|
90
|
+
* Convenience helper: register CopilotKit routes on a Hono-like app using VoltAgent agents.
|
|
91
|
+
*/
|
|
92
|
+
declare function registerCopilotKitRoutes(options: RegisterCopilotKitRoutesOptions): void;
|
|
93
|
+
|
|
94
|
+
export { type CopilotKitHandlerOptions, type RegisterCopilotKitRoutesOptions, VoltAgentAGUI, createCopilotKitHandler, createVoltAgentAGUI, registerCopilotKitRoutes };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { AbstractAgent } from '@ag-ui/client';
|
|
2
|
+
import { RunAgentInput } from '@ag-ui/core';
|
|
3
|
+
import { Agent } from '@voltagent/core';
|
|
4
|
+
import { CopilotServiceAdapter } from '@copilotkit/runtime';
|
|
5
|
+
|
|
6
|
+
type VoltAgentAGUIConfig = {
|
|
7
|
+
agent: Agent;
|
|
8
|
+
/**
|
|
9
|
+
* Optional function to derive userId for VoltAgent memory/telemetry.
|
|
10
|
+
*/
|
|
11
|
+
deriveUserId?: (input: RunAgentInput) => string | undefined;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* VoltAgent adapter that speaks the AG-UI protocol.
|
|
15
|
+
* Mirrors the Mastra integration strategy: preserve AG-UI state in working memory
|
|
16
|
+
* and stream VoltAgent events as AG-UI BaseEvents.
|
|
17
|
+
*/
|
|
18
|
+
declare class VoltAgentAGUI extends AbstractAgent {
|
|
19
|
+
private readonly agent;
|
|
20
|
+
private readonly deriveUserId?;
|
|
21
|
+
constructor(config: VoltAgentAGUIConfig);
|
|
22
|
+
run(input: RunAgentInput): ReturnType<AbstractAgent["run"]>;
|
|
23
|
+
private buildStreamOptions;
|
|
24
|
+
private persistStateToWorkingMemory;
|
|
25
|
+
private readWorkingMemorySnapshot;
|
|
26
|
+
}
|
|
27
|
+
declare function createVoltAgentAGUI(config: VoltAgentAGUIConfig): VoltAgentAGUI;
|
|
28
|
+
|
|
29
|
+
type CopilotKitHandlerOptions = {
|
|
30
|
+
/**
|
|
31
|
+
* Static map of AG-UI agents. Use either this or `loadAgents`.
|
|
32
|
+
*/
|
|
33
|
+
agents?: Record<string, AbstractAgent>;
|
|
34
|
+
/**
|
|
35
|
+
* Lazy loader for AG-UI agents. If provided, it overrides `agents`.
|
|
36
|
+
*/
|
|
37
|
+
loadAgents?: () => Promise<Record<string, AbstractAgent>> | Record<string, AbstractAgent>;
|
|
38
|
+
/**
|
|
39
|
+
* Optional service adapter. Defaults to ExperimentalEmptyAdapter.
|
|
40
|
+
*/
|
|
41
|
+
serviceAdapter?: CopilotServiceAdapter;
|
|
42
|
+
/**
|
|
43
|
+
* Endpoint path used by CopilotKit clients. Defaults to "/copilotkit".
|
|
44
|
+
*/
|
|
45
|
+
endpoint?: string;
|
|
46
|
+
};
|
|
47
|
+
type RegisterCopilotKitRoutesOptions = {
|
|
48
|
+
/**
|
|
49
|
+
* Hono-style app instance with `all(path, handler)` support.
|
|
50
|
+
*/
|
|
51
|
+
app: {
|
|
52
|
+
all: (path: string, handler: (c: any) => any) => any;
|
|
53
|
+
post?: (path: string, handler: (c: any) => any) => any;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* VoltAgent agents to expose to CopilotKit. Will be wrapped lazily.
|
|
57
|
+
*/
|
|
58
|
+
agents?: Record<string, Agent>;
|
|
59
|
+
/**
|
|
60
|
+
* Optional resource IDs to pick from the global AgentRegistry if `agents` is not provided.
|
|
61
|
+
* If omitted and no agents are provided, all registered agents will be exposed.
|
|
62
|
+
*/
|
|
63
|
+
resourceIds?: string[];
|
|
64
|
+
/**
|
|
65
|
+
* Path to mount CopilotKit endpoint. Defaults to "/copilotkit".
|
|
66
|
+
*/
|
|
67
|
+
path?: string;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Create a framework-agnostic fetch handler for CopilotKit that serves VoltAgent-backed AG-UI agents.
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```ts
|
|
74
|
+
* import { createCopilotKitHandler } from "@voltagent/ag-ui";
|
|
75
|
+
* import { createVoltAgentAGUI } from "@voltagent/ag-ui";
|
|
76
|
+
* import { agent } from "./agent"; // VoltAgent instance
|
|
77
|
+
*
|
|
78
|
+
* const handler = createCopilotKitHandler({
|
|
79
|
+
* agents: { assistant: createVoltAgentAGUI({ agent }) },
|
|
80
|
+
* endpoint: "/api/copilotkit",
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* export default {
|
|
84
|
+
* fetch: handler,
|
|
85
|
+
* };
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
declare function createCopilotKitHandler(options: CopilotKitHandlerOptions): (req: Request) => Promise<Response>;
|
|
89
|
+
/**
|
|
90
|
+
* Convenience helper: register CopilotKit routes on a Hono-like app using VoltAgent agents.
|
|
91
|
+
*/
|
|
92
|
+
declare function registerCopilotKitRoutes(options: RegisterCopilotKitRoutesOptions): void;
|
|
93
|
+
|
|
94
|
+
export { type CopilotKitHandlerOptions, type RegisterCopilotKitRoutesOptions, VoltAgentAGUI, createCopilotKitHandler, createVoltAgentAGUI, registerCopilotKitRoutes };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var index_exports = {};
|
|
23
|
+
__export(index_exports, {
|
|
24
|
+
VoltAgentAGUI: () => VoltAgentAGUI,
|
|
25
|
+
createCopilotKitHandler: () => createCopilotKitHandler,
|
|
26
|
+
createVoltAgentAGUI: () => createVoltAgentAGUI,
|
|
27
|
+
registerCopilotKitRoutes: () => registerCopilotKitRoutes
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/voltagent-agent.ts
|
|
32
|
+
var import_client = require("@ag-ui/client");
|
|
33
|
+
var import_core = require("@ag-ui/core");
|
|
34
|
+
var import_utils = require("@voltagent/internal/utils");
|
|
35
|
+
var import_rxjs = require("rxjs");
|
|
36
|
+
function debugLog(message, data) {
|
|
37
|
+
console.log(`[VoltAgentAGUI] ${message}`, data ?? {});
|
|
38
|
+
}
|
|
39
|
+
__name(debugLog, "debugLog");
|
|
40
|
+
var VoltAgentAGUI = class extends import_client.AbstractAgent {
|
|
41
|
+
static {
|
|
42
|
+
__name(this, "VoltAgentAGUI");
|
|
43
|
+
}
|
|
44
|
+
agent;
|
|
45
|
+
deriveUserId;
|
|
46
|
+
constructor(config) {
|
|
47
|
+
super();
|
|
48
|
+
this.agent = config.agent;
|
|
49
|
+
this.deriveUserId = config.deriveUserId;
|
|
50
|
+
}
|
|
51
|
+
run(input) {
|
|
52
|
+
const stream$ = new import_rxjs.Observable((subscriber) => {
|
|
53
|
+
const abortController = new AbortController();
|
|
54
|
+
let finishedSent = false;
|
|
55
|
+
debugLog("run start", { threadId: input.threadId, runId: input.runId });
|
|
56
|
+
const runStarted = {
|
|
57
|
+
type: import_core.EventType.RUN_STARTED,
|
|
58
|
+
threadId: input.threadId,
|
|
59
|
+
runId: input.runId
|
|
60
|
+
};
|
|
61
|
+
subscriber.next(runStarted);
|
|
62
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
63
|
+
let currentMessageId = generateId();
|
|
64
|
+
try {
|
|
65
|
+
await this.persistStateToWorkingMemory(input);
|
|
66
|
+
const streamOptions = this.buildStreamOptions(input, abortController);
|
|
67
|
+
const voltMessages = convertAGUIMessagesToVoltMessages(input.messages);
|
|
68
|
+
debugLog("calling agent.streamText", { messagesLength: voltMessages.length });
|
|
69
|
+
const result = await this.agent.streamText(voltMessages, streamOptions);
|
|
70
|
+
for await (const part of result.fullStream) {
|
|
71
|
+
debugLog("fullStream part", { partType: part.type, id: part.id });
|
|
72
|
+
const events = convertVoltStreamPartToEvents(part, currentMessageId);
|
|
73
|
+
if (!events) continue;
|
|
74
|
+
for (const event of events) {
|
|
75
|
+
debugLog("emit event", { type: event.type, messageId: event.messageId });
|
|
76
|
+
subscriber.next(event);
|
|
77
|
+
if ((event.type === import_core.EventType.TEXT_MESSAGE_START || event.type === import_core.EventType.TEXT_MESSAGE_CHUNK || event.type === import_core.EventType.TEXT_MESSAGE_END) && "messageId" in event && event.messageId) {
|
|
78
|
+
currentMessageId = event.messageId;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const snapshotEvent = await this.readWorkingMemorySnapshot(input);
|
|
83
|
+
if (snapshotEvent) {
|
|
84
|
+
subscriber.next(snapshotEvent);
|
|
85
|
+
}
|
|
86
|
+
const finished = {
|
|
87
|
+
type: import_core.EventType.RUN_FINISHED,
|
|
88
|
+
threadId: input.threadId,
|
|
89
|
+
runId: input.runId
|
|
90
|
+
};
|
|
91
|
+
subscriber.next(finished);
|
|
92
|
+
finishedSent = true;
|
|
93
|
+
subscriber.complete();
|
|
94
|
+
debugLog("run finished", { threadId: input.threadId, runId: input.runId });
|
|
95
|
+
} catch (error) {
|
|
96
|
+
debugLog("run error", {
|
|
97
|
+
threadId: input.threadId,
|
|
98
|
+
runId: input.runId,
|
|
99
|
+
error: error instanceof Error ? error.message : String(error),
|
|
100
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
101
|
+
});
|
|
102
|
+
const runError = {
|
|
103
|
+
type: import_core.EventType.RUN_ERROR,
|
|
104
|
+
message: error instanceof Error ? error.message : "Unknown error"
|
|
105
|
+
};
|
|
106
|
+
subscriber.next(runError);
|
|
107
|
+
const finished = {
|
|
108
|
+
type: import_core.EventType.RUN_FINISHED,
|
|
109
|
+
threadId: input.threadId,
|
|
110
|
+
runId: input.runId
|
|
111
|
+
};
|
|
112
|
+
subscriber.next(finished);
|
|
113
|
+
finishedSent = true;
|
|
114
|
+
subscriber.complete();
|
|
115
|
+
}
|
|
116
|
+
}, "run");
|
|
117
|
+
void run();
|
|
118
|
+
return () => {
|
|
119
|
+
debugLog("run abort/unsubscribe", {
|
|
120
|
+
threadId: input.threadId,
|
|
121
|
+
runId: input.runId,
|
|
122
|
+
finishedSent
|
|
123
|
+
});
|
|
124
|
+
abortController.abort();
|
|
125
|
+
if (!finishedSent) {
|
|
126
|
+
const finished = {
|
|
127
|
+
type: import_core.EventType.RUN_FINISHED,
|
|
128
|
+
threadId: input.threadId,
|
|
129
|
+
runId: input.runId
|
|
130
|
+
};
|
|
131
|
+
subscriber.next(finished);
|
|
132
|
+
finishedSent = true;
|
|
133
|
+
subscriber.complete();
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
return stream$;
|
|
138
|
+
}
|
|
139
|
+
buildStreamOptions(input, abortController) {
|
|
140
|
+
const context = /* @__PURE__ */ new Map();
|
|
141
|
+
const aguiContext = {
|
|
142
|
+
state: input.state || void 0,
|
|
143
|
+
context: input.context,
|
|
144
|
+
forwardedProps: input.forwardedProps
|
|
145
|
+
};
|
|
146
|
+
context.set("agui:context", aguiContext);
|
|
147
|
+
return {
|
|
148
|
+
abortSignal: abortController.signal,
|
|
149
|
+
conversationId: input.threadId,
|
|
150
|
+
userId: this.deriveUserId?.(input),
|
|
151
|
+
context
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
async persistStateToWorkingMemory(input) {
|
|
155
|
+
const state = input.state;
|
|
156
|
+
if (!state || typeof state !== "object" || Object.keys(state).length === 0) {
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const memory = this.agent.getMemory?.();
|
|
160
|
+
if (!memory) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
await memory.updateWorkingMemory({
|
|
165
|
+
conversationId: input.threadId,
|
|
166
|
+
content: (0, import_utils.safeStringify)(state)
|
|
167
|
+
});
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.debug?.("Failed to persist AG-UI state to working memory", error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async readWorkingMemorySnapshot(input) {
|
|
173
|
+
const memory = this.agent.getMemory?.();
|
|
174
|
+
if (!memory) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
const raw = await memory.getWorkingMemory({
|
|
179
|
+
conversationId: input.threadId
|
|
180
|
+
});
|
|
181
|
+
if (!raw) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
let snapshot = raw;
|
|
185
|
+
try {
|
|
186
|
+
snapshot = JSON.parse(raw);
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
type: import_core.EventType.STATE_SNAPSHOT,
|
|
191
|
+
snapshot
|
|
192
|
+
};
|
|
193
|
+
} catch (error) {
|
|
194
|
+
console.debug?.("Failed to read AG-UI working memory snapshot", error);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
var isUserMessage = /* @__PURE__ */ __name((message) => message.role === "user", "isUserMessage");
|
|
200
|
+
var isAssistantMessage = /* @__PURE__ */ __name((message) => message.role === "assistant", "isAssistantMessage");
|
|
201
|
+
var isSystemMessage = /* @__PURE__ */ __name((message) => message.role === "system", "isSystemMessage");
|
|
202
|
+
var isDeveloperMessage = /* @__PURE__ */ __name((message) => message.role === "developer", "isDeveloperMessage");
|
|
203
|
+
var isToolMessage = /* @__PURE__ */ __name((message) => message.role === "tool", "isToolMessage");
|
|
204
|
+
function convertAGUIMessagesToVoltMessages(messages) {
|
|
205
|
+
const toolNameById = /* @__PURE__ */ new Map();
|
|
206
|
+
return messages.map((msg) => {
|
|
207
|
+
const messageId = msg.id || generateId();
|
|
208
|
+
if (isUserMessage(msg)) {
|
|
209
|
+
return {
|
|
210
|
+
id: messageId,
|
|
211
|
+
role: "user",
|
|
212
|
+
content: extractTextContent(msg.content)
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
if (isAssistantMessage(msg)) {
|
|
216
|
+
const parts = [];
|
|
217
|
+
const textContent = msg.content ? extractTextContent(msg.content) : "";
|
|
218
|
+
if (textContent) {
|
|
219
|
+
parts.push({ type: "text", text: textContent });
|
|
220
|
+
}
|
|
221
|
+
for (const call of msg.toolCalls ?? []) {
|
|
222
|
+
const args = safelyParseJson(call.function.arguments);
|
|
223
|
+
toolNameById.set(call.id, call.function.name);
|
|
224
|
+
parts.push({
|
|
225
|
+
type: "tool-call",
|
|
226
|
+
toolCallId: call.id,
|
|
227
|
+
toolName: call.function.name,
|
|
228
|
+
args
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
id: messageId,
|
|
233
|
+
role: "assistant",
|
|
234
|
+
parts
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
if (isSystemMessage(msg) || isDeveloperMessage(msg)) {
|
|
238
|
+
return {
|
|
239
|
+
id: messageId,
|
|
240
|
+
role: "system",
|
|
241
|
+
content: msg.content
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
if (isToolMessage(msg)) {
|
|
245
|
+
const toolName = msg.toolCallId ? toolNameById.get(msg.toolCallId) : void 0;
|
|
246
|
+
return {
|
|
247
|
+
id: messageId,
|
|
248
|
+
role: "tool",
|
|
249
|
+
parts: [
|
|
250
|
+
{
|
|
251
|
+
type: "tool-result",
|
|
252
|
+
toolCallId: msg.toolCallId,
|
|
253
|
+
toolName: toolName ?? "tool",
|
|
254
|
+
output: safelyParseJson(msg.content)
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
id: messageId,
|
|
261
|
+
role: "assistant",
|
|
262
|
+
parts: [{ type: "text", text: (0, import_utils.safeStringify)(msg.content ?? "") }]
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
__name(convertAGUIMessagesToVoltMessages, "convertAGUIMessagesToVoltMessages");
|
|
267
|
+
function extractTextContent(content) {
|
|
268
|
+
if (!content) return "";
|
|
269
|
+
if (typeof content === "string") return content;
|
|
270
|
+
if (!Array.isArray(content)) return "";
|
|
271
|
+
const parts = content;
|
|
272
|
+
return parts.map((part) => {
|
|
273
|
+
const textValue = typeof part.text === "string" ? part.text : "";
|
|
274
|
+
return textValue;
|
|
275
|
+
}).filter((text) => text.length > 0).join("\n");
|
|
276
|
+
}
|
|
277
|
+
__name(extractTextContent, "extractTextContent");
|
|
278
|
+
function safelyParseJson(value) {
|
|
279
|
+
if (typeof value !== "string") return value;
|
|
280
|
+
try {
|
|
281
|
+
return JSON.parse(value);
|
|
282
|
+
} catch {
|
|
283
|
+
return value;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
__name(safelyParseJson, "safelyParseJson");
|
|
287
|
+
function convertVoltStreamPartToEvents(part, fallbackMessageId) {
|
|
288
|
+
const payload = part.payload ?? part;
|
|
289
|
+
switch (part.type) {
|
|
290
|
+
case "text-start": {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
case "text-delta": {
|
|
294
|
+
const event = {
|
|
295
|
+
type: import_core.EventType.TEXT_MESSAGE_CHUNK,
|
|
296
|
+
delta: part.text ?? "",
|
|
297
|
+
messageId: part.id ?? fallbackMessageId,
|
|
298
|
+
role: "assistant"
|
|
299
|
+
};
|
|
300
|
+
return [event];
|
|
301
|
+
}
|
|
302
|
+
case "text-end": {
|
|
303
|
+
return null;
|
|
304
|
+
}
|
|
305
|
+
case "tool-call": {
|
|
306
|
+
const toolCallId = payload.toolCallId ?? generateId();
|
|
307
|
+
const toolName = payload.toolName ?? "tool";
|
|
308
|
+
const rawArgs = payload.args ?? payload.input ?? payload.arguments;
|
|
309
|
+
const argsEvent = {
|
|
310
|
+
type: import_core.EventType.TOOL_CALL_ARGS,
|
|
311
|
+
toolCallId,
|
|
312
|
+
delta: (0, import_utils.safeStringify)(rawArgs ?? {})
|
|
313
|
+
};
|
|
314
|
+
const startEvent = {
|
|
315
|
+
type: import_core.EventType.TOOL_CALL_START,
|
|
316
|
+
toolCallId,
|
|
317
|
+
toolCallName: toolName,
|
|
318
|
+
parentMessageId: fallbackMessageId
|
|
319
|
+
};
|
|
320
|
+
const endEvent = {
|
|
321
|
+
type: import_core.EventType.TOOL_CALL_END,
|
|
322
|
+
toolCallId
|
|
323
|
+
};
|
|
324
|
+
return [startEvent, argsEvent, endEvent];
|
|
325
|
+
}
|
|
326
|
+
case "tool-result": {
|
|
327
|
+
const rawResult = payload.result ?? payload.output ?? payload.data ?? payload;
|
|
328
|
+
const resultEvent = {
|
|
329
|
+
type: import_core.EventType.TOOL_CALL_RESULT,
|
|
330
|
+
toolCallId: payload.toolCallId ?? generateId(),
|
|
331
|
+
content: (0, import_utils.safeStringify)(rawResult ?? {}),
|
|
332
|
+
messageId: generateId(),
|
|
333
|
+
role: "tool"
|
|
334
|
+
};
|
|
335
|
+
return [resultEvent];
|
|
336
|
+
}
|
|
337
|
+
case "error": {
|
|
338
|
+
const errorEvent = {
|
|
339
|
+
type: import_core.EventType.TEXT_MESSAGE_CHUNK,
|
|
340
|
+
delta: `Error: ${payload.error}`,
|
|
341
|
+
messageId: fallbackMessageId,
|
|
342
|
+
role: "assistant"
|
|
343
|
+
};
|
|
344
|
+
return [errorEvent];
|
|
345
|
+
}
|
|
346
|
+
default:
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
__name(convertVoltStreamPartToEvents, "convertVoltStreamPartToEvents");
|
|
351
|
+
function createVoltAgentAGUI(config) {
|
|
352
|
+
return new VoltAgentAGUI(config);
|
|
353
|
+
}
|
|
354
|
+
__name(createVoltAgentAGUI, "createVoltAgentAGUI");
|
|
355
|
+
function generateId() {
|
|
356
|
+
const cryptoApi = typeof globalThis !== "undefined" ? globalThis.crypto : void 0;
|
|
357
|
+
if (cryptoApi && typeof cryptoApi.randomUUID === "function") {
|
|
358
|
+
return cryptoApi.randomUUID();
|
|
359
|
+
}
|
|
360
|
+
const random = /* @__PURE__ */ __name(() => Math.floor(Math.random() * 65535), "random");
|
|
361
|
+
let uuid = "";
|
|
362
|
+
uuid += random().toString(16).padStart(4, "0");
|
|
363
|
+
uuid += random().toString(16).padStart(4, "0");
|
|
364
|
+
uuid += "-";
|
|
365
|
+
uuid += random().toString(16).padStart(4, "0");
|
|
366
|
+
uuid += "-";
|
|
367
|
+
uuid += (random() & 4095 | 16384).toString(16).padStart(4, "0");
|
|
368
|
+
uuid += "-";
|
|
369
|
+
uuid += (random() & 16383 | 32768).toString(16).padStart(4, "0");
|
|
370
|
+
uuid += "-";
|
|
371
|
+
uuid += random().toString(16).padStart(4, "0");
|
|
372
|
+
uuid += random().toString(16).padStart(4, "0");
|
|
373
|
+
uuid += random().toString(16).padStart(4, "0");
|
|
374
|
+
return uuid;
|
|
375
|
+
}
|
|
376
|
+
__name(generateId, "generateId");
|
|
377
|
+
|
|
378
|
+
// src/copilotkit.ts
|
|
379
|
+
var import_client2 = require("@ag-ui/client");
|
|
380
|
+
var import_runtime2 = require("@copilotkit/runtime");
|
|
381
|
+
var import_core2 = require("@voltagent/core");
|
|
382
|
+
function createCopilotKitHandler(options) {
|
|
383
|
+
const endpoint = options.endpoint ?? "/copilotkit";
|
|
384
|
+
const serviceAdapter = options.serviceAdapter ?? new import_runtime2.ExperimentalEmptyAdapter();
|
|
385
|
+
return async (req) => {
|
|
386
|
+
await req.clone().text().catch(() => void 0);
|
|
387
|
+
const agents = await options.loadAgents?.() ?? options.agents ?? (() => {
|
|
388
|
+
throw new Error("No agents provided to CopilotKit handler");
|
|
389
|
+
})();
|
|
390
|
+
const wrappedAgents = {};
|
|
391
|
+
for (const [id, agent] of Object.entries(agents)) {
|
|
392
|
+
wrappedAgents[id] = new class extends import_client2.AbstractAgent {
|
|
393
|
+
run(input) {
|
|
394
|
+
console.log("[CopilotKit] agent.run", {
|
|
395
|
+
agentId: id,
|
|
396
|
+
threadId: input.threadId,
|
|
397
|
+
runId: input.runId
|
|
398
|
+
});
|
|
399
|
+
return agent.run(input);
|
|
400
|
+
}
|
|
401
|
+
// Forward connect if the agent implements it
|
|
402
|
+
connect(input) {
|
|
403
|
+
console.log("[CopilotKit] agent.connect", {
|
|
404
|
+
agentId: id,
|
|
405
|
+
threadId: input.threadId,
|
|
406
|
+
runId: input.runId
|
|
407
|
+
});
|
|
408
|
+
return agent.connect?.(input);
|
|
409
|
+
}
|
|
410
|
+
clone() {
|
|
411
|
+
return this;
|
|
412
|
+
}
|
|
413
|
+
}();
|
|
414
|
+
}
|
|
415
|
+
const runtime = new import_runtime2.CopilotRuntime({ agents: wrappedAgents });
|
|
416
|
+
const { handleRequest } = (0, import_runtime2.copilotRuntimeNextJSAppRouterEndpoint)({
|
|
417
|
+
runtime,
|
|
418
|
+
serviceAdapter,
|
|
419
|
+
endpoint
|
|
420
|
+
});
|
|
421
|
+
let response;
|
|
422
|
+
try {
|
|
423
|
+
response = await handleRequest(req);
|
|
424
|
+
} catch (error) {
|
|
425
|
+
console.error("[CopilotKit] handler failed", {
|
|
426
|
+
error: error instanceof Error ? error.message : String(error),
|
|
427
|
+
stack: error instanceof Error ? error.stack : void 0
|
|
428
|
+
});
|
|
429
|
+
throw error;
|
|
430
|
+
}
|
|
431
|
+
return response;
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
__name(createCopilotKitHandler, "createCopilotKitHandler");
|
|
435
|
+
function registerCopilotKitRoutes(options) {
|
|
436
|
+
const path = options.path ?? "/copilotkit";
|
|
437
|
+
const resolveAgents = /* @__PURE__ */ __name(() => {
|
|
438
|
+
if (options.agents) return options.agents;
|
|
439
|
+
const registry = import_core2.AgentRegistry.getInstance();
|
|
440
|
+
const ids = options.resourceIds;
|
|
441
|
+
if (ids && ids.length > 0) {
|
|
442
|
+
return Object.fromEntries(
|
|
443
|
+
ids.map((id) => {
|
|
444
|
+
const agent = registry.getAgent(id);
|
|
445
|
+
return agent ? [id, agent] : void 0;
|
|
446
|
+
}).filter(Boolean)
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
return Object.fromEntries(registry.getAllAgents().map((agent) => [agent.id, agent]));
|
|
450
|
+
}, "resolveAgents");
|
|
451
|
+
const handler = createCopilotKitHandler({
|
|
452
|
+
loadAgents: /* @__PURE__ */ __name(() => Object.fromEntries(
|
|
453
|
+
Object.entries(resolveAgents()).map(([id, agent]) => [id, createVoltAgentAGUI({ agent })])
|
|
454
|
+
), "loadAgents"),
|
|
455
|
+
endpoint: path
|
|
456
|
+
});
|
|
457
|
+
const routeHandler = /* @__PURE__ */ __name(async (c) => {
|
|
458
|
+
const method = c.req?.method;
|
|
459
|
+
if (method && method !== "POST") {
|
|
460
|
+
return c.json?.({ success: false, error: "Use POST with CopilotKit runtime requests." }, 405);
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
return await handler(c.req?.raw ?? c.request ?? c);
|
|
464
|
+
} catch (error) {
|
|
465
|
+
console.error("[copilotkit] handler error", error);
|
|
466
|
+
return c.json?.(
|
|
467
|
+
{ success: false, error: "CopilotKit handler failed", detail: `${error}` },
|
|
468
|
+
500
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
}, "routeHandler");
|
|
472
|
+
const register = /* @__PURE__ */ __name((p) => {
|
|
473
|
+
if (typeof options.app.post === "function") {
|
|
474
|
+
options.app.post(p, routeHandler);
|
|
475
|
+
} else {
|
|
476
|
+
options.app.all(p, routeHandler);
|
|
477
|
+
}
|
|
478
|
+
}, "register");
|
|
479
|
+
[path, `${path}/*`].forEach(register);
|
|
480
|
+
}
|
|
481
|
+
__name(registerCopilotKitRoutes, "registerCopilotKitRoutes");
|
|
482
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
483
|
+
0 && (module.exports = {
|
|
484
|
+
VoltAgentAGUI,
|
|
485
|
+
createCopilotKitHandler,
|
|
486
|
+
createVoltAgentAGUI,
|
|
487
|
+
registerCopilotKitRoutes
|
|
488
|
+
});
|
|
489
|
+
//# sourceMappingURL=index.js.map
|