@cloudbase/agent-server 0.0.15 → 0.0.16
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 +42 -1
- package/dist/index.js +193 -28
- package/package.json +5 -2
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,14 @@ import { Repeater } from '@repeaterjs/repeater';
|
|
|
10
10
|
import * as _whatwg_node_server from '@whatwg-node/server';
|
|
11
11
|
import { OpenAI } from 'openai';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Type-only reference to ObservabilityConfig for documentation purposes.
|
|
15
|
+
* The actual type is: ObservabilityConfig | ObservabilityConfig[]
|
|
16
|
+
*
|
|
17
|
+
* At runtime, this accepts any value matching the ObservabilityConfig interface
|
|
18
|
+
* from @cloudbase/agent-observability/server package (if installed).
|
|
19
|
+
*/
|
|
20
|
+
type ObservabilityConfigOrArray = any;
|
|
13
21
|
/**
|
|
14
22
|
* Context passed to the agent factory function.
|
|
15
23
|
* Contains request information for per-request agent configuration.
|
|
@@ -53,16 +61,49 @@ interface ICreateServer {
|
|
|
53
61
|
* createExpressServer({ createAgent, logger: pino({ level: 'info' }) });
|
|
54
62
|
*/
|
|
55
63
|
logger?: Logger;
|
|
64
|
+
/**
|
|
65
|
+
* Observability configuration for trace exporters.
|
|
66
|
+
*
|
|
67
|
+
* Requires @cloudbase/agent-observability package to be installed.
|
|
68
|
+
* If the package is not installed, this option is silently ignored.
|
|
69
|
+
*
|
|
70
|
+
* Type reference: ObservabilityConfig | ObservabilityConfig[] from @cloudbase/agent-observability/server
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* // Console exporter (from env AUTO_TRACES_STDOUT)
|
|
74
|
+
* createExpressServer({ createAgent, observability: { type: 'console' } });
|
|
75
|
+
*
|
|
76
|
+
* // OTLP exporter (Langfuse, Jaeger, etc.)
|
|
77
|
+
* createExpressServer({
|
|
78
|
+
* createAgent,
|
|
79
|
+
* observability: {
|
|
80
|
+
* type: 'otlp',
|
|
81
|
+
* url: 'https://cloud.langfuse.com/api/public/otlp/v1/traces',
|
|
82
|
+
* headers: { 'Authorization': 'Basic xxx' }
|
|
83
|
+
* }
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* // Multiple exporters
|
|
87
|
+
* createExpressServer({
|
|
88
|
+
* createAgent,
|
|
89
|
+
* observability: [
|
|
90
|
+
* { type: 'console' },
|
|
91
|
+
* { type: 'otlp', url: 'http://localhost:4318/v1/traces' }
|
|
92
|
+
* ]
|
|
93
|
+
* });
|
|
94
|
+
*/
|
|
95
|
+
observability?: ObservabilityConfigOrArray;
|
|
56
96
|
}
|
|
57
97
|
interface IRun extends ICreateServer {
|
|
58
98
|
port?: number | string;
|
|
59
99
|
}
|
|
60
100
|
interface ICreateExpressRoutes extends Omit<ICreateServer, "cors"> {
|
|
61
101
|
express: Express;
|
|
102
|
+
observability?: ICreateServer["observability"];
|
|
62
103
|
}
|
|
63
104
|
declare function run(props: IRun): void;
|
|
64
105
|
declare function createExpressServer(props: ICreateServer): Express;
|
|
65
|
-
declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, logger: _logger, }: ICreateExpressRoutes): expressLib.Express;
|
|
106
|
+
declare function createExpressRoutes({ createAgent, basePath: _basePath, express, useAGUI: _useAGUI, aguiOptions, logger: _logger, observability, }: ICreateExpressRoutes): expressLib.Express;
|
|
66
107
|
interface AGUIOptions {
|
|
67
108
|
runtimeOptions?: Partial<CopilotRuntimeOptions>;
|
|
68
109
|
endpointOptions?: Partial<CreateCopilotRuntimeServerOptions>;
|
package/dist/index.js
CHANGED
|
@@ -389,12 +389,45 @@ var ErrorCode = {
|
|
|
389
389
|
};
|
|
390
390
|
|
|
391
391
|
// src/agui/sendMessageAGUI/server.ts
|
|
392
|
+
var startObservation;
|
|
393
|
+
var setupObservability;
|
|
394
|
+
var observabilityLoadAttempted = false;
|
|
395
|
+
async function loadObservability() {
|
|
396
|
+
if (!observabilityLoadAttempted) {
|
|
397
|
+
observabilityLoadAttempted = true;
|
|
398
|
+
try {
|
|
399
|
+
const obs = await import("@cloudbase/agent-observability");
|
|
400
|
+
const obsServer = await import("@cloudbase/agent-observability/server");
|
|
401
|
+
startObservation = obs.startObservation;
|
|
402
|
+
setupObservability = obsServer.setupObservability;
|
|
403
|
+
return true;
|
|
404
|
+
} catch (e) {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return !!startObservation;
|
|
409
|
+
}
|
|
410
|
+
async function ensureObservabilityReady() {
|
|
411
|
+
if (!setupObservability) return false;
|
|
412
|
+
try {
|
|
413
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
414
|
+
setTimeout(() => reject(new Error("Observability setup timeout")), 2e3);
|
|
415
|
+
});
|
|
416
|
+
await Promise.race([
|
|
417
|
+
setupObservability(),
|
|
418
|
+
timeoutPromise
|
|
419
|
+
]);
|
|
420
|
+
return true;
|
|
421
|
+
} catch (e) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
392
425
|
function createServerAdapter2(createAgent, options) {
|
|
393
426
|
var _a;
|
|
394
427
|
const { logger: parentLogger = import_agent_shared2.noopLogger } = options ?? {};
|
|
395
428
|
const adapterLogger = ((_a = parentLogger.child) == null ? void 0 : _a.call(parentLogger, { component: "sendMessageAGUI" })) ?? parentLogger;
|
|
396
429
|
return (0, import_server3.createServerAdapter)(async (request) => {
|
|
397
|
-
var _a2, _b, _c, _d, _e, _f, _g, _h;
|
|
430
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
398
431
|
const requestId = getOrGenerateRequestId(request.headers, "agui");
|
|
399
432
|
const logger = ((_a2 = adapterLogger.child) == null ? void 0 : _a2.call(adapterLogger, { requestId })) ?? adapterLogger;
|
|
400
433
|
(_b = logger.info) == null ? void 0 : _b.call(logger, "Request received");
|
|
@@ -474,11 +507,46 @@ function createServerAdapter2(createAgent, options) {
|
|
|
474
507
|
}
|
|
475
508
|
);
|
|
476
509
|
}
|
|
477
|
-
const
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
)
|
|
481
|
-
|
|
510
|
+
const hasObservability = await loadObservability();
|
|
511
|
+
let serverSpan = null;
|
|
512
|
+
let serverContextData = null;
|
|
513
|
+
if (hasObservability && startObservation) {
|
|
514
|
+
try {
|
|
515
|
+
const isReady = await ensureObservabilityReady();
|
|
516
|
+
if (isReady) {
|
|
517
|
+
serverSpan = startObservation(
|
|
518
|
+
"AG-UI.Server",
|
|
519
|
+
{
|
|
520
|
+
"http.method": request.method,
|
|
521
|
+
"http.url": request.url,
|
|
522
|
+
"http.host": request.headers.get("host") || "unknown",
|
|
523
|
+
"http.user_agent": request.headers.get("user-agent") || "unknown",
|
|
524
|
+
"agui.thread_id": inputRes.result.threadId,
|
|
525
|
+
"agui.run_id": inputRes.result.runId
|
|
526
|
+
},
|
|
527
|
+
{ asType: "span" }
|
|
528
|
+
);
|
|
529
|
+
const spanContext = serverSpan.otelSpan.spanContext();
|
|
530
|
+
serverContextData = {
|
|
531
|
+
traceId: spanContext.traceId,
|
|
532
|
+
spanId: spanContext.spanId,
|
|
533
|
+
traceFlags: spanContext.traceFlags
|
|
534
|
+
};
|
|
535
|
+
inputRes.result.forwardedProps = {
|
|
536
|
+
...inputRes.result.forwardedProps,
|
|
537
|
+
__agui_server_context: serverContextData
|
|
538
|
+
};
|
|
539
|
+
(_i = logger.debug) == null ? void 0 : _i.call(logger, "\u2713 Server span created:", {
|
|
540
|
+
traceId: serverContextData.traceId,
|
|
541
|
+
spanId: serverContextData.spanId
|
|
542
|
+
});
|
|
543
|
+
} else {
|
|
544
|
+
(_j = logger.debug) == null ? void 0 : _j.call(logger, "Observability not ready, skipping span creation");
|
|
545
|
+
}
|
|
546
|
+
} catch (e) {
|
|
547
|
+
(_k = logger.debug) == null ? void 0 : _k.call(logger, "Failed to create server span:", e);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
482
550
|
let cleanupCalled = false;
|
|
483
551
|
const safeCleanup = () => {
|
|
484
552
|
var _a3, _b2, _c2;
|
|
@@ -491,9 +559,36 @@ function createServerAdapter2(createAgent, options) {
|
|
|
491
559
|
}
|
|
492
560
|
}
|
|
493
561
|
};
|
|
562
|
+
const eventsResult = safe(
|
|
563
|
+
() => handler2(
|
|
564
|
+
inputRes.result,
|
|
565
|
+
createAgentRes.result.agent
|
|
566
|
+
)
|
|
567
|
+
);
|
|
568
|
+
if ("error" in eventsResult) {
|
|
569
|
+
const { error } = eventsResult;
|
|
570
|
+
(_l = logger.error) == null ? void 0 : _l.call(logger, { err: error }, "Run agent failed");
|
|
571
|
+
const errorCode = (0, import_agent_shared3.isErrorWithCode)(error) ? error.code : ErrorCode.INTERNAL_ERROR;
|
|
572
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
573
|
+
return new Response(
|
|
574
|
+
JSON.stringify({
|
|
575
|
+
error: {
|
|
576
|
+
code: errorCode,
|
|
577
|
+
message: errorMessage
|
|
578
|
+
},
|
|
579
|
+
requestId
|
|
580
|
+
}),
|
|
581
|
+
{
|
|
582
|
+
status: 500,
|
|
583
|
+
headers: { "Content-Type": "application/json" }
|
|
584
|
+
}
|
|
585
|
+
);
|
|
586
|
+
}
|
|
587
|
+
const { result: events } = eventsResult;
|
|
588
|
+
let heartbeat;
|
|
494
589
|
const stream = new ReadableStream({
|
|
495
590
|
async start(controller) {
|
|
496
|
-
var _a3, _b2, _c2, _d2;
|
|
591
|
+
var _a3, _b2, _c2, _d2, _e2;
|
|
497
592
|
const encoder = new TextEncoder();
|
|
498
593
|
heartbeat = setInterval(() => {
|
|
499
594
|
controller.enqueue(encoder.encode(":ping\n\n"));
|
|
@@ -532,13 +627,21 @@ function createServerAdapter2(createAgent, options) {
|
|
|
532
627
|
if (heartbeat) clearInterval(heartbeat);
|
|
533
628
|
controller.close();
|
|
534
629
|
safeCleanup();
|
|
630
|
+
if (serverSpan) {
|
|
631
|
+
serverSpan.end();
|
|
632
|
+
(_e2 = logger.debug) == null ? void 0 : _e2.call(logger, "\u2713 Server span ended");
|
|
633
|
+
}
|
|
535
634
|
}
|
|
536
635
|
},
|
|
537
636
|
cancel() {
|
|
538
|
-
var _a3;
|
|
637
|
+
var _a3, _b2;
|
|
539
638
|
(_a3 = logger.info) == null ? void 0 : _a3.call(logger, "Request cancelled by client");
|
|
540
639
|
if (heartbeat) clearInterval(heartbeat);
|
|
541
640
|
safeCleanup();
|
|
641
|
+
if (serverSpan) {
|
|
642
|
+
serverSpan.end();
|
|
643
|
+
(_b2 = logger.debug) == null ? void 0 : _b2.call(logger, "\u2713 Server span ended (cancelled)");
|
|
644
|
+
}
|
|
542
645
|
}
|
|
543
646
|
});
|
|
544
647
|
const headers = new Headers({
|
|
@@ -558,6 +661,15 @@ async function safeAsync(fn) {
|
|
|
558
661
|
return { error };
|
|
559
662
|
}
|
|
560
663
|
}
|
|
664
|
+
function safe(fn) {
|
|
665
|
+
try {
|
|
666
|
+
return {
|
|
667
|
+
result: fn()
|
|
668
|
+
};
|
|
669
|
+
} catch (error) {
|
|
670
|
+
return { error };
|
|
671
|
+
}
|
|
672
|
+
}
|
|
561
673
|
|
|
562
674
|
// src/agui/healthz/index.ts
|
|
563
675
|
var healthz_exports = {};
|
|
@@ -756,6 +868,13 @@ var import_cors = __toESM(require("cors"));
|
|
|
756
868
|
var import_async_hooks = require("async_hooks");
|
|
757
869
|
var import_server8 = require("@whatwg-node/server");
|
|
758
870
|
var DefaultFetchAPI = __toESM(require("@whatwg-node/fetch"));
|
|
871
|
+
async function setupObservabilityIfAvailable(configs) {
|
|
872
|
+
try {
|
|
873
|
+
const { setupObservability: setupObservability2 } = await import("@cloudbase/agent-observability/server");
|
|
874
|
+
await setupObservability2(configs);
|
|
875
|
+
} catch (error) {
|
|
876
|
+
}
|
|
877
|
+
}
|
|
759
878
|
var preparedAgentStorage = new import_async_hooks.AsyncLocalStorage();
|
|
760
879
|
function agentCloneFn() {
|
|
761
880
|
const preparedAgent = preparedAgentStorage.getStore();
|
|
@@ -790,33 +909,77 @@ function createExpressRoutes({
|
|
|
790
909
|
express,
|
|
791
910
|
useAGUI: _useAGUI,
|
|
792
911
|
aguiOptions,
|
|
793
|
-
logger: _logger
|
|
912
|
+
logger: _logger,
|
|
913
|
+
observability
|
|
794
914
|
}) {
|
|
795
|
-
var _a, _b, _c;
|
|
915
|
+
var _a, _b, _c, _d;
|
|
796
916
|
const useAGUI = _useAGUI ?? true;
|
|
797
917
|
const logger = _logger ?? import_agent_shared2.noopLogger;
|
|
798
|
-
const
|
|
918
|
+
const userProvidedBasePath = _basePath !== void 0;
|
|
799
919
|
const serverLogger = ((_a = logger.child) == null ? void 0 : _a.call(logger, { component: "server" })) ?? logger;
|
|
800
|
-
(_b = serverLogger.debug) == null ? void 0 : _b.call(
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
logger: serverLogger,
|
|
808
|
-
...aguiOptions || {}
|
|
920
|
+
(_b = serverLogger.debug) == null ? void 0 : _b.call(
|
|
921
|
+
serverLogger,
|
|
922
|
+
{ basePath: _basePath, useAGUI, userProvidedBasePath },
|
|
923
|
+
"Initializing server routes"
|
|
924
|
+
);
|
|
925
|
+
if (observability) {
|
|
926
|
+
setupObservabilityIfAvailable(observability).catch(() => {
|
|
809
927
|
});
|
|
810
928
|
}
|
|
929
|
+
const sendMessageServerAdapter = useAGUI ? sendMessageAGUI_exports.createServerAdapter(createAgent, {
|
|
930
|
+
logger: serverLogger
|
|
931
|
+
}) : sendMessage_exports.createServerAdapter(createAgent);
|
|
811
932
|
const openaiServerAdapter = openai_exports.createServerAdapter(createAgent);
|
|
812
933
|
const healthzServerAdapter = healthz_exports.serverAdapter;
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
934
|
+
if (userProvidedBasePath) {
|
|
935
|
+
const basePath = _basePath;
|
|
936
|
+
if (useAGUI) {
|
|
937
|
+
createAGUIRoute({
|
|
938
|
+
basePath,
|
|
939
|
+
express,
|
|
940
|
+
createAgent,
|
|
941
|
+
logger: serverLogger,
|
|
942
|
+
...aguiOptions || {}
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
express.use(`${basePath}send-message`, sendMessageServerAdapter);
|
|
946
|
+
express.use(`${basePath}healthz`, healthzServerAdapter);
|
|
947
|
+
express.use(`${basePath}chat/completions`, openaiServerAdapter);
|
|
948
|
+
(_c = serverLogger.info) == null ? void 0 : _c.call(serverLogger, { basePath }, "Server routes initialized");
|
|
949
|
+
} else {
|
|
950
|
+
const simplePath = "/";
|
|
951
|
+
const scfPath = "/v1/aibot/bots/:agentId/";
|
|
952
|
+
if (useAGUI) {
|
|
953
|
+
createAGUIRoute({
|
|
954
|
+
basePath: simplePath,
|
|
955
|
+
express,
|
|
956
|
+
createAgent,
|
|
957
|
+
logger: serverLogger,
|
|
958
|
+
...aguiOptions || {}
|
|
959
|
+
});
|
|
960
|
+
createAGUIRoute({
|
|
961
|
+
basePath: scfPath,
|
|
962
|
+
express,
|
|
963
|
+
createAgent,
|
|
964
|
+
logger: serverLogger,
|
|
965
|
+
...aguiOptions || {}
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
express.use(`${simplePath}send-message`, sendMessageServerAdapter);
|
|
969
|
+
express.use(`${simplePath}healthz`, healthzServerAdapter);
|
|
970
|
+
express.use(`${simplePath}chat/completions`, openaiServerAdapter);
|
|
971
|
+
express.use(`${scfPath}send-message`, sendMessageServerAdapter);
|
|
972
|
+
express.use(`${scfPath}healthz`, healthzServerAdapter);
|
|
973
|
+
express.use(`${scfPath}chat/completions`, openaiServerAdapter);
|
|
974
|
+
(_d = serverLogger.info) == null ? void 0 : _d.call(
|
|
975
|
+
serverLogger,
|
|
976
|
+
{ simplePath, scfPath },
|
|
977
|
+
"Server routes initialized (dual endpoints)"
|
|
978
|
+
);
|
|
979
|
+
}
|
|
817
980
|
return express;
|
|
818
981
|
}
|
|
819
|
-
var
|
|
982
|
+
var AGUIRpcHandlerPromiseMap = /* @__PURE__ */ new Map();
|
|
820
983
|
function getAGUIRpcHandler({
|
|
821
984
|
createAgent,
|
|
822
985
|
runtimeOptions,
|
|
@@ -826,8 +989,9 @@ function getAGUIRpcHandler({
|
|
|
826
989
|
logger,
|
|
827
990
|
requestId
|
|
828
991
|
}) {
|
|
829
|
-
|
|
830
|
-
|
|
992
|
+
const cached = AGUIRpcHandlerPromiseMap.get(basePath);
|
|
993
|
+
if (cached) return cached;
|
|
994
|
+
const handlerPromise = (async () => {
|
|
831
995
|
const { agent } = await createAgent({ request, logger, requestId });
|
|
832
996
|
const templateAgent = "toAGUIAgent" in agent ? agent.toAGUIAgent() : agent;
|
|
833
997
|
templateAgent.clone = agentCloneFn;
|
|
@@ -844,7 +1008,8 @@ function getAGUIRpcHandler({
|
|
|
844
1008
|
...endpointOptions || {}
|
|
845
1009
|
});
|
|
846
1010
|
})();
|
|
847
|
-
|
|
1011
|
+
AGUIRpcHandlerPromiseMap.set(basePath, handlerPromise);
|
|
1012
|
+
return handlerPromise;
|
|
848
1013
|
}
|
|
849
1014
|
function createAGUIRoute({
|
|
850
1015
|
express,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/agent-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/",
|
|
@@ -20,11 +20,14 @@
|
|
|
20
20
|
"express": "^5.1.0",
|
|
21
21
|
"openai": "6.3.0",
|
|
22
22
|
"uuid": "^10.0.0",
|
|
23
|
-
"@cloudbase/agent-shared": "^0.0.
|
|
23
|
+
"@cloudbase/agent-shared": "^0.0.16"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"zod": "^3.25.0 || ^4.0.0"
|
|
27
27
|
},
|
|
28
|
+
"optionalDependencies": {
|
|
29
|
+
"@cloudbase/agent-observability": "0.0.16"
|
|
30
|
+
},
|
|
28
31
|
"devDependencies": {
|
|
29
32
|
"@types/cors": "^2.8.19",
|
|
30
33
|
"@types/express": "^5.0.3",
|