@cloudbase/agent-server 1.0.1-alpha.7 → 1.0.1-alpha.8

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/README.md ADDED
@@ -0,0 +1,253 @@
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/)
package/dist/index.d.ts CHANGED
@@ -4,7 +4,8 @@ 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 { SendMessageInput } from '@cloudbase/agent-shared';
7
+ import { Logger, SendMessageInput } from '@cloudbase/agent-shared';
8
+ export { LogFn, Logger, createConsoleLogger, noopLogger } from '@cloudbase/agent-shared';
8
9
  import { Repeater } from '@repeaterjs/repeater';
9
10
  import * as _whatwg_node_server from '@whatwg-node/server';
10
11
  import { OpenAI } from 'openai';
@@ -16,6 +17,10 @@ import { OpenAI } from 'openai';
16
17
  interface AgentCreatorContext {
17
18
  /** The incoming HTTP request (Web Standard Request) */
18
19
  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;
19
24
  }
20
25
  type AgentCreatorRet = {
21
26
  agent: AbstractAgent | {
@@ -34,6 +39,20 @@ interface ICreateServer {
34
39
  cors?: boolean | cors.CorsOptions;
35
40
  useAGUI?: boolean;
36
41
  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;
37
56
  }
38
57
  interface IRun extends ICreateServer {
39
58
  port?: number | string;
@@ -43,7 +62,7 @@ interface ICreateExpressRoutes extends Omit<ICreateServer, "cors"> {
43
62
  }
44
63
  declare function run(props: IRun): void;
45
64
  declare function createExpressServer(props: ICreateServer): Express;
46
- declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, }: ICreateExpressRoutes): expressLib.Express;
65
+ declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, logger: _logger, }: ICreateExpressRoutes): expressLib.Express;
47
66
  interface AGUIOptions {
48
67
  runtimeOptions?: Partial<CopilotRuntimeOptions>;
49
68
  endpointOptions?: Partial<CreateCopilotRuntimeServerOptions>;
@@ -86,10 +105,21 @@ declare function handler$1(input: RunAgentInput, agent: AbstractAgent): Repeater
86
105
  rawEvent?: any;
87
106
  }, any, unknown>;
88
107
 
89
- declare function createServerAdapter$1(createAgent: AgentCreator): _whatwg_node_server.ServerAdapter<{}, _whatwg_node_server.ServerAdapterBaseObject<{}, (request: Request) => Promise<Response>>>;
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>>>;
90
119
 
120
+ type index$3_CreateServerAdapterOptions = CreateServerAdapterOptions;
91
121
  declare namespace index$3 {
92
- export { createServerAdapter$1 as createServerAdapter, handler$1 as handler };
122
+ export { type index$3_CreateServerAdapterOptions as CreateServerAdapterOptions, createServerAdapter$1 as createServerAdapter, handler$1 as handler };
93
123
  }
94
124
 
95
125
  declare const serverAdapter: _whatwg_node_server.ServerAdapter<{}, _whatwg_node_server.ServerAdapterBaseObject<{}, () => Response>>;
@@ -119,4 +149,43 @@ declare namespace index {
119
149
  export { index$2 as healthz, index$1 as openai, index$4 as sendMessage, index$3 as sendMessageAGUI };
120
150
  }
121
151
 
122
- export { type AgentCreator, type AgentCreatorContext, index as agui, createExpressRoutes, createExpressServer, run };
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 };
package/dist/index.js CHANGED
@@ -30,8 +30,13 @@ 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,
33
34
  createExpressRoutes: () => createExpressRoutes,
34
35
  createExpressServer: () => createExpressServer,
36
+ extractRequestId: () => extractRequestId,
37
+ generateRequestId: () => generateRequestId,
38
+ getOrGenerateRequestId: () => getOrGenerateRequestId,
39
+ noopLogger: () => import_agent_shared2.noopLogger,
35
40
  run: () => run
36
41
  });
37
42
  module.exports = __toCommonJS(index_exports);
@@ -231,9 +236,46 @@ function handler2(input, agent) {
231
236
  // src/agui/sendMessageAGUI/server.ts
232
237
  var import_server3 = require("@whatwg-node/server");
233
238
  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
234
245
  var import_uuid2 = require("uuid");
235
- function createServerAdapter2(createAgent) {
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;
236
274
  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");
237
279
  const inputRes = await safeAsync(async () => {
238
280
  const rawInput = await request.json();
239
281
  const inputWithDefaults = {
@@ -242,16 +284,21 @@ function createServerAdapter2(createAgent) {
242
284
  state: {},
243
285
  forwardedProps: {},
244
286
  ...rawInput,
245
- runId: typeof rawInput.runId === "string" && rawInput.runId ? rawInput.runId : (0, import_uuid2.v4)()
287
+ runId: typeof rawInput.runId === "string" && rawInput.runId ? rawInput.runId : (0, import_uuid3.v4)()
246
288
  };
247
289
  return import_client2.RunAgentInputSchema.parse(inputWithDefaults);
248
290
  });
249
291
  if ("error" in inputRes) {
250
292
  const { error } = inputRes;
251
- console.error("[AGUI Server] Pre-stream error:", error);
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
+ );
252
298
  return new Response(
253
299
  JSON.stringify({
254
- error: error instanceof Error ? error.message : String(error)
300
+ error: error instanceof Error ? error.message : String(error),
301
+ requestId
255
302
  }),
256
303
  {
257
304
  status: 400,
@@ -259,8 +306,25 @@ function createServerAdapter2(createAgent) {
259
306
  }
260
307
  );
261
308
  }
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");
262
324
  const createAgentRes = await safeAsync(async () => {
263
- const res = await Promise.resolve(createAgent({ request }));
325
+ const res = await Promise.resolve(
326
+ createAgent({ request, logger, requestId })
327
+ );
264
328
  return {
265
329
  cleanup: res.cleanup,
266
330
  agent: "toAGUIAgent" in res.agent ? res.agent.toAGUIAgent() : res.agent
@@ -268,10 +332,11 @@ function createServerAdapter2(createAgent) {
268
332
  });
269
333
  if ("error" in createAgentRes) {
270
334
  const { error } = createAgentRes;
271
- console.error("[AGUI Server] Pre-stream error:", error);
335
+ (_h = logger.error) == null ? void 0 : _h.call(logger, { err: error }, "Agent creation failed");
272
336
  return new Response(
273
337
  JSON.stringify({
274
- error: error instanceof Error ? error.message : String(error)
338
+ error: error instanceof Error ? error.message : String(error),
339
+ requestId
275
340
  }),
276
341
  {
277
342
  status: 500,
@@ -283,31 +348,41 @@ function createServerAdapter2(createAgent) {
283
348
  let heartbeat;
284
349
  let cleanupCalled = false;
285
350
  const safeCleanup = () => {
286
- var _a, _b;
351
+ var _a3, _b2, _c2;
287
352
  if (!cleanupCalled) {
288
353
  cleanupCalled = true;
289
354
  try {
290
- (_b = (_a = createAgentRes.result).cleanup) == null ? void 0 : _b.call(_a);
355
+ (_b2 = (_a3 = createAgentRes.result).cleanup) == null ? void 0 : _b2.call(_a3);
291
356
  } catch (e) {
292
- console.error(e);
357
+ (_c2 = logger.error) == null ? void 0 : _c2.call(logger, { err: e }, "Cleanup error");
293
358
  }
294
359
  }
295
360
  };
296
361
  const stream = new ReadableStream({
297
362
  async start(controller) {
363
+ var _a3, _b2, _c2, _d2;
298
364
  const encoder = new TextEncoder();
299
365
  heartbeat = setInterval(() => {
300
366
  controller.enqueue(encoder.encode(":ping\n\n"));
301
367
  }, 15 * 1e3);
368
+ let eventCount = 0;
302
369
  try {
303
370
  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");
304
378
  const sseChunk = `data: ${JSON.stringify(event)}
305
379
 
306
380
  `;
307
381
  controller.enqueue(encoder.encode(sseChunk));
308
382
  }
383
+ (_c2 = logger.info) == null ? void 0 : _c2.call(logger, { eventCount }, "Request completed");
309
384
  } catch (error) {
310
- console.error("[AGUI Server] Stream error:", error);
385
+ (_d2 = logger.error) == null ? void 0 : _d2.call(logger, { err: error }, "Stream error");
311
386
  const errorEvent = {
312
387
  type: import_client2.EventType.RUN_ERROR,
313
388
  message: error instanceof Error ? error.message : String(error)
@@ -324,6 +399,8 @@ function createServerAdapter2(createAgent) {
324
399
  }
325
400
  },
326
401
  cancel() {
402
+ var _a3;
403
+ (_a3 = logger.info) == null ? void 0 : _a3.call(logger, "Request cancelled by client");
327
404
  if (heartbeat) clearInterval(heartbeat);
328
405
  safeCleanup();
329
406
  }
@@ -362,7 +439,7 @@ __export(openai_exports, {
362
439
  });
363
440
 
364
441
  // src/agui/openai/handler.ts
365
- var import_uuid3 = require("uuid");
442
+ var import_uuid4 = require("uuid");
366
443
  var import_repeater3 = require("@repeaterjs/repeater");
367
444
  function handler3(input, agent) {
368
445
  var _a;
@@ -374,12 +451,12 @@ function handler3(input, agent) {
374
451
  description: tool.function.description,
375
452
  parameters: tool.function.parameters
376
453
  })),
377
- conversationId: (0, import_uuid3.v4)()
454
+ conversationId: (0, import_uuid4.v4)()
378
455
  },
379
456
  agent
380
457
  );
381
458
  return new import_repeater3.Repeater(async (push, stop) => {
382
- const id = (0, import_uuid3.v4)();
459
+ const id = (0, import_uuid4.v4)();
383
460
  let tools = [];
384
461
  let lastWithToolCall = false;
385
462
  let maxIndex = 0;
@@ -576,16 +653,22 @@ function createExpressRoutes({
576
653
  basePath: _basePath,
577
654
  express,
578
655
  useAGUI: _useAGUI,
579
- aguiOptions
656
+ aguiOptions,
657
+ logger: _logger
580
658
  }) {
659
+ var _a, _b, _c;
581
660
  const useAGUI = _useAGUI ?? true;
661
+ const logger = _logger ?? import_agent_shared2.noopLogger;
582
662
  const basePath = _basePath ?? (process.env.TENCENTCLOUD_RUNENV === "SCF" ? "/v1/aibot/bots/:agentId/" : "/");
583
- const sendMessageServerAdapter = useAGUI ? sendMessageAGUI_exports.createServerAdapter(createAgent) : sendMessage_exports.createServerAdapter(createAgent);
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);
584
666
  if (useAGUI) {
585
667
  createAGUIRoute({
586
668
  basePath,
587
669
  express,
588
670
  createAgent,
671
+ logger: serverLogger,
589
672
  ...aguiOptions || {}
590
673
  });
591
674
  }
@@ -594,6 +677,7 @@ function createExpressRoutes({
594
677
  express.use(`${basePath}send-message`, sendMessageServerAdapter);
595
678
  express.use(`${basePath}healthz`, healthzServerAdapter);
596
679
  express.use(`${basePath}chat/completions`, openaiServerAdapter);
680
+ (_c = serverLogger.info) == null ? void 0 : _c.call(serverLogger, { basePath }, "Server routes initialized");
597
681
  return express;
598
682
  }
599
683
  var AGUIRpcHandlerPromise = null;
@@ -602,11 +686,13 @@ function getAGUIRpcHandler({
602
686
  runtimeOptions,
603
687
  basePath,
604
688
  endpointOptions,
605
- request
689
+ request,
690
+ logger,
691
+ requestId
606
692
  }) {
607
693
  if (AGUIRpcHandlerPromise) return AGUIRpcHandlerPromise;
608
694
  AGUIRpcHandlerPromise = (async () => {
609
- const { agent } = await createAgent({ request });
695
+ const { agent } = await createAgent({ request, logger, requestId });
610
696
  const templateAgent = "toAGUIAgent" in agent ? agent.toAGUIAgent() : agent;
611
697
  templateAgent.clone = agentCloneFn;
612
698
  const runtime = new import_runtime.CopilotRuntime({
@@ -629,12 +715,21 @@ function createAGUIRoute({
629
715
  basePath,
630
716
  createAgent,
631
717
  runtimeOptions,
632
- endpointOptions
718
+ endpointOptions,
719
+ logger
633
720
  }) {
721
+ var _a;
722
+ const routeLogger = ((_a = logger.child) == null ? void 0 : _a.call(logger, { component: "agui-route" })) ?? logger;
634
723
  express.post(`${basePath}agui`, import_express.default.json(), async (req, res) => {
724
+ var _a2, _b;
635
725
  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");
636
729
  const { agent: rawAgent, cleanup } = await createAgent({
637
- request: webRequest
730
+ request: webRequest,
731
+ logger: requestLogger,
732
+ requestId
638
733
  });
639
734
  const preparedAgent = "toAGUIAgent" in rawAgent ? rawAgent.toAGUIAgent() : rawAgent;
640
735
  preparedAgent.clone = agentCloneFn;
@@ -643,7 +738,9 @@ function createAGUIRoute({
643
738
  basePath,
644
739
  runtimeOptions,
645
740
  endpointOptions,
646
- request: webRequest
741
+ request: webRequest,
742
+ logger: requestLogger,
743
+ requestId
647
744
  });
648
745
  preparedAgentStorage.run(preparedAgent, () => {
649
746
  rpcHandler(req, res);
@@ -659,7 +756,12 @@ function isCorsOptions(cors2) {
659
756
  // Annotate the CommonJS export names for ESM import in node:
660
757
  0 && (module.exports = {
661
758
  agui,
759
+ createConsoleLogger,
662
760
  createExpressRoutes,
663
761
  createExpressServer,
762
+ extractRequestId,
763
+ generateRequestId,
764
+ getOrGenerateRequestId,
765
+ noopLogger,
664
766
  run
665
767
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/agent-server",
3
- "version": "1.0.1-alpha.7",
3
+ "version": "1.0.1-alpha.8",
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": "^1.0.1-alpha.7"
24
+ "@cloudbase/agent-shared": "^1.0.1-alpha.8"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/cors": "^2.8.19",