@cloudbase/agent-server 0.0.13 → 1.0.1-alpha.7
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 +5 -74
- package/dist/index.js +21 -123
- package/package.json +2 -2
- package/README.md +0 -253
package/dist/index.d.ts
CHANGED
|
@@ -4,8 +4,7 @@ import expressLib, { Express } from 'express';
|
|
|
4
4
|
import * as _ag_ui_client from '@ag-ui/client';
|
|
5
5
|
import { AbstractAgent, RunAgentInput } from '@ag-ui/client';
|
|
6
6
|
import cors from 'cors';
|
|
7
|
-
import {
|
|
8
|
-
export { LogFn, Logger, createConsoleLogger, noopLogger } from '@cloudbase/agent-shared';
|
|
7
|
+
import { SendMessageInput } from '@cloudbase/agent-shared';
|
|
9
8
|
import { Repeater } from '@repeaterjs/repeater';
|
|
10
9
|
import * as _whatwg_node_server from '@whatwg-node/server';
|
|
11
10
|
import { OpenAI } from 'openai';
|
|
@@ -17,10 +16,6 @@ import { OpenAI } from 'openai';
|
|
|
17
16
|
interface AgentCreatorContext {
|
|
18
17
|
/** The incoming HTTP request (Web Standard Request) */
|
|
19
18
|
request: Request;
|
|
20
|
-
/** Logger instance for this request (with requestId context). Only available when using AGUI routes. */
|
|
21
|
-
logger?: Logger;
|
|
22
|
-
/** Unique request ID for tracing. Only available when using AGUI routes. */
|
|
23
|
-
requestId?: string;
|
|
24
19
|
}
|
|
25
20
|
type AgentCreatorRet = {
|
|
26
21
|
agent: AbstractAgent | {
|
|
@@ -39,20 +34,6 @@ interface ICreateServer {
|
|
|
39
34
|
cors?: boolean | cors.CorsOptions;
|
|
40
35
|
useAGUI?: boolean;
|
|
41
36
|
aguiOptions?: AGUIOptions;
|
|
42
|
-
/**
|
|
43
|
-
* Logger instance for structured logging.
|
|
44
|
-
*
|
|
45
|
-
* @default noopLogger (silent - no output)
|
|
46
|
-
*
|
|
47
|
-
* @example
|
|
48
|
-
* // Development: see all logs
|
|
49
|
-
* createExpressServer({ createAgent, logger: console });
|
|
50
|
-
*
|
|
51
|
-
* // Production: structured JSON logs
|
|
52
|
-
* import pino from 'pino';
|
|
53
|
-
* createExpressServer({ createAgent, logger: pino({ level: 'info' }) });
|
|
54
|
-
*/
|
|
55
|
-
logger?: Logger;
|
|
56
37
|
}
|
|
57
38
|
interface IRun extends ICreateServer {
|
|
58
39
|
port?: number | string;
|
|
@@ -62,7 +43,7 @@ interface ICreateExpressRoutes extends Omit<ICreateServer, "cors"> {
|
|
|
62
43
|
}
|
|
63
44
|
declare function run(props: IRun): void;
|
|
64
45
|
declare function createExpressServer(props: ICreateServer): Express;
|
|
65
|
-
declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions,
|
|
46
|
+
declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, }: ICreateExpressRoutes): expressLib.Express;
|
|
66
47
|
interface AGUIOptions {
|
|
67
48
|
runtimeOptions?: Partial<CopilotRuntimeOptions>;
|
|
68
49
|
endpointOptions?: Partial<CreateCopilotRuntimeServerOptions>;
|
|
@@ -105,21 +86,10 @@ declare function handler$1(input: RunAgentInput, agent: AbstractAgent): Repeater
|
|
|
105
86
|
rawEvent?: any;
|
|
106
87
|
}, any, unknown>;
|
|
107
88
|
|
|
108
|
-
|
|
109
|
-
* Options for createServerAdapter
|
|
110
|
-
*/
|
|
111
|
-
interface CreateServerAdapterOptions {
|
|
112
|
-
/**
|
|
113
|
-
* Logger instance for structured logging.
|
|
114
|
-
* @default noopLogger (silent)
|
|
115
|
-
*/
|
|
116
|
-
logger?: Logger;
|
|
117
|
-
}
|
|
118
|
-
declare function createServerAdapter$1(createAgent: AgentCreator, options?: CreateServerAdapterOptions): _whatwg_node_server.ServerAdapter<{}, _whatwg_node_server.ServerAdapterBaseObject<{}, (request: Request) => Promise<Response>>>;
|
|
89
|
+
declare function createServerAdapter$1(createAgent: AgentCreator): _whatwg_node_server.ServerAdapter<{}, _whatwg_node_server.ServerAdapterBaseObject<{}, (request: Request) => Promise<Response>>>;
|
|
119
90
|
|
|
120
|
-
type index$3_CreateServerAdapterOptions = CreateServerAdapterOptions;
|
|
121
91
|
declare namespace index$3 {
|
|
122
|
-
export {
|
|
92
|
+
export { createServerAdapter$1 as createServerAdapter, handler$1 as handler };
|
|
123
93
|
}
|
|
124
94
|
|
|
125
95
|
declare const serverAdapter: _whatwg_node_server.ServerAdapter<{}, _whatwg_node_server.ServerAdapterBaseObject<{}, () => Response>>;
|
|
@@ -149,43 +119,4 @@ declare namespace index {
|
|
|
149
119
|
export { index$2 as healthz, index$1 as openai, index$4 as sendMessage, index$3 as sendMessageAGUI };
|
|
150
120
|
}
|
|
151
121
|
|
|
152
|
-
|
|
153
|
-
* Generates a unique request ID for tracing.
|
|
154
|
-
*
|
|
155
|
-
* The request ID is used to:
|
|
156
|
-
* 1. Correlate all logs from a single request
|
|
157
|
-
* 2. Include in error responses for debugging
|
|
158
|
-
* 3. Trace requests across distributed systems
|
|
159
|
-
*
|
|
160
|
-
* @param prefix - Optional prefix for the request ID (default: 'req')
|
|
161
|
-
* @returns A unique request ID string
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* generateRequestId() // => 'req-a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
|
165
|
-
* generateRequestId('agui') // => 'agui-a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
|
166
|
-
*/
|
|
167
|
-
declare function generateRequestId(prefix?: string): string;
|
|
168
|
-
/**
|
|
169
|
-
* Extracts request ID from incoming request headers.
|
|
170
|
-
* Supports common request ID header conventions.
|
|
171
|
-
*
|
|
172
|
-
* Header priority (first found wins):
|
|
173
|
-
* 1. x-request-id
|
|
174
|
-
* 2. x-correlation-id
|
|
175
|
-
* 3. x-trace-id
|
|
176
|
-
*
|
|
177
|
-
* @param headers - Request headers (Headers object or plain object)
|
|
178
|
-
* @returns The request ID from headers, or undefined if not found
|
|
179
|
-
*/
|
|
180
|
-
declare function extractRequestId(headers: Headers | Record<string, string | string[] | undefined>): string | undefined;
|
|
181
|
-
/**
|
|
182
|
-
* Gets or generates a request ID.
|
|
183
|
-
* First tries to extract from headers, then generates a new one.
|
|
184
|
-
*
|
|
185
|
-
* @param headers - Request headers
|
|
186
|
-
* @param prefix - Prefix for generated IDs (default: 'req')
|
|
187
|
-
* @returns Request ID (either extracted or generated)
|
|
188
|
-
*/
|
|
189
|
-
declare function getOrGenerateRequestId(headers: Headers | Record<string, string | string[] | undefined>, prefix?: string): string;
|
|
190
|
-
|
|
191
|
-
export { type AgentCreator, type AgentCreatorContext, index as agui, createExpressRoutes, createExpressServer, extractRequestId, generateRequestId, getOrGenerateRequestId, run };
|
|
122
|
+
export { type AgentCreator, type AgentCreatorContext, index as agui, createExpressRoutes, createExpressServer, run };
|
package/dist/index.js
CHANGED
|
@@ -30,13 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
32
|
agui: () => agui_exports,
|
|
33
|
-
createConsoleLogger: () => import_agent_shared2.createConsoleLogger,
|
|
34
33
|
createExpressRoutes: () => createExpressRoutes,
|
|
35
34
|
createExpressServer: () => createExpressServer,
|
|
36
|
-
extractRequestId: () => extractRequestId,
|
|
37
|
-
generateRequestId: () => generateRequestId,
|
|
38
|
-
getOrGenerateRequestId: () => getOrGenerateRequestId,
|
|
39
|
-
noopLogger: () => import_agent_shared2.noopLogger,
|
|
40
35
|
run: () => run
|
|
41
36
|
});
|
|
42
37
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -236,46 +231,9 @@ function handler2(input, agent) {
|
|
|
236
231
|
// src/agui/sendMessageAGUI/server.ts
|
|
237
232
|
var import_server3 = require("@whatwg-node/server");
|
|
238
233
|
var import_client2 = require("@ag-ui/client");
|
|
239
|
-
var import_uuid3 = require("uuid");
|
|
240
|
-
|
|
241
|
-
// src/logger/index.ts
|
|
242
|
-
var import_agent_shared2 = require("@cloudbase/agent-shared");
|
|
243
|
-
|
|
244
|
-
// src/logger/request-id.ts
|
|
245
234
|
var import_uuid2 = require("uuid");
|
|
246
|
-
function
|
|
247
|
-
return `${prefix}-${(0, import_uuid2.v4)()}`;
|
|
248
|
-
}
|
|
249
|
-
function extractRequestId(headers) {
|
|
250
|
-
const headerNames = ["x-request-id", "x-correlation-id", "x-trace-id"];
|
|
251
|
-
for (const name of headerNames) {
|
|
252
|
-
let value;
|
|
253
|
-
if (headers instanceof Headers) {
|
|
254
|
-
value = headers.get(name) || void 0;
|
|
255
|
-
} else {
|
|
256
|
-
const raw = headers[name];
|
|
257
|
-
value = Array.isArray(raw) ? raw[0] : raw;
|
|
258
|
-
}
|
|
259
|
-
if (value) {
|
|
260
|
-
return value;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
return void 0;
|
|
264
|
-
}
|
|
265
|
-
function getOrGenerateRequestId(headers, prefix = "req") {
|
|
266
|
-
return extractRequestId(headers) || generateRequestId(prefix);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// src/agui/sendMessageAGUI/server.ts
|
|
270
|
-
function createServerAdapter2(createAgent, options) {
|
|
271
|
-
var _a;
|
|
272
|
-
const { logger: parentLogger = import_agent_shared2.noopLogger } = options ?? {};
|
|
273
|
-
const adapterLogger = ((_a = parentLogger.child) == null ? void 0 : _a.call(parentLogger, { component: "sendMessageAGUI" })) ?? parentLogger;
|
|
235
|
+
function createServerAdapter2(createAgent) {
|
|
274
236
|
return (0, import_server3.createServerAdapter)(async (request) => {
|
|
275
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
276
|
-
const requestId = getOrGenerateRequestId(request.headers, "agui");
|
|
277
|
-
const logger = ((_a2 = adapterLogger.child) == null ? void 0 : _a2.call(adapterLogger, { requestId })) ?? adapterLogger;
|
|
278
|
-
(_b = logger.info) == null ? void 0 : _b.call(logger, "Request received");
|
|
279
237
|
const inputRes = await safeAsync(async () => {
|
|
280
238
|
const rawInput = await request.json();
|
|
281
239
|
const inputWithDefaults = {
|
|
@@ -284,21 +242,16 @@ function createServerAdapter2(createAgent, options) {
|
|
|
284
242
|
state: {},
|
|
285
243
|
forwardedProps: {},
|
|
286
244
|
...rawInput,
|
|
287
|
-
runId: typeof rawInput.runId === "string" && rawInput.runId ? rawInput.runId : (0,
|
|
245
|
+
runId: typeof rawInput.runId === "string" && rawInput.runId ? rawInput.runId : (0, import_uuid2.v4)()
|
|
288
246
|
};
|
|
289
247
|
return import_client2.RunAgentInputSchema.parse(inputWithDefaults);
|
|
290
248
|
});
|
|
291
249
|
if ("error" in inputRes) {
|
|
292
250
|
const { error } = inputRes;
|
|
293
|
-
(
|
|
294
|
-
logger,
|
|
295
|
-
{ err: error instanceof Error ? error.message : String(error) },
|
|
296
|
-
"Input validation failed"
|
|
297
|
-
);
|
|
251
|
+
console.error("[AGUI Server] Pre-stream error:", error);
|
|
298
252
|
return new Response(
|
|
299
253
|
JSON.stringify({
|
|
300
|
-
error: error instanceof Error ? error.message : String(error)
|
|
301
|
-
requestId
|
|
254
|
+
error: error instanceof Error ? error.message : String(error)
|
|
302
255
|
}),
|
|
303
256
|
{
|
|
304
257
|
status: 400,
|
|
@@ -306,25 +259,8 @@ function createServerAdapter2(createAgent, options) {
|
|
|
306
259
|
}
|
|
307
260
|
);
|
|
308
261
|
}
|
|
309
|
-
const input = inputRes.result;
|
|
310
|
-
const lastUserMessage = input.messages.filter((m) => m.role === "user").pop();
|
|
311
|
-
(_f = logger.debug) == null ? void 0 : _f.call(
|
|
312
|
-
logger,
|
|
313
|
-
{
|
|
314
|
-
runId: input.runId,
|
|
315
|
-
threadId: input.threadId,
|
|
316
|
-
messageCount: input.messages.length,
|
|
317
|
-
toolCount: ((_d = input.tools) == null ? void 0 : _d.length) ?? 0,
|
|
318
|
-
tools: (_e = input.tools) == null ? void 0 : _e.map((t) => t.name),
|
|
319
|
-
lastUserMessage: typeof (lastUserMessage == null ? void 0 : lastUserMessage.content) === "string" ? lastUserMessage.content.slice(0, 200) : void 0
|
|
320
|
-
},
|
|
321
|
-
"Input validated"
|
|
322
|
-
);
|
|
323
|
-
(_g = logger.trace) == null ? void 0 : _g.call(logger, { input }, "Full request input");
|
|
324
262
|
const createAgentRes = await safeAsync(async () => {
|
|
325
|
-
const res = await Promise.resolve(
|
|
326
|
-
createAgent({ request, logger, requestId })
|
|
327
|
-
);
|
|
263
|
+
const res = await Promise.resolve(createAgent({ request }));
|
|
328
264
|
return {
|
|
329
265
|
cleanup: res.cleanup,
|
|
330
266
|
agent: "toAGUIAgent" in res.agent ? res.agent.toAGUIAgent() : res.agent
|
|
@@ -332,11 +268,10 @@ function createServerAdapter2(createAgent, options) {
|
|
|
332
268
|
});
|
|
333
269
|
if ("error" in createAgentRes) {
|
|
334
270
|
const { error } = createAgentRes;
|
|
335
|
-
|
|
271
|
+
console.error("[AGUI Server] Pre-stream error:", error);
|
|
336
272
|
return new Response(
|
|
337
273
|
JSON.stringify({
|
|
338
|
-
error: error instanceof Error ? error.message : String(error)
|
|
339
|
-
requestId
|
|
274
|
+
error: error instanceof Error ? error.message : String(error)
|
|
340
275
|
}),
|
|
341
276
|
{
|
|
342
277
|
status: 500,
|
|
@@ -348,41 +283,31 @@ function createServerAdapter2(createAgent, options) {
|
|
|
348
283
|
let heartbeat;
|
|
349
284
|
let cleanupCalled = false;
|
|
350
285
|
const safeCleanup = () => {
|
|
351
|
-
var
|
|
286
|
+
var _a, _b;
|
|
352
287
|
if (!cleanupCalled) {
|
|
353
288
|
cleanupCalled = true;
|
|
354
289
|
try {
|
|
355
|
-
(
|
|
290
|
+
(_b = (_a = createAgentRes.result).cleanup) == null ? void 0 : _b.call(_a);
|
|
356
291
|
} catch (e) {
|
|
357
|
-
|
|
292
|
+
console.error(e);
|
|
358
293
|
}
|
|
359
294
|
}
|
|
360
295
|
};
|
|
361
296
|
const stream = new ReadableStream({
|
|
362
297
|
async start(controller) {
|
|
363
|
-
var _a3, _b2, _c2, _d2;
|
|
364
298
|
const encoder = new TextEncoder();
|
|
365
299
|
heartbeat = setInterval(() => {
|
|
366
300
|
controller.enqueue(encoder.encode(":ping\n\n"));
|
|
367
301
|
}, 15 * 1e3);
|
|
368
|
-
let eventCount = 0;
|
|
369
302
|
try {
|
|
370
303
|
for await (const event of events) {
|
|
371
|
-
eventCount++;
|
|
372
|
-
(_a3 = logger.debug) == null ? void 0 : _a3.call(
|
|
373
|
-
logger,
|
|
374
|
-
{ eventType: event.type, eventCount },
|
|
375
|
-
"Emitting SSE event"
|
|
376
|
-
);
|
|
377
|
-
(_b2 = logger.trace) == null ? void 0 : _b2.call(logger, { aguiEvent: event }, "SSE event content");
|
|
378
304
|
const sseChunk = `data: ${JSON.stringify(event)}
|
|
379
305
|
|
|
380
306
|
`;
|
|
381
307
|
controller.enqueue(encoder.encode(sseChunk));
|
|
382
308
|
}
|
|
383
|
-
(_c2 = logger.info) == null ? void 0 : _c2.call(logger, { eventCount }, "Request completed");
|
|
384
309
|
} catch (error) {
|
|
385
|
-
|
|
310
|
+
console.error("[AGUI Server] Stream error:", error);
|
|
386
311
|
const errorEvent = {
|
|
387
312
|
type: import_client2.EventType.RUN_ERROR,
|
|
388
313
|
message: error instanceof Error ? error.message : String(error)
|
|
@@ -399,8 +324,6 @@ function createServerAdapter2(createAgent, options) {
|
|
|
399
324
|
}
|
|
400
325
|
},
|
|
401
326
|
cancel() {
|
|
402
|
-
var _a3;
|
|
403
|
-
(_a3 = logger.info) == null ? void 0 : _a3.call(logger, "Request cancelled by client");
|
|
404
327
|
if (heartbeat) clearInterval(heartbeat);
|
|
405
328
|
safeCleanup();
|
|
406
329
|
}
|
|
@@ -439,7 +362,7 @@ __export(openai_exports, {
|
|
|
439
362
|
});
|
|
440
363
|
|
|
441
364
|
// src/agui/openai/handler.ts
|
|
442
|
-
var
|
|
365
|
+
var import_uuid3 = require("uuid");
|
|
443
366
|
var import_repeater3 = require("@repeaterjs/repeater");
|
|
444
367
|
function handler3(input, agent) {
|
|
445
368
|
var _a;
|
|
@@ -451,12 +374,12 @@ function handler3(input, agent) {
|
|
|
451
374
|
description: tool.function.description,
|
|
452
375
|
parameters: tool.function.parameters
|
|
453
376
|
})),
|
|
454
|
-
conversationId: (0,
|
|
377
|
+
conversationId: (0, import_uuid3.v4)()
|
|
455
378
|
},
|
|
456
379
|
agent
|
|
457
380
|
);
|
|
458
381
|
return new import_repeater3.Repeater(async (push, stop) => {
|
|
459
|
-
const id = (0,
|
|
382
|
+
const id = (0, import_uuid3.v4)();
|
|
460
383
|
let tools = [];
|
|
461
384
|
let lastWithToolCall = false;
|
|
462
385
|
let maxIndex = 0;
|
|
@@ -653,22 +576,16 @@ function createExpressRoutes({
|
|
|
653
576
|
basePath: _basePath,
|
|
654
577
|
express,
|
|
655
578
|
useAGUI: _useAGUI,
|
|
656
|
-
aguiOptions
|
|
657
|
-
logger: _logger
|
|
579
|
+
aguiOptions
|
|
658
580
|
}) {
|
|
659
|
-
var _a, _b, _c;
|
|
660
581
|
const useAGUI = _useAGUI ?? true;
|
|
661
|
-
const logger = _logger ?? import_agent_shared2.noopLogger;
|
|
662
582
|
const basePath = _basePath ?? (process.env.TENCENTCLOUD_RUNENV === "SCF" ? "/v1/aibot/bots/:agentId/" : "/");
|
|
663
|
-
const
|
|
664
|
-
(_b = serverLogger.debug) == null ? void 0 : _b.call(serverLogger, { basePath, useAGUI }, "Initializing server routes");
|
|
665
|
-
const sendMessageServerAdapter = useAGUI ? sendMessageAGUI_exports.createServerAdapter(createAgent, { logger: serverLogger }) : sendMessage_exports.createServerAdapter(createAgent);
|
|
583
|
+
const sendMessageServerAdapter = useAGUI ? sendMessageAGUI_exports.createServerAdapter(createAgent) : sendMessage_exports.createServerAdapter(createAgent);
|
|
666
584
|
if (useAGUI) {
|
|
667
585
|
createAGUIRoute({
|
|
668
586
|
basePath,
|
|
669
587
|
express,
|
|
670
588
|
createAgent,
|
|
671
|
-
logger: serverLogger,
|
|
672
589
|
...aguiOptions || {}
|
|
673
590
|
});
|
|
674
591
|
}
|
|
@@ -677,7 +594,6 @@ function createExpressRoutes({
|
|
|
677
594
|
express.use(`${basePath}send-message`, sendMessageServerAdapter);
|
|
678
595
|
express.use(`${basePath}healthz`, healthzServerAdapter);
|
|
679
596
|
express.use(`${basePath}chat/completions`, openaiServerAdapter);
|
|
680
|
-
(_c = serverLogger.info) == null ? void 0 : _c.call(serverLogger, { basePath }, "Server routes initialized");
|
|
681
597
|
return express;
|
|
682
598
|
}
|
|
683
599
|
var AGUIRpcHandlerPromise = null;
|
|
@@ -686,13 +602,11 @@ function getAGUIRpcHandler({
|
|
|
686
602
|
runtimeOptions,
|
|
687
603
|
basePath,
|
|
688
604
|
endpointOptions,
|
|
689
|
-
request
|
|
690
|
-
logger,
|
|
691
|
-
requestId
|
|
605
|
+
request
|
|
692
606
|
}) {
|
|
693
607
|
if (AGUIRpcHandlerPromise) return AGUIRpcHandlerPromise;
|
|
694
608
|
AGUIRpcHandlerPromise = (async () => {
|
|
695
|
-
const { agent } = await createAgent({ request
|
|
609
|
+
const { agent } = await createAgent({ request });
|
|
696
610
|
const templateAgent = "toAGUIAgent" in agent ? agent.toAGUIAgent() : agent;
|
|
697
611
|
templateAgent.clone = agentCloneFn;
|
|
698
612
|
const runtime = new import_runtime.CopilotRuntime({
|
|
@@ -715,21 +629,12 @@ function createAGUIRoute({
|
|
|
715
629
|
basePath,
|
|
716
630
|
createAgent,
|
|
717
631
|
runtimeOptions,
|
|
718
|
-
endpointOptions
|
|
719
|
-
logger
|
|
632
|
+
endpointOptions
|
|
720
633
|
}) {
|
|
721
|
-
var _a;
|
|
722
|
-
const routeLogger = ((_a = logger.child) == null ? void 0 : _a.call(logger, { component: "agui-route" })) ?? logger;
|
|
723
634
|
express.post(`${basePath}agui`, import_express.default.json(), async (req, res) => {
|
|
724
|
-
var _a2, _b;
|
|
725
635
|
const webRequest = (0, import_server8.normalizeNodeRequest)(req, DefaultFetchAPI);
|
|
726
|
-
const requestId = getOrGenerateRequestId(webRequest.headers, "agui");
|
|
727
|
-
const requestLogger = ((_a2 = routeLogger.child) == null ? void 0 : _a2.call(routeLogger, { requestId })) ?? routeLogger;
|
|
728
|
-
(_b = requestLogger.info) == null ? void 0 : _b.call(requestLogger, { path: `${basePath}agui` }, "Request received");
|
|
729
636
|
const { agent: rawAgent, cleanup } = await createAgent({
|
|
730
|
-
request: webRequest
|
|
731
|
-
logger: requestLogger,
|
|
732
|
-
requestId
|
|
637
|
+
request: webRequest
|
|
733
638
|
});
|
|
734
639
|
const preparedAgent = "toAGUIAgent" in rawAgent ? rawAgent.toAGUIAgent() : rawAgent;
|
|
735
640
|
preparedAgent.clone = agentCloneFn;
|
|
@@ -738,9 +643,7 @@ function createAGUIRoute({
|
|
|
738
643
|
basePath,
|
|
739
644
|
runtimeOptions,
|
|
740
645
|
endpointOptions,
|
|
741
|
-
request: webRequest
|
|
742
|
-
logger: requestLogger,
|
|
743
|
-
requestId
|
|
646
|
+
request: webRequest
|
|
744
647
|
});
|
|
745
648
|
preparedAgentStorage.run(preparedAgent, () => {
|
|
746
649
|
rpcHandler(req, res);
|
|
@@ -756,12 +659,7 @@ function isCorsOptions(cors2) {
|
|
|
756
659
|
// Annotate the CommonJS export names for ESM import in node:
|
|
757
660
|
0 && (module.exports = {
|
|
758
661
|
agui,
|
|
759
|
-
createConsoleLogger,
|
|
760
662
|
createExpressRoutes,
|
|
761
663
|
createExpressServer,
|
|
762
|
-
extractRequestId,
|
|
763
|
-
generateRequestId,
|
|
764
|
-
getOrGenerateRequestId,
|
|
765
|
-
noopLogger,
|
|
766
664
|
run
|
|
767
665
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/agent-server",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1-alpha.7",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"openai": "6.3.0",
|
|
22
22
|
"uuid": "^10.0.0",
|
|
23
23
|
"zod": "^4.1.12",
|
|
24
|
-
"@cloudbase/agent-shared": "^
|
|
24
|
+
"@cloudbase/agent-shared": "^1.0.1-alpha.7"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/cors": "^2.8.19",
|
package/README.md
DELETED
|
@@ -1,253 +0,0 @@
|
|
|
1
|
-
# @cloudbase/agent-server
|
|
2
|
-
|
|
3
|
-
将 AG-UI 兼容的 Agent 部署为 HTTP 服务。
|
|
4
|
-
|
|
5
|
-
## 什么是 AG-UI?
|
|
6
|
-
|
|
7
|
-
[AG-UI](https://ag-ui.com/) 是一个开放、轻量级、基于事件的协议,用于标准化 AI Agent 与用户界面的交互。它让 Agent 可以:
|
|
8
|
-
|
|
9
|
-
- 实时流式对话
|
|
10
|
-
- 双向状态同步
|
|
11
|
-
- 前端工具集成(Client Tools)
|
|
12
|
-
- 人机协作(Human-in-the-loop)
|
|
13
|
-
|
|
14
|
-
## 这个包解决什么问题?
|
|
15
|
-
|
|
16
|
-
- **快速部署 Agent 为 HTTP 服务**:一行代码将 Agent 部署为支持 AG-UI 协议的 HTTP 服务
|
|
17
|
-
- **多端点支持**:自动创建 `/send-message`、`/healthz` 等端点
|
|
18
|
-
- **云函数兼容**:自动适配腾讯云开发 HTTP 云函数环境
|
|
19
|
-
|
|
20
|
-
### 架构图
|
|
21
|
-
|
|
22
|
-
```mermaid
|
|
23
|
-
flowchart LR
|
|
24
|
-
Client[AG-UI 客户端] -->|AG-UI 协议| Server["@cloudbase/agent-server"]
|
|
25
|
-
Server --> Adapter[Adapter<br/>LangGraph / LangChain]
|
|
26
|
-
Adapter --> Agent[Agent 框架]
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## 配合使用
|
|
30
|
-
|
|
31
|
-
| 包名 | 作用 |
|
|
32
|
-
|------|------|
|
|
33
|
-
| `@cloudbase/agent-adapter-langgraph` | LangGraph 工作流适配器 |
|
|
34
|
-
| `@cloudbase/agent-adapter-langchain` | LangChain Agent 适配器 |
|
|
35
|
-
| `express` | HTTP 服务框架 |
|
|
36
|
-
|
|
37
|
-
## 安装
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
pnpm add @cloudbase/agent-server express
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## 快速开始
|
|
44
|
-
|
|
45
|
-
### 方式一:使用 run(最简单)
|
|
46
|
-
|
|
47
|
-
```typescript
|
|
48
|
-
import { run } from "@cloudbase/agent-server";
|
|
49
|
-
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
|
|
50
|
-
import { workflow } from "./workflow.js"; // 你的 LangGraph 工作流
|
|
51
|
-
|
|
52
|
-
run({
|
|
53
|
-
createAgent: () => ({
|
|
54
|
-
agent: new LanggraphAgent({ workflow }),
|
|
55
|
-
}),
|
|
56
|
-
port: 9000,
|
|
57
|
-
});
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 方式二:使用 createExpressServer
|
|
61
|
-
|
|
62
|
-
创建一个配置好的 Express 应用:
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
import { createExpressServer } from "@cloudbase/agent-server";
|
|
66
|
-
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
|
|
67
|
-
import { workflow } from "./workflow.js";
|
|
68
|
-
|
|
69
|
-
const app = createExpressServer({
|
|
70
|
-
createAgent: () => ({
|
|
71
|
-
agent: new LanggraphAgent({ workflow }),
|
|
72
|
-
}),
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
app.listen(9000, () => console.log("Listening on 9000!"));
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### 方式三:使用 createExpressRoutes
|
|
79
|
-
|
|
80
|
-
将路由挂载到现有的 Express 应用:
|
|
81
|
-
|
|
82
|
-
```typescript
|
|
83
|
-
import { createExpressRoutes } from "@cloudbase/agent-server";
|
|
84
|
-
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
|
|
85
|
-
import { workflow } from "./workflow.js";
|
|
86
|
-
import express from "express";
|
|
87
|
-
|
|
88
|
-
const app = express();
|
|
89
|
-
|
|
90
|
-
createExpressRoutes({
|
|
91
|
-
createAgent: () => ({
|
|
92
|
-
agent: new LanggraphAgent({ workflow }),
|
|
93
|
-
}),
|
|
94
|
-
express: app,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
app.listen(9000, () => console.log("Listening on 9000!"));
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## API 参考
|
|
101
|
-
|
|
102
|
-
### run
|
|
103
|
-
|
|
104
|
-
创建并启动 HTTP 服务。
|
|
105
|
-
|
|
106
|
-
```typescript
|
|
107
|
-
run({
|
|
108
|
-
createAgent,
|
|
109
|
-
port: 9000,
|
|
110
|
-
});
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**参数:**
|
|
114
|
-
|
|
115
|
-
| 参数 | 类型 | 说明 |
|
|
116
|
-
|------|------|------|
|
|
117
|
-
| `createAgent` | `AgentCreator` | Agent 创建函数,见下方说明 |
|
|
118
|
-
| `port` | `number \| string` | 监听端口 |
|
|
119
|
-
| `basePath` | `string` | 可选,路由基础路径,默认为 `/`,云函数环境默认为 `/v1/aibot/bots/:agentId/` |
|
|
120
|
-
| `cors` | `boolean \| CorsOptions` | 可选,CORS 配置,默认启用 |
|
|
121
|
-
| `logger` | `Logger` | 可选,日志实例,用于记录服务端日志 |
|
|
122
|
-
|
|
123
|
-
### createExpressServer
|
|
124
|
-
|
|
125
|
-
创建一个配置好的 Express 应用。
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
const app = createExpressServer({
|
|
129
|
-
createAgent,
|
|
130
|
-
cors: true, // 可选,默认启用 CORS
|
|
131
|
-
});
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**参数:**
|
|
135
|
-
|
|
136
|
-
| 参数 | 类型 | 说明 |
|
|
137
|
-
|------|------|------|
|
|
138
|
-
| `createAgent` | `AgentCreator` | Agent 创建函数,见下方说明 |
|
|
139
|
-
| `basePath` | `string` | 可选,路由基础路径 |
|
|
140
|
-
| `cors` | `boolean \| CorsOptions` | 可选,CORS 配置,默认启用 |
|
|
141
|
-
| `logger` | `Logger` | 可选,日志实例,用于记录服务端日志 |
|
|
142
|
-
|
|
143
|
-
### createExpressRoutes
|
|
144
|
-
|
|
145
|
-
将 AG-UI 路由挂载到现有的 Express 应用。
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
createExpressRoutes({
|
|
149
|
-
createAgent,
|
|
150
|
-
express: app,
|
|
151
|
-
basePath, // 可选
|
|
152
|
-
});
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
**参数:**
|
|
156
|
-
|
|
157
|
-
| 参数 | 类型 | 说明 |
|
|
158
|
-
|------|------|------|
|
|
159
|
-
| `createAgent` | `AgentCreator` | Agent 创建函数,见下方说明 |
|
|
160
|
-
| `express` | `Express` | Express 应用实例 |
|
|
161
|
-
| `basePath` | `string` | 可选,路由基础路径,默认为 `/`,云函数环境默认为 `/v1/aibot/bots/:agentId/` |
|
|
162
|
-
| `logger` | `Logger` | 可选,日志实例,用于记录服务端日志 |
|
|
163
|
-
|
|
164
|
-
## 自动创建的端点
|
|
165
|
-
|
|
166
|
-
| 端点 | 说明 |
|
|
167
|
-
|------|------|
|
|
168
|
-
| `{basePath}send-message` | AG-UI 消息发送端点 |
|
|
169
|
-
| `{basePath}healthz` | 健康检查端点 |
|
|
170
|
-
|
|
171
|
-
## createAgent 参数
|
|
172
|
-
|
|
173
|
-
`createAgent` 返回一个对象:
|
|
174
|
-
- `agent`:符合 [AG-UI 协议](https://docs.ag-ui.com) 的 Agent
|
|
175
|
-
- `cleanup`:可选,请求结束后的清理函数
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
type AgentCreator = (context?: {
|
|
179
|
-
request: Request; // 当前 HTTP 请求(Web Standard Request)
|
|
180
|
-
logger?: Logger; // 日志实例(带 requestId 上下文)
|
|
181
|
-
requestId?: string; // 请求追踪 ID
|
|
182
|
-
}) => AgentCreatorResult | Promise<AgentCreatorResult>; // 支持异步
|
|
183
|
-
|
|
184
|
-
type AgentCreatorResult = {
|
|
185
|
-
agent: AbstractAgent | { toAGUIAgent(): AbstractAgent }; // AG-UI 兼容的 Agent
|
|
186
|
-
cleanup?: () => void; // 可选,清理函数
|
|
187
|
-
};
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
使用适配器将你的 Agent 框架转换为 AG-UI 兼容的 Agent:
|
|
191
|
-
|
|
192
|
-
| 适配器 | 包名 | 说明 |
|
|
193
|
-
|--------|------|------|
|
|
194
|
-
| `LanggraphAgent` | `@cloudbase/agent-adapter-langgraph` | LangGraph 工作流适配器 |
|
|
195
|
-
| `LangchainAgent` | `@cloudbase/agent-adapter-langchain` | LangChain Agent 适配器 |
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
import { LanggraphAgent } from "@cloudbase/agent-adapter-langgraph";
|
|
199
|
-
|
|
200
|
-
createAgent: () => ({
|
|
201
|
-
agent: new LanggraphAgent({ workflow }),
|
|
202
|
-
})
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
**高级用法:** `createAgent` 可以接收请求上下文,也支持异步:
|
|
206
|
-
|
|
207
|
-
```typescript
|
|
208
|
-
createAgent: async (context) => {
|
|
209
|
-
console.log("Request ID:", context.requestId);
|
|
210
|
-
return { agent: new LanggraphAgent({ workflow }) };
|
|
211
|
-
}
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## Logger
|
|
215
|
-
|
|
216
|
-
`logger` 参数用于记录服务端日志。需要实现以下接口:
|
|
217
|
-
|
|
218
|
-
```typescript
|
|
219
|
-
interface Logger {
|
|
220
|
-
info?(message: string): void;
|
|
221
|
-
info?(obj: object, message?: string): void;
|
|
222
|
-
debug?(message: string): void;
|
|
223
|
-
debug?(obj: object, message?: string): void;
|
|
224
|
-
warn?(message: string): void;
|
|
225
|
-
warn?(obj: object, message?: string): void;
|
|
226
|
-
error?(message: string): void;
|
|
227
|
-
error?(obj: object, message?: string): void;
|
|
228
|
-
trace?(message: string): void;
|
|
229
|
-
trace?(obj: object, message?: string): void;
|
|
230
|
-
child?(bindings: object): Logger; // 创建带上下文的子 logger
|
|
231
|
-
}
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
**示例:**
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
// 开发环境:使用 console
|
|
238
|
-
run({ createAgent, logger: console, port: 9000 });
|
|
239
|
-
|
|
240
|
-
// 生产环境:使用 pino
|
|
241
|
-
import pino from "pino";
|
|
242
|
-
run({ createAgent, logger: pino({ level: "info" }), port: 9000 });
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## 文档
|
|
246
|
-
|
|
247
|
-
📚 完整文档请参阅 [云开发 Agent 开发指南](https://docs.cloudbase.net/ai/agent-development/)
|
|
248
|
-
|
|
249
|
-
## 相关资源
|
|
250
|
-
|
|
251
|
-
- [AG-UI 协议](https://docs.cloudbase.net/ai/agent-development/ag-ui-protocol)
|
|
252
|
-
- [框架开发指南](https://docs.cloudbase.net/ai/agent-development/frameworks/)
|
|
253
|
-
- [部署指南](https://docs.cloudbase.net/ai/agent-development/deploy/)
|