@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 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 { Logger, SendMessageInput } from '@cloudbase/agent-shared';
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, logger: _logger, }: ICreateExpressRoutes): expressLib.Express;
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 { type index$3_CreateServerAdapterOptions as CreateServerAdapterOptions, createServerAdapter$1 as createServerAdapter, handler$1 as handler };
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 generateRequestId(prefix = "req") {
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, import_uuid3.v4)()
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
- (_c = logger.warn) == null ? void 0 : _c.call(
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
- (_h = logger.error) == null ? void 0 : _h.call(logger, { err: error }, "Agent creation failed");
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 _a3, _b2, _c2;
286
+ var _a, _b;
352
287
  if (!cleanupCalled) {
353
288
  cleanupCalled = true;
354
289
  try {
355
- (_b2 = (_a3 = createAgentRes.result).cleanup) == null ? void 0 : _b2.call(_a3);
290
+ (_b = (_a = createAgentRes.result).cleanup) == null ? void 0 : _b.call(_a);
356
291
  } catch (e) {
357
- (_c2 = logger.error) == null ? void 0 : _c2.call(logger, { err: e }, "Cleanup error");
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
- (_d2 = logger.error) == null ? void 0 : _d2.call(logger, { err: error }, "Stream error");
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 import_uuid4 = require("uuid");
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, import_uuid4.v4)()
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, import_uuid4.v4)();
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 serverLogger = ((_a = logger.child) == null ? void 0 : _a.call(logger, { component: "server" })) ?? logger;
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, logger, requestId });
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": "0.0.13",
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": "^0.0.13"
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/)