elsium-ai 0.4.3 → 0.6.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 +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1051 -2
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -13,10 +13,10 @@ export { ElsiumError, ok, err, isOk, isErr, unwrap, unwrapOr, tryCatch, tryCatch
|
|
|
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
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, } 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, } 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';
|
|
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,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7858,6 +7858,35 @@ var currentTimeTool = defineTool({
|
|
|
7858
7858
|
};
|
|
7859
7859
|
}
|
|
7860
7860
|
});
|
|
7861
|
+
// ../tools/src/retrieval.ts
|
|
7862
|
+
function defaultFormatResults(results) {
|
|
7863
|
+
if (results.length === 0)
|
|
7864
|
+
return "No relevant results found.";
|
|
7865
|
+
return results.map((r, i) => {
|
|
7866
|
+
const source = r.source ? ` (source: ${r.source})` : "";
|
|
7867
|
+
return `[${i + 1}]${source} (score: ${r.score.toFixed(2)})
|
|
7868
|
+
${r.content}`;
|
|
7869
|
+
}).join(`
|
|
7870
|
+
|
|
7871
|
+
---
|
|
7872
|
+
|
|
7873
|
+
`);
|
|
7874
|
+
}
|
|
7875
|
+
function createRetrievalTool(config) {
|
|
7876
|
+
const topK = config.topK ?? 5;
|
|
7877
|
+
const formatResult = config.formatResult ?? defaultFormatResults;
|
|
7878
|
+
return defineTool({
|
|
7879
|
+
name: config.name ?? "search_knowledge",
|
|
7880
|
+
description: config.description ?? "Search the knowledge base for relevant information. Use this when you need to find facts, documentation, or context to answer questions.",
|
|
7881
|
+
input: exports_external.object({
|
|
7882
|
+
query: exports_external.string().describe("The search query to find relevant information")
|
|
7883
|
+
}),
|
|
7884
|
+
async handler(input) {
|
|
7885
|
+
const results = await config.retrieve(input.query, { topK });
|
|
7886
|
+
return formatResult(results);
|
|
7887
|
+
}
|
|
7888
|
+
});
|
|
7889
|
+
}
|
|
7861
7890
|
// ../agents/src/approval.ts
|
|
7862
7891
|
function createApprovalGate(config) {
|
|
7863
7892
|
const timeoutMs = config.timeoutMs ?? 300000;
|
|
@@ -8036,6 +8065,35 @@ function createMemory(config) {
|
|
|
8036
8065
|
messages.shift();
|
|
8037
8066
|
}
|
|
8038
8067
|
}
|
|
8068
|
+
let summaryPending = false;
|
|
8069
|
+
function needsSummarization() {
|
|
8070
|
+
if (config.strategy !== "summary")
|
|
8071
|
+
return false;
|
|
8072
|
+
if (!config.summarize)
|
|
8073
|
+
return false;
|
|
8074
|
+
return messages.length > maxMessages;
|
|
8075
|
+
}
|
|
8076
|
+
async function runSummarization() {
|
|
8077
|
+
if (summaryPending || !config.summarize)
|
|
8078
|
+
return;
|
|
8079
|
+
if (messages.length <= maxMessages)
|
|
8080
|
+
return;
|
|
8081
|
+
summaryPending = true;
|
|
8082
|
+
try {
|
|
8083
|
+
const keepCount = Math.floor(maxMessages / 2);
|
|
8084
|
+
const toSummarize = messages.splice(0, messages.length - keepCount);
|
|
8085
|
+
const summaryText = await config.summarize(toSummarize);
|
|
8086
|
+
messages.unshift({
|
|
8087
|
+
role: "system",
|
|
8088
|
+
content: `[Conversation summary]: ${summaryText}`
|
|
8089
|
+
});
|
|
8090
|
+
} finally {
|
|
8091
|
+
summaryPending = false;
|
|
8092
|
+
}
|
|
8093
|
+
if (config.store && config.agentId) {
|
|
8094
|
+
config.store.save(config.agentId, [...messages]).catch(() => {});
|
|
8095
|
+
}
|
|
8096
|
+
}
|
|
8039
8097
|
return {
|
|
8040
8098
|
strategy: config.strategy,
|
|
8041
8099
|
add(message) {
|
|
@@ -8047,6 +8105,8 @@ function createMemory(config) {
|
|
|
8047
8105
|
case "token-limited":
|
|
8048
8106
|
trimToTokenLimit();
|
|
8049
8107
|
break;
|
|
8108
|
+
case "summary":
|
|
8109
|
+
break;
|
|
8050
8110
|
case "unlimited":
|
|
8051
8111
|
break;
|
|
8052
8112
|
}
|
|
@@ -8077,9 +8137,28 @@ function createMemory(config) {
|
|
|
8077
8137
|
if (!config.store || !config.agentId)
|
|
8078
8138
|
return;
|
|
8079
8139
|
await config.store.save(config.agentId, [...messages]);
|
|
8140
|
+
},
|
|
8141
|
+
async summarizeIfNeeded() {
|
|
8142
|
+
if (needsSummarization()) {
|
|
8143
|
+
await runSummarization();
|
|
8144
|
+
}
|
|
8080
8145
|
}
|
|
8081
8146
|
};
|
|
8082
8147
|
}
|
|
8148
|
+
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.";
|
|
8149
|
+
function createSummarizeFn(complete) {
|
|
8150
|
+
return async (messages) => {
|
|
8151
|
+
const text = messages.map((m) => `${m.role}: ${extractText(m.content)}`).join(`
|
|
8152
|
+
`);
|
|
8153
|
+
const response = await complete({
|
|
8154
|
+
messages: [{ role: "user", content: `Summarize this conversation:
|
|
8155
|
+
|
|
8156
|
+
${text}` }],
|
|
8157
|
+
system: SUMMARIZE_SYSTEM
|
|
8158
|
+
});
|
|
8159
|
+
return extractText(response.message.content);
|
|
8160
|
+
};
|
|
8161
|
+
}
|
|
8083
8162
|
|
|
8084
8163
|
// ../agents/src/security.ts
|
|
8085
8164
|
var INJECTION_PATTERNS2 = [
|
|
@@ -8670,6 +8749,219 @@ async function executeToolCalls(toolCalls, toolMap, history, signal, hooks, appr
|
|
|
8670
8749
|
return results;
|
|
8671
8750
|
}
|
|
8672
8751
|
|
|
8752
|
+
// ../agents/src/streaming.ts
|
|
8753
|
+
async function accumulateStreamedResponse(stream, emit) {
|
|
8754
|
+
let textContent = "";
|
|
8755
|
+
const toolCalls = [];
|
|
8756
|
+
const toolArgBuffers = {};
|
|
8757
|
+
let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
8758
|
+
let stopReason = "end_turn";
|
|
8759
|
+
for await (const event of stream) {
|
|
8760
|
+
switch (event.type) {
|
|
8761
|
+
case "text_delta":
|
|
8762
|
+
textContent += event.text;
|
|
8763
|
+
emit({ type: "text_delta", text: event.text });
|
|
8764
|
+
break;
|
|
8765
|
+
case "tool_call_start":
|
|
8766
|
+
toolArgBuffers[event.toolCall.id] = "";
|
|
8767
|
+
toolCalls.push({ id: event.toolCall.id, name: event.toolCall.name, arguments: {} });
|
|
8768
|
+
emit({ type: "tool_call_start", toolCall: event.toolCall });
|
|
8769
|
+
break;
|
|
8770
|
+
case "tool_call_delta":
|
|
8771
|
+
if (toolArgBuffers[event.toolCallId] !== undefined) {
|
|
8772
|
+
toolArgBuffers[event.toolCallId] += event.arguments;
|
|
8773
|
+
}
|
|
8774
|
+
emit({
|
|
8775
|
+
type: "tool_call_delta",
|
|
8776
|
+
toolCallId: event.toolCallId,
|
|
8777
|
+
arguments: event.arguments
|
|
8778
|
+
});
|
|
8779
|
+
break;
|
|
8780
|
+
case "tool_call_end": {
|
|
8781
|
+
const tc = toolCalls.find((t) => t.id === event.toolCallId);
|
|
8782
|
+
if (tc && toolArgBuffers[event.toolCallId]) {
|
|
8783
|
+
try {
|
|
8784
|
+
tc.arguments = JSON.parse(toolArgBuffers[event.toolCallId]);
|
|
8785
|
+
} catch {
|
|
8786
|
+
tc.arguments = {};
|
|
8787
|
+
}
|
|
8788
|
+
}
|
|
8789
|
+
emit({ type: "tool_call_end", toolCallId: event.toolCallId });
|
|
8790
|
+
break;
|
|
8791
|
+
}
|
|
8792
|
+
case "message_end":
|
|
8793
|
+
usage = event.usage;
|
|
8794
|
+
stopReason = event.stopReason;
|
|
8795
|
+
break;
|
|
8796
|
+
}
|
|
8797
|
+
}
|
|
8798
|
+
return {
|
|
8799
|
+
message: {
|
|
8800
|
+
role: "assistant",
|
|
8801
|
+
content: textContent,
|
|
8802
|
+
...toolCalls.length ? { toolCalls } : {}
|
|
8803
|
+
},
|
|
8804
|
+
usage,
|
|
8805
|
+
stopReason
|
|
8806
|
+
};
|
|
8807
|
+
}
|
|
8808
|
+
async function executeStreamToolCalls(toolCalls, ctx, emit) {
|
|
8809
|
+
const results = [];
|
|
8810
|
+
const history = [];
|
|
8811
|
+
for (const tc of toolCalls) {
|
|
8812
|
+
const tool = ctx.toolMap.get(tc.name);
|
|
8813
|
+
if (!tool) {
|
|
8814
|
+
const errorResult = {
|
|
8815
|
+
success: false,
|
|
8816
|
+
error: `Unknown tool: ${tc.name}. Available: ${Array.from(ctx.toolMap.keys()).join(", ")}`,
|
|
8817
|
+
toolCallId: tc.id,
|
|
8818
|
+
durationMs: 0
|
|
8819
|
+
};
|
|
8820
|
+
emit({ type: "tool_result", toolCallId: tc.id, name: tc.name, result: errorResult });
|
|
8821
|
+
history.push({ name: tc.name, arguments: tc.arguments, result: errorResult });
|
|
8822
|
+
results.push(formatToolResult(errorResult));
|
|
8823
|
+
continue;
|
|
8824
|
+
}
|
|
8825
|
+
const result = await tool.execute(tc.arguments, {
|
|
8826
|
+
toolCallId: tc.id,
|
|
8827
|
+
signal: ctx.options.signal
|
|
8828
|
+
});
|
|
8829
|
+
emit({ type: "tool_result", toolCallId: tc.id, name: tc.name, result });
|
|
8830
|
+
history.push({ name: tc.name, arguments: tc.arguments, result });
|
|
8831
|
+
results.push(formatToolResult(result));
|
|
8832
|
+
}
|
|
8833
|
+
return {
|
|
8834
|
+
toolMessage: { role: "tool", content: "", toolResults: results },
|
|
8835
|
+
history
|
|
8836
|
+
};
|
|
8837
|
+
}
|
|
8838
|
+
function createAgentStream(messages, ctx) {
|
|
8839
|
+
let resolveResult;
|
|
8840
|
+
let rejectResult;
|
|
8841
|
+
const resultPromise = new Promise((resolve2, reject) => {
|
|
8842
|
+
resolveResult = resolve2;
|
|
8843
|
+
rejectResult = reject;
|
|
8844
|
+
});
|
|
8845
|
+
const events = [];
|
|
8846
|
+
let resolve = null;
|
|
8847
|
+
let done = false;
|
|
8848
|
+
function emit(event) {
|
|
8849
|
+
if (resolve) {
|
|
8850
|
+
const r = resolve;
|
|
8851
|
+
resolve = null;
|
|
8852
|
+
r({ value: event, done: false });
|
|
8853
|
+
} else {
|
|
8854
|
+
events.push(event);
|
|
8855
|
+
}
|
|
8856
|
+
}
|
|
8857
|
+
function finish() {
|
|
8858
|
+
done = true;
|
|
8859
|
+
if (resolve) {
|
|
8860
|
+
const r = resolve;
|
|
8861
|
+
resolve = null;
|
|
8862
|
+
r({ value: undefined, done: true });
|
|
8863
|
+
}
|
|
8864
|
+
}
|
|
8865
|
+
runStreamLoop(messages, ctx, emit).then((agentResult) => {
|
|
8866
|
+
resolveResult(agentResult);
|
|
8867
|
+
finish();
|
|
8868
|
+
}).catch((err2) => {
|
|
8869
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
8870
|
+
emit({ type: "error", error });
|
|
8871
|
+
rejectResult?.(error);
|
|
8872
|
+
finish();
|
|
8873
|
+
});
|
|
8874
|
+
resultPromise.catch(() => {});
|
|
8875
|
+
const iterable = {
|
|
8876
|
+
[Symbol.asyncIterator]() {
|
|
8877
|
+
return {
|
|
8878
|
+
next() {
|
|
8879
|
+
const next = events.shift();
|
|
8880
|
+
if (next) {
|
|
8881
|
+
return Promise.resolve({ value: next, done: false });
|
|
8882
|
+
}
|
|
8883
|
+
if (done) {
|
|
8884
|
+
return Promise.resolve({ value: undefined, done: true });
|
|
8885
|
+
}
|
|
8886
|
+
return new Promise((r) => {
|
|
8887
|
+
resolve = r;
|
|
8888
|
+
});
|
|
8889
|
+
}
|
|
8890
|
+
};
|
|
8891
|
+
},
|
|
8892
|
+
result() {
|
|
8893
|
+
return resultPromise;
|
|
8894
|
+
}
|
|
8895
|
+
};
|
|
8896
|
+
return iterable;
|
|
8897
|
+
}
|
|
8898
|
+
async function runStreamLoop(messages, ctx, emit) {
|
|
8899
|
+
const { config, deps, memory, options } = ctx;
|
|
8900
|
+
const traceId = options.traceId ?? generateTraceId();
|
|
8901
|
+
let totalInputTokens = 0;
|
|
8902
|
+
let totalOutputTokens = 0;
|
|
8903
|
+
const totalCost = 0;
|
|
8904
|
+
let iterations = 0;
|
|
8905
|
+
const allToolCalls = [];
|
|
8906
|
+
const scopedMessages = [...memory.getMessages()];
|
|
8907
|
+
const conversationMessages = [...scopedMessages, ...messages];
|
|
8908
|
+
while (iterations < ctx.maxIterations) {
|
|
8909
|
+
iterations++;
|
|
8910
|
+
if (options.signal?.aborted) {
|
|
8911
|
+
throw new ElsiumError({
|
|
8912
|
+
code: "VALIDATION_ERROR",
|
|
8913
|
+
message: `Agent "${config.name}" was aborted`,
|
|
8914
|
+
retryable: false
|
|
8915
|
+
});
|
|
8916
|
+
}
|
|
8917
|
+
if (totalInputTokens + totalOutputTokens > ctx.maxTokenBudget) {
|
|
8918
|
+
throw ElsiumError.budgetExceeded(totalInputTokens + totalOutputTokens, ctx.maxTokenBudget);
|
|
8919
|
+
}
|
|
8920
|
+
emit({ type: "iteration_start", iteration: iterations });
|
|
8921
|
+
const request = {
|
|
8922
|
+
messages: conversationMessages,
|
|
8923
|
+
model: config.model,
|
|
8924
|
+
system: config.system,
|
|
8925
|
+
tools: config.tools?.map((t) => t.toDefinition())
|
|
8926
|
+
};
|
|
8927
|
+
const llmStream = deps.stream(request);
|
|
8928
|
+
const { message, usage, stopReason } = await accumulateStreamedResponse(llmStream, emit);
|
|
8929
|
+
totalInputTokens += usage.inputTokens;
|
|
8930
|
+
totalOutputTokens += usage.outputTokens;
|
|
8931
|
+
conversationMessages.push(message);
|
|
8932
|
+
if (!message.toolCalls?.length || stopReason !== "tool_use") {
|
|
8933
|
+
emit({ type: "iteration_end", iteration: iterations });
|
|
8934
|
+
for (const msg of conversationMessages.slice(scopedMessages.length)) {
|
|
8935
|
+
memory.add(msg);
|
|
8936
|
+
}
|
|
8937
|
+
const agentResult = {
|
|
8938
|
+
message,
|
|
8939
|
+
usage: {
|
|
8940
|
+
totalInputTokens,
|
|
8941
|
+
totalOutputTokens,
|
|
8942
|
+
totalTokens: totalInputTokens + totalOutputTokens,
|
|
8943
|
+
totalCost,
|
|
8944
|
+
iterations
|
|
8945
|
+
},
|
|
8946
|
+
toolCalls: allToolCalls,
|
|
8947
|
+
traceId
|
|
8948
|
+
};
|
|
8949
|
+
emit({ type: "agent_end", result: agentResult });
|
|
8950
|
+
return agentResult;
|
|
8951
|
+
}
|
|
8952
|
+
const { toolMessage, history } = await executeStreamToolCalls(message.toolCalls, ctx, emit);
|
|
8953
|
+
allToolCalls.push(...history);
|
|
8954
|
+
conversationMessages.push(toolMessage);
|
|
8955
|
+
emit({ type: "iteration_end", iteration: iterations });
|
|
8956
|
+
}
|
|
8957
|
+
throw new ElsiumError({
|
|
8958
|
+
code: "MAX_ITERATIONS",
|
|
8959
|
+
message: `Agent "${config.name}" reached maximum iterations (${ctx.maxIterations})`,
|
|
8960
|
+
retryable: false,
|
|
8961
|
+
metadata: { iterations, maxIterations: ctx.maxIterations }
|
|
8962
|
+
});
|
|
8963
|
+
}
|
|
8964
|
+
|
|
8673
8965
|
// ../agents/src/agent.ts
|
|
8674
8966
|
async function safeHook2(fn) {
|
|
8675
8967
|
if (!fn)
|
|
@@ -8683,7 +8975,10 @@ function resolveDependencies(config, deps) {
|
|
|
8683
8975
|
return deps;
|
|
8684
8976
|
if (typeof config.provider === "object" && config.provider !== null) {
|
|
8685
8977
|
const provider = config.provider;
|
|
8686
|
-
return {
|
|
8978
|
+
return {
|
|
8979
|
+
complete: (req) => provider.complete(req),
|
|
8980
|
+
stream: (req) => provider.stream(req)
|
|
8981
|
+
};
|
|
8687
8982
|
}
|
|
8688
8983
|
if (!config.provider || !config.apiKey) {
|
|
8689
8984
|
throw ElsiumError.validation("Either provide AgentDependencies as second argument, set provider and apiKey in config, or pass an LLMProvider object as provider");
|
|
@@ -8694,7 +8989,10 @@ function resolveDependencies(config, deps) {
|
|
|
8694
8989
|
baseUrl: config.baseUrl,
|
|
8695
8990
|
model: config.model
|
|
8696
8991
|
});
|
|
8697
|
-
return {
|
|
8992
|
+
return {
|
|
8993
|
+
complete: (req) => gw.complete(req),
|
|
8994
|
+
stream: (req) => gw.stream(req)
|
|
8995
|
+
};
|
|
8698
8996
|
}
|
|
8699
8997
|
function defineAgent(config, deps) {
|
|
8700
8998
|
const resolvedDeps = resolveDependencies(config, deps);
|
|
@@ -8934,6 +9232,51 @@ function defineAgent(config, deps) {
|
|
|
8934
9232
|
const userMessage = { role: "user", content: input };
|
|
8935
9233
|
return executeLoop([userMessage], options);
|
|
8936
9234
|
},
|
|
9235
|
+
async generate(input, schema, options = {}) {
|
|
9236
|
+
validateInputText(input);
|
|
9237
|
+
const jsonSchema = zodToJsonSchema(schema);
|
|
9238
|
+
const schemaInstruction = [
|
|
9239
|
+
"You MUST respond with valid JSON matching this schema:",
|
|
9240
|
+
JSON.stringify(jsonSchema, null, 2),
|
|
9241
|
+
"Respond ONLY with the JSON object, no markdown or explanation."
|
|
9242
|
+
].join(`
|
|
9243
|
+
`);
|
|
9244
|
+
const augmentedInput = `${input}
|
|
9245
|
+
|
|
9246
|
+
${schemaInstruction}`;
|
|
9247
|
+
const userMessage = { role: "user", content: augmentedInput };
|
|
9248
|
+
const agentResult = await executeLoop([userMessage], options);
|
|
9249
|
+
const text = extractText(agentResult.message.content);
|
|
9250
|
+
const cleaned = text.replace(/^```(?:json)?\s*\n?([\s\S]*?)\n?\s*```$/gm, "$1").trim();
|
|
9251
|
+
const jsonMatch = cleaned.match(/(\{[\s\S]*\}|\[[\s\S]*\])/);
|
|
9252
|
+
if (!jsonMatch) {
|
|
9253
|
+
throw ElsiumError.validation("Agent response did not contain valid JSON");
|
|
9254
|
+
}
|
|
9255
|
+
const parsed = schema.safeParse(JSON.parse(jsonMatch[0]));
|
|
9256
|
+
if (!parsed.success) {
|
|
9257
|
+
throw ElsiumError.validation("Agent response did not match schema", {
|
|
9258
|
+
errors: parsed.error.issues
|
|
9259
|
+
});
|
|
9260
|
+
}
|
|
9261
|
+
return { data: parsed.data, result: agentResult };
|
|
9262
|
+
},
|
|
9263
|
+
stream(input, options = {}) {
|
|
9264
|
+
validateInputText(input);
|
|
9265
|
+
const streamDeps = resolvedDeps;
|
|
9266
|
+
if (!streamDeps.stream) {
|
|
9267
|
+
throw ElsiumError.validation("Streaming requires a stream function in agent dependencies. " + "Pass { complete, stream } or use a provider that supports streaming.");
|
|
9268
|
+
}
|
|
9269
|
+
const userMessage = { role: "user", content: input };
|
|
9270
|
+
return createAgentStream([userMessage], {
|
|
9271
|
+
config,
|
|
9272
|
+
deps: streamDeps,
|
|
9273
|
+
memory,
|
|
9274
|
+
toolMap,
|
|
9275
|
+
options,
|
|
9276
|
+
maxIterations: guardrails.maxIterations,
|
|
9277
|
+
maxTokenBudget: guardrails.maxTokenBudget
|
|
9278
|
+
});
|
|
9279
|
+
},
|
|
8937
9280
|
async chat(messages, options = {}) {
|
|
8938
9281
|
for (const msg of messages) {
|
|
8939
9282
|
if (msg.role !== "user")
|
|
@@ -9130,6 +9473,698 @@ async function runSupervisor(supervisor, workers, input, options) {
|
|
|
9130
9473
|
};
|
|
9131
9474
|
return supervisor.run(supervisorInput, agentOptions);
|
|
9132
9475
|
}
|
|
9476
|
+
// ../agents/src/thread.ts
|
|
9477
|
+
function createThread(config) {
|
|
9478
|
+
const id = config.id ?? generateId("thread");
|
|
9479
|
+
const messages = [];
|
|
9480
|
+
const metadata = { ...config.metadata };
|
|
9481
|
+
const createdAt = Date.now();
|
|
9482
|
+
let updatedAt = createdAt;
|
|
9483
|
+
function addMessage(message) {
|
|
9484
|
+
messages.push(message);
|
|
9485
|
+
updatedAt = Date.now();
|
|
9486
|
+
if (config.store) {
|
|
9487
|
+
config.store.save({
|
|
9488
|
+
id,
|
|
9489
|
+
messages: [...messages],
|
|
9490
|
+
createdAt,
|
|
9491
|
+
updatedAt,
|
|
9492
|
+
metadata
|
|
9493
|
+
}).catch(() => {});
|
|
9494
|
+
}
|
|
9495
|
+
}
|
|
9496
|
+
return {
|
|
9497
|
+
id,
|
|
9498
|
+
metadata,
|
|
9499
|
+
async send(input, options = {}) {
|
|
9500
|
+
const userMessage = { role: "user", content: input };
|
|
9501
|
+
addMessage(userMessage);
|
|
9502
|
+
const result = await config.agent.chat([...messages], options);
|
|
9503
|
+
addMessage(result.message);
|
|
9504
|
+
return result;
|
|
9505
|
+
},
|
|
9506
|
+
stream(input, options = {}) {
|
|
9507
|
+
const userMessage = { role: "user", content: input };
|
|
9508
|
+
addMessage(userMessage);
|
|
9509
|
+
const agentStream = config.agent.stream(input, options);
|
|
9510
|
+
const originalResult = agentStream.result.bind(agentStream);
|
|
9511
|
+
const wrappedStream = {
|
|
9512
|
+
[Symbol.asyncIterator]() {
|
|
9513
|
+
const inner = agentStream[Symbol.asyncIterator]();
|
|
9514
|
+
return {
|
|
9515
|
+
async next() {
|
|
9516
|
+
const iterResult = await inner.next();
|
|
9517
|
+
if (!iterResult.done && iterResult.value.type === "agent_end") {
|
|
9518
|
+
addMessage(iterResult.value.result.message);
|
|
9519
|
+
}
|
|
9520
|
+
return iterResult;
|
|
9521
|
+
}
|
|
9522
|
+
};
|
|
9523
|
+
},
|
|
9524
|
+
async result() {
|
|
9525
|
+
const r = await originalResult();
|
|
9526
|
+
return r;
|
|
9527
|
+
}
|
|
9528
|
+
};
|
|
9529
|
+
return wrappedStream;
|
|
9530
|
+
},
|
|
9531
|
+
getMessages() {
|
|
9532
|
+
return [...messages];
|
|
9533
|
+
},
|
|
9534
|
+
addMessage(message) {
|
|
9535
|
+
addMessage(message);
|
|
9536
|
+
},
|
|
9537
|
+
fork(options) {
|
|
9538
|
+
const forked = createThread({
|
|
9539
|
+
id: options?.id,
|
|
9540
|
+
agent: config.agent,
|
|
9541
|
+
metadata: { ...metadata, forkedFrom: id },
|
|
9542
|
+
store: config.store
|
|
9543
|
+
});
|
|
9544
|
+
for (const msg of messages) {
|
|
9545
|
+
forked.addMessage({ ...msg });
|
|
9546
|
+
}
|
|
9547
|
+
return forked;
|
|
9548
|
+
},
|
|
9549
|
+
clear() {
|
|
9550
|
+
messages.length = 0;
|
|
9551
|
+
updatedAt = Date.now();
|
|
9552
|
+
},
|
|
9553
|
+
async save() {
|
|
9554
|
+
if (!config.store)
|
|
9555
|
+
return;
|
|
9556
|
+
await config.store.save({
|
|
9557
|
+
id,
|
|
9558
|
+
messages: [...messages],
|
|
9559
|
+
createdAt,
|
|
9560
|
+
updatedAt,
|
|
9561
|
+
metadata
|
|
9562
|
+
});
|
|
9563
|
+
}
|
|
9564
|
+
};
|
|
9565
|
+
}
|
|
9566
|
+
async function loadThread(threadId, config) {
|
|
9567
|
+
const snapshot = await config.store.load(threadId);
|
|
9568
|
+
if (!snapshot)
|
|
9569
|
+
return null;
|
|
9570
|
+
const thread = createThread({
|
|
9571
|
+
id: threadId,
|
|
9572
|
+
agent: config.agent,
|
|
9573
|
+
metadata: snapshot.metadata,
|
|
9574
|
+
store: config.store
|
|
9575
|
+
});
|
|
9576
|
+
for (const msg of snapshot.messages) {
|
|
9577
|
+
thread.addMessage(msg);
|
|
9578
|
+
}
|
|
9579
|
+
return thread;
|
|
9580
|
+
}
|
|
9581
|
+
function createInMemoryThreadStore() {
|
|
9582
|
+
const store = new Map;
|
|
9583
|
+
return {
|
|
9584
|
+
async load(threadId) {
|
|
9585
|
+
const snapshot = store.get(threadId);
|
|
9586
|
+
if (!snapshot)
|
|
9587
|
+
return null;
|
|
9588
|
+
return { ...snapshot, messages: [...snapshot.messages] };
|
|
9589
|
+
},
|
|
9590
|
+
async save(snapshot) {
|
|
9591
|
+
store.set(snapshot.id, { ...snapshot, messages: [...snapshot.messages] });
|
|
9592
|
+
},
|
|
9593
|
+
async delete(threadId) {
|
|
9594
|
+
store.delete(threadId);
|
|
9595
|
+
},
|
|
9596
|
+
async list(options) {
|
|
9597
|
+
const limit = options?.limit ?? 50;
|
|
9598
|
+
const offset = options?.offset ?? 0;
|
|
9599
|
+
const entries = [...store.values()].sort((a, b) => b.updatedAt - a.updatedAt).slice(offset, offset + limit);
|
|
9600
|
+
return entries.map((s) => {
|
|
9601
|
+
const lastMsg = s.messages[s.messages.length - 1];
|
|
9602
|
+
const lastMessage = lastMsg ? typeof lastMsg.content === "string" ? lastMsg.content.slice(0, 100) : undefined : undefined;
|
|
9603
|
+
return {
|
|
9604
|
+
id: s.id,
|
|
9605
|
+
messageCount: s.messages.length,
|
|
9606
|
+
createdAt: s.createdAt,
|
|
9607
|
+
updatedAt: s.updatedAt,
|
|
9608
|
+
lastMessage,
|
|
9609
|
+
metadata: s.metadata
|
|
9610
|
+
};
|
|
9611
|
+
});
|
|
9612
|
+
}
|
|
9613
|
+
};
|
|
9614
|
+
}
|
|
9615
|
+
// ../agents/src/async-agent.ts
|
|
9616
|
+
function createAsyncAgent(config) {
|
|
9617
|
+
const tasks = new Map;
|
|
9618
|
+
function emitProgress(task, event) {
|
|
9619
|
+
try {
|
|
9620
|
+
config.onProgress?.(toPublicTask(task), event);
|
|
9621
|
+
} catch {}
|
|
9622
|
+
}
|
|
9623
|
+
function toPublicTask(task) {
|
|
9624
|
+
return {
|
|
9625
|
+
id: task.id,
|
|
9626
|
+
agentName: task.agentName,
|
|
9627
|
+
input: task.input,
|
|
9628
|
+
status: task.status,
|
|
9629
|
+
result: task.result,
|
|
9630
|
+
error: task.error,
|
|
9631
|
+
createdAt: task.createdAt,
|
|
9632
|
+
startedAt: task.startedAt,
|
|
9633
|
+
completedAt: task.completedAt,
|
|
9634
|
+
metadata: task.metadata,
|
|
9635
|
+
cancel() {
|
|
9636
|
+
if (task.status === "pending" || task.status === "running") {
|
|
9637
|
+
task.status = "cancelled";
|
|
9638
|
+
task.completedAt = Date.now();
|
|
9639
|
+
task.abortController.abort();
|
|
9640
|
+
emitProgress(task, { type: "cancelled", taskId: task.id });
|
|
9641
|
+
task.reject(new ElsiumError({
|
|
9642
|
+
code: "VALIDATION_ERROR",
|
|
9643
|
+
message: `Task ${task.id} was cancelled`,
|
|
9644
|
+
retryable: false
|
|
9645
|
+
}));
|
|
9646
|
+
}
|
|
9647
|
+
},
|
|
9648
|
+
wait() {
|
|
9649
|
+
return task.promise;
|
|
9650
|
+
}
|
|
9651
|
+
};
|
|
9652
|
+
}
|
|
9653
|
+
async function executeTask(task) {
|
|
9654
|
+
task.status = "running";
|
|
9655
|
+
task.startedAt = Date.now();
|
|
9656
|
+
emitProgress(task, { type: "started", taskId: task.id });
|
|
9657
|
+
try {
|
|
9658
|
+
const result = await config.agent.run(task.input, {
|
|
9659
|
+
signal: task.abortController.signal,
|
|
9660
|
+
traceId: task.metadata.traceId
|
|
9661
|
+
});
|
|
9662
|
+
if (task.status === "cancelled")
|
|
9663
|
+
return;
|
|
9664
|
+
task.status = "completed";
|
|
9665
|
+
task.result = result;
|
|
9666
|
+
task.completedAt = Date.now();
|
|
9667
|
+
emitProgress(task, { type: "completed", taskId: task.id, result });
|
|
9668
|
+
try {
|
|
9669
|
+
config.onComplete?.(toPublicTask(task));
|
|
9670
|
+
} catch {}
|
|
9671
|
+
task.resolve(result);
|
|
9672
|
+
} catch (err2) {
|
|
9673
|
+
if (task.status === "cancelled")
|
|
9674
|
+
return;
|
|
9675
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
9676
|
+
task.status = "failed";
|
|
9677
|
+
task.error = error;
|
|
9678
|
+
task.completedAt = Date.now();
|
|
9679
|
+
emitProgress(task, { type: "failed", taskId: task.id, error });
|
|
9680
|
+
try {
|
|
9681
|
+
config.onError?.(toPublicTask(task), error);
|
|
9682
|
+
} catch {}
|
|
9683
|
+
task.reject(error);
|
|
9684
|
+
}
|
|
9685
|
+
}
|
|
9686
|
+
return {
|
|
9687
|
+
submit(input, options = {}) {
|
|
9688
|
+
const taskId = options.taskId ?? generateId("task");
|
|
9689
|
+
const abortController = new AbortController;
|
|
9690
|
+
if (options.signal) {
|
|
9691
|
+
options.signal.addEventListener("abort", () => abortController.abort(), { once: true });
|
|
9692
|
+
}
|
|
9693
|
+
let resolvePromise;
|
|
9694
|
+
let rejectPromise;
|
|
9695
|
+
const promise = new Promise((resolve, reject) => {
|
|
9696
|
+
resolvePromise = resolve;
|
|
9697
|
+
rejectPromise = reject;
|
|
9698
|
+
});
|
|
9699
|
+
const task = {
|
|
9700
|
+
id: taskId,
|
|
9701
|
+
agentName: config.agent.name,
|
|
9702
|
+
input,
|
|
9703
|
+
status: "pending",
|
|
9704
|
+
result: null,
|
|
9705
|
+
error: null,
|
|
9706
|
+
createdAt: Date.now(),
|
|
9707
|
+
startedAt: null,
|
|
9708
|
+
completedAt: null,
|
|
9709
|
+
metadata: { ...options.metadata },
|
|
9710
|
+
abortController,
|
|
9711
|
+
promise,
|
|
9712
|
+
resolve: resolvePromise,
|
|
9713
|
+
reject: rejectPromise
|
|
9714
|
+
};
|
|
9715
|
+
tasks.set(taskId, task);
|
|
9716
|
+
executeTask(task);
|
|
9717
|
+
return toPublicTask(task);
|
|
9718
|
+
},
|
|
9719
|
+
getTask(taskId) {
|
|
9720
|
+
const task = tasks.get(taskId);
|
|
9721
|
+
return task ? toPublicTask(task) : null;
|
|
9722
|
+
},
|
|
9723
|
+
listTasks(filter) {
|
|
9724
|
+
const all = [...tasks.values()];
|
|
9725
|
+
const filtered = filter?.status ? all.filter((t) => t.status === filter.status) : all;
|
|
9726
|
+
return filtered.map(toPublicTask);
|
|
9727
|
+
},
|
|
9728
|
+
cancelAll() {
|
|
9729
|
+
for (const task of tasks.values()) {
|
|
9730
|
+
if (task.status === "pending" || task.status === "running") {
|
|
9731
|
+
task.status = "cancelled";
|
|
9732
|
+
task.completedAt = Date.now();
|
|
9733
|
+
task.abortController.abort();
|
|
9734
|
+
emitProgress(task, { type: "cancelled", taskId: task.id });
|
|
9735
|
+
task.reject(new ElsiumError({
|
|
9736
|
+
code: "VALIDATION_ERROR",
|
|
9737
|
+
message: `Task ${task.id} was cancelled`,
|
|
9738
|
+
retryable: false
|
|
9739
|
+
}));
|
|
9740
|
+
}
|
|
9741
|
+
}
|
|
9742
|
+
}
|
|
9743
|
+
};
|
|
9744
|
+
}
|
|
9745
|
+
// ../agents/src/channels.ts
|
|
9746
|
+
function createWebhookChannel(config) {
|
|
9747
|
+
let messageHandler = null;
|
|
9748
|
+
return {
|
|
9749
|
+
name: config.name,
|
|
9750
|
+
async start() {},
|
|
9751
|
+
async stop() {},
|
|
9752
|
+
async send(userId, message) {
|
|
9753
|
+
await config.onSend?.(userId, message);
|
|
9754
|
+
},
|
|
9755
|
+
onMessage(handler) {
|
|
9756
|
+
messageHandler = handler;
|
|
9757
|
+
},
|
|
9758
|
+
receive(message) {
|
|
9759
|
+
if (!messageHandler)
|
|
9760
|
+
return;
|
|
9761
|
+
messageHandler({ ...message, channelName: config.name });
|
|
9762
|
+
}
|
|
9763
|
+
};
|
|
9764
|
+
}
|
|
9765
|
+
function createChannelGateway(config) {
|
|
9766
|
+
const adapterMap = new Map;
|
|
9767
|
+
for (const adapter of config.adapters) {
|
|
9768
|
+
if (adapter.name === "__proto__" || adapter.name === "constructor" || adapter.name === "prototype")
|
|
9769
|
+
continue;
|
|
9770
|
+
adapterMap.set(adapter.name, adapter);
|
|
9771
|
+
}
|
|
9772
|
+
function findAdapter(channelName) {
|
|
9773
|
+
return adapterMap.get(channelName);
|
|
9774
|
+
}
|
|
9775
|
+
async function handleIncoming(message) {
|
|
9776
|
+
const agent = config.resolveAgent?.(message) ?? config.agent;
|
|
9777
|
+
try {
|
|
9778
|
+
const session = await config.router.resolve({
|
|
9779
|
+
channelName: message.channelName,
|
|
9780
|
+
userId: message.userId,
|
|
9781
|
+
agent
|
|
9782
|
+
});
|
|
9783
|
+
const result = await session.send(message.text);
|
|
9784
|
+
const responseText = typeof result.message.content === "string" ? result.message.content : "";
|
|
9785
|
+
const adapter = findAdapter(message.channelName);
|
|
9786
|
+
if (adapter && responseText) {
|
|
9787
|
+
await adapter.send(message.userId, { text: responseText });
|
|
9788
|
+
}
|
|
9789
|
+
} catch (err2) {
|
|
9790
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
9791
|
+
try {
|
|
9792
|
+
config.onError?.(error, message);
|
|
9793
|
+
} catch {}
|
|
9794
|
+
}
|
|
9795
|
+
}
|
|
9796
|
+
for (const adapter of config.adapters) {
|
|
9797
|
+
adapter.onMessage(handleIncoming);
|
|
9798
|
+
}
|
|
9799
|
+
return {
|
|
9800
|
+
adapters: adapterMap,
|
|
9801
|
+
async start() {
|
|
9802
|
+
const startPromises = [...adapterMap.values()].map((a) => a.start());
|
|
9803
|
+
await Promise.all(startPromises);
|
|
9804
|
+
},
|
|
9805
|
+
async stop() {
|
|
9806
|
+
const stopPromises = [...adapterMap.values()].map((a) => a.stop());
|
|
9807
|
+
await Promise.all(stopPromises);
|
|
9808
|
+
}
|
|
9809
|
+
};
|
|
9810
|
+
}
|
|
9811
|
+
// ../agents/src/session.ts
|
|
9812
|
+
function sessionKey(channelName, userId) {
|
|
9813
|
+
return `${channelName}::${userId}`;
|
|
9814
|
+
}
|
|
9815
|
+
function createSessionRouter(config) {
|
|
9816
|
+
const sessions = new Map;
|
|
9817
|
+
const concurrency = config.concurrency ?? "serial";
|
|
9818
|
+
const sessionTimeout = config.sessionTimeout ?? 0;
|
|
9819
|
+
let cleanupTimer = null;
|
|
9820
|
+
if (sessionTimeout > 0) {
|
|
9821
|
+
cleanupTimer = setInterval(() => {
|
|
9822
|
+
const now = Date.now();
|
|
9823
|
+
for (const [key, session] of sessions) {
|
|
9824
|
+
if (now - session.lastActiveAt > sessionTimeout) {
|
|
9825
|
+
sessions.delete(key);
|
|
9826
|
+
try {
|
|
9827
|
+
config.onSessionExpired?.({
|
|
9828
|
+
sessionId: session.sessionId,
|
|
9829
|
+
channelName: session.channelName,
|
|
9830
|
+
userId: session.userId,
|
|
9831
|
+
agentName: session.agent.name,
|
|
9832
|
+
createdAt: session.createdAt,
|
|
9833
|
+
lastActiveAt: session.lastActiveAt
|
|
9834
|
+
});
|
|
9835
|
+
} catch {}
|
|
9836
|
+
}
|
|
9837
|
+
}
|
|
9838
|
+
}, Math.min(sessionTimeout, 60000));
|
|
9839
|
+
if (typeof cleanupTimer === "object" && "unref" in cleanupTimer) {
|
|
9840
|
+
cleanupTimer.unref();
|
|
9841
|
+
}
|
|
9842
|
+
}
|
|
9843
|
+
function toPublicSession(session) {
|
|
9844
|
+
return {
|
|
9845
|
+
sessionId: session.sessionId,
|
|
9846
|
+
channelName: session.channelName,
|
|
9847
|
+
userId: session.userId,
|
|
9848
|
+
agentName: session.agent.name,
|
|
9849
|
+
createdAt: session.createdAt,
|
|
9850
|
+
lastActiveAt: session.lastActiveAt
|
|
9851
|
+
};
|
|
9852
|
+
}
|
|
9853
|
+
async function createNewSession(key, channelName, userId, agent) {
|
|
9854
|
+
const sessionId = generateId("sess");
|
|
9855
|
+
const threadId = `${channelName}-${userId}-${sessionId}`;
|
|
9856
|
+
let thread = null;
|
|
9857
|
+
if (config.store) {
|
|
9858
|
+
thread = await loadThread(threadId, { agent, store: config.store });
|
|
9859
|
+
}
|
|
9860
|
+
if (!thread) {
|
|
9861
|
+
thread = createThread({
|
|
9862
|
+
id: threadId,
|
|
9863
|
+
agent,
|
|
9864
|
+
metadata: { channelName, userId, sessionId },
|
|
9865
|
+
store: config.store
|
|
9866
|
+
});
|
|
9867
|
+
}
|
|
9868
|
+
const now = Date.now();
|
|
9869
|
+
const session = {
|
|
9870
|
+
sessionId,
|
|
9871
|
+
channelName,
|
|
9872
|
+
userId,
|
|
9873
|
+
agent,
|
|
9874
|
+
thread,
|
|
9875
|
+
createdAt: now,
|
|
9876
|
+
lastActiveAt: now,
|
|
9877
|
+
lock: null,
|
|
9878
|
+
lockResolve: null
|
|
9879
|
+
};
|
|
9880
|
+
sessions.set(key, session);
|
|
9881
|
+
try {
|
|
9882
|
+
config.onSessionCreated?.(toPublicSession(session));
|
|
9883
|
+
} catch {}
|
|
9884
|
+
return session;
|
|
9885
|
+
}
|
|
9886
|
+
function wrapThreadWithConcurrency(session) {
|
|
9887
|
+
if (concurrency !== "serial")
|
|
9888
|
+
return session.thread;
|
|
9889
|
+
const originalSend = session.thread.send.bind(session.thread);
|
|
9890
|
+
return {
|
|
9891
|
+
...session.thread,
|
|
9892
|
+
async send(input, options) {
|
|
9893
|
+
while (session.lock) {
|
|
9894
|
+
await session.lock;
|
|
9895
|
+
}
|
|
9896
|
+
let unlock;
|
|
9897
|
+
session.lock = new Promise((resolve) => {
|
|
9898
|
+
unlock = resolve;
|
|
9899
|
+
});
|
|
9900
|
+
session.lockResolve = unlock;
|
|
9901
|
+
try {
|
|
9902
|
+
const result = await originalSend(input, options);
|
|
9903
|
+
session.lastActiveAt = Date.now();
|
|
9904
|
+
return result;
|
|
9905
|
+
} finally {
|
|
9906
|
+
session.lock = null;
|
|
9907
|
+
session.lockResolve = null;
|
|
9908
|
+
unlock();
|
|
9909
|
+
}
|
|
9910
|
+
}
|
|
9911
|
+
};
|
|
9912
|
+
}
|
|
9913
|
+
return {
|
|
9914
|
+
async resolve(options) {
|
|
9915
|
+
const agent = options.agent ?? config.defaultAgent;
|
|
9916
|
+
const key = sessionKey(options.channelName, options.userId);
|
|
9917
|
+
let session = sessions.get(key);
|
|
9918
|
+
if (session && sessionTimeout > 0) {
|
|
9919
|
+
const now = Date.now();
|
|
9920
|
+
if (now - session.lastActiveAt > sessionTimeout) {
|
|
9921
|
+
sessions.delete(key);
|
|
9922
|
+
try {
|
|
9923
|
+
config.onSessionExpired?.(toPublicSession(session));
|
|
9924
|
+
} catch {}
|
|
9925
|
+
session = undefined;
|
|
9926
|
+
}
|
|
9927
|
+
}
|
|
9928
|
+
if (!session) {
|
|
9929
|
+
session = await createNewSession(key, options.channelName, options.userId, agent);
|
|
9930
|
+
}
|
|
9931
|
+
session.lastActiveAt = Date.now();
|
|
9932
|
+
return wrapThreadWithConcurrency(session);
|
|
9933
|
+
},
|
|
9934
|
+
getSession(channelName, userId) {
|
|
9935
|
+
const session = sessions.get(sessionKey(channelName, userId));
|
|
9936
|
+
return session ? toPublicSession(session) : null;
|
|
9937
|
+
},
|
|
9938
|
+
listSessions() {
|
|
9939
|
+
return [...sessions.values()].map(toPublicSession);
|
|
9940
|
+
},
|
|
9941
|
+
endSession(channelName, userId) {
|
|
9942
|
+
return sessions.delete(sessionKey(channelName, userId));
|
|
9943
|
+
},
|
|
9944
|
+
endAllSessions() {
|
|
9945
|
+
sessions.clear();
|
|
9946
|
+
if (cleanupTimer) {
|
|
9947
|
+
clearInterval(cleanupTimer);
|
|
9948
|
+
cleanupTimer = null;
|
|
9949
|
+
}
|
|
9950
|
+
}
|
|
9951
|
+
};
|
|
9952
|
+
}
|
|
9953
|
+
// ../agents/src/scheduler.ts
|
|
9954
|
+
function parseCronExpression(expression) {
|
|
9955
|
+
const parts = expression.trim().split(/\s+/);
|
|
9956
|
+
if (parts.length !== 5)
|
|
9957
|
+
return null;
|
|
9958
|
+
const minute = parseCronField(parts[0], 0, 59);
|
|
9959
|
+
const hour = parseCronField(parts[1], 0, 23);
|
|
9960
|
+
const dayOfMonth = parseCronField(parts[2], 1, 31);
|
|
9961
|
+
const month = parseCronField(parts[3], 1, 12);
|
|
9962
|
+
const dayOfWeek = parseCronField(parts[4], 0, 6);
|
|
9963
|
+
if (!minute || !hour || !dayOfMonth || !month || !dayOfWeek)
|
|
9964
|
+
return null;
|
|
9965
|
+
return { minute, hour, dayOfMonth, month, dayOfWeek };
|
|
9966
|
+
}
|
|
9967
|
+
function parseStepPart(match, min, max) {
|
|
9968
|
+
const step = Number.parseInt(match[2], 10);
|
|
9969
|
+
if (step <= 0)
|
|
9970
|
+
return null;
|
|
9971
|
+
let rangeStart = min;
|
|
9972
|
+
let rangeEnd = max;
|
|
9973
|
+
if (match[1] !== "*") {
|
|
9974
|
+
const rangeParts = match[1].split("-");
|
|
9975
|
+
rangeStart = Number.parseInt(rangeParts[0], 10);
|
|
9976
|
+
rangeEnd = rangeParts[1] ? Number.parseInt(rangeParts[1], 10) : max;
|
|
9977
|
+
}
|
|
9978
|
+
const values = [];
|
|
9979
|
+
for (let i = rangeStart;i <= rangeEnd; i += step) {
|
|
9980
|
+
if (i >= min && i <= max)
|
|
9981
|
+
values.push(i);
|
|
9982
|
+
}
|
|
9983
|
+
return values;
|
|
9984
|
+
}
|
|
9985
|
+
function parseRangePart(match, min, max) {
|
|
9986
|
+
const start = Number.parseInt(match[1], 10);
|
|
9987
|
+
const end = Number.parseInt(match[2], 10);
|
|
9988
|
+
if (start > end || start < min || end > max)
|
|
9989
|
+
return null;
|
|
9990
|
+
const values = [];
|
|
9991
|
+
for (let i = start;i <= end; i++) {
|
|
9992
|
+
values.push(i);
|
|
9993
|
+
}
|
|
9994
|
+
return values;
|
|
9995
|
+
}
|
|
9996
|
+
function parseSinglePart(part, min, max) {
|
|
9997
|
+
const stepMatch = part.match(/^(\*|\d+(?:-\d+)?)\/(\d+)$/);
|
|
9998
|
+
if (stepMatch)
|
|
9999
|
+
return parseStepPart(stepMatch, min, max);
|
|
10000
|
+
const rangeMatch = part.match(/^(\d+)-(\d+)$/);
|
|
10001
|
+
if (rangeMatch)
|
|
10002
|
+
return parseRangePart(rangeMatch, min, max);
|
|
10003
|
+
const num = Number.parseInt(part, 10);
|
|
10004
|
+
if (Number.isNaN(num) || num < min || num > max)
|
|
10005
|
+
return null;
|
|
10006
|
+
return [num];
|
|
10007
|
+
}
|
|
10008
|
+
function parseCronField(field, min, max) {
|
|
10009
|
+
if (field === "*") {
|
|
10010
|
+
return Array.from({ length: max - min + 1 }, (_, i) => min + i);
|
|
10011
|
+
}
|
|
10012
|
+
const values = [];
|
|
10013
|
+
for (const part of field.split(",")) {
|
|
10014
|
+
const result = parseSinglePart(part, min, max);
|
|
10015
|
+
if (!result)
|
|
10016
|
+
return null;
|
|
10017
|
+
values.push(...result);
|
|
10018
|
+
}
|
|
10019
|
+
return values.length > 0 ? values : null;
|
|
10020
|
+
}
|
|
10021
|
+
function cronMatchesDate(fields, date) {
|
|
10022
|
+
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());
|
|
10023
|
+
}
|
|
10024
|
+
function getNextCronDate(fields, after) {
|
|
10025
|
+
const next = new Date(after.getTime());
|
|
10026
|
+
next.setSeconds(0, 0);
|
|
10027
|
+
next.setMinutes(next.getMinutes() + 1);
|
|
10028
|
+
const maxIterations = 525600;
|
|
10029
|
+
for (let i = 0;i < maxIterations; i++) {
|
|
10030
|
+
if (cronMatchesDate(fields, next))
|
|
10031
|
+
return next;
|
|
10032
|
+
next.setMinutes(next.getMinutes() + 1);
|
|
10033
|
+
}
|
|
10034
|
+
return next;
|
|
10035
|
+
}
|
|
10036
|
+
function createScheduler(config) {
|
|
10037
|
+
const tasks = new Map;
|
|
10038
|
+
let timer = null;
|
|
10039
|
+
const tickInterval = config.tickIntervalMs ?? 60000;
|
|
10040
|
+
function toPublicTask(task) {
|
|
10041
|
+
return {
|
|
10042
|
+
id: task.id,
|
|
10043
|
+
name: task.name,
|
|
10044
|
+
cronExpression: task.cronExpression,
|
|
10045
|
+
enabled: task.enabled,
|
|
10046
|
+
lastRunAt: task.lastRunAt,
|
|
10047
|
+
nextRunAt: task.nextRunAt,
|
|
10048
|
+
runCount: task.runCount
|
|
10049
|
+
};
|
|
10050
|
+
}
|
|
10051
|
+
function updateNextRun(task) {
|
|
10052
|
+
const fields = parseCronExpression(task.cronExpression);
|
|
10053
|
+
task.nextRunAt = fields ? getNextCronDate(fields, new Date).getTime() : null;
|
|
10054
|
+
}
|
|
10055
|
+
function handleTaskSuccess(task, result) {
|
|
10056
|
+
task.lastRunAt = Date.now();
|
|
10057
|
+
task.runCount++;
|
|
10058
|
+
task.running = false;
|
|
10059
|
+
if (task.maxRuns !== null && task.runCount >= task.maxRuns) {
|
|
10060
|
+
task.enabled = false;
|
|
10061
|
+
task.nextRunAt = null;
|
|
10062
|
+
} else {
|
|
10063
|
+
updateNextRun(task);
|
|
10064
|
+
}
|
|
10065
|
+
try {
|
|
10066
|
+
config.onComplete?.(toPublicTask(task), result);
|
|
10067
|
+
} catch {}
|
|
10068
|
+
}
|
|
10069
|
+
function handleTaskError(task, err2) {
|
|
10070
|
+
task.running = false;
|
|
10071
|
+
task.lastRunAt = Date.now();
|
|
10072
|
+
updateNextRun(task);
|
|
10073
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
10074
|
+
try {
|
|
10075
|
+
config.onError?.(toPublicTask(task), error);
|
|
10076
|
+
} catch {}
|
|
10077
|
+
}
|
|
10078
|
+
async function executeTask(task) {
|
|
10079
|
+
if (task.running)
|
|
10080
|
+
return;
|
|
10081
|
+
task.running = true;
|
|
10082
|
+
const agent = config.resolveAgent?.(toPublicTask(task)) ?? config.agent;
|
|
10083
|
+
try {
|
|
10084
|
+
const result = await agent.run(task.input);
|
|
10085
|
+
handleTaskSuccess(task, result);
|
|
10086
|
+
} catch (err2) {
|
|
10087
|
+
handleTaskError(task, err2);
|
|
10088
|
+
}
|
|
10089
|
+
}
|
|
10090
|
+
function tick() {
|
|
10091
|
+
const now = Date.now();
|
|
10092
|
+
for (const task of tasks.values()) {
|
|
10093
|
+
if (!task.enabled || task.running)
|
|
10094
|
+
continue;
|
|
10095
|
+
if (task.nextRunAt !== null && task.nextRunAt <= now) {
|
|
10096
|
+
executeTask(task);
|
|
10097
|
+
}
|
|
10098
|
+
}
|
|
10099
|
+
}
|
|
10100
|
+
return {
|
|
10101
|
+
schedule(cronExpression, input, options = {}) {
|
|
10102
|
+
const fields = parseCronExpression(cronExpression);
|
|
10103
|
+
if (!fields) {
|
|
10104
|
+
throw new Error(`Invalid cron expression: ${cronExpression}`);
|
|
10105
|
+
}
|
|
10106
|
+
const id = options.id ?? generateId("sched");
|
|
10107
|
+
const now = new Date;
|
|
10108
|
+
const nextRunAt = options.startImmediately ? Date.now() : getNextCronDate(fields, now).getTime();
|
|
10109
|
+
const task = {
|
|
10110
|
+
id,
|
|
10111
|
+
name: options.name ?? `task-${id}`,
|
|
10112
|
+
cronExpression,
|
|
10113
|
+
input,
|
|
10114
|
+
enabled: true,
|
|
10115
|
+
lastRunAt: null,
|
|
10116
|
+
nextRunAt,
|
|
10117
|
+
runCount: 0,
|
|
10118
|
+
maxRuns: options.maxRuns ?? null,
|
|
10119
|
+
metadata: options.metadata ?? {},
|
|
10120
|
+
running: false
|
|
10121
|
+
};
|
|
10122
|
+
tasks.set(id, task);
|
|
10123
|
+
if (options.startImmediately) {
|
|
10124
|
+
executeTask(task);
|
|
10125
|
+
}
|
|
10126
|
+
return toPublicTask(task);
|
|
10127
|
+
},
|
|
10128
|
+
unschedule(taskId) {
|
|
10129
|
+
return tasks.delete(taskId);
|
|
10130
|
+
},
|
|
10131
|
+
getTask(taskId) {
|
|
10132
|
+
const task = tasks.get(taskId);
|
|
10133
|
+
return task ? toPublicTask(task) : null;
|
|
10134
|
+
},
|
|
10135
|
+
listTasks() {
|
|
10136
|
+
return [...tasks.values()].map(toPublicTask);
|
|
10137
|
+
},
|
|
10138
|
+
pause(taskId) {
|
|
10139
|
+
const task = tasks.get(taskId);
|
|
10140
|
+
if (!task)
|
|
10141
|
+
return false;
|
|
10142
|
+
task.enabled = false;
|
|
10143
|
+
return true;
|
|
10144
|
+
},
|
|
10145
|
+
resume(taskId) {
|
|
10146
|
+
const task = tasks.get(taskId);
|
|
10147
|
+
if (!task)
|
|
10148
|
+
return false;
|
|
10149
|
+
task.enabled = true;
|
|
10150
|
+
const fields = parseCronExpression(task.cronExpression);
|
|
10151
|
+
task.nextRunAt = fields ? getNextCronDate(fields, new Date).getTime() : null;
|
|
10152
|
+
return true;
|
|
10153
|
+
},
|
|
10154
|
+
start() {
|
|
10155
|
+
if (timer)
|
|
10156
|
+
return;
|
|
10157
|
+
tick();
|
|
10158
|
+
timer = setInterval(tick, tickInterval);
|
|
10159
|
+
},
|
|
10160
|
+
stop() {
|
|
10161
|
+
if (timer) {
|
|
10162
|
+
clearInterval(timer);
|
|
10163
|
+
timer = null;
|
|
10164
|
+
}
|
|
10165
|
+
}
|
|
10166
|
+
};
|
|
10167
|
+
}
|
|
9133
10168
|
// ../rag/src/loaders.ts
|
|
9134
10169
|
function createDocument(content, metadata) {
|
|
9135
10170
|
return {
|
|
@@ -15230,11 +16265,13 @@ export {
|
|
|
15230
16265
|
redactSecrets,
|
|
15231
16266
|
rag,
|
|
15232
16267
|
parseTraceparent,
|
|
16268
|
+
parseCronExpression,
|
|
15233
16269
|
outputGuardrailMiddleware,
|
|
15234
16270
|
ok,
|
|
15235
16271
|
observe,
|
|
15236
16272
|
mockProvider,
|
|
15237
16273
|
loggingMiddleware,
|
|
16274
|
+
loadThread,
|
|
15238
16275
|
loadFixture,
|
|
15239
16276
|
listProviders,
|
|
15240
16277
|
jsonParseTool,
|
|
@@ -15244,6 +16281,7 @@ export {
|
|
|
15244
16281
|
httpFetchTool,
|
|
15245
16282
|
getProviderMetadata,
|
|
15246
16283
|
getProviderFactory,
|
|
16284
|
+
getNextCronDate,
|
|
15247
16285
|
generateTraceId,
|
|
15248
16286
|
generateId,
|
|
15249
16287
|
gateway,
|
|
@@ -15268,12 +16306,19 @@ export {
|
|
|
15268
16306
|
defineBranchWorkflow,
|
|
15269
16307
|
defineAgent,
|
|
15270
16308
|
currentTimeTool,
|
|
16309
|
+
cronMatchesDate,
|
|
16310
|
+
createWebhookChannel,
|
|
15271
16311
|
createToolkit,
|
|
16312
|
+
createThread,
|
|
16313
|
+
createSummarizeFn,
|
|
15272
16314
|
createStream,
|
|
15273
16315
|
createSqliteMemoryStore,
|
|
15274
16316
|
createSpan,
|
|
15275
16317
|
createSnapshotStore,
|
|
16318
|
+
createSessionRouter,
|
|
15276
16319
|
createSemanticValidator,
|
|
16320
|
+
createScheduler,
|
|
16321
|
+
createRetrievalTool,
|
|
15277
16322
|
createReplayRecorder,
|
|
15278
16323
|
createReplayPlayer,
|
|
15279
16324
|
createRegressionSuite,
|
|
@@ -15291,6 +16336,7 @@ export {
|
|
|
15291
16336
|
createMCPServer,
|
|
15292
16337
|
createMCPClient,
|
|
15293
16338
|
createLogger,
|
|
16339
|
+
createInMemoryThreadStore,
|
|
15294
16340
|
createInMemoryStore,
|
|
15295
16341
|
createInMemoryMemoryStore,
|
|
15296
16342
|
createInMemoryCache,
|
|
@@ -15301,9 +16347,12 @@ export {
|
|
|
15301
16347
|
createContextManager,
|
|
15302
16348
|
createConfidenceScorer,
|
|
15303
16349
|
createClient,
|
|
16350
|
+
createChannelGateway,
|
|
15304
16351
|
createBatch,
|
|
16352
|
+
createAsyncAgent,
|
|
15305
16353
|
createApp,
|
|
15306
16354
|
createAnthropicProvider,
|
|
16355
|
+
createAgentStream,
|
|
15307
16356
|
createAgentSecurity,
|
|
15308
16357
|
countTokens,
|
|
15309
16358
|
costTrackingMiddleware,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "elsium-ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.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.6.0",
|
|
29
|
+
"@elsium-ai/gateway": "^0.6.0",
|
|
30
|
+
"@elsium-ai/agents": "^0.6.0",
|
|
31
|
+
"@elsium-ai/tools": "^0.6.0",
|
|
32
|
+
"@elsium-ai/rag": "^0.6.0",
|
|
33
|
+
"@elsium-ai/workflows": "^0.6.0",
|
|
34
|
+
"@elsium-ai/observe": "^0.6.0",
|
|
35
|
+
"@elsium-ai/app": "^0.6.0",
|
|
36
|
+
"@elsium-ai/testing": "^0.6.0",
|
|
37
|
+
"@elsium-ai/mcp": "^0.6.0",
|
|
38
|
+
"@elsium-ai/client": "^0.6.0"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"typescript": "^5.7.0"
|