@artinet/sdk
Version:
A TypeScript SDK for building collaborative AI agents.
156 lines (155 loc) • 4.07 kB
JavaScript
/**
* @fileoverview Global configuration for the Artinet runtime.
*
* Provides a centralized configuration interface that consumers use to
* inject their implementations of observability, storage, and other
* platform-specific dependencies.
*
* Design principles:
* - Single configuration point for the entire SDK
* - No-op defaults for all optional dependencies
* - Type-safe configuration interface
* - Configure once at application startup
*
* @module config
*
* @example
* ```typescript
* import { configure, getLogger, getTracer } from '@artinet/armada';
* import pino from 'pino';
*
* // Configure at app startup
* configure({
* logger: {
* debug: (msg, ctx) => pino().debug(ctx, msg),
* info: (msg, ctx) => pino().info(ctx, msg),
* warn: (msg, ctx) => pino().warn(ctx, msg),
* error: (msg, ctx) => pino().error(ctx, msg),
* },
* });
*
* // Later in your code
* const logger = getLogger();
* logger.info('Application started');
* ```
*/
import { noopLogger } from "./observability.js";
import { trace } from "@opentelemetry/api";
/**
* Internal configuration state.
* @internal
*/
let _config = {};
/**
* Configure the Artinet SDK.
*
* Call this once at application startup to inject your implementations.
* Subsequent calls will merge with existing configuration.
*
* @param config - Configuration options
*
* @example
* ```typescript
* // Basic configuration with console
* configure({ logger: console });
* ```
*
* @example
* ```typescript
* // Production configuration with Pino and OpenTelemetry
* import pino from 'pino';
* import { trace } from '@opentelemetry/api';
*
* const pinoLogger = pino();
*
* configure({
* logger: {
* debug: (msg, ...args) => pinoLogger.debug(Object.assign({}, ...args), msg),
* info: (msg, ...args) => pinoLogger.info(Object.assign({}, ...args), msg),
* warn: (msg, ...args) => pinoLogger.warn(Object.assign({}, ...args), msg),
* error: (msg, ...args) => pinoLogger.error(Object.assign({}, ...args), msg),
* },
* tracer: {
* startSpan: (name, attrs) => {
* const span = trace.getTracer('my-app').startSpan(name);
* // ... wrap span
* return wrappedSpan;
* },
* },
* });
* ```
*/
export function configure(config) {
_config = { ..._config, ...config };
}
/**
* Reset configuration to defaults.
*
* Primarily useful for testing to ensure clean state between tests.
*
* @example
* ```typescript
* beforeEach(() => {
* resetConfig();
* });
* ```
*/
export function resetConfig() {
_config = {};
}
/**
* Get the current configuration.
*
* Returns a copy to prevent external mutation.
*
* @returns Current configuration (readonly copy)
*/
export function getConfig() {
return { ..._config };
}
/**
* Get the configured logger or no-op default.
*
* @returns Logger implementation
*
* @example
* ```typescript
* const logger = getLogger();
* logger.info('Processing request', { requestId: '123' }, 'extra data');
* ```
*/
export function getLogger() {
return _config.logger ?? noopLogger;
}
/**
* Get the configured tracer or no-op default.
*
* @returns Tracer implementation
*
* @example
* ```typescript
* const tracer = getTracer();
* const span = tracer.startSpan('processRequest', { requestId: '123' });
* try {
* // ... do work
* span.setStatus('ok');
* } catch (error) {
* span.setStatus('error', error.message);
* throw error;
* } finally {
* span.end();
* }
* ```
*/
export function getTracer() {
return _config.tracer ?? trace.getTracer("artinet");
}
export const logger = {
debug: (msg, ...args) => getLogger()?.debug?.(msg, ...args),
info: (msg, ...args) => getLogger()?.info?.(msg, ...args),
warn: (msg, ...args) => getLogger()?.warn?.(msg, ...args),
error: (msg, err) => getLogger()?.error?.(msg, err),
setLevel: (level) => getLogger()?.setLevel?.(level),
getLevel: () => getLogger()?.getLevel?.() ?? "info",
child: (context) => getLogger()?.child?.(context) ?? noopLogger,
};