@cuylabs/agent-foundry-agentserver-invocations 4.8.1 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -6
- package/dist/index.js +20 -180
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Request, Response, Express } from 'express';
|
|
2
2
|
import { Server } from 'node:http';
|
|
3
|
+
import { AgentServerLogger } from '@cuylabs/agent-foundry-agentserver-core';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Shared types for the Foundry Invocations protocol.
|
|
@@ -280,12 +281,7 @@ interface InvocationsServerOptions {
|
|
|
280
281
|
*/
|
|
281
282
|
configureObservability?: boolean;
|
|
282
283
|
}
|
|
283
|
-
|
|
284
|
-
info(message: string, meta?: Record<string, unknown>): void;
|
|
285
|
-
warn(message: string, meta?: Record<string, unknown>): void;
|
|
286
|
-
error(message: string, meta?: Record<string, unknown>): void;
|
|
287
|
-
debug?(message: string, meta?: Record<string, unknown>): void;
|
|
288
|
-
}
|
|
284
|
+
type InvocationsServerLogger = AgentServerLogger;
|
|
289
285
|
interface InvocationsServer {
|
|
290
286
|
readonly app: Express;
|
|
291
287
|
readonly server: Server;
|
package/dist/index.js
CHANGED
|
@@ -318,17 +318,28 @@ import express from "express";
|
|
|
318
318
|
import {
|
|
319
319
|
CHAT_ISOLATION_HEADER,
|
|
320
320
|
INVOCATION_ID_HEADER,
|
|
321
|
-
REQUEST_ID_HEADER,
|
|
322
321
|
SESSION_ID_HEADER,
|
|
323
322
|
USER_ISOLATION_HEADER,
|
|
324
323
|
AGENTSERVER_CORE_PACKAGE_VERSION,
|
|
324
|
+
addProtectedHeaders,
|
|
325
|
+
agentServerLoggingMiddleware,
|
|
326
|
+
agentServerRequestHeadersMiddleware,
|
|
325
327
|
buildPlatformServerHeader,
|
|
328
|
+
closeServerWithTimeout,
|
|
326
329
|
configureAgentServerObservability,
|
|
330
|
+
configureExpressAgentServerApp,
|
|
327
331
|
createErrorBody,
|
|
332
|
+
defaultAgentServerLogger,
|
|
333
|
+
errorMiddleware,
|
|
334
|
+
formatError,
|
|
335
|
+
healthzHandler,
|
|
336
|
+
logAgentServerStartupConfiguration,
|
|
337
|
+
methodNotAllowed,
|
|
338
|
+
notFoundMiddleware,
|
|
339
|
+
readinessHandler,
|
|
328
340
|
resolveAgentServerConfig,
|
|
329
341
|
resolveInvocationIdentity as resolveInvocationIdentity2,
|
|
330
342
|
resolveRequestId,
|
|
331
|
-
sanitizeProtocolId,
|
|
332
343
|
startAgentServerRequestSpan
|
|
333
344
|
} from "@cuylabs/agent-foundry-agentserver-core";
|
|
334
345
|
|
|
@@ -345,7 +356,7 @@ var AGENTSERVER_INVOCATIONS_PACKAGE_VERSION = readPackageVersion();
|
|
|
345
356
|
var DEFAULT_HOST = "0.0.0.0";
|
|
346
357
|
var DEFAULT_BODY_LIMIT = "1mb";
|
|
347
358
|
function createInvocationsApp(options) {
|
|
348
|
-
const logger = options.logger ??
|
|
359
|
+
const logger = options.logger ?? defaultAgentServerLogger("invocations");
|
|
349
360
|
const config = resolveAgentServerConfig({
|
|
350
361
|
port: options.port,
|
|
351
362
|
gracefulShutdownTimeoutSeconds: options.gracefulShutdownTimeoutSeconds
|
|
@@ -366,8 +377,7 @@ function createInvocationsApp(options) {
|
|
|
366
377
|
]);
|
|
367
378
|
const observabilityReady = options.configureObservability === false ? Promise.resolve(void 0) : configureAgentServerObservability({ config, logger });
|
|
368
379
|
const app = express();
|
|
369
|
-
app
|
|
370
|
-
app.set("trust proxy", trustProxy);
|
|
380
|
+
configureExpressAgentServerApp(app, { trustProxy });
|
|
371
381
|
app.use(express.raw({ type: "*/*", limit: bodyLimit }));
|
|
372
382
|
app.use(async (_req, _res, next) => {
|
|
373
383
|
try {
|
|
@@ -380,17 +390,9 @@ function createInvocationsApp(options) {
|
|
|
380
390
|
next();
|
|
381
391
|
}
|
|
382
392
|
});
|
|
383
|
-
app.use((
|
|
384
|
-
const requestId = resolveRequestId((name) => req.header(name));
|
|
385
|
-
req.agentServerRequestId = requestId;
|
|
386
|
-
addProtectedHeaders(res, {
|
|
387
|
-
[REQUEST_ID_HEADER]: requestId,
|
|
388
|
-
"x-platform-server": platformServer
|
|
389
|
-
});
|
|
390
|
-
next();
|
|
391
|
-
});
|
|
393
|
+
app.use(agentServerRequestHeadersMiddleware({ platformServer }));
|
|
392
394
|
if (requestLogging) {
|
|
393
|
-
app.use(
|
|
395
|
+
app.use(agentServerLoggingMiddleware(logger));
|
|
394
396
|
}
|
|
395
397
|
const handlerProvider = makeHandlerProvider(options.handler);
|
|
396
398
|
app.get("/", (_req, res) => {
|
|
@@ -405,9 +407,7 @@ function createInvocationsApp(options) {
|
|
|
405
407
|
openapi: "/invocations/docs/openapi.json"
|
|
406
408
|
});
|
|
407
409
|
});
|
|
408
|
-
app.get("/healthz",
|
|
409
|
-
res.json({ ok: true });
|
|
410
|
-
});
|
|
410
|
+
app.get("/healthz", healthzHandler);
|
|
411
411
|
app.get("/readiness", readinessHandler);
|
|
412
412
|
app.get("/readyz", readinessHandler);
|
|
413
413
|
app.get("/invocations/docs/openapi.json", (_req, res) => {
|
|
@@ -543,7 +543,7 @@ async function runInvocationsServer(options) {
|
|
|
543
543
|
});
|
|
544
544
|
const port = config.port;
|
|
545
545
|
const host = options.host ?? DEFAULT_HOST;
|
|
546
|
-
const logger = options.logger ??
|
|
546
|
+
const logger = options.logger ?? defaultAgentServerLogger("invocations");
|
|
547
547
|
const appName = options.appName ?? "foundry-invocations-host";
|
|
548
548
|
const platformServer = buildPlatformServerHeader([
|
|
549
549
|
{
|
|
@@ -557,7 +557,7 @@ async function runInvocationsServer(options) {
|
|
|
557
557
|
]);
|
|
558
558
|
const server = await new Promise((resolve, reject) => {
|
|
559
559
|
const httpServer = app.listen(port, host, () => {
|
|
560
|
-
|
|
560
|
+
logAgentServerStartupConfiguration(logger, config, platformServer);
|
|
561
561
|
logger.info(
|
|
562
562
|
`${appName} listening on http://${host}:${port}/invocations`
|
|
563
563
|
);
|
|
@@ -606,71 +606,6 @@ function startInvocationRequestSpan(options) {
|
|
|
606
606
|
});
|
|
607
607
|
return span;
|
|
608
608
|
}
|
|
609
|
-
async function closeServerWithTimeout(server, timeoutSeconds) {
|
|
610
|
-
const closePromise = new Promise((resolve, reject) => {
|
|
611
|
-
server.close((error) => {
|
|
612
|
-
if (!error || error.code === "ERR_SERVER_NOT_RUNNING") {
|
|
613
|
-
resolve();
|
|
614
|
-
return;
|
|
615
|
-
}
|
|
616
|
-
reject(error);
|
|
617
|
-
});
|
|
618
|
-
});
|
|
619
|
-
if (timeoutSeconds <= 0) {
|
|
620
|
-
await closePromise;
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
let timeout;
|
|
624
|
-
const timeoutPromise = new Promise((resolve) => {
|
|
625
|
-
timeout = setTimeout(() => {
|
|
626
|
-
server.closeAllConnections?.();
|
|
627
|
-
resolve();
|
|
628
|
-
}, timeoutSeconds * 1e3);
|
|
629
|
-
});
|
|
630
|
-
try {
|
|
631
|
-
await Promise.race([closePromise, timeoutPromise]);
|
|
632
|
-
} finally {
|
|
633
|
-
if (timeout) {
|
|
634
|
-
clearTimeout(timeout);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
function logStartupConfiguration(logger, config, platformServer) {
|
|
639
|
-
logger.info("Foundry Agent Server platform environment", {
|
|
640
|
-
isHosted: config.isHosted,
|
|
641
|
-
agentName: config.agentName || "(not set)",
|
|
642
|
-
agentVersion: config.agentVersion || "(not set)",
|
|
643
|
-
port: config.port,
|
|
644
|
-
sessionId: config.sessionId || "(not set)",
|
|
645
|
-
sseKeepAliveIntervalSeconds: config.sseKeepAliveIntervalSeconds > 0 ? config.sseKeepAliveIntervalSeconds : "disabled"
|
|
646
|
-
});
|
|
647
|
-
logger.info("Foundry Agent Server connectivity", {
|
|
648
|
-
projectEndpoint: maskUri(config.projectEndpoint),
|
|
649
|
-
otlpEndpoint: maskUri(config.otlpEndpoint),
|
|
650
|
-
applicationInsightsConfigured: Boolean(
|
|
651
|
-
config.applicationInsightsConnectionString.trim()
|
|
652
|
-
)
|
|
653
|
-
});
|
|
654
|
-
logger.info("Foundry Agent Server host options", {
|
|
655
|
-
gracefulShutdownTimeoutSeconds: config.gracefulShutdownTimeoutSeconds,
|
|
656
|
-
platformServer
|
|
657
|
-
});
|
|
658
|
-
}
|
|
659
|
-
function readinessHandler(_req, res) {
|
|
660
|
-
res.json({ status: "healthy" });
|
|
661
|
-
}
|
|
662
|
-
function maskUri(uri) {
|
|
663
|
-
const normalized = uri.trim();
|
|
664
|
-
if (!normalized) {
|
|
665
|
-
return "(not set)";
|
|
666
|
-
}
|
|
667
|
-
try {
|
|
668
|
-
const parsed = new URL(normalized);
|
|
669
|
-
return `${parsed.protocol}//${parsed.host}`;
|
|
670
|
-
} catch {
|
|
671
|
-
return "(redacted)";
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
609
|
function makeHandlerProvider(input) {
|
|
675
610
|
if (typeof input === "function") {
|
|
676
611
|
return input;
|
|
@@ -706,42 +641,6 @@ function buildContextFromRequest(req, res) {
|
|
|
706
641
|
signal: controller.signal
|
|
707
642
|
};
|
|
708
643
|
}
|
|
709
|
-
function loggingMiddleware(logger) {
|
|
710
|
-
return (req, res, next) => {
|
|
711
|
-
const start = Date.now();
|
|
712
|
-
res.on("finish", () => {
|
|
713
|
-
logger.info("http request", {
|
|
714
|
-
method: req.method,
|
|
715
|
-
path: req.path,
|
|
716
|
-
statusCode: res.statusCode,
|
|
717
|
-
durationMs: Date.now() - start,
|
|
718
|
-
requestId: req.agentServerRequestId,
|
|
719
|
-
clientRequestId: req.header("x-ms-client-request-id")
|
|
720
|
-
});
|
|
721
|
-
});
|
|
722
|
-
next();
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
|
-
function notFoundMiddleware() {
|
|
726
|
-
return (_req, res, _next) => {
|
|
727
|
-
res.status(404).json(createErrorBody("not_found", "No route matched this path."));
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
function errorMiddleware(logger) {
|
|
731
|
-
return (err, _req, res, _next) => {
|
|
732
|
-
logger.error("Unhandled middleware error", { error: formatError(err) });
|
|
733
|
-
if (res.headersSent) {
|
|
734
|
-
res.end();
|
|
735
|
-
return;
|
|
736
|
-
}
|
|
737
|
-
res.status(500).json(
|
|
738
|
-
createErrorBody(
|
|
739
|
-
"internal_error",
|
|
740
|
-
err instanceof Error ? err.message : String(err)
|
|
741
|
-
)
|
|
742
|
-
);
|
|
743
|
-
};
|
|
744
|
-
}
|
|
745
644
|
function handleHandlerError(res, error, logger, hookName) {
|
|
746
645
|
logger.error(`Invocation handler hook ${hookName} threw`, {
|
|
747
646
|
error: formatError(error)
|
|
@@ -757,65 +656,6 @@ function handleHandlerError(res, error, logger, hookName) {
|
|
|
757
656
|
)
|
|
758
657
|
);
|
|
759
658
|
}
|
|
760
|
-
function formatError(error) {
|
|
761
|
-
if (error instanceof Error) {
|
|
762
|
-
return error.stack ?? error.message;
|
|
763
|
-
}
|
|
764
|
-
return String(error);
|
|
765
|
-
}
|
|
766
|
-
function addProtectedHeaders(res, headers) {
|
|
767
|
-
const protectedRes = res;
|
|
768
|
-
if (!protectedRes.__agentServerProtectedHeaders) {
|
|
769
|
-
const protectedHeaders = /* @__PURE__ */ new Map();
|
|
770
|
-
const originalSetHeader2 = res.setHeader.bind(res);
|
|
771
|
-
protectedRes.__agentServerProtectedHeaders = protectedHeaders;
|
|
772
|
-
protectedRes.__agentServerOriginalSetHeader = originalSetHeader2;
|
|
773
|
-
res.setHeader = ((name, value) => {
|
|
774
|
-
const protectedValue = protectedHeaders.get(name.toLowerCase());
|
|
775
|
-
if (protectedValue !== void 0) {
|
|
776
|
-
return originalSetHeader2(name, protectedValue);
|
|
777
|
-
}
|
|
778
|
-
return originalSetHeader2(name, value);
|
|
779
|
-
});
|
|
780
|
-
}
|
|
781
|
-
const originalSetHeader = protectedRes.__agentServerOriginalSetHeader ?? res.setHeader.bind(res);
|
|
782
|
-
for (const [name, value] of Object.entries(headers)) {
|
|
783
|
-
const safeValue = name.toLowerCase() === INVOCATION_ID_HEADER || name.toLowerCase() === SESSION_ID_HEADER ? sanitizeProtocolId(value, value) : value;
|
|
784
|
-
protectedRes.__agentServerProtectedHeaders.set(
|
|
785
|
-
name.toLowerCase(),
|
|
786
|
-
safeValue
|
|
787
|
-
);
|
|
788
|
-
originalSetHeader(name, safeValue);
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
function methodNotAllowed(allowedMethods) {
|
|
792
|
-
return (_req, res) => {
|
|
793
|
-
res.setHeader("Allow", allowedMethods.join(", "));
|
|
794
|
-
res.status(405).json(
|
|
795
|
-
createErrorBody(
|
|
796
|
-
"method_not_allowed",
|
|
797
|
-
`Allowed methods: ${allowedMethods.join(", ")}`
|
|
798
|
-
)
|
|
799
|
-
);
|
|
800
|
-
};
|
|
801
|
-
}
|
|
802
|
-
function defaultLogger() {
|
|
803
|
-
return {
|
|
804
|
-
info: (message, meta) => {
|
|
805
|
-
if (meta) {
|
|
806
|
-
console.log(`[invocations] ${message}`, meta);
|
|
807
|
-
} else {
|
|
808
|
-
console.log(`[invocations] ${message}`);
|
|
809
|
-
}
|
|
810
|
-
},
|
|
811
|
-
warn: (message, meta) => {
|
|
812
|
-
console.warn(`[invocations] ${message}`, meta ?? "");
|
|
813
|
-
},
|
|
814
|
-
error: (message, meta) => {
|
|
815
|
-
console.error(`[invocations] ${message}`, meta ?? "");
|
|
816
|
-
}
|
|
817
|
-
};
|
|
818
|
-
}
|
|
819
659
|
export {
|
|
820
660
|
InvocationHandler,
|
|
821
661
|
buildInvocationsOpenApiSpec,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cuylabs/agent-foundry-agentserver-invocations",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "TypeScript Foundry Agent Server Invocations-protocol host (mirrors azure-ai-agentserver-invocations)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"express": "^5.0.0",
|
|
21
|
-
"@cuylabs/agent-foundry-agentserver-core": "^4.
|
|
21
|
+
"@cuylabs/agent-foundry-agentserver-core": "^4.10.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@opentelemetry/api": "^1.9.0",
|