@openai/agents-core
Version:
The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.
191 lines • 7.71 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TraceProvider = void 0;
exports.getGlobalTraceProvider = getGlobalTraceProvider;
const context_1 = require("./context.js");
const config_1 = require("../config.js");
const logger_1 = __importDefault(require("../logger.js"));
const processor_1 = require("./processor.js");
const spans_1 = require("./spans.js");
const traces_1 = require("./traces.js");
const utils_1 = require("./utils.js");
class TraceProvider {
#multiProcessor;
#disabled;
constructor() {
this.#multiProcessor = new processor_1.MultiTracingProcessor();
this.#disabled = config_1.tracing.disabled;
this.#addCleanupListeners();
}
/**
* Add a processor to the list of processors. Each processor will receive all traces/spans.
*
* @param processor - The processor to add.
*/
registerProcessor(processor) {
this.#multiProcessor.addTraceProcessor(processor);
}
/**
* Set the list of processors. This will replace any existing processors.
*
* @param processors - The list of processors to set.
*/
setProcessors(processors) {
this.#multiProcessor.setProcessors(processors);
}
/**
* Get the current trace.
*
* @returns The current trace.
*/
getCurrentTrace() {
return (0, context_1.getCurrentTrace)();
}
getCurrentSpan() {
return (0, context_1.getCurrentSpan)();
}
setDisabled(disabled) {
this.#disabled = disabled;
}
startExportLoop() {
this.#multiProcessor.start();
}
createTrace(traceOptions) {
if (this.#disabled) {
logger_1.default.debug('Tracing is disabled, Not creating trace %o', traceOptions);
return new traces_1.NoopTrace();
}
const traceId = traceOptions.traceId ?? (0, utils_1.generateTraceId)();
const name = traceOptions.name ?? 'Agent workflow';
logger_1.default.debug('Creating trace %s with name %s', traceId, name);
return new traces_1.Trace({ ...traceOptions, name, traceId }, this.#multiProcessor);
}
createSpan(spanOptions, parent) {
if (this.#disabled || spanOptions.disabled) {
logger_1.default.debug('Tracing is disabled, Not creating span %o', spanOptions);
return new spans_1.NoopSpan(spanOptions.data, this.#multiProcessor);
}
let parentId;
let traceId;
if (!parent) {
const currentTrace = (0, context_1.getCurrentTrace)();
const currentSpan = (0, context_1.getCurrentSpan)();
if (!currentTrace) {
logger_1.default.error('No active trace. Make sure to start a trace with `withTrace()` first. Returning NoopSpan.');
return new spans_1.NoopSpan(spanOptions.data, this.#multiProcessor);
}
if (currentSpan instanceof spans_1.NoopSpan ||
currentTrace instanceof traces_1.NoopTrace) {
logger_1.default.debug(`Parent ${currentSpan} or ${currentTrace} is no-op, returning NoopSpan`);
return new spans_1.NoopSpan(spanOptions.data, this.#multiProcessor);
}
traceId = currentTrace.traceId;
if (currentSpan) {
logger_1.default.debug('Using parent span %s', currentSpan.spanId);
parentId = currentSpan.spanId;
}
else {
logger_1.default.debug('No parent span, using current trace %s', currentTrace.traceId);
}
}
else if (parent instanceof traces_1.Trace) {
if (parent instanceof traces_1.NoopTrace) {
logger_1.default.debug('Parent trace is no-op, returning NoopSpan');
return new spans_1.NoopSpan(spanOptions.data, this.#multiProcessor);
}
traceId = parent.traceId;
}
else if (parent instanceof spans_1.Span) {
if (parent instanceof spans_1.NoopSpan) {
logger_1.default.debug('Parent span is no-op, returning NoopSpan');
return new spans_1.NoopSpan(spanOptions.data, this.#multiProcessor);
}
parentId = parent.spanId;
traceId = parent.traceId;
}
if (!traceId) {
logger_1.default.error('No traceId found. Make sure to start a trace with `withTrace()` first. Returning NoopSpan.');
return new spans_1.NoopSpan(spanOptions.data, this.#multiProcessor);
}
logger_1.default.debug(`Creating span ${JSON.stringify(spanOptions.data)} with id ${spanOptions.spanId ?? traceId}`);
return new spans_1.Span({
...spanOptions,
traceId,
parentId,
}, this.#multiProcessor);
}
async shutdown(timeout) {
try {
logger_1.default.debug('Shutting down tracing provider');
await this.#multiProcessor.shutdown(timeout);
}
catch (error) {
logger_1.default.error('Error shutting down tracing provider %o', error);
}
}
/** Adds listeners to `process` to ensure `shutdown` occurs before exit. */
#addCleanupListeners() {
if (typeof process !== 'undefined' && typeof process.on === 'function') {
// handling Node.js process termination
const cleanup = async () => {
const timeout = setTimeout(() => {
console.warn('Cleanup timeout, forcing exit');
process.exit(1);
}, 5000);
try {
await this.shutdown();
}
finally {
clearTimeout(timeout);
}
};
// Handle normal termination
process.on('beforeExit', cleanup);
// Handle CTRL+C (SIGINT)
process.on('SIGINT', async () => {
await cleanup();
if (!hasOtherListenersForSignals('SIGINT')) {
// Only when there are no other listeners, exit the process on this SDK side
process.exit(130);
}
});
// Handle termination (SIGTERM)
process.on('SIGTERM', async () => {
await cleanup();
if (!hasOtherListenersForSignals('SIGTERM')) {
// Only when there are no other listeners, exit the process on this SDK side
process.exit(0);
}
});
process.on('unhandledRejection', async (reason, promise) => {
logger_1.default.error('Unhandled rejection', reason, promise);
await cleanup();
if (!hasOtherListenersForEvents('unhandledRejection')) {
// Only when there are no other listeners, exit the process on this SDK side
process.exit(1);
}
});
}
}
async forceFlush() {
await this.#multiProcessor.forceFlush();
}
}
exports.TraceProvider = TraceProvider;
function hasOtherListenersForSignals(event) {
return process.listeners(event).length > 1;
}
function hasOtherListenersForEvents(event) {
return process.listeners(event).length > 1;
}
let GLOBAL_TRACE_PROVIDER = undefined;
function getGlobalTraceProvider() {
if (!GLOBAL_TRACE_PROVIDER) {
GLOBAL_TRACE_PROVIDER = new TraceProvider();
}
return GLOBAL_TRACE_PROVIDER;
}
//# sourceMappingURL=provider.js.map