elsium-ai 0.5.0 → 0.7.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 +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +591 -31
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
export { ElsiumError, ok, err, isOk, isErr, unwrap, unwrapOr, tryCatch, tryCatchSync, createStream, createLogger, env, envNumber, envBool, generateId, generateTraceId, extractText, sleep, retry, zodToJsonSchema, createRegistry, countTokens, createContextManager, } from '@elsium-ai/core';
|
|
13
13
|
export type { Role, ContentPart, TextContent, ImageContent, AudioContent, DocumentContent, Message, ToolCall, ToolResult, TokenUsage, CostBreakdown, StopReason, LLMResponse, StreamEvent, XRayData, StreamCheckpoint, ProviderConfig, CompletionRequest, ToolDefinition, TenantContext, Middleware, Result, Ok, Err, ElsiumStream, ResilientStreamOptions, LogLevel, Logger, ErrorCode, Registry, ContextStrategy, ContextManagerConfig, ContextManager, } from '@elsium-ai/core';
|
|
14
14
|
export { gateway, registerProviderFactory, registerProvider, getProviderFactory, listProviders, registerProviderMetadata, getProviderMetadata, calculateCost, registerPricing, composeMiddleware, loggingMiddleware, costTrackingMiddleware, xrayMiddleware, createAnthropicProvider, createOpenAIProvider, createGoogleProvider, createProviderMesh, securityMiddleware, detectPromptInjection, detectJailbreak, redactSecrets, checkBlockedPatterns, cacheMiddleware, createInMemoryCache, outputGuardrailMiddleware, createBatch, } from '@elsium-ai/gateway';
|
|
15
|
-
export type { LLMProvider, ProviderFactory, ProviderMetadata, ModelPricing, ModelTier, Gateway, GatewayConfig, XRayStore, ProviderMeshConfig, ProviderEntry, RoutingStrategy, ProviderMesh, SecurityMiddlewareConfig, SecurityViolation, SecurityResult, CacheAdapter, CacheStats, CacheMiddlewareConfig, OutputGuardrailConfig, OutputGuardrailRule, OutputViolation, BatchConfig, BatchResult, BatchResultItem, } from '@elsium-ai/gateway';
|
|
16
|
-
export { defineAgent, runSequential, runParallel, runSupervisor, createMemory, createSemanticValidator, createAgentSecurity, createConfidenceScorer, executeStateMachine, createInMemoryMemoryStore, createSqliteMemoryStore, createAgentStream, createThread, loadThread, createInMemoryThreadStore, createAsyncAgent, } from '@elsium-ai/agents';
|
|
17
|
-
export type { Agent, AgentDependencies, AgentConfig, AgentResult, AgentRunOptions, GuardrailConfig, AgentHooks, Memory, MemoryConfig, SemanticGuardrailConfig, SemanticCheck, SemanticCheckResult, SemanticValidationResult, SemanticValidator, AgentSecurityConfig, AgentSecurityResult, ConfidenceConfig, ConfidenceResult, StateDefinition, StateHistoryEntry, StateMachineResult, MemoryStore, SqliteMemoryStoreConfig, AgentStreamEvent, AgentStream, StreamingAgentDependencies, Thread, ThreadConfig, ThreadStore, ThreadSnapshot, ThreadSummary, AsyncAgent, AsyncAgentConfig, AsyncAgentRunOptions, AgentTask, TaskStatus, TaskProgressEvent, } from '@elsium-ai/agents';
|
|
18
|
-
export { defineTool, createToolkit, httpFetchTool, calculatorTool, jsonParseTool, currentTimeTool, formatToolResult, formatToolResultAsText, } from '@elsium-ai/tools';
|
|
19
|
-
export type { Tool, ToolConfig, ToolContext, ToolExecutionResult, Toolkit, } from '@elsium-ai/tools';
|
|
15
|
+
export type { LLMProvider, ProviderFactory, ProviderMetadata, ModelPricing, ModelTier, Gateway, GatewayConfig, XRayStore, ProviderMeshConfig, ProviderEntry, RoutingStrategy, ProviderMesh, MeshAuditLogger, SecurityMiddlewareConfig, SecurityViolation, SecurityResult, CacheAdapter, CacheStats, CacheMiddlewareConfig, OutputGuardrailConfig, OutputGuardrailRule, OutputViolation, BatchConfig, BatchResult, BatchResultItem, } from '@elsium-ai/gateway';
|
|
16
|
+
export { defineAgent, runSequential, runParallel, runSupervisor, createMemory, createSummarizeFn, createSemanticValidator, createAgentSecurity, createConfidenceScorer, executeStateMachine, createInMemoryMemoryStore, createSqliteMemoryStore, createAgentStream, createThread, loadThread, createInMemoryThreadStore, createAsyncAgent, createChannelGateway, createWebhookChannel, createSessionRouter, createScheduler, parseCronExpression, cronMatchesDate, getNextCronDate, } from '@elsium-ai/agents';
|
|
17
|
+
export type { Agent, AgentDependencies, AgentGenerateResult, AgentConfig, AgentResult, AgentRunOptions, GuardrailConfig, AgentHooks, Memory, MemoryConfig, SummarizeFn, SemanticGuardrailConfig, SemanticCheck, SemanticCheckResult, SemanticValidationResult, SemanticValidator, AgentSecurityConfig, AgentSecurityResult, ConfidenceConfig, ConfidenceResult, StateDefinition, StateHistoryEntry, StateMachineResult, MemoryStore, SqliteMemoryStoreConfig, AgentStreamEvent, AgentStream, StreamingAgentDependencies, Thread, ThreadConfig, ThreadStore, ThreadSnapshot, ThreadSummary, AsyncAgent, AsyncAgentConfig, AsyncAgentRunOptions, AgentTask, TaskStatus, TaskProgressEvent, ChannelAdapter, ChannelGateway, ChannelGatewayConfig, IncomingMessage, OutgoingMessage, ChannelAttachment, WebhookChannelConfig, SessionRouter, SessionRouterConfig, SessionInfo, SessionResolveOptions, Scheduler, SchedulerConfig, ScheduleOptions, ScheduledTask, CronFields, } from '@elsium-ai/agents';
|
|
18
|
+
export { defineTool, createToolkit, httpFetchTool, calculatorTool, jsonParseTool, currentTimeTool, formatToolResult, formatToolResultAsText, createRetrievalTool, } from '@elsium-ai/tools';
|
|
19
|
+
export type { Tool, ToolConfig, ToolContext, ToolExecutionResult, Toolkit, RetrievalToolConfig, RetrievalResult as ToolRetrievalResult, RetrieveFn, } from '@elsium-ai/tools';
|
|
20
20
|
export { rag, createInMemoryStore, createOpenAIEmbeddings, createMockEmbeddings, vectorStoreRegistry, embeddingProviderRegistry, createPgVectorStore, } from '@elsium-ai/rag';
|
|
21
21
|
export type { RAGPipeline, RAGPipelineConfig, IngestResult, Document, Chunk, EmbeddedChunk, RetrievalResult, QueryOptions, EmbeddingProvider, VectorStore, VectorStoreFactory, EmbeddingProviderFactory, PgVectorStoreConfig, } from '@elsium-ai/rag';
|
|
22
22
|
export { defineWorkflow, defineParallelWorkflow, defineBranchWorkflow, step, } from '@elsium-ai/workflows';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAEN,WAAW,EAEX,EAAE,EACF,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EAEZ,YAAY,EAEZ,YAAY,EAEZ,GAAG,EACH,SAAS,EACT,OAAO,EAEP,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,EACL,KAAK,EAEL,eAAe,EAEf,cAAc,EAEd,WAAW,EACX,oBAAoB,GACpB,MAAM,iBAAiB,CAAA;AAExB,YAAY,EAEX,IAAI,EACJ,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,UAAU,EAEV,MAAM,EACN,EAAE,EACF,GAAG,EAEH,YAAY,EACZ,sBAAsB,EAEtB,QAAQ,EACR,MAAM,EAEN,SAAS,EAET,QAAQ,EAER,eAAe,EACf,oBAAoB,EACpB,cAAc,GACd,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACN,OAAO,EACP,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,oBAAoB,EAEpB,eAAe,EACf,mBAAmB,EAEnB,yBAAyB,EAEzB,WAAW,GACX,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACX,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,OAAO,EACP,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EAEd,YAAY,EACZ,UAAU,EACV,qBAAqB,EAErB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EAEf,WAAW,EACX,WAAW,EACX,eAAe,GACf,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACN,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EAEnB,yBAAyB,EACzB,uBAAuB,EAEvB,iBAAiB,EAEjB,YAAY,EACZ,UAAU,EACV,yBAAyB,EAEzB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAEN,WAAW,EAEX,EAAE,EACF,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,YAAY,EAEZ,YAAY,EAEZ,YAAY,EAEZ,GAAG,EACH,SAAS,EACT,OAAO,EAEP,UAAU,EACV,eAAe,EACf,WAAW,EACX,KAAK,EACL,KAAK,EAEL,eAAe,EAEf,cAAc,EAEd,WAAW,EACX,oBAAoB,GACpB,MAAM,iBAAiB,CAAA;AAExB,YAAY,EAEX,IAAI,EACJ,WAAW,EACX,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,UAAU,EAEV,MAAM,EACN,EAAE,EACF,GAAG,EAEH,YAAY,EACZ,sBAAsB,EAEtB,QAAQ,EACR,MAAM,EAEN,SAAS,EAET,QAAQ,EAER,eAAe,EACf,oBAAoB,EACpB,cAAc,GACd,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACN,OAAO,EACP,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,wBAAwB,EACxB,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,sBAAsB,EACtB,cAAc,EACd,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,oBAAoB,EAEpB,eAAe,EACf,mBAAmB,EAEnB,yBAAyB,EAEzB,WAAW,GACX,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACX,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,OAAO,EACP,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,eAAe,EACf,wBAAwB,EACxB,iBAAiB,EACjB,cAAc,EAEd,YAAY,EACZ,UAAU,EACV,qBAAqB,EAErB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EAEf,WAAW,EACX,WAAW,EACX,eAAe,GACf,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACN,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EAEnB,yBAAyB,EACzB,uBAAuB,EAEvB,iBAAiB,EAEjB,YAAY,EACZ,UAAU,EACV,yBAAyB,EAEzB,gBAAgB,EAEhB,oBAAoB,EACpB,oBAAoB,EAEpB,mBAAmB,EAEnB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,GACf,MAAM,mBAAmB,CAAA;AAE1B,YAAY,EACX,KAAK,EACL,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,WAAW,EACX,eAAe,EACf,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,EACZ,WAAW,EACX,uBAAuB,EACvB,aAAa,EACb,mBAAmB,EACnB,wBAAwB,EACxB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAElB,WAAW,EACX,uBAAuB,EAEvB,gBAAgB,EAChB,WAAW,EACX,0BAA0B,EAE1B,MAAM,EACN,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EAEb,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,iBAAiB,EAEjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EAEpB,aAAa,EACb,mBAAmB,EACnB,WAAW,EACX,qBAAqB,EAErB,SAAS,EACT,eAAe,EACf,eAAe,EACf,aAAa,EACb,UAAU,GACV,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACN,UAAU,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,mBAAmB,GACnB,MAAM,kBAAkB,CAAA;AAEzB,YAAY,EACX,IAAI,EACJ,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,OAAO,EACP,mBAAmB,EACnB,eAAe,IAAI,mBAAmB,EACtC,UAAU,GACV,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACN,GAAG,EACH,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EAEpB,mBAAmB,EACnB,yBAAyB,EAEzB,mBAAmB,GACnB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACX,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,GACnB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACN,cAAc,EACd,sBAAsB,EACtB,oBAAoB,EACpB,IAAI,GACJ,MAAM,sBAAsB,CAAA;AAE7B,YAAY,EACX,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,UAAU,GACV,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACN,OAAO,EACP,UAAU,EACV,aAAa,EACb,gBAAgB,EAEhB,gBAAgB,EAEhB,UAAU,EACV,mBAAmB,EACnB,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACX,MAAM,EACN,YAAY,EACZ,cAAc,EACd,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,sBAAsB,EACtB,eAAe,EAEf,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EAEjB,QAAQ,EACR,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,GAClB,MAAM,oBAAoB,CAAA;AAG3B,OAAO,EACN,SAAS,EAET,UAAU,EACV,SAAS,EACT,cAAc,EAEd,gBAAgB,EAChB,yBAAyB,GACzB,MAAM,gBAAgB,CAAA;AAEvB,YAAY,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEjE,YAAY,EACX,SAAS,EACT,eAAe,EACf,WAAW,EACX,SAAS,EACT,eAAe,GACf,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAEhD,YAAY,EACX,YAAY,EACZ,YAAY,GACZ,MAAM,mBAAmB,CAAA;AAG1B,OAAO,EACN,YAAY,EACZ,aAAa,EACb,WAAW,EACX,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,GAClB,MAAM,oBAAoB,CAAA;AAE3B,YAAY,EACX,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,aAAa,EACb,UAAU,EACV,eAAe,EACf,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,WAAW,EACX,cAAc,EACd,YAAY,GACZ,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3232,6 +3232,7 @@ function createProviderMesh(config) {
|
|
|
3232
3232
|
const sortedProviders = [...config.providers];
|
|
3233
3233
|
const gateways = new Map;
|
|
3234
3234
|
const circuitBreakers = new Map;
|
|
3235
|
+
const audit = config.audit;
|
|
3235
3236
|
for (const entry of sortedProviders) {
|
|
3236
3237
|
const gw = gateway({
|
|
3237
3238
|
provider: entry.name,
|
|
@@ -3242,7 +3243,19 @@ function createProviderMesh(config) {
|
|
|
3242
3243
|
gateways.set(entry.name, gw);
|
|
3243
3244
|
if (config.circuitBreaker) {
|
|
3244
3245
|
const cbConfig = typeof config.circuitBreaker === "boolean" ? {} : config.circuitBreaker;
|
|
3245
|
-
|
|
3246
|
+
const providerName = entry.name;
|
|
3247
|
+
const wrappedConfig = {
|
|
3248
|
+
...cbConfig,
|
|
3249
|
+
onStateChange(from, to) {
|
|
3250
|
+
cbConfig.onStateChange?.(from, to);
|
|
3251
|
+
audit?.log("circuit_breaker_state_change", {
|
|
3252
|
+
provider: providerName,
|
|
3253
|
+
fromState: from,
|
|
3254
|
+
toState: to
|
|
3255
|
+
});
|
|
3256
|
+
}
|
|
3257
|
+
};
|
|
3258
|
+
circuitBreakers.set(entry.name, createCircuitBreaker(wrappedConfig));
|
|
3246
3259
|
}
|
|
3247
3260
|
}
|
|
3248
3261
|
function callWithCircuitBreaker(providerName, fn) {
|
|
@@ -3264,23 +3277,41 @@ function createProviderMesh(config) {
|
|
|
3264
3277
|
}
|
|
3265
3278
|
return gw;
|
|
3266
3279
|
}
|
|
3267
|
-
|
|
3280
|
+
function attemptProvider(entry, request) {
|
|
3281
|
+
const gw = getGateway(entry.name);
|
|
3282
|
+
return callWithCircuitBreaker(entry.name, () => gw.complete({ ...request, model: request.model ?? entry.model }));
|
|
3283
|
+
}
|
|
3284
|
+
function logFailover(fromProvider, toProvider, reason) {
|
|
3285
|
+
audit?.log("provider_failover", {
|
|
3286
|
+
fromProvider,
|
|
3287
|
+
toProvider,
|
|
3288
|
+
strategy: config.strategy,
|
|
3289
|
+
reason
|
|
3290
|
+
});
|
|
3291
|
+
}
|
|
3292
|
+
function toError2(err2) {
|
|
3293
|
+
return err2 instanceof Error ? err2 : new Error(String(err2));
|
|
3294
|
+
}
|
|
3295
|
+
async function tryProvidersWithAudit(providers, request, errorMessage) {
|
|
3268
3296
|
let lastError = null;
|
|
3269
|
-
|
|
3297
|
+
let failedProvider = null;
|
|
3298
|
+
for (const entry of providers) {
|
|
3270
3299
|
if (!isProviderAvailable(entry.name))
|
|
3271
3300
|
continue;
|
|
3272
3301
|
try {
|
|
3273
|
-
const
|
|
3274
|
-
|
|
3302
|
+
const response = await attemptProvider(entry, request);
|
|
3303
|
+
if (failedProvider)
|
|
3304
|
+
logFailover(failedProvider, entry.name, lastError?.message);
|
|
3305
|
+
return response;
|
|
3275
3306
|
} catch (err2) {
|
|
3276
|
-
|
|
3307
|
+
failedProvider = entry.name;
|
|
3308
|
+
lastError = toError2(err2);
|
|
3277
3309
|
}
|
|
3278
3310
|
}
|
|
3279
|
-
throw lastError ?? new ElsiumError({
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
});
|
|
3311
|
+
throw lastError ?? new ElsiumError({ code: "PROVIDER_ERROR", message: errorMessage, retryable: false });
|
|
3312
|
+
}
|
|
3313
|
+
async function fallbackComplete(request) {
|
|
3314
|
+
return tryProvidersWithAudit(sortedProviders, request, "All providers failed");
|
|
3284
3315
|
}
|
|
3285
3316
|
async function costOptimizedComplete(request) {
|
|
3286
3317
|
const optimizer = config.costOptimizer;
|
|
@@ -3293,7 +3324,13 @@ function createProviderMesh(config) {
|
|
|
3293
3324
|
const gw = getGateway(target.provider);
|
|
3294
3325
|
try {
|
|
3295
3326
|
return await gw.complete({ ...request, model: target.model });
|
|
3296
|
-
} catch {
|
|
3327
|
+
} catch (err2) {
|
|
3328
|
+
audit?.log("provider_failover", {
|
|
3329
|
+
fromProvider: target.provider,
|
|
3330
|
+
toProvider: "fallback-chain",
|
|
3331
|
+
strategy: "cost-optimized",
|
|
3332
|
+
reason: err2 instanceof Error ? err2.message : String(err2)
|
|
3333
|
+
});
|
|
3297
3334
|
return fallbackComplete(request);
|
|
3298
3335
|
}
|
|
3299
3336
|
}
|
|
@@ -3337,31 +3374,13 @@ function createProviderMesh(config) {
|
|
|
3337
3374
|
return capabilities.every((c) => providerCaps.includes(c));
|
|
3338
3375
|
});
|
|
3339
3376
|
}
|
|
3340
|
-
async function tryProviders(providers, request) {
|
|
3341
|
-
let lastError = null;
|
|
3342
|
-
for (const entry of providers) {
|
|
3343
|
-
if (!isProviderAvailable(entry.name))
|
|
3344
|
-
continue;
|
|
3345
|
-
try {
|
|
3346
|
-
const gw = getGateway(entry.name);
|
|
3347
|
-
return await callWithCircuitBreaker(entry.name, () => gw.complete({ ...request, model: request.model ?? entry.model }));
|
|
3348
|
-
} catch (err2) {
|
|
3349
|
-
lastError = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
3350
|
-
}
|
|
3351
|
-
}
|
|
3352
|
-
throw lastError ?? new ElsiumError({
|
|
3353
|
-
code: "PROVIDER_ERROR",
|
|
3354
|
-
message: "No capable provider succeeded",
|
|
3355
|
-
retryable: false
|
|
3356
|
-
});
|
|
3357
|
-
}
|
|
3358
3377
|
async function capabilityAwareComplete(request) {
|
|
3359
3378
|
const capabilities = detectRequiredCapabilities(request);
|
|
3360
3379
|
const capable = filterCapableProviders(capabilities);
|
|
3361
3380
|
if (capable.length === 0) {
|
|
3362
3381
|
return fallbackComplete(request);
|
|
3363
3382
|
}
|
|
3364
|
-
return
|
|
3383
|
+
return tryProvidersWithAudit(capable, request, "No capable provider succeeded");
|
|
3365
3384
|
}
|
|
3366
3385
|
function defaultCapabilities(provider) {
|
|
3367
3386
|
const meta = getProviderMetadata(provider);
|
|
@@ -7858,6 +7877,35 @@ var currentTimeTool = defineTool({
|
|
|
7858
7877
|
};
|
|
7859
7878
|
}
|
|
7860
7879
|
});
|
|
7880
|
+
// ../tools/src/retrieval.ts
|
|
7881
|
+
function defaultFormatResults(results) {
|
|
7882
|
+
if (results.length === 0)
|
|
7883
|
+
return "No relevant results found.";
|
|
7884
|
+
return results.map((r, i) => {
|
|
7885
|
+
const source = r.source ? ` (source: ${r.source})` : "";
|
|
7886
|
+
return `[${i + 1}]${source} (score: ${r.score.toFixed(2)})
|
|
7887
|
+
${r.content}`;
|
|
7888
|
+
}).join(`
|
|
7889
|
+
|
|
7890
|
+
---
|
|
7891
|
+
|
|
7892
|
+
`);
|
|
7893
|
+
}
|
|
7894
|
+
function createRetrievalTool(config) {
|
|
7895
|
+
const topK = config.topK ?? 5;
|
|
7896
|
+
const formatResult = config.formatResult ?? defaultFormatResults;
|
|
7897
|
+
return defineTool({
|
|
7898
|
+
name: config.name ?? "search_knowledge",
|
|
7899
|
+
description: config.description ?? "Search the knowledge base for relevant information. Use this when you need to find facts, documentation, or context to answer questions.",
|
|
7900
|
+
input: exports_external.object({
|
|
7901
|
+
query: exports_external.string().describe("The search query to find relevant information")
|
|
7902
|
+
}),
|
|
7903
|
+
async handler(input) {
|
|
7904
|
+
const results = await config.retrieve(input.query, { topK });
|
|
7905
|
+
return formatResult(results);
|
|
7906
|
+
}
|
|
7907
|
+
});
|
|
7908
|
+
}
|
|
7861
7909
|
// ../agents/src/approval.ts
|
|
7862
7910
|
function createApprovalGate(config) {
|
|
7863
7911
|
const timeoutMs = config.timeoutMs ?? 300000;
|
|
@@ -8036,6 +8084,35 @@ function createMemory(config) {
|
|
|
8036
8084
|
messages.shift();
|
|
8037
8085
|
}
|
|
8038
8086
|
}
|
|
8087
|
+
let summaryPending = false;
|
|
8088
|
+
function needsSummarization() {
|
|
8089
|
+
if (config.strategy !== "summary")
|
|
8090
|
+
return false;
|
|
8091
|
+
if (!config.summarize)
|
|
8092
|
+
return false;
|
|
8093
|
+
return messages.length > maxMessages;
|
|
8094
|
+
}
|
|
8095
|
+
async function runSummarization() {
|
|
8096
|
+
if (summaryPending || !config.summarize)
|
|
8097
|
+
return;
|
|
8098
|
+
if (messages.length <= maxMessages)
|
|
8099
|
+
return;
|
|
8100
|
+
summaryPending = true;
|
|
8101
|
+
try {
|
|
8102
|
+
const keepCount = Math.floor(maxMessages / 2);
|
|
8103
|
+
const toSummarize = messages.splice(0, messages.length - keepCount);
|
|
8104
|
+
const summaryText = await config.summarize(toSummarize);
|
|
8105
|
+
messages.unshift({
|
|
8106
|
+
role: "system",
|
|
8107
|
+
content: `[Conversation summary]: ${summaryText}`
|
|
8108
|
+
});
|
|
8109
|
+
} finally {
|
|
8110
|
+
summaryPending = false;
|
|
8111
|
+
}
|
|
8112
|
+
if (config.store && config.agentId) {
|
|
8113
|
+
config.store.save(config.agentId, [...messages]).catch(() => {});
|
|
8114
|
+
}
|
|
8115
|
+
}
|
|
8039
8116
|
return {
|
|
8040
8117
|
strategy: config.strategy,
|
|
8041
8118
|
add(message) {
|
|
@@ -8047,6 +8124,8 @@ function createMemory(config) {
|
|
|
8047
8124
|
case "token-limited":
|
|
8048
8125
|
trimToTokenLimit();
|
|
8049
8126
|
break;
|
|
8127
|
+
case "summary":
|
|
8128
|
+
break;
|
|
8050
8129
|
case "unlimited":
|
|
8051
8130
|
break;
|
|
8052
8131
|
}
|
|
@@ -8077,9 +8156,28 @@ function createMemory(config) {
|
|
|
8077
8156
|
if (!config.store || !config.agentId)
|
|
8078
8157
|
return;
|
|
8079
8158
|
await config.store.save(config.agentId, [...messages]);
|
|
8159
|
+
},
|
|
8160
|
+
async summarizeIfNeeded() {
|
|
8161
|
+
if (needsSummarization()) {
|
|
8162
|
+
await runSummarization();
|
|
8163
|
+
}
|
|
8080
8164
|
}
|
|
8081
8165
|
};
|
|
8082
8166
|
}
|
|
8167
|
+
var SUMMARIZE_SYSTEM = "You are a conversation summarizer. Given a conversation, produce a concise summary that preserves all key facts, decisions, user preferences, and context needed to continue the conversation. Be factual and complete. Do not add commentary.";
|
|
8168
|
+
function createSummarizeFn(complete) {
|
|
8169
|
+
return async (messages) => {
|
|
8170
|
+
const text = messages.map((m) => `${m.role}: ${extractText(m.content)}`).join(`
|
|
8171
|
+
`);
|
|
8172
|
+
const response = await complete({
|
|
8173
|
+
messages: [{ role: "user", content: `Summarize this conversation:
|
|
8174
|
+
|
|
8175
|
+
${text}` }],
|
|
8176
|
+
system: SUMMARIZE_SYSTEM
|
|
8177
|
+
});
|
|
8178
|
+
return extractText(response.message.content);
|
|
8179
|
+
};
|
|
8180
|
+
}
|
|
8083
8181
|
|
|
8084
8182
|
// ../agents/src/security.ts
|
|
8085
8183
|
var INJECTION_PATTERNS2 = [
|
|
@@ -9153,6 +9251,34 @@ function defineAgent(config, deps) {
|
|
|
9153
9251
|
const userMessage = { role: "user", content: input };
|
|
9154
9252
|
return executeLoop([userMessage], options);
|
|
9155
9253
|
},
|
|
9254
|
+
async generate(input, schema, options = {}) {
|
|
9255
|
+
validateInputText(input);
|
|
9256
|
+
const jsonSchema = zodToJsonSchema(schema);
|
|
9257
|
+
const schemaInstruction = [
|
|
9258
|
+
"You MUST respond with valid JSON matching this schema:",
|
|
9259
|
+
JSON.stringify(jsonSchema, null, 2),
|
|
9260
|
+
"Respond ONLY with the JSON object, no markdown or explanation."
|
|
9261
|
+
].join(`
|
|
9262
|
+
`);
|
|
9263
|
+
const augmentedInput = `${input}
|
|
9264
|
+
|
|
9265
|
+
${schemaInstruction}`;
|
|
9266
|
+
const userMessage = { role: "user", content: augmentedInput };
|
|
9267
|
+
const agentResult = await executeLoop([userMessage], options);
|
|
9268
|
+
const text = extractText(agentResult.message.content);
|
|
9269
|
+
const cleaned = text.replace(/^```(?:json)?\s*\n?([\s\S]*?)\n?\s*```$/gm, "$1").trim();
|
|
9270
|
+
const jsonMatch = cleaned.match(/(\{[\s\S]*\}|\[[\s\S]*\])/);
|
|
9271
|
+
if (!jsonMatch) {
|
|
9272
|
+
throw ElsiumError.validation("Agent response did not contain valid JSON");
|
|
9273
|
+
}
|
|
9274
|
+
const parsed = schema.safeParse(JSON.parse(jsonMatch[0]));
|
|
9275
|
+
if (!parsed.success) {
|
|
9276
|
+
throw ElsiumError.validation("Agent response did not match schema", {
|
|
9277
|
+
errors: parsed.error.issues
|
|
9278
|
+
});
|
|
9279
|
+
}
|
|
9280
|
+
return { data: parsed.data, result: agentResult };
|
|
9281
|
+
},
|
|
9156
9282
|
stream(input, options = {}) {
|
|
9157
9283
|
validateInputText(input);
|
|
9158
9284
|
const streamDeps = resolvedDeps;
|
|
@@ -9635,6 +9761,429 @@ function createAsyncAgent(config) {
|
|
|
9635
9761
|
}
|
|
9636
9762
|
};
|
|
9637
9763
|
}
|
|
9764
|
+
// ../agents/src/channels.ts
|
|
9765
|
+
function createWebhookChannel(config) {
|
|
9766
|
+
let messageHandler = null;
|
|
9767
|
+
return {
|
|
9768
|
+
name: config.name,
|
|
9769
|
+
async start() {},
|
|
9770
|
+
async stop() {},
|
|
9771
|
+
async send(userId, message) {
|
|
9772
|
+
await config.onSend?.(userId, message);
|
|
9773
|
+
},
|
|
9774
|
+
onMessage(handler) {
|
|
9775
|
+
messageHandler = handler;
|
|
9776
|
+
},
|
|
9777
|
+
receive(message) {
|
|
9778
|
+
if (!messageHandler)
|
|
9779
|
+
return;
|
|
9780
|
+
messageHandler({ ...message, channelName: config.name });
|
|
9781
|
+
}
|
|
9782
|
+
};
|
|
9783
|
+
}
|
|
9784
|
+
function createChannelGateway(config) {
|
|
9785
|
+
const adapterMap = new Map;
|
|
9786
|
+
for (const adapter of config.adapters) {
|
|
9787
|
+
if (adapter.name === "__proto__" || adapter.name === "constructor" || adapter.name === "prototype")
|
|
9788
|
+
continue;
|
|
9789
|
+
adapterMap.set(adapter.name, adapter);
|
|
9790
|
+
}
|
|
9791
|
+
function findAdapter(channelName) {
|
|
9792
|
+
return adapterMap.get(channelName);
|
|
9793
|
+
}
|
|
9794
|
+
async function handleIncoming(message) {
|
|
9795
|
+
const agent = config.resolveAgent?.(message) ?? config.agent;
|
|
9796
|
+
try {
|
|
9797
|
+
const session = await config.router.resolve({
|
|
9798
|
+
channelName: message.channelName,
|
|
9799
|
+
userId: message.userId,
|
|
9800
|
+
agent
|
|
9801
|
+
});
|
|
9802
|
+
const result = await session.send(message.text);
|
|
9803
|
+
const responseText = typeof result.message.content === "string" ? result.message.content : "";
|
|
9804
|
+
const adapter = findAdapter(message.channelName);
|
|
9805
|
+
if (adapter && responseText) {
|
|
9806
|
+
await adapter.send(message.userId, { text: responseText });
|
|
9807
|
+
}
|
|
9808
|
+
} catch (err2) {
|
|
9809
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
9810
|
+
try {
|
|
9811
|
+
config.onError?.(error, message);
|
|
9812
|
+
} catch {}
|
|
9813
|
+
}
|
|
9814
|
+
}
|
|
9815
|
+
for (const adapter of config.adapters) {
|
|
9816
|
+
adapter.onMessage(handleIncoming);
|
|
9817
|
+
}
|
|
9818
|
+
return {
|
|
9819
|
+
adapters: adapterMap,
|
|
9820
|
+
async start() {
|
|
9821
|
+
const startPromises = [...adapterMap.values()].map((a) => a.start());
|
|
9822
|
+
await Promise.all(startPromises);
|
|
9823
|
+
},
|
|
9824
|
+
async stop() {
|
|
9825
|
+
const stopPromises = [...adapterMap.values()].map((a) => a.stop());
|
|
9826
|
+
await Promise.all(stopPromises);
|
|
9827
|
+
}
|
|
9828
|
+
};
|
|
9829
|
+
}
|
|
9830
|
+
// ../agents/src/session.ts
|
|
9831
|
+
function sessionKey(channelName, userId) {
|
|
9832
|
+
return `${channelName}::${userId}`;
|
|
9833
|
+
}
|
|
9834
|
+
function createSessionRouter(config) {
|
|
9835
|
+
const sessions = new Map;
|
|
9836
|
+
const concurrency = config.concurrency ?? "serial";
|
|
9837
|
+
const sessionTimeout = config.sessionTimeout ?? 0;
|
|
9838
|
+
let cleanupTimer = null;
|
|
9839
|
+
if (sessionTimeout > 0) {
|
|
9840
|
+
cleanupTimer = setInterval(() => {
|
|
9841
|
+
const now = Date.now();
|
|
9842
|
+
for (const [key, session] of sessions) {
|
|
9843
|
+
if (now - session.lastActiveAt > sessionTimeout) {
|
|
9844
|
+
sessions.delete(key);
|
|
9845
|
+
try {
|
|
9846
|
+
config.onSessionExpired?.({
|
|
9847
|
+
sessionId: session.sessionId,
|
|
9848
|
+
channelName: session.channelName,
|
|
9849
|
+
userId: session.userId,
|
|
9850
|
+
agentName: session.agent.name,
|
|
9851
|
+
createdAt: session.createdAt,
|
|
9852
|
+
lastActiveAt: session.lastActiveAt
|
|
9853
|
+
});
|
|
9854
|
+
} catch {}
|
|
9855
|
+
}
|
|
9856
|
+
}
|
|
9857
|
+
}, Math.min(sessionTimeout, 60000));
|
|
9858
|
+
if (typeof cleanupTimer === "object" && "unref" in cleanupTimer) {
|
|
9859
|
+
cleanupTimer.unref();
|
|
9860
|
+
}
|
|
9861
|
+
}
|
|
9862
|
+
function toPublicSession(session) {
|
|
9863
|
+
return {
|
|
9864
|
+
sessionId: session.sessionId,
|
|
9865
|
+
channelName: session.channelName,
|
|
9866
|
+
userId: session.userId,
|
|
9867
|
+
agentName: session.agent.name,
|
|
9868
|
+
createdAt: session.createdAt,
|
|
9869
|
+
lastActiveAt: session.lastActiveAt
|
|
9870
|
+
};
|
|
9871
|
+
}
|
|
9872
|
+
async function createNewSession(key, channelName, userId, agent) {
|
|
9873
|
+
const sessionId = generateId("sess");
|
|
9874
|
+
const threadId = `${channelName}-${userId}-${sessionId}`;
|
|
9875
|
+
let thread = null;
|
|
9876
|
+
if (config.store) {
|
|
9877
|
+
thread = await loadThread(threadId, { agent, store: config.store });
|
|
9878
|
+
}
|
|
9879
|
+
if (!thread) {
|
|
9880
|
+
thread = createThread({
|
|
9881
|
+
id: threadId,
|
|
9882
|
+
agent,
|
|
9883
|
+
metadata: { channelName, userId, sessionId },
|
|
9884
|
+
store: config.store
|
|
9885
|
+
});
|
|
9886
|
+
}
|
|
9887
|
+
const now = Date.now();
|
|
9888
|
+
const session = {
|
|
9889
|
+
sessionId,
|
|
9890
|
+
channelName,
|
|
9891
|
+
userId,
|
|
9892
|
+
agent,
|
|
9893
|
+
thread,
|
|
9894
|
+
createdAt: now,
|
|
9895
|
+
lastActiveAt: now,
|
|
9896
|
+
lock: null,
|
|
9897
|
+
lockResolve: null
|
|
9898
|
+
};
|
|
9899
|
+
sessions.set(key, session);
|
|
9900
|
+
try {
|
|
9901
|
+
config.onSessionCreated?.(toPublicSession(session));
|
|
9902
|
+
} catch {}
|
|
9903
|
+
return session;
|
|
9904
|
+
}
|
|
9905
|
+
function wrapThreadWithConcurrency(session) {
|
|
9906
|
+
if (concurrency !== "serial")
|
|
9907
|
+
return session.thread;
|
|
9908
|
+
const originalSend = session.thread.send.bind(session.thread);
|
|
9909
|
+
return {
|
|
9910
|
+
...session.thread,
|
|
9911
|
+
async send(input, options) {
|
|
9912
|
+
while (session.lock) {
|
|
9913
|
+
await session.lock;
|
|
9914
|
+
}
|
|
9915
|
+
let unlock;
|
|
9916
|
+
session.lock = new Promise((resolve) => {
|
|
9917
|
+
unlock = resolve;
|
|
9918
|
+
});
|
|
9919
|
+
session.lockResolve = unlock;
|
|
9920
|
+
try {
|
|
9921
|
+
const result = await originalSend(input, options);
|
|
9922
|
+
session.lastActiveAt = Date.now();
|
|
9923
|
+
return result;
|
|
9924
|
+
} finally {
|
|
9925
|
+
session.lock = null;
|
|
9926
|
+
session.lockResolve = null;
|
|
9927
|
+
unlock();
|
|
9928
|
+
}
|
|
9929
|
+
}
|
|
9930
|
+
};
|
|
9931
|
+
}
|
|
9932
|
+
return {
|
|
9933
|
+
async resolve(options) {
|
|
9934
|
+
const agent = options.agent ?? config.defaultAgent;
|
|
9935
|
+
const key = sessionKey(options.channelName, options.userId);
|
|
9936
|
+
let session = sessions.get(key);
|
|
9937
|
+
if (session && sessionTimeout > 0) {
|
|
9938
|
+
const now = Date.now();
|
|
9939
|
+
if (now - session.lastActiveAt > sessionTimeout) {
|
|
9940
|
+
sessions.delete(key);
|
|
9941
|
+
try {
|
|
9942
|
+
config.onSessionExpired?.(toPublicSession(session));
|
|
9943
|
+
} catch {}
|
|
9944
|
+
session = undefined;
|
|
9945
|
+
}
|
|
9946
|
+
}
|
|
9947
|
+
if (!session) {
|
|
9948
|
+
session = await createNewSession(key, options.channelName, options.userId, agent);
|
|
9949
|
+
}
|
|
9950
|
+
session.lastActiveAt = Date.now();
|
|
9951
|
+
return wrapThreadWithConcurrency(session);
|
|
9952
|
+
},
|
|
9953
|
+
getSession(channelName, userId) {
|
|
9954
|
+
const session = sessions.get(sessionKey(channelName, userId));
|
|
9955
|
+
return session ? toPublicSession(session) : null;
|
|
9956
|
+
},
|
|
9957
|
+
listSessions() {
|
|
9958
|
+
return [...sessions.values()].map(toPublicSession);
|
|
9959
|
+
},
|
|
9960
|
+
endSession(channelName, userId) {
|
|
9961
|
+
return sessions.delete(sessionKey(channelName, userId));
|
|
9962
|
+
},
|
|
9963
|
+
endAllSessions() {
|
|
9964
|
+
sessions.clear();
|
|
9965
|
+
if (cleanupTimer) {
|
|
9966
|
+
clearInterval(cleanupTimer);
|
|
9967
|
+
cleanupTimer = null;
|
|
9968
|
+
}
|
|
9969
|
+
}
|
|
9970
|
+
};
|
|
9971
|
+
}
|
|
9972
|
+
// ../agents/src/scheduler.ts
|
|
9973
|
+
function parseCronExpression(expression) {
|
|
9974
|
+
const parts = expression.trim().split(/\s+/);
|
|
9975
|
+
if (parts.length !== 5)
|
|
9976
|
+
return null;
|
|
9977
|
+
const minute = parseCronField(parts[0], 0, 59);
|
|
9978
|
+
const hour = parseCronField(parts[1], 0, 23);
|
|
9979
|
+
const dayOfMonth = parseCronField(parts[2], 1, 31);
|
|
9980
|
+
const month = parseCronField(parts[3], 1, 12);
|
|
9981
|
+
const dayOfWeek = parseCronField(parts[4], 0, 6);
|
|
9982
|
+
if (!minute || !hour || !dayOfMonth || !month || !dayOfWeek)
|
|
9983
|
+
return null;
|
|
9984
|
+
return { minute, hour, dayOfMonth, month, dayOfWeek };
|
|
9985
|
+
}
|
|
9986
|
+
function parseStepPart(match, min, max) {
|
|
9987
|
+
const step = Number.parseInt(match[2], 10);
|
|
9988
|
+
if (step <= 0)
|
|
9989
|
+
return null;
|
|
9990
|
+
let rangeStart = min;
|
|
9991
|
+
let rangeEnd = max;
|
|
9992
|
+
if (match[1] !== "*") {
|
|
9993
|
+
const rangeParts = match[1].split("-");
|
|
9994
|
+
rangeStart = Number.parseInt(rangeParts[0], 10);
|
|
9995
|
+
rangeEnd = rangeParts[1] ? Number.parseInt(rangeParts[1], 10) : max;
|
|
9996
|
+
}
|
|
9997
|
+
const values = [];
|
|
9998
|
+
for (let i = rangeStart;i <= rangeEnd; i += step) {
|
|
9999
|
+
if (i >= min && i <= max)
|
|
10000
|
+
values.push(i);
|
|
10001
|
+
}
|
|
10002
|
+
return values;
|
|
10003
|
+
}
|
|
10004
|
+
function parseRangePart(match, min, max) {
|
|
10005
|
+
const start = Number.parseInt(match[1], 10);
|
|
10006
|
+
const end = Number.parseInt(match[2], 10);
|
|
10007
|
+
if (start > end || start < min || end > max)
|
|
10008
|
+
return null;
|
|
10009
|
+
const values = [];
|
|
10010
|
+
for (let i = start;i <= end; i++) {
|
|
10011
|
+
values.push(i);
|
|
10012
|
+
}
|
|
10013
|
+
return values;
|
|
10014
|
+
}
|
|
10015
|
+
function parseSinglePart(part, min, max) {
|
|
10016
|
+
const stepMatch = part.match(/^(\*|\d+(?:-\d+)?)\/(\d+)$/);
|
|
10017
|
+
if (stepMatch)
|
|
10018
|
+
return parseStepPart(stepMatch, min, max);
|
|
10019
|
+
const rangeMatch = part.match(/^(\d+)-(\d+)$/);
|
|
10020
|
+
if (rangeMatch)
|
|
10021
|
+
return parseRangePart(rangeMatch, min, max);
|
|
10022
|
+
const num = Number.parseInt(part, 10);
|
|
10023
|
+
if (Number.isNaN(num) || num < min || num > max)
|
|
10024
|
+
return null;
|
|
10025
|
+
return [num];
|
|
10026
|
+
}
|
|
10027
|
+
function parseCronField(field, min, max) {
|
|
10028
|
+
if (field === "*") {
|
|
10029
|
+
return Array.from({ length: max - min + 1 }, (_, i) => min + i);
|
|
10030
|
+
}
|
|
10031
|
+
const values = [];
|
|
10032
|
+
for (const part of field.split(",")) {
|
|
10033
|
+
const result = parseSinglePart(part, min, max);
|
|
10034
|
+
if (!result)
|
|
10035
|
+
return null;
|
|
10036
|
+
values.push(...result);
|
|
10037
|
+
}
|
|
10038
|
+
return values.length > 0 ? values : null;
|
|
10039
|
+
}
|
|
10040
|
+
function cronMatchesDate(fields, date) {
|
|
10041
|
+
return fields.minute.includes(date.getMinutes()) && fields.hour.includes(date.getHours()) && fields.dayOfMonth.includes(date.getDate()) && fields.month.includes(date.getMonth() + 1) && fields.dayOfWeek.includes(date.getDay());
|
|
10042
|
+
}
|
|
10043
|
+
function getNextCronDate(fields, after) {
|
|
10044
|
+
const next = new Date(after.getTime());
|
|
10045
|
+
next.setSeconds(0, 0);
|
|
10046
|
+
next.setMinutes(next.getMinutes() + 1);
|
|
10047
|
+
const maxIterations = 525600;
|
|
10048
|
+
for (let i = 0;i < maxIterations; i++) {
|
|
10049
|
+
if (cronMatchesDate(fields, next))
|
|
10050
|
+
return next;
|
|
10051
|
+
next.setMinutes(next.getMinutes() + 1);
|
|
10052
|
+
}
|
|
10053
|
+
return next;
|
|
10054
|
+
}
|
|
10055
|
+
function createScheduler(config) {
|
|
10056
|
+
const tasks = new Map;
|
|
10057
|
+
let timer = null;
|
|
10058
|
+
const tickInterval = config.tickIntervalMs ?? 60000;
|
|
10059
|
+
function toPublicTask(task) {
|
|
10060
|
+
return {
|
|
10061
|
+
id: task.id,
|
|
10062
|
+
name: task.name,
|
|
10063
|
+
cronExpression: task.cronExpression,
|
|
10064
|
+
enabled: task.enabled,
|
|
10065
|
+
lastRunAt: task.lastRunAt,
|
|
10066
|
+
nextRunAt: task.nextRunAt,
|
|
10067
|
+
runCount: task.runCount
|
|
10068
|
+
};
|
|
10069
|
+
}
|
|
10070
|
+
function updateNextRun(task) {
|
|
10071
|
+
const fields = parseCronExpression(task.cronExpression);
|
|
10072
|
+
task.nextRunAt = fields ? getNextCronDate(fields, new Date).getTime() : null;
|
|
10073
|
+
}
|
|
10074
|
+
function handleTaskSuccess(task, result) {
|
|
10075
|
+
task.lastRunAt = Date.now();
|
|
10076
|
+
task.runCount++;
|
|
10077
|
+
task.running = false;
|
|
10078
|
+
if (task.maxRuns !== null && task.runCount >= task.maxRuns) {
|
|
10079
|
+
task.enabled = false;
|
|
10080
|
+
task.nextRunAt = null;
|
|
10081
|
+
} else {
|
|
10082
|
+
updateNextRun(task);
|
|
10083
|
+
}
|
|
10084
|
+
try {
|
|
10085
|
+
config.onComplete?.(toPublicTask(task), result);
|
|
10086
|
+
} catch {}
|
|
10087
|
+
}
|
|
10088
|
+
function handleTaskError(task, err2) {
|
|
10089
|
+
task.running = false;
|
|
10090
|
+
task.lastRunAt = Date.now();
|
|
10091
|
+
updateNextRun(task);
|
|
10092
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
10093
|
+
try {
|
|
10094
|
+
config.onError?.(toPublicTask(task), error);
|
|
10095
|
+
} catch {}
|
|
10096
|
+
}
|
|
10097
|
+
async function executeTask(task) {
|
|
10098
|
+
if (task.running)
|
|
10099
|
+
return;
|
|
10100
|
+
task.running = true;
|
|
10101
|
+
const agent = config.resolveAgent?.(toPublicTask(task)) ?? config.agent;
|
|
10102
|
+
try {
|
|
10103
|
+
const result = await agent.run(task.input);
|
|
10104
|
+
handleTaskSuccess(task, result);
|
|
10105
|
+
} catch (err2) {
|
|
10106
|
+
handleTaskError(task, err2);
|
|
10107
|
+
}
|
|
10108
|
+
}
|
|
10109
|
+
function tick() {
|
|
10110
|
+
const now = Date.now();
|
|
10111
|
+
for (const task of tasks.values()) {
|
|
10112
|
+
if (!task.enabled || task.running)
|
|
10113
|
+
continue;
|
|
10114
|
+
if (task.nextRunAt !== null && task.nextRunAt <= now) {
|
|
10115
|
+
executeTask(task);
|
|
10116
|
+
}
|
|
10117
|
+
}
|
|
10118
|
+
}
|
|
10119
|
+
return {
|
|
10120
|
+
schedule(cronExpression, input, options = {}) {
|
|
10121
|
+
const fields = parseCronExpression(cronExpression);
|
|
10122
|
+
if (!fields) {
|
|
10123
|
+
throw new Error(`Invalid cron expression: ${cronExpression}`);
|
|
10124
|
+
}
|
|
10125
|
+
const id = options.id ?? generateId("sched");
|
|
10126
|
+
const now = new Date;
|
|
10127
|
+
const nextRunAt = options.startImmediately ? Date.now() : getNextCronDate(fields, now).getTime();
|
|
10128
|
+
const task = {
|
|
10129
|
+
id,
|
|
10130
|
+
name: options.name ?? `task-${id}`,
|
|
10131
|
+
cronExpression,
|
|
10132
|
+
input,
|
|
10133
|
+
enabled: true,
|
|
10134
|
+
lastRunAt: null,
|
|
10135
|
+
nextRunAt,
|
|
10136
|
+
runCount: 0,
|
|
10137
|
+
maxRuns: options.maxRuns ?? null,
|
|
10138
|
+
metadata: options.metadata ?? {},
|
|
10139
|
+
running: false
|
|
10140
|
+
};
|
|
10141
|
+
tasks.set(id, task);
|
|
10142
|
+
if (options.startImmediately) {
|
|
10143
|
+
executeTask(task);
|
|
10144
|
+
}
|
|
10145
|
+
return toPublicTask(task);
|
|
10146
|
+
},
|
|
10147
|
+
unschedule(taskId) {
|
|
10148
|
+
return tasks.delete(taskId);
|
|
10149
|
+
},
|
|
10150
|
+
getTask(taskId) {
|
|
10151
|
+
const task = tasks.get(taskId);
|
|
10152
|
+
return task ? toPublicTask(task) : null;
|
|
10153
|
+
},
|
|
10154
|
+
listTasks() {
|
|
10155
|
+
return [...tasks.values()].map(toPublicTask);
|
|
10156
|
+
},
|
|
10157
|
+
pause(taskId) {
|
|
10158
|
+
const task = tasks.get(taskId);
|
|
10159
|
+
if (!task)
|
|
10160
|
+
return false;
|
|
10161
|
+
task.enabled = false;
|
|
10162
|
+
return true;
|
|
10163
|
+
},
|
|
10164
|
+
resume(taskId) {
|
|
10165
|
+
const task = tasks.get(taskId);
|
|
10166
|
+
if (!task)
|
|
10167
|
+
return false;
|
|
10168
|
+
task.enabled = true;
|
|
10169
|
+
const fields = parseCronExpression(task.cronExpression);
|
|
10170
|
+
task.nextRunAt = fields ? getNextCronDate(fields, new Date).getTime() : null;
|
|
10171
|
+
return true;
|
|
10172
|
+
},
|
|
10173
|
+
start() {
|
|
10174
|
+
if (timer)
|
|
10175
|
+
return;
|
|
10176
|
+
tick();
|
|
10177
|
+
timer = setInterval(tick, tickInterval);
|
|
10178
|
+
},
|
|
10179
|
+
stop() {
|
|
10180
|
+
if (timer) {
|
|
10181
|
+
clearInterval(timer);
|
|
10182
|
+
timer = null;
|
|
10183
|
+
}
|
|
10184
|
+
}
|
|
10185
|
+
};
|
|
10186
|
+
}
|
|
9638
10187
|
// ../rag/src/loaders.ts
|
|
9639
10188
|
function createDocument(content, metadata) {
|
|
9640
10189
|
return {
|
|
@@ -11339,6 +11888,8 @@ function createMetrics(options) {
|
|
|
11339
11888
|
}
|
|
11340
11889
|
};
|
|
11341
11890
|
}
|
|
11891
|
+
// ../observe/src/audit.ts
|
|
11892
|
+
var ZERO_HASH = "0".repeat(64);
|
|
11342
11893
|
// ../observe/src/experiment.ts
|
|
11343
11894
|
import { createHash as createHash2 } from "node:crypto";
|
|
11344
11895
|
var log10 = createLogger();
|
|
@@ -15735,6 +16286,7 @@ export {
|
|
|
15735
16286
|
redactSecrets,
|
|
15736
16287
|
rag,
|
|
15737
16288
|
parseTraceparent,
|
|
16289
|
+
parseCronExpression,
|
|
15738
16290
|
outputGuardrailMiddleware,
|
|
15739
16291
|
ok,
|
|
15740
16292
|
observe,
|
|
@@ -15750,6 +16302,7 @@ export {
|
|
|
15750
16302
|
httpFetchTool,
|
|
15751
16303
|
getProviderMetadata,
|
|
15752
16304
|
getProviderFactory,
|
|
16305
|
+
getNextCronDate,
|
|
15753
16306
|
generateTraceId,
|
|
15754
16307
|
generateId,
|
|
15755
16308
|
gateway,
|
|
@@ -15774,13 +16327,19 @@ export {
|
|
|
15774
16327
|
defineBranchWorkflow,
|
|
15775
16328
|
defineAgent,
|
|
15776
16329
|
currentTimeTool,
|
|
16330
|
+
cronMatchesDate,
|
|
16331
|
+
createWebhookChannel,
|
|
15777
16332
|
createToolkit,
|
|
15778
16333
|
createThread,
|
|
16334
|
+
createSummarizeFn,
|
|
15779
16335
|
createStream,
|
|
15780
16336
|
createSqliteMemoryStore,
|
|
15781
16337
|
createSpan,
|
|
15782
16338
|
createSnapshotStore,
|
|
16339
|
+
createSessionRouter,
|
|
15783
16340
|
createSemanticValidator,
|
|
16341
|
+
createScheduler,
|
|
16342
|
+
createRetrievalTool,
|
|
15784
16343
|
createReplayRecorder,
|
|
15785
16344
|
createReplayPlayer,
|
|
15786
16345
|
createRegressionSuite,
|
|
@@ -15809,6 +16368,7 @@ export {
|
|
|
15809
16368
|
createContextManager,
|
|
15810
16369
|
createConfidenceScorer,
|
|
15811
16370
|
createClient,
|
|
16371
|
+
createChannelGateway,
|
|
15812
16372
|
createBatch,
|
|
15813
16373
|
createAsyncAgent,
|
|
15814
16374
|
createApp,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elsium-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "ElsiumAI — A high-performance, TypeScript-first AI framework",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Eric Utrera <ebutrera9103@gmail.com>",
|
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
"build": "bun build ./src/index.ts --outdir ./dist --target node && bun x tsc -p tsconfig.build.json --emitDeclarationOnly"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@elsium-ai/core": "^0.
|
|
29
|
-
"@elsium-ai/gateway": "^0.
|
|
30
|
-
"@elsium-ai/agents": "^0.
|
|
31
|
-
"@elsium-ai/tools": "^0.
|
|
32
|
-
"@elsium-ai/rag": "^0.
|
|
33
|
-
"@elsium-ai/workflows": "^0.
|
|
34
|
-
"@elsium-ai/observe": "^0.
|
|
35
|
-
"@elsium-ai/app": "^0.
|
|
36
|
-
"@elsium-ai/testing": "^0.
|
|
37
|
-
"@elsium-ai/mcp": "^0.
|
|
38
|
-
"@elsium-ai/client": "^0.
|
|
28
|
+
"@elsium-ai/core": "^0.7.0",
|
|
29
|
+
"@elsium-ai/gateway": "^0.7.0",
|
|
30
|
+
"@elsium-ai/agents": "^0.7.0",
|
|
31
|
+
"@elsium-ai/tools": "^0.7.0",
|
|
32
|
+
"@elsium-ai/rag": "^0.7.0",
|
|
33
|
+
"@elsium-ai/workflows": "^0.7.0",
|
|
34
|
+
"@elsium-ai/observe": "^0.7.0",
|
|
35
|
+
"@elsium-ai/app": "^0.7.0",
|
|
36
|
+
"@elsium-ai/testing": "^0.7.0",
|
|
37
|
+
"@elsium-ai/mcp": "^0.7.0",
|
|
38
|
+
"@elsium-ai/client": "^0.7.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"typescript": "^5.7.0"
|