@ariaflowagents/core 0.7.0 → 0.8.1
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/README.md +90 -1
- package/dist/agents/Agent.d.ts +188 -9
- package/dist/agents/Agent.d.ts.map +1 -1
- package/dist/agents/Agent.js +246 -24
- package/dist/agents/Agent.js.map +1 -1
- package/dist/agents/CompositeAgent.d.ts +4 -3
- package/dist/agents/CompositeAgent.d.ts.map +1 -1
- package/dist/agents/CompositeAgent.js +19 -9
- package/dist/agents/CompositeAgent.js.map +1 -1
- package/dist/agents/FlowAgent.d.ts +3 -2
- package/dist/agents/FlowAgent.d.ts.map +1 -1
- package/dist/agents/FlowAgent.js +16 -6
- package/dist/agents/FlowAgent.js.map +1 -1
- package/dist/agents/TriageAgent.d.ts +8 -2
- package/dist/agents/TriageAgent.d.ts.map +1 -1
- package/dist/agents/TriageAgent.js +39 -6
- package/dist/agents/TriageAgent.js.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +0 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/flows/FlowManager.d.ts +8 -0
- package/dist/flows/FlowManager.d.ts.map +1 -1
- package/dist/flows/FlowManager.js +38 -4
- package/dist/flows/FlowManager.js.map +1 -1
- package/dist/flows/template.d.ts +2 -2
- package/dist/flows/template.d.ts.map +1 -1
- package/dist/flows/template.js +13 -0
- package/dist/flows/template.js.map +1 -1
- package/dist/foundation/AgentDefinition.d.ts +18 -0
- package/dist/foundation/AgentDefinition.d.ts.map +1 -0
- package/dist/foundation/AgentDefinition.js +2 -0
- package/dist/foundation/AgentDefinition.js.map +1 -0
- package/dist/foundation/AgentStateController.d.ts +26 -0
- package/dist/foundation/AgentStateController.d.ts.map +1 -0
- package/dist/foundation/AgentStateController.js +2 -0
- package/dist/foundation/AgentStateController.js.map +1 -0
- package/dist/foundation/ConversationEventLog.d.ts +72 -0
- package/dist/foundation/ConversationEventLog.d.ts.map +1 -0
- package/dist/foundation/ConversationEventLog.js +2 -0
- package/dist/foundation/ConversationEventLog.js.map +1 -0
- package/dist/foundation/ConversationState.d.ts +31 -0
- package/dist/foundation/ConversationState.d.ts.map +1 -0
- package/dist/foundation/ConversationState.js +2 -0
- package/dist/foundation/ConversationState.js.map +1 -0
- package/dist/foundation/DefaultAgentStateController.d.ts +24 -0
- package/dist/foundation/DefaultAgentStateController.d.ts.map +1 -0
- package/dist/foundation/DefaultAgentStateController.js +49 -0
- package/dist/foundation/DefaultAgentStateController.js.map +1 -0
- package/dist/foundation/DefaultConversationEventLog.d.ts +28 -0
- package/dist/foundation/DefaultConversationEventLog.d.ts.map +1 -0
- package/dist/foundation/DefaultConversationEventLog.js +195 -0
- package/dist/foundation/DefaultConversationEventLog.js.map +1 -0
- package/dist/foundation/DefaultConversationState.d.ts +34 -0
- package/dist/foundation/DefaultConversationState.d.ts.map +1 -0
- package/dist/foundation/DefaultConversationState.js +100 -0
- package/dist/foundation/DefaultConversationState.js.map +1 -0
- package/dist/foundation/DefaultToolExecutor.d.ts +58 -0
- package/dist/foundation/DefaultToolExecutor.d.ts.map +1 -0
- package/dist/foundation/DefaultToolExecutor.js +128 -0
- package/dist/foundation/DefaultToolExecutor.js.map +1 -0
- package/dist/foundation/ToolExecutor.d.ts +44 -0
- package/dist/foundation/ToolExecutor.d.ts.map +1 -0
- package/dist/foundation/ToolExecutor.js +2 -0
- package/dist/foundation/ToolExecutor.js.map +1 -0
- package/dist/foundation/createFoundation.d.ts +33 -0
- package/dist/foundation/createFoundation.d.ts.map +1 -0
- package/dist/foundation/createFoundation.js +34 -0
- package/dist/foundation/createFoundation.js.map +1 -0
- package/dist/foundation/index.d.ts +15 -0
- package/dist/foundation/index.d.ts.map +1 -0
- package/dist/foundation/index.js +8 -0
- package/dist/foundation/index.js.map +1 -0
- package/dist/hooks/HookRunner.d.ts +2 -0
- package/dist/hooks/HookRunner.d.ts.map +1 -1
- package/dist/hooks/HookRunner.js +4 -0
- package/dist/hooks/HookRunner.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/memory/MemoryService.d.ts +40 -0
- package/dist/memory/MemoryService.d.ts.map +1 -0
- package/dist/memory/MemoryService.js +2 -0
- package/dist/memory/MemoryService.js.map +1 -0
- package/dist/memory/index.d.ts +5 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +3 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/preloadMemory.d.ts +17 -0
- package/dist/memory/preloadMemory.d.ts.map +1 -0
- package/dist/memory/preloadMemory.js +62 -0
- package/dist/memory/preloadMemory.js.map +1 -0
- package/dist/memory/stores/InMemoryMemoryService.d.ts +20 -0
- package/dist/memory/stores/InMemoryMemoryService.d.ts.map +1 -0
- package/dist/memory/stores/InMemoryMemoryService.js +92 -0
- package/dist/memory/stores/InMemoryMemoryService.js.map +1 -0
- package/dist/memory/types.d.ts +49 -0
- package/dist/memory/types.d.ts.map +1 -0
- package/dist/memory/types.js +8 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/prompts/AgentPrompt.d.ts +110 -0
- package/dist/prompts/AgentPrompt.d.ts.map +1 -0
- package/dist/prompts/AgentPrompt.js +373 -0
- package/dist/prompts/AgentPrompt.js.map +1 -0
- package/dist/prompts/PromptAssembly.d.ts +119 -0
- package/dist/prompts/PromptAssembly.d.ts.map +1 -0
- package/dist/prompts/PromptAssembly.js +150 -0
- package/dist/prompts/PromptAssembly.js.map +1 -0
- package/dist/prompts/PromptBuilder.d.ts +22 -3
- package/dist/prompts/PromptBuilder.d.ts.map +1 -1
- package/dist/prompts/PromptBuilder.js +242 -13
- package/dist/prompts/PromptBuilder.js.map +1 -1
- package/dist/prompts/PromptRenderer.d.ts +43 -0
- package/dist/prompts/PromptRenderer.d.ts.map +1 -0
- package/dist/prompts/PromptRenderer.js +114 -0
- package/dist/prompts/PromptRenderer.js.map +1 -0
- package/dist/prompts/brandVoice.d.ts +10 -0
- package/dist/prompts/brandVoice.d.ts.map +1 -0
- package/dist/prompts/brandVoice.js +87 -0
- package/dist/prompts/brandVoice.js.map +1 -0
- package/dist/prompts/index.d.ts +11 -4
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +7 -2
- package/dist/prompts/index.js.map +1 -1
- package/dist/prompts/security.d.ts +5 -0
- package/dist/prompts/security.d.ts.map +1 -0
- package/dist/prompts/security.js +52 -0
- package/dist/prompts/security.js.map +1 -0
- package/dist/prompts/types.d.ts +65 -1
- package/dist/prompts/types.d.ts.map +1 -1
- package/dist/prompts/types.js +26 -0
- package/dist/prompts/types.js.map +1 -1
- package/dist/runtime/ContextBudget.d.ts +57 -0
- package/dist/runtime/ContextBudget.d.ts.map +1 -0
- package/dist/runtime/ContextBudget.js +103 -0
- package/dist/runtime/ContextBudget.js.map +1 -0
- package/dist/runtime/ContextManager.d.ts +8 -5
- package/dist/runtime/ContextManager.d.ts.map +1 -1
- package/dist/runtime/ContextManager.js +47 -14
- package/dist/runtime/ContextManager.js.map +1 -1
- package/dist/runtime/FlowExecutor.d.ts +16 -11
- package/dist/runtime/FlowExecutor.d.ts.map +1 -1
- package/dist/runtime/FlowExecutor.js +32 -138
- package/dist/runtime/FlowExecutor.js.map +1 -1
- package/dist/runtime/Runtime.d.ts +31 -78
- package/dist/runtime/Runtime.d.ts.map +1 -1
- package/dist/runtime/Runtime.js +225 -1406
- package/dist/runtime/Runtime.js.map +1 -1
- package/dist/runtime/SessionCache.d.ts +16 -0
- package/dist/runtime/SessionCache.d.ts.map +1 -0
- package/dist/runtime/SessionCache.js +49 -0
- package/dist/runtime/SessionCache.js.map +1 -0
- package/dist/runtime/SessionMutex.d.ts +37 -0
- package/dist/runtime/SessionMutex.d.ts.map +1 -0
- package/dist/runtime/SessionMutex.js +59 -0
- package/dist/runtime/SessionMutex.js.map +1 -0
- package/dist/runtime/StreamEmitter.d.ts +34 -0
- package/dist/runtime/StreamEmitter.d.ts.map +1 -0
- package/dist/runtime/StreamEmitter.js +91 -0
- package/dist/runtime/StreamEmitter.js.map +1 -0
- package/dist/runtime/handoffFilters.d.ts +60 -0
- package/dist/runtime/handoffFilters.d.ts.map +1 -0
- package/dist/runtime/handoffFilters.js +95 -0
- package/dist/runtime/handoffFilters.js.map +1 -0
- package/dist/runtime/pipeline/AgentExecuteStage.d.ts +22 -0
- package/dist/runtime/pipeline/AgentExecuteStage.d.ts.map +1 -0
- package/dist/runtime/pipeline/AgentExecuteStage.js +889 -0
- package/dist/runtime/pipeline/AgentExecuteStage.js.map +1 -0
- package/dist/runtime/pipeline/ContextAssembleStage.d.ts +26 -0
- package/dist/runtime/pipeline/ContextAssembleStage.d.ts.map +1 -0
- package/dist/runtime/pipeline/ContextAssembleStage.js +253 -0
- package/dist/runtime/pipeline/ContextAssembleStage.js.map +1 -0
- package/dist/runtime/pipeline/ContextGatherStage.d.ts +21 -0
- package/dist/runtime/pipeline/ContextGatherStage.d.ts.map +1 -0
- package/dist/runtime/pipeline/ContextGatherStage.js +161 -0
- package/dist/runtime/pipeline/ContextGatherStage.js.map +1 -0
- package/dist/runtime/pipeline/IntakeStage.d.ts +25 -0
- package/dist/runtime/pipeline/IntakeStage.d.ts.map +1 -0
- package/dist/runtime/pipeline/IntakeStage.js +126 -0
- package/dist/runtime/pipeline/IntakeStage.js.map +1 -0
- package/dist/runtime/pipeline/PostStreamStage.d.ts +26 -0
- package/dist/runtime/pipeline/PostStreamStage.d.ts.map +1 -0
- package/dist/runtime/pipeline/PostStreamStage.js +129 -0
- package/dist/runtime/pipeline/PostStreamStage.js.map +1 -0
- package/dist/runtime/pipeline/TurnPipeline.d.ts +54 -0
- package/dist/runtime/pipeline/TurnPipeline.d.ts.map +1 -0
- package/dist/runtime/pipeline/TurnPipeline.js +15 -0
- package/dist/runtime/pipeline/TurnPipeline.js.map +1 -0
- package/dist/runtime/pipeline/TurnServices.d.ts +48 -0
- package/dist/runtime/pipeline/TurnServices.d.ts.map +1 -0
- package/dist/runtime/pipeline/TurnServices.js +2 -0
- package/dist/runtime/pipeline/TurnServices.js.map +1 -0
- package/dist/runtime/pipeline/agentTypeGuards.d.ts +4 -0
- package/dist/runtime/pipeline/agentTypeGuards.d.ts.map +1 -0
- package/dist/runtime/pipeline/agentTypeGuards.js +7 -0
- package/dist/runtime/pipeline/agentTypeGuards.js.map +1 -0
- package/dist/runtime/pipeline/index.d.ts +11 -0
- package/dist/runtime/pipeline/index.d.ts.map +1 -0
- package/dist/runtime/pipeline/index.js +13 -0
- package/dist/runtime/pipeline/index.js.map +1 -0
- package/dist/runtime/pipeline/outputProcessing.d.ts +23 -0
- package/dist/runtime/pipeline/outputProcessing.d.ts.map +1 -0
- package/dist/runtime/pipeline/outputProcessing.js +63 -0
- package/dist/runtime/pipeline/outputProcessing.js.map +1 -0
- package/dist/runtime/pipeline/sessionUtils.d.ts +12 -0
- package/dist/runtime/pipeline/sessionUtils.d.ts.map +1 -0
- package/dist/runtime/pipeline/sessionUtils.js +73 -0
- package/dist/runtime/pipeline/sessionUtils.js.map +1 -0
- package/dist/tools/Tool.d.ts +7 -0
- package/dist/tools/Tool.d.ts.map +1 -1
- package/dist/tools/Tool.js +12 -3
- package/dist/tools/Tool.js.map +1 -1
- package/dist/tools/memory.d.ts +26 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +51 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/types/index.d.ts +177 -6
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/guides/AGENTS.md +173 -0
- package/guides/README.md +12 -0
- package/guides/TOOLS.md +93 -27
- package/package.json +12 -4
- package/dist/agents/LLMAgent.d.ts +0 -11
- package/dist/agents/LLMAgent.d.ts.map +0 -1
- package/dist/agents/LLMAgent.js +0 -31
- package/dist/agents/LLMAgent.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,7 +22,10 @@ This package exports:
|
|
|
22
22
|
- **Runtime:** `Runtime`, `createRuntime`
|
|
23
23
|
- **Flows:** `FlowManager`, `FlowGraph`, `FlowNode`, `createFlowTransition`, `validateFlowConfig`
|
|
24
24
|
- **Session:** `SessionManager`, `SessionStore`, `MemoryStore`, `RedisStore`
|
|
25
|
-
- **Tools:** `createTool`, `createToolWithFiller`, `createHandoffTool`, `createHttpTool`
|
|
25
|
+
- **Tools:** `createTool`, `createToolWithFiller`, `createHandoffTool`, `createHttpTool`, `createLoadMemoryTool`
|
|
26
|
+
- **Memory:** `InMemoryMemoryService`, `preloadMemoryContext`, `MemoryService` (interface)
|
|
27
|
+
- **Context Budget:** `DEFAULT_CONTEXT_BUDGET`, `computeMessageHistoryBudget`, `truncateToTokenBudget`, `formatMemoryWithBudget`, `estimateTokenCount`
|
|
28
|
+
- **Handoff Filters:** `handoffFilters`, `composeFilters`, `removeToolHistory`, `keepRecentMessages`, `removeKeys`
|
|
26
29
|
- **System Injections:** `InjectionQueue`, `commonInjections`
|
|
27
30
|
- **Prompts:** `PromptTemplateBuilder`, `PromptBuilder`
|
|
28
31
|
- **Hooks:** `HookRunner`, `loggingHooks`, `createMetricsHooks`
|
|
@@ -325,3 +328,89 @@ const bookingFlow = {
|
|
|
325
328
|
],
|
|
326
329
|
};
|
|
327
330
|
```
|
|
331
|
+
|
|
332
|
+
## Changelog
|
|
333
|
+
|
|
334
|
+
### Unreleased — Memory System, Context Budget, Handoff Filters (RFC-008)
|
|
335
|
+
|
|
336
|
+
#### Long-Term Memory
|
|
337
|
+
|
|
338
|
+
Cross-session memory for agents. Facts from past conversations are ingested, stored, and automatically preloaded into future sessions.
|
|
339
|
+
|
|
340
|
+
- **`MemoryService` interface** — pluggable backend for memory storage (`addSessionToMemory`, `searchMemory`, `deleteMemories`)
|
|
341
|
+
- **`InMemoryMemoryService`** — in-process implementation with keyword-based search and idempotent ingestion
|
|
342
|
+
- **`preloadMemoryContext()`** — retrieves relevant memories and formats them as a `## Context from Past Conversations` block injected into the system prompt
|
|
343
|
+
- **`createLoadMemoryTool()`** — gives agents an on-demand tool to search long-term memory mid-conversation
|
|
344
|
+
- **Runtime integration** — new config flags `memoryService`, `preloadMemory: true`, `memoryIngestion: 'onEnd'`
|
|
345
|
+
- **Store adapters** — `RedisMemoryService` (`@ariaflowagents/redis-store`) and `PostgresMemoryService` (`@ariaflowagents/postgres-store`)
|
|
346
|
+
|
|
347
|
+
```ts
|
|
348
|
+
import { Runtime, InMemoryMemoryService, createLoadMemoryTool } from '@ariaflowagents/core';
|
|
349
|
+
|
|
350
|
+
const runtime = new Runtime({
|
|
351
|
+
agents: [agent],
|
|
352
|
+
defaultAgentId: 'agent',
|
|
353
|
+
memoryService: new InMemoryMemoryService(),
|
|
354
|
+
preloadMemory: true, // auto-inject past context each turn
|
|
355
|
+
memoryIngestion: 'onEnd', // ingest memories when session stream ends
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
#### Context Budget
|
|
360
|
+
|
|
361
|
+
Token budget enforcement across all system prompt components (base prompt, memory, working memory, policy injections, message history).
|
|
362
|
+
|
|
363
|
+
- **`ContextBudgetConfig`** — configurable token limits per component (`modelContextWindow`, `responseReserve`, `maxLongTermMemoryTokens`, etc.)
|
|
364
|
+
- **`computeMessageHistoryBudget()`** — computes residual tokens available for message history after all prompt components
|
|
365
|
+
- **`truncateToTokenBudget()` / `formatMemoryWithBudget()`** — helpers for fitting content within token budgets
|
|
366
|
+
- **`onBeforeModelCall` hook** — receives `tokenBreakdown` and `estimatedTokens` for observability
|
|
367
|
+
- **Budget telemetry** — stored in `session.workingMemory.__ariaContextBudget` for inspection
|
|
368
|
+
|
|
369
|
+
#### Handoff Filters
|
|
370
|
+
|
|
371
|
+
Context filtering during agent-to-agent handoffs. Control what conversation history and working memory passes between agents.
|
|
372
|
+
|
|
373
|
+
- **`handoffFilters.removeToolHistory`** — strips tool call/result messages
|
|
374
|
+
- **`handoffFilters.keepRecentMessages(n)`** — retains only the last N messages
|
|
375
|
+
- **`handoffFilters.removeKeys(keys)`** — removes specific working memory keys
|
|
376
|
+
- **`composeFilters(...filters)`** — chains multiple filters in sequence
|
|
377
|
+
- Applied via `AgentRoute.inputFilter` on triage agent routes
|
|
378
|
+
|
|
379
|
+
```ts
|
|
380
|
+
const triageAgent: TriageAgentConfig = {
|
|
381
|
+
type: 'triage',
|
|
382
|
+
routes: [{
|
|
383
|
+
agentId: 'refunds',
|
|
384
|
+
inputFilter: composeFilters(
|
|
385
|
+
handoffFilters.removeToolHistory,
|
|
386
|
+
handoffFilters.keepRecentMessages(5),
|
|
387
|
+
),
|
|
388
|
+
}],
|
|
389
|
+
};
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### ContextManager Coordination
|
|
393
|
+
|
|
394
|
+
- `ContextManagerContext` now accepts `maxTokensOverride` — the Runtime passes the computed message history budget so the ContextManager prunes messages to fit within the remaining token budget after system prompt assembly
|
|
395
|
+
|
|
396
|
+
#### Examples
|
|
397
|
+
|
|
398
|
+
New interactive demos in `examples/agents/memory-demo/`:
|
|
399
|
+
|
|
400
|
+
| File | Description |
|
|
401
|
+
|------|-------------|
|
|
402
|
+
| `run.ts` | Multi-session memory chat — facts recalled across sessions |
|
|
403
|
+
| `validate.ts` | Programmatic end-to-end validation (9 checks) |
|
|
404
|
+
| `context-budget.ts` | Token budget enforcement with `onBeforeModelCall` observability |
|
|
405
|
+
| `handoff-filters.ts` | Multi-agent handoff with context filtering |
|
|
406
|
+
| `form-filler-extraction-with-memory.ts` | Extraction-based form filler with cross-session patient recall |
|
|
407
|
+
| `form-filler-with-memory.ts` | Questionnaire-based form filler with cross-session memory |
|
|
408
|
+
|
|
409
|
+
#### Tests
|
|
410
|
+
|
|
411
|
+
- `test/memory/InMemoryMemoryService.test.js` — unit tests for in-memory store
|
|
412
|
+
- `test/memory/preloadMemory.test.js` — preload formatting and budget compliance
|
|
413
|
+
- `test/runtime/ContextBudget.test.js` — budget computation and truncation
|
|
414
|
+
- `test/runtime/ContextManagerCoordination.test.js` — budget override integration
|
|
415
|
+
- `test/runtime/handoffFilters.test.js` — filter composition and edge cases
|
|
416
|
+
- `test/runtime/integration-memory-budget.test.js` — full pipeline integration (9 tests)
|
package/dist/agents/Agent.d.ts
CHANGED
|
@@ -1,16 +1,195 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Unified Agent class — a single agent primitive that supports both
|
|
3
|
+
* standalone usage (generate, stream, asTool) and runtime-orchestrated
|
|
4
|
+
* usage (run, canHandle, initialize, cleanup).
|
|
5
|
+
*
|
|
6
|
+
* Standalone agents can be used directly via {@link Agent.generate} or
|
|
7
|
+
* {@link Agent.stream}. They can also be converted into tools via
|
|
8
|
+
* {@link Agent.asTool}, enabling the "agent-as-tool" composition pattern.
|
|
9
|
+
*
|
|
10
|
+
* When used with a Runtime, the {@link Agent.run} method provides the
|
|
11
|
+
* default LLM agent implementation (streaming text with tool support).
|
|
12
|
+
* Subclasses like FlowAgent, TriageAgent, and CompositeAgent override
|
|
13
|
+
* `run()` with their specific logic.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { type LanguageModel, type ToolSet } from 'ai';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
import { createTool } from '../tools/Tool.js';
|
|
20
|
+
import type { AgentPrompt } from '../prompts/AgentPrompt.js';
|
|
21
|
+
import type { AgentContext, AgentStreamPart as RuntimeAgentStreamPart } from '../types/index.js';
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for creating an {@link Agent}.
|
|
24
|
+
*/
|
|
25
|
+
export interface AgentConstructorConfig {
|
|
26
|
+
/** Unique identifier for this agent. */
|
|
27
|
+
id: string;
|
|
28
|
+
/** Human-readable name. Defaults to `id`. */
|
|
29
|
+
name?: string;
|
|
30
|
+
/** Description of the agent's capabilities (used by `.asTool()`). */
|
|
31
|
+
description?: string;
|
|
32
|
+
/** The language model to use (e.g. `openai('gpt-4o')`). */
|
|
33
|
+
model: LanguageModel;
|
|
34
|
+
/** System prompt — either a plain string or an {@link AgentPrompt} instance. */
|
|
35
|
+
prompt: string | AgentPrompt;
|
|
36
|
+
/** Optional tool set available to the agent during generation. */
|
|
37
|
+
tools?: ToolSet;
|
|
38
|
+
/** Maximum number of tool-call steps before stopping. Defaults to 10. */
|
|
39
|
+
maxSteps?: number;
|
|
40
|
+
/** List of agent IDs this agent can hand off to. Defaults to []. */
|
|
41
|
+
canHandoffTo?: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Options for {@link Agent.generate} and {@link Agent.stream}.
|
|
45
|
+
*/
|
|
46
|
+
export interface GenerateOptions {
|
|
47
|
+
/** Prior conversation messages to prepend before the user input. */
|
|
48
|
+
messages?: Array<{
|
|
49
|
+
role: string;
|
|
50
|
+
content: string;
|
|
51
|
+
}>;
|
|
52
|
+
/** Abort signal for cancelling the generation. */
|
|
53
|
+
abortSignal?: AbortSignal;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Result returned by {@link Agent.generate}.
|
|
57
|
+
*/
|
|
58
|
+
export interface GenerateResult {
|
|
59
|
+
/** The final text response from the agent. */
|
|
60
|
+
text: string;
|
|
61
|
+
/** Token usage breakdown, if available. */
|
|
62
|
+
usage?: {
|
|
63
|
+
inputTokens: number | undefined;
|
|
64
|
+
outputTokens: number | undefined;
|
|
65
|
+
};
|
|
66
|
+
/** Reason the generation finished (e.g. 'stop', 'tool-calls'). */
|
|
67
|
+
finishReason: string;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* A single part emitted by {@link Agent.stream}.
|
|
71
|
+
*/
|
|
72
|
+
export interface AgentStreamPart {
|
|
73
|
+
type: 'text-delta' | 'tool-call' | 'tool-result' | 'error' | 'finish-step' | 'done';
|
|
74
|
+
text?: string;
|
|
75
|
+
toolName?: string;
|
|
76
|
+
toolCallId?: string;
|
|
77
|
+
args?: unknown;
|
|
78
|
+
result?: unknown;
|
|
79
|
+
error?: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Configuration for {@link Agent.asTool}.
|
|
83
|
+
*/
|
|
84
|
+
export interface AsToolConfig {
|
|
85
|
+
/** Override the tool description. Defaults to the agent's description. */
|
|
86
|
+
description?: string;
|
|
87
|
+
/** Custom input schema. Defaults to `z.object({ query: z.string() })`. */
|
|
88
|
+
inputSchema?: z.ZodType;
|
|
89
|
+
/** How to handle execution errors. Defaults to 'return_error'. */
|
|
90
|
+
errorBehavior?: 'throw' | 'return_error';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A unified agent that supports both standalone usage (generate/stream/asTool)
|
|
94
|
+
* and runtime-orchestrated usage (run/canHandle/initialize/cleanup).
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const agent = new Agent({
|
|
99
|
+
* id: 'helper',
|
|
100
|
+
* model: openai('gpt-4o'),
|
|
101
|
+
* prompt: 'You are a helpful assistant.',
|
|
102
|
+
* });
|
|
103
|
+
*
|
|
104
|
+
* // One-shot generation
|
|
105
|
+
* const result = await agent.generate('Hello!');
|
|
106
|
+
* console.log(result.text);
|
|
107
|
+
*
|
|
108
|
+
* // Streaming
|
|
109
|
+
* for await (const part of agent.stream('Hello!')) {
|
|
110
|
+
* if (part.type === 'text-delta') process.stdout.write(part.text!);
|
|
111
|
+
* }
|
|
112
|
+
*
|
|
113
|
+
* // Use as a tool in another agent
|
|
114
|
+
* const tool = agent.asTool({ description: 'Ask the helper' });
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
export declare class Agent {
|
|
118
|
+
/** Unique identifier. */
|
|
3
119
|
readonly id: string;
|
|
120
|
+
/** Human-readable name. */
|
|
4
121
|
readonly name: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
122
|
+
/** Description of capabilities. */
|
|
123
|
+
readonly description: string;
|
|
124
|
+
/** The language model backing this agent. */
|
|
125
|
+
readonly model: LanguageModel;
|
|
126
|
+
/** System prompt (string or AgentPrompt). */
|
|
127
|
+
readonly prompt: string | AgentPrompt;
|
|
128
|
+
/** Tools available to the agent. */
|
|
129
|
+
readonly tools: ToolSet;
|
|
130
|
+
/** Maximum tool-call steps per generation. */
|
|
131
|
+
readonly maxSteps: number;
|
|
132
|
+
/** List of agent IDs this agent can hand off to. */
|
|
133
|
+
readonly canHandoffTo: string[];
|
|
134
|
+
constructor(config: AgentConstructorConfig);
|
|
135
|
+
/**
|
|
136
|
+
* Resolves the system prompt to a string. If `this.prompt` is an
|
|
137
|
+
* {@link AgentPrompt}, calls its `.render()` method.
|
|
138
|
+
*/
|
|
139
|
+
protected resolveSystemPrompt(): Promise<string>;
|
|
140
|
+
/**
|
|
141
|
+
* Generates a complete response for the given input (non-streaming).
|
|
142
|
+
*
|
|
143
|
+
* @param input - The user message to process.
|
|
144
|
+
* @param options - Optional prior messages and abort signal.
|
|
145
|
+
* @returns The complete generation result.
|
|
146
|
+
*/
|
|
147
|
+
generate(input: string, options?: GenerateOptions): Promise<GenerateResult>;
|
|
148
|
+
/**
|
|
149
|
+
* Streams a response for the given input, yielding {@link AgentStreamPart}
|
|
150
|
+
* chunks as they arrive.
|
|
151
|
+
*
|
|
152
|
+
* @param input - The user message to process.
|
|
153
|
+
* @param options - Optional prior messages and abort signal.
|
|
154
|
+
* @yields Stream parts: text-delta, tool-call, tool-result, error, finish-step, done.
|
|
155
|
+
*/
|
|
156
|
+
stream(input: string, options?: GenerateOptions): AsyncGenerator<AgentStreamPart>;
|
|
157
|
+
/**
|
|
158
|
+
* Wraps this agent as a tool that can be given to another agent.
|
|
159
|
+
*
|
|
160
|
+
* The returned tool accepts a `{ query: string }` input (or a custom schema),
|
|
161
|
+
* calls {@link Agent.generate} internally, and returns the text response.
|
|
162
|
+
*
|
|
163
|
+
* @param config - Optional overrides for description, schema, and error handling.
|
|
164
|
+
* @returns A tool compatible with the AI SDK tool set.
|
|
165
|
+
*/
|
|
166
|
+
asTool(config?: AsToolConfig): ReturnType<typeof createTool<unknown, unknown>>;
|
|
167
|
+
/**
|
|
168
|
+
* Processes a user message within a runtime context, yielding stream parts.
|
|
169
|
+
* This is the default LLM agent implementation that streams text with tool support.
|
|
170
|
+
*
|
|
171
|
+
* Subclasses (FlowAgent, TriageAgent, CompositeAgent) override this method
|
|
172
|
+
* with their specific logic.
|
|
173
|
+
*
|
|
174
|
+
* @param _input - The user message to process.
|
|
175
|
+
* @param context - The runtime agent context with session, messages, etc.
|
|
176
|
+
* @yields AgentStreamPart chunks.
|
|
177
|
+
*/
|
|
178
|
+
run(_input: string, context: AgentContext): AsyncGenerator<RuntimeAgentStreamPart>;
|
|
179
|
+
/**
|
|
180
|
+
* Determines whether this agent can handle the given input.
|
|
181
|
+
* Returns true by default. Subclasses can override for conditional routing.
|
|
182
|
+
*/
|
|
9
183
|
canHandle(_input: string, _context: AgentContext): Promise<boolean>;
|
|
184
|
+
/**
|
|
185
|
+
* Called when the agent is first activated in a runtime context.
|
|
186
|
+
* No-op by default. Subclasses can override for setup logic.
|
|
187
|
+
*/
|
|
10
188
|
initialize(_context: AgentContext): Promise<void>;
|
|
189
|
+
/**
|
|
190
|
+
* Called when the agent is deactivated in a runtime context.
|
|
191
|
+
* No-op by default. Subclasses can override for teardown logic.
|
|
192
|
+
*/
|
|
11
193
|
cleanup(_context: AgentContext): Promise<void>;
|
|
12
|
-
get canHandoffTo(): string[];
|
|
13
|
-
protected buildSystemPrompt(context: AgentContext): string;
|
|
14
|
-
protected getSystemPromptString(): string;
|
|
15
194
|
}
|
|
16
195
|
//# sourceMappingURL=Agent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Agent.d.ts","sourceRoot":"","sources":["../../src/agents/Agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"Agent.d.ts","sourceRoot":"","sources":["../../src/agents/Agent.ts"],"names":[],"mappings":"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"}
|
package/dist/agents/Agent.js
CHANGED
|
@@ -1,42 +1,264 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Unified Agent class — a single agent primitive that supports both
|
|
3
|
+
* standalone usage (generate, stream, asTool) and runtime-orchestrated
|
|
4
|
+
* usage (run, canHandle, initialize, cleanup).
|
|
5
|
+
*
|
|
6
|
+
* Standalone agents can be used directly via {@link Agent.generate} or
|
|
7
|
+
* {@link Agent.stream}. They can also be converted into tools via
|
|
8
|
+
* {@link Agent.asTool}, enabling the "agent-as-tool" composition pattern.
|
|
9
|
+
*
|
|
10
|
+
* When used with a Runtime, the {@link Agent.run} method provides the
|
|
11
|
+
* default LLM agent implementation (streaming text with tool support).
|
|
12
|
+
* Subclasses like FlowAgent, TriageAgent, and CompositeAgent override
|
|
13
|
+
* `run()` with their specific logic.
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import { generateText, streamText, stepCountIs } from 'ai';
|
|
18
|
+
import { z } from 'zod';
|
|
19
|
+
import { createTool } from '../tools/Tool.js';
|
|
20
|
+
import { processAIStream } from '../utils/aiStream.js';
|
|
21
|
+
// ============================================
|
|
22
|
+
// Agent
|
|
23
|
+
// ============================================
|
|
24
|
+
/**
|
|
25
|
+
* A unified agent that supports both standalone usage (generate/stream/asTool)
|
|
26
|
+
* and runtime-orchestrated usage (run/canHandle/initialize/cleanup).
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const agent = new Agent({
|
|
31
|
+
* id: 'helper',
|
|
32
|
+
* model: openai('gpt-4o'),
|
|
33
|
+
* prompt: 'You are a helpful assistant.',
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // One-shot generation
|
|
37
|
+
* const result = await agent.generate('Hello!');
|
|
38
|
+
* console.log(result.text);
|
|
39
|
+
*
|
|
40
|
+
* // Streaming
|
|
41
|
+
* for await (const part of agent.stream('Hello!')) {
|
|
42
|
+
* if (part.type === 'text-delta') process.stdout.write(part.text!);
|
|
43
|
+
* }
|
|
44
|
+
*
|
|
45
|
+
* // Use as a tool in another agent
|
|
46
|
+
* const tool = agent.asTool({ description: 'Ask the helper' });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
2
49
|
export class Agent {
|
|
50
|
+
/** Unique identifier. */
|
|
3
51
|
id;
|
|
52
|
+
/** Human-readable name. */
|
|
4
53
|
name;
|
|
54
|
+
/** Description of capabilities. */
|
|
5
55
|
description;
|
|
6
|
-
|
|
56
|
+
/** The language model backing this agent. */
|
|
57
|
+
model;
|
|
58
|
+
/** System prompt (string or AgentPrompt). */
|
|
59
|
+
prompt;
|
|
60
|
+
/** Tools available to the agent. */
|
|
61
|
+
tools;
|
|
62
|
+
/** Maximum tool-call steps per generation. */
|
|
63
|
+
maxSteps;
|
|
64
|
+
/** List of agent IDs this agent can hand off to. */
|
|
65
|
+
canHandoffTo;
|
|
7
66
|
constructor(config) {
|
|
8
67
|
this.id = config.id;
|
|
9
|
-
this.name = config.name;
|
|
10
|
-
this.description = config.description;
|
|
11
|
-
this.
|
|
68
|
+
this.name = config.name ?? config.id;
|
|
69
|
+
this.description = config.description ?? '';
|
|
70
|
+
this.model = config.model;
|
|
71
|
+
this.prompt = config.prompt;
|
|
72
|
+
this.tools = config.tools ?? {};
|
|
73
|
+
this.maxSteps = config.maxSteps ?? 10;
|
|
74
|
+
this.canHandoffTo = config.canHandoffTo ?? [];
|
|
12
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Resolves the system prompt to a string. If `this.prompt` is an
|
|
78
|
+
* {@link AgentPrompt}, calls its `.render()` method.
|
|
79
|
+
*/
|
|
80
|
+
async resolveSystemPrompt() {
|
|
81
|
+
if (typeof this.prompt === 'string')
|
|
82
|
+
return this.prompt;
|
|
83
|
+
if (this.prompt && 'render' in this.prompt && typeof this.prompt.render === 'function') {
|
|
84
|
+
return this.prompt.render();
|
|
85
|
+
}
|
|
86
|
+
return String(this.prompt);
|
|
87
|
+
}
|
|
88
|
+
// ============================================
|
|
89
|
+
// Standalone API
|
|
90
|
+
// ============================================
|
|
91
|
+
/**
|
|
92
|
+
* Generates a complete response for the given input (non-streaming).
|
|
93
|
+
*
|
|
94
|
+
* @param input - The user message to process.
|
|
95
|
+
* @param options - Optional prior messages and abort signal.
|
|
96
|
+
* @returns The complete generation result.
|
|
97
|
+
*/
|
|
98
|
+
async generate(input, options) {
|
|
99
|
+
const system = await this.resolveSystemPrompt();
|
|
100
|
+
const priorMessages = (options?.messages ?? []).map(m => ({
|
|
101
|
+
role: m.role,
|
|
102
|
+
content: m.content,
|
|
103
|
+
}));
|
|
104
|
+
const hasTools = Object.keys(this.tools).length > 0;
|
|
105
|
+
const result = await generateText({
|
|
106
|
+
model: this.model,
|
|
107
|
+
system,
|
|
108
|
+
messages: [...priorMessages, { role: 'user', content: input }],
|
|
109
|
+
tools: hasTools ? this.tools : undefined,
|
|
110
|
+
...(hasTools ? { stopWhen: stepCountIs(this.maxSteps) } : {}),
|
|
111
|
+
abortSignal: options?.abortSignal,
|
|
112
|
+
});
|
|
113
|
+
return {
|
|
114
|
+
text: result.text,
|
|
115
|
+
usage: {
|
|
116
|
+
inputTokens: result.usage.inputTokens,
|
|
117
|
+
outputTokens: result.usage.outputTokens,
|
|
118
|
+
},
|
|
119
|
+
finishReason: result.finishReason,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Streams a response for the given input, yielding {@link AgentStreamPart}
|
|
124
|
+
* chunks as they arrive.
|
|
125
|
+
*
|
|
126
|
+
* @param input - The user message to process.
|
|
127
|
+
* @param options - Optional prior messages and abort signal.
|
|
128
|
+
* @yields Stream parts: text-delta, tool-call, tool-result, error, finish-step, done.
|
|
129
|
+
*/
|
|
130
|
+
async *stream(input, options) {
|
|
131
|
+
const system = await this.resolveSystemPrompt();
|
|
132
|
+
const priorMessages = (options?.messages ?? []).map(m => ({
|
|
133
|
+
role: m.role,
|
|
134
|
+
content: m.content,
|
|
135
|
+
}));
|
|
136
|
+
const hasTools = Object.keys(this.tools).length > 0;
|
|
137
|
+
const result = streamText({
|
|
138
|
+
model: this.model,
|
|
139
|
+
system,
|
|
140
|
+
messages: [...priorMessages, { role: 'user', content: input }],
|
|
141
|
+
tools: hasTools ? this.tools : undefined,
|
|
142
|
+
...(hasTools ? { stopWhen: stepCountIs(this.maxSteps) } : {}),
|
|
143
|
+
abortSignal: options?.abortSignal,
|
|
144
|
+
});
|
|
145
|
+
for await (const chunk of result.fullStream) {
|
|
146
|
+
switch (chunk.type) {
|
|
147
|
+
case 'text-delta':
|
|
148
|
+
yield { type: 'text-delta', text: chunk.text };
|
|
149
|
+
break;
|
|
150
|
+
case 'tool-call': {
|
|
151
|
+
const c = chunk;
|
|
152
|
+
yield {
|
|
153
|
+
type: 'tool-call',
|
|
154
|
+
toolName: c.toolName,
|
|
155
|
+
toolCallId: c.toolCallId,
|
|
156
|
+
args: c.input ?? c.args,
|
|
157
|
+
};
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case 'tool-result': {
|
|
161
|
+
const c = chunk;
|
|
162
|
+
yield {
|
|
163
|
+
type: 'tool-result',
|
|
164
|
+
toolName: c.toolName,
|
|
165
|
+
toolCallId: c.toolCallId,
|
|
166
|
+
result: c.output ?? c.result,
|
|
167
|
+
};
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 'error':
|
|
171
|
+
yield { type: 'error', error: String(chunk.error) };
|
|
172
|
+
break;
|
|
173
|
+
case 'finish-step':
|
|
174
|
+
yield { type: 'finish-step' };
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
yield { type: 'done' };
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Wraps this agent as a tool that can be given to another agent.
|
|
182
|
+
*
|
|
183
|
+
* The returned tool accepts a `{ query: string }` input (or a custom schema),
|
|
184
|
+
* calls {@link Agent.generate} internally, and returns the text response.
|
|
185
|
+
*
|
|
186
|
+
* @param config - Optional overrides for description, schema, and error handling.
|
|
187
|
+
* @returns A tool compatible with the AI SDK tool set.
|
|
188
|
+
*/
|
|
189
|
+
asTool(config) {
|
|
190
|
+
const agent = this;
|
|
191
|
+
const errorBehavior = config?.errorBehavior ?? 'return_error';
|
|
192
|
+
// Cast through unknown to satisfy the AI SDK's NoInfer-wrapped output type.
|
|
193
|
+
return createTool({
|
|
194
|
+
description: config?.description || agent.description || `Consult the ${agent.name} agent`,
|
|
195
|
+
inputSchema: (config?.inputSchema ?? z.object({
|
|
196
|
+
query: z.string().describe('The question to ask the specialist agent'),
|
|
197
|
+
})),
|
|
198
|
+
execute: async (rawInput) => {
|
|
199
|
+
const input = rawInput;
|
|
200
|
+
const query = typeof rawInput === 'string' ? rawInput : (input.query ?? '');
|
|
201
|
+
try {
|
|
202
|
+
const result = await agent.generate(query);
|
|
203
|
+
return { agentId: agent.id, response: result.text };
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
if (errorBehavior === 'throw')
|
|
207
|
+
throw error;
|
|
208
|
+
return {
|
|
209
|
+
agentId: agent.id,
|
|
210
|
+
error: `Agent "${agent.id}" failed: ${error.message}`,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
// ============================================
|
|
217
|
+
// Runtime-orchestrated API
|
|
218
|
+
// ============================================
|
|
219
|
+
/**
|
|
220
|
+
* Processes a user message within a runtime context, yielding stream parts.
|
|
221
|
+
* This is the default LLM agent implementation that streams text with tool support.
|
|
222
|
+
*
|
|
223
|
+
* Subclasses (FlowAgent, TriageAgent, CompositeAgent) override this method
|
|
224
|
+
* with their specific logic.
|
|
225
|
+
*
|
|
226
|
+
* @param _input - The user message to process.
|
|
227
|
+
* @param context - The runtime agent context with session, messages, etc.
|
|
228
|
+
* @yields AgentStreamPart chunks.
|
|
229
|
+
*/
|
|
230
|
+
async *run(_input, context) {
|
|
231
|
+
const systemPrompt = await this.resolveSystemPrompt();
|
|
232
|
+
const result = streamText({
|
|
233
|
+
model: this.model,
|
|
234
|
+
system: systemPrompt,
|
|
235
|
+
messages: context.messages,
|
|
236
|
+
tools: this.tools,
|
|
237
|
+
abortSignal: context.abortSignal,
|
|
238
|
+
});
|
|
239
|
+
yield* processAIStream(result.fullStream);
|
|
240
|
+
yield { type: 'turn-end', metadata: { response: await result.response } };
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Determines whether this agent can handle the given input.
|
|
244
|
+
* Returns true by default. Subclasses can override for conditional routing.
|
|
245
|
+
*/
|
|
13
246
|
async canHandle(_input, _context) {
|
|
14
247
|
return true;
|
|
15
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* Called when the agent is first activated in a runtime context.
|
|
251
|
+
* No-op by default. Subclasses can override for setup logic.
|
|
252
|
+
*/
|
|
16
253
|
async initialize(_context) {
|
|
17
254
|
// Optional in subclasses
|
|
18
255
|
}
|
|
256
|
+
/**
|
|
257
|
+
* Called when the agent is deactivated in a runtime context.
|
|
258
|
+
* No-op by default. Subclasses can override for teardown logic.
|
|
259
|
+
*/
|
|
19
260
|
async cleanup(_context) {
|
|
20
261
|
// Optional in subclasses
|
|
21
262
|
}
|
|
22
|
-
get canHandoffTo() {
|
|
23
|
-
return this.config.canHandoffTo ?? [];
|
|
24
|
-
}
|
|
25
|
-
buildSystemPrompt(context) {
|
|
26
|
-
let prompt = this.getSystemPromptString();
|
|
27
|
-
const memory = context.workingMemory.toJSON();
|
|
28
|
-
if (Object.keys(memory).length > 0) {
|
|
29
|
-
prompt += `\n\n## Known Information\n${JSON.stringify(memory, null, 2)}`;
|
|
30
|
-
}
|
|
31
|
-
return prompt;
|
|
32
|
-
}
|
|
33
|
-
getSystemPromptString() {
|
|
34
|
-
const sp = this.config.systemPrompt;
|
|
35
|
-
if (typeof sp === 'string') {
|
|
36
|
-
return sp;
|
|
37
|
-
}
|
|
38
|
-
// It's a PromptTemplate
|
|
39
|
-
return new PromptBuilder(sp).build();
|
|
40
|
-
}
|
|
41
263
|
}
|
|
42
264
|
//# sourceMappingURL=Agent.js.map
|
package/dist/agents/Agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Agent.js","sourceRoot":"","sources":["../../src/agents/Agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Agent.js","sourceRoot":"","sources":["../../src/agents/Agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,14 +6,15 @@ export interface CompositeAgentConfig extends AgentConfig {
|
|
|
6
6
|
entryAgent: string;
|
|
7
7
|
maxHandoffs?: number;
|
|
8
8
|
}
|
|
9
|
-
export declare class CompositeAgent extends Agent
|
|
9
|
+
export declare class CompositeAgent extends Agent {
|
|
10
|
+
private compositeConfig;
|
|
10
11
|
private agents;
|
|
11
12
|
private entryAgentId;
|
|
12
|
-
private
|
|
13
|
+
private maxHandoffsLimit;
|
|
13
14
|
constructor(config: CompositeAgentConfig);
|
|
14
15
|
initialize(context: AgentContext): Promise<void>;
|
|
15
16
|
cleanup(context: AgentContext): Promise<void>;
|
|
16
|
-
|
|
17
|
+
run(input: string, context: AgentContext): AsyncGenerator<AgentStreamPart>;
|
|
17
18
|
getAgent(id: string): Agent | undefined;
|
|
18
19
|
get subAgentIds(): string[];
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompositeAgent.d.ts","sourceRoot":"","sources":["../../src/agents/CompositeAgent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAe,SAAQ,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"CompositeAgent.d.ts","sourceRoot":"","sources":["../../src/agents/CompositeAgent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,gBAAgB,CAAS;gBAErB,MAAM,EAAE,oBAAoB;IAmBlC,UAAU,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhD,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,GAAG,CACR,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,YAAY,GACpB,cAAc,CAAC,eAAe,CAAC;IAmDlC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS;IAIvC,IAAI,WAAW,IAAI,MAAM,EAAE,CAE1B;CACF"}
|