@kuralle-agents/core 0.13.0 → 0.14.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.
Files changed (158) hide show
  1. package/README.md +4 -4
  2. package/dist/ai-sdk/uiMessageStream.d.ts +2 -2
  3. package/dist/ai-sdk/uiMessageStream.js +42 -29
  4. package/dist/capabilities/LivePromptAssembler.d.ts +1 -1
  5. package/dist/capabilities/LivePromptAssembler.js +1 -1
  6. package/dist/capabilities/index.d.ts +1 -1
  7. package/dist/eval/EvalRunner.js +4 -4
  8. package/dist/eval/simulation.js +4 -3
  9. package/dist/events/TurnHandle.d.ts +3 -3
  10. package/dist/flow/collectUntilComplete.js +4 -4
  11. package/dist/flow/degrade.js +8 -4
  12. package/dist/flow/emitInteractive.d.ts +2 -2
  13. package/dist/flow/emitInteractive.js +6 -3
  14. package/dist/flow/extraction.d.ts +2 -2
  15. package/dist/flow/extraction.js +10 -4
  16. package/dist/flow/reduceTransition.d.ts +2 -2
  17. package/dist/flow/reduceTransition.js +7 -3
  18. package/dist/flow/runFlow.js +34 -12
  19. package/dist/foundation/AgentStateController.d.ts +1 -1
  20. package/dist/foundation/ToolExecutor.d.ts +2 -2
  21. package/dist/foundation/index.d.ts +0 -11
  22. package/dist/foundation/index.js +0 -5
  23. package/dist/index.d.ts +9 -14
  24. package/dist/index.js +5 -6
  25. package/dist/outcomes/streamPart.d.ts +2 -2
  26. package/dist/outcomes/streamPart.js +2 -3
  27. package/dist/prompts/PromptBuilder.d.ts +3 -3
  28. package/dist/prompts/PromptBuilder.js +6 -6
  29. package/dist/prompts/index.d.ts +1 -1
  30. package/dist/prompts/types.d.ts +7 -2
  31. package/dist/runtime/InMemoryRetrievalCache.d.ts +1 -1
  32. package/dist/runtime/KnowledgeProvider.d.ts +3 -2
  33. package/dist/runtime/KnowledgeProvider.js +54 -30
  34. package/dist/runtime/Runtime.d.ts +3 -1
  35. package/dist/runtime/Runtime.js +84 -30
  36. package/dist/runtime/TraceRecorder.d.ts +22 -4
  37. package/dist/runtime/TraceRecorder.js +65 -29
  38. package/dist/runtime/buildAgentToolSurface.js +1 -1
  39. package/dist/runtime/channels/TextDriver.js +12 -9
  40. package/dist/runtime/channels/executeModelTool.d.ts +6 -0
  41. package/dist/runtime/channels/executeModelTool.js +70 -10
  42. package/dist/runtime/channels/extractionTurn.js +1 -1
  43. package/dist/runtime/channels/index.d.ts +0 -3
  44. package/dist/runtime/channels/index.js +0 -6
  45. package/dist/runtime/channels/streaming/hostControlSpeak.js +5 -1
  46. package/dist/runtime/channels/streaming/speakGated.js +24 -12
  47. package/dist/runtime/citations/index.d.ts +3 -3
  48. package/dist/runtime/closeRun.js +3 -2
  49. package/dist/runtime/controlFlowSignal.d.ts +24 -0
  50. package/dist/runtime/controlFlowSignal.js +29 -0
  51. package/dist/runtime/ctx.d.ts +3 -4
  52. package/dist/runtime/ctx.js +39 -5
  53. package/dist/runtime/durable/RunStore.js +1 -1
  54. package/dist/runtime/grounding/gather.d.ts +1 -1
  55. package/dist/runtime/grounding/inMemoryKnowledge.d.ts +1 -1
  56. package/dist/runtime/grounding/knowledge.d.ts +1 -1
  57. package/dist/runtime/hostLoop.js +26 -6
  58. package/dist/runtime/index.d.ts +1 -2
  59. package/dist/runtime/index.js +1 -1
  60. package/dist/runtime/outcomeMarking.d.ts +2 -2
  61. package/dist/runtime/outcomeMarking.js +2 -1
  62. package/dist/runtime/policies/agentTurn.d.ts +1 -1
  63. package/dist/runtime/runHookSafely.d.ts +3 -0
  64. package/dist/runtime/runHookSafely.js +19 -0
  65. package/dist/scheduler/index.d.ts +2 -2
  66. package/dist/scheduler/index.js +1 -1
  67. package/dist/services/TracingService.js +2 -3
  68. package/dist/skills/collectSkills.d.ts +11 -3
  69. package/dist/skills/collectSkills.js +51 -8
  70. package/dist/skills/compositeSkillStore.d.ts +26 -0
  71. package/dist/skills/compositeSkillStore.js +54 -0
  72. package/dist/skills/defineSkill.d.ts +21 -0
  73. package/dist/skills/defineSkill.js +26 -0
  74. package/dist/skills/fsSkillStore.d.ts +3 -0
  75. package/dist/skills/fsSkillStore.js +79 -0
  76. package/dist/skills/index.d.ts +4 -0
  77. package/dist/skills/index.js +4 -0
  78. package/dist/skills/parseSkillFrontmatter.d.ts +14 -0
  79. package/dist/skills/parseSkillFrontmatter.js +183 -0
  80. package/dist/skills/wireAgentSkills.d.ts +2 -1
  81. package/dist/skills/wireAgentSkills.js +2 -2
  82. package/dist/testing/mocks.d.ts +3 -3
  83. package/dist/testing/mocks.js +7 -3
  84. package/dist/tools/controlResults.d.ts +14 -0
  85. package/dist/tools/controlResults.js +15 -0
  86. package/dist/tools/effect/ToolExecutor.d.ts +6 -0
  87. package/dist/tools/effect/ToolExecutor.js +71 -35
  88. package/dist/tools/effect/defineTool.d.ts +9 -0
  89. package/dist/tools/effect/defineTool.js +1 -0
  90. package/dist/tools/effect/errors.d.ts +2 -5
  91. package/dist/tools/effect/errors.js +2 -5
  92. package/dist/tools/index.d.ts +0 -1
  93. package/dist/tools/index.js +0 -1
  94. package/dist/types/effectTool.d.ts +2 -0
  95. package/dist/types/flow.d.ts +1 -1
  96. package/dist/types/guardrails.d.ts +5 -0
  97. package/dist/types/hooks.d.ts +2 -2
  98. package/dist/types/index.d.ts +25 -16
  99. package/dist/types/index.js +8 -13
  100. package/dist/types/knowledge.d.ts +213 -0
  101. package/dist/types/processors.d.ts +0 -58
  102. package/dist/types/run-context.d.ts +3 -7
  103. package/dist/types/runtime.d.ts +3 -74
  104. package/dist/types/session.d.ts +1 -1
  105. package/dist/types/skills.d.ts +15 -1
  106. package/dist/types/stream.d.ts +133 -71
  107. package/dist/types/stream.js +34 -1
  108. package/dist/types/trace.d.ts +2 -0
  109. package/guides/AGENTS.md +3 -3
  110. package/guides/FLOWS.md +1 -1
  111. package/guides/GETTING_STARTED.md +1 -1
  112. package/guides/RUNTIME.md +20 -15
  113. package/guides/TOOLS.md +1 -1
  114. package/package.json +3 -13
  115. package/dist/foundation/AgentDefinition.d.ts +0 -17
  116. package/dist/foundation/ConversationEventLog.d.ts +0 -71
  117. package/dist/foundation/ConversationEventLog.js +0 -1
  118. package/dist/foundation/ConversationState.d.ts +0 -33
  119. package/dist/foundation/ConversationState.js +0 -1
  120. package/dist/foundation/DefaultConversationEventLog.d.ts +0 -27
  121. package/dist/foundation/DefaultConversationEventLog.js +0 -205
  122. package/dist/foundation/DefaultConversationState.d.ts +0 -36
  123. package/dist/foundation/DefaultConversationState.js +0 -103
  124. package/dist/foundation/DefaultToolExecutor.d.ts +0 -57
  125. package/dist/foundation/DefaultToolExecutor.js +0 -132
  126. package/dist/foundation/createFoundation.d.ts +0 -32
  127. package/dist/foundation/createFoundation.js +0 -33
  128. package/dist/hooks/HookRunner.d.ts +0 -37
  129. package/dist/hooks/HookRunner.js +0 -111
  130. package/dist/hooks/builtin/logging.d.ts +0 -5
  131. package/dist/hooks/builtin/logging.js +0 -98
  132. package/dist/hooks/builtin/metrics.d.ts +0 -7
  133. package/dist/hooks/builtin/metrics.js +0 -60
  134. package/dist/hooks/builtin/observability.d.ts +0 -20
  135. package/dist/hooks/builtin/observability.js +0 -572
  136. package/dist/hooks/helpers.d.ts +0 -22
  137. package/dist/hooks/helpers.js +0 -183
  138. package/dist/hooks/index.d.ts +0 -8
  139. package/dist/hooks/index.js +0 -6
  140. package/dist/realtime/RealtimeAudioClient.d.ts +0 -166
  141. package/dist/realtime/RealtimeAudioClient.js +0 -14
  142. package/dist/realtime/RealtimeSessionHandle.d.ts +0 -6
  143. package/dist/realtime/RealtimeSessionHandle.js +0 -1
  144. package/dist/realtime/index.d.ts +0 -2
  145. package/dist/realtime/index.js +0 -1
  146. package/dist/runtime/channels/VoiceDriver.d.ts +0 -31
  147. package/dist/runtime/channels/VoiceDriver.js +0 -321
  148. package/dist/runtime/channels/voiceTools.d.ts +0 -9
  149. package/dist/runtime/channels/voiceTools.js +0 -51
  150. package/dist/tools/errorHandling.d.ts +0 -35
  151. package/dist/tools/errorHandling.js +0 -145
  152. package/dist/types/voice.d.ts +0 -517
  153. package/dist/types/voice.js +0 -14
  154. package/dist/utils/isRecord.d.ts +0 -1
  155. package/dist/utils/isRecord.js +0 -3
  156. package/dist/utils/messageNormalization.d.ts +0 -2
  157. package/dist/utils/messageNormalization.js +0 -137
  158. /package/dist/{foundation/AgentDefinition.js → types/knowledge.js} +0 -0
package/dist/index.d.ts CHANGED
@@ -30,12 +30,6 @@ export type { PromptSection, PromptTemplate, ToolGuideline } from './prompts/ind
30
30
  export { BuiltinPersonas, composePersonaPrompt } from './persona/index.js';
31
31
  export { resolvePersonaExperiment } from './persona/index.js';
32
32
  export type { PersonaConfig, PersonaExperimentCohort, PersonaExperimentConfig, PersonaExperimentMetadata, PersonaExperimentResolution, PersonaLanguagePolicy, PersonaRegister, PersonaVoice, } from './persona/index.js';
33
- export { HookRunner, createHookRunner } from './hooks/HookRunner.js';
34
- export { loggingHooks, createLoggingHooks } from './hooks/builtin/logging.js';
35
- export { createMetricsHooks, InMemoryMetrics } from './hooks/builtin/metrics.js';
36
- export type { Metrics } from './hooks/builtin/metrics.js';
37
- export { createObservabilityHooks } from './hooks/builtin/observability.js';
38
- export type { ObservabilityConfig } from './hooks/builtin/observability.js';
39
33
  export type { SessionTrace, TraceStreamEvent } from './types/telemetry.js';
40
34
  export { createPromptInjectionGuard } from './processors/builtin/promptInjectionGuard.js';
41
35
  export type { PromptInjectionGuardOptions } from './processors/builtin/promptInjectionGuard.js';
@@ -76,8 +70,8 @@ export { applyPromptCache, applyAnthropicCacheControl, buildOpenAIResponsesProvi
76
70
  export type { AnthropicCacheTtl, OpenAIResponsesCompactOptions } from './runtime/promptCache.js';
77
71
  export { handoffFilters, removeToolHistory, keepRecentMessages, removeKeys, composeFilters, } from './runtime/handoffFilters.js';
78
72
  export type { HandoffInputFilter, HandoffInputData, HandoffInputResult, } from './runtime/handoffFilters.js';
79
- export { DefaultToolExecutor, DefaultConversationState, DefaultConversationEventLog, DefaultAgentStateController, createFoundation, } from './foundation/index.js';
80
- export type { ToolExecutor, ConversationState, ConversationEventLog, ConversationEvent, AgentStateController, Foundation, FoundationConfig, } from './foundation/index.js';
73
+ export { DefaultAgentStateController } from './foundation/index.js';
74
+ export type { ToolExecutor, AgentStateController, } from './foundation/index.js';
81
75
  export type * from './types/index.js';
82
76
  export { CapabilityHost, ExtractionCapability, GuardrailCapability, AutoRetrieveCapability, PassThroughRefinement, PassThroughValidation, toGeminiDeclarations, toAISDKTools, } from './capabilities/index.js';
83
77
  export type { Capability, CapabilityAction, ExtractionToolResponseEnvelope, FlowReconfigureTransition, ToolDeclaration, PromptSection as CapabilityPromptSection, GeminiFunctionDeclaration, ExtractionCapabilityConfig, RetrieveProvider, AutoRetrieveCapabilityConfig, RefinementCapability, RefineInput, RefineDecision, ValidationCapability, ValidateInput, ValidateDecision, SourceRef, } from './capabilities/index.js';
@@ -87,9 +81,7 @@ export { createInProcessScheduler, createWakeJobRunner, createScheduleFollowupTo
87
81
  export type { Scheduler, ScheduledJob, InjectableTimer, WakeOptions, WakeJobPayload, WakeDelivery, WakeRunnable, } from './scheduler/index.js';
88
82
  export { filterAuditEntries } from './audit/index.js';
89
83
  export type { AuditConfig, AuditEntryBase, AuditEntryType, AuditListOptions, AuditReplayOptions, ConversationAuditEntry, ConversationAuditLog, } from './audit/types.js';
90
- export type { RealtimeAudioClient, RealtimeSessionConfig, RealtimeAudioConfig, RealtimeToolResponse, RealtimeEventMap, RealtimeSessionHandle, } from './realtime/index.js';
91
84
  export type { Hooks } from './types/hooks.js';
92
- export type { HarnessHooks } from './types/runtime.js';
93
85
  export { defineAgent, defineFlow, reply, collect, action, decide, confirmGate, } from './authoring/index.js';
94
86
  export { defineTool } from './types/effectTool.js';
95
87
  export { fsErrorCode } from './types/filesystem.js';
@@ -98,8 +90,8 @@ export type { CreateFsToolOptions, GrepHit } from './tools/fs/createFsTool.js';
98
90
  export { createShellTool } from './tools/fs/createShellTool.js';
99
91
  export type { CreateShellToolOptions } from './tools/fs/createShellTool.js';
100
92
  export type { Shell, ShellResult, ShellExecOptions } from './types/shell.js';
101
- export { SkillsCapability, wireAgentSkills, collectRegisteredNames, validateSkillAllowedTools, prepareSkillStore, isSkillStore, InlineSkillStore, } from './skills/index.js';
102
- export type { WiredAgentSkills, SkillWireAgent } from './skills/index.js';
93
+ export { SkillsCapability, wireAgentSkills, collectRegisteredNames, validateSkillAllowedTools, prepareSkillStore, isSkillStore, InlineSkillStore, CompositeSkillStore, fsSkillStore, defineSkill, parseSkillFrontmatter, } from './skills/index.js';
94
+ export type { WiredAgentSkills, SkillWireAgent, DefineSkillConfig, ParsedSkill, } from './skills/index.js';
103
95
  export { buildToolSet, toolToAiSdk, wrapAiSdkTool, ToolApprovalDeniedError, ToolTimeoutError, } from './tools/effect/index.js';
104
96
  export type { Tool as EffectTool } from './types/effectTool.js';
105
97
  export type { AgentRoute } from './types/processors.js';
@@ -108,12 +100,15 @@ export type { Flow, FlowNode, Transition, CollectNode, DecideNode, ConfirmGate,
108
100
  export { parseConfirmation } from './flow/confirmParse.js';
109
101
  export type { ConfirmVerdict } from './flow/confirmParse.js';
110
102
  export type { Route } from './types/route.js';
111
- export type { TurnHandle } from './types/stream.js';
112
- export type { HarnessStreamPart } from './types/stream.js';
103
+ export { PART_CHANNEL } from './types/stream.js';
104
+ export type { StreamChannel, StreamPartBase, TextStartPayload, TextDeltaPayload, TextEndPayload, TextCancelPayload, ToolCallPayload, ToolResultPayload, FlowEnterPayload, FlowEndPayload, NodeEnterPayload, NodeExitPayload, FlowTransitionPayload, HandoffPayload, InterruptedPayload, PausedPayload, ConversationOutcomePayload, InteractivePayload, TurnEndPayload, PipelineValidationBlockPayload, SafetyBlockedPayload, WakePayload, EscalationPayload, ContextCompactedPayload, CompactionSkippedPayload, ContextOverflowRecoveredPayload, ErrorPayload, CustomPayload, DonePayload, KnowledgeCacheHitPayload, KnowledgeCacheMissPayload, KnowledgeSearchPayload, KnowledgeQualityCheckPayload, KnowledgeReformulationPayload, StreamPart, TurnHandle, } from './types/stream.js';
113
105
  export type { AgentSpan, AgentTrace, SpanKind } from './types/trace.js';
114
106
  export { MemoryTraceStore, isTraceStore, type MemoryTraceStoreOptions, type TraceListWindow, type TraceSink, type TraceStore, } from './tracing/index.js';
115
107
  export { OtelTraceSink, langfuseSink, otelSink, toOtlpPayload, type LangfuseSinkOptions, type OtelTraceSinkOptions, } from './tracing/index.js';
116
108
  export { TraceRecorder, runOnce, type TraceRecorderOptions } from './runtime/TraceRecorder.js';
109
+ export { TracingService } from './services/TracingService.js';
110
+ export { InMemoryMetricsService } from './services/MetricsService.js';
111
+ export type { MetricsService } from './services/MetricsService.js';
117
112
  export { harnessToUIMessageStream } from './ai-sdk/uiMessageStream.js';
118
113
  export type { KuralleMetadata, KuralleDataParts, KuralleUIMessage, } from './ai-sdk/uiMessageStream.js';
119
114
  export type { ChoiceOption, ResolvedSelection } from './types/selection.js';
package/dist/index.js CHANGED
@@ -18,10 +18,6 @@ export { createLoadMemoryTool } from './tools/memory.js';
18
18
  export { PromptTemplateBuilder, PromptBuilder, createPromptTemplate, SUPPORT_AGENT_TEMPLATE, SALES_AGENT_TEMPLATE, TRIAGE_AGENT_TEMPLATE, createSupportAgentTemplate, DEFAULT_HANDOFF_INSTRUCTION, } from './prompts/index.js';
19
19
  export { BuiltinPersonas, composePersonaPrompt } from './persona/index.js';
20
20
  export { resolvePersonaExperiment } from './persona/index.js';
21
- export { HookRunner, createHookRunner } from './hooks/HookRunner.js';
22
- export { loggingHooks, createLoggingHooks } from './hooks/builtin/logging.js';
23
- export { createMetricsHooks, InMemoryMetrics } from './hooks/builtin/metrics.js';
24
- export { createObservabilityHooks } from './hooks/builtin/observability.js';
25
21
  export { createPromptInjectionGuard } from './processors/builtin/promptInjectionGuard.js';
26
22
  export { createPiiInputGuard, createPiiOutputGuard, redactPii, } from './processors/builtin/piiGuard.js';
27
23
  export { createModerationGuard, createModerationOutputGuard, } from './processors/builtin/moderationGuard.js';
@@ -45,7 +41,7 @@ export { compactMessages, estimateMessagesTokens, DEFAULT_COMPACTION_TRIGGER_TOK
45
41
  export { isContextOverflowError, recoverFromContextOverflow, } from './runtime/contextOverflow.js';
46
42
  export { applyPromptCache, applyAnthropicCacheControl, buildOpenAIResponsesProviderOptions, isAnthropicLanguageModel, isOpenAIResponsesModel, } from './runtime/promptCache.js';
47
43
  export { handoffFilters, removeToolHistory, keepRecentMessages, removeKeys, composeFilters, } from './runtime/handoffFilters.js';
48
- export { DefaultToolExecutor, DefaultConversationState, DefaultConversationEventLog, DefaultAgentStateController, createFoundation, } from './foundation/index.js';
44
+ export { DefaultAgentStateController } from './foundation/index.js';
49
45
  export { CapabilityHost, ExtractionCapability, GuardrailCapability, AutoRetrieveCapability, PassThroughRefinement, PassThroughValidation, toGeminiDeclarations, toAISDKTools, } from './capabilities/index.js';
50
46
  export { buildEscalationRequest, ensureSessionMetadata } from './escalation/escalation.js';
51
47
  export { createInProcessScheduler, createWakeJobRunner, createScheduleFollowupTool, wakeJob, isWakeJob, WAKE_JOB_KIND, } from './scheduler/index.js';
@@ -55,12 +51,15 @@ export { defineTool } from './types/effectTool.js';
55
51
  export { fsErrorCode } from './types/filesystem.js';
56
52
  export { createFsTool } from './tools/fs/createFsTool.js';
57
53
  export { createShellTool } from './tools/fs/createShellTool.js';
58
- export { SkillsCapability, wireAgentSkills, collectRegisteredNames, validateSkillAllowedTools, prepareSkillStore, isSkillStore, InlineSkillStore, } from './skills/index.js';
54
+ export { SkillsCapability, wireAgentSkills, collectRegisteredNames, validateSkillAllowedTools, prepareSkillStore, isSkillStore, InlineSkillStore, CompositeSkillStore, fsSkillStore, defineSkill, parseSkillFrontmatter, } from './skills/index.js';
59
55
  export { buildToolSet, toolToAiSdk, wrapAiSdkTool, ToolApprovalDeniedError, ToolTimeoutError, } from './tools/effect/index.js';
60
56
  export { parseConfirmation } from './flow/confirmParse.js';
57
+ export { PART_CHANNEL } from './types/stream.js';
61
58
  export { MemoryTraceStore, isTraceStore, } from './tracing/index.js';
62
59
  export { OtelTraceSink, langfuseSink, otelSink, toOtlpPayload, } from './tracing/index.js';
63
60
  export { TraceRecorder, runOnce } from './runtime/TraceRecorder.js';
61
+ export { TracingService } from './services/TracingService.js';
62
+ export { InMemoryMetricsService } from './services/MetricsService.js';
64
63
  export { harnessToUIMessageStream } from './ai-sdk/uiMessageStream.js';
65
64
  export { DURABLE_RUNS_KEY } from './runtime/durable/types.js';
66
65
  export { createRuntime, Runtime, } from './runtime/Runtime.js';
@@ -1,3 +1,3 @@
1
- import type { HarnessStreamPart } from '../types/voice.js';
1
+ import type { StreamPart } from '../types/stream.js';
2
2
  import type { ConversationOutcomeRecord } from './types.js';
3
- export declare function toConversationOutcomeStreamPart(record: ConversationOutcomeRecord): HarnessStreamPart;
3
+ export declare function toConversationOutcomeStreamPart(record: ConversationOutcomeRecord): StreamPart;
@@ -1,8 +1,7 @@
1
1
  export function toConversationOutcomeStreamPart(record) {
2
2
  return {
3
+ channel: 'client',
3
4
  type: 'conversation-outcome',
4
- outcome: record.outcome,
5
- ...(record.reason ? { reason: record.reason } : {}),
6
- markedBy: record.markedBy,
5
+ payload: { outcome: record.outcome },
7
6
  };
8
7
  }
@@ -1,5 +1,5 @@
1
1
  import type { ToolSet } from '../tools/Tool.js';
2
- import type { PromptTemplate, PromptBuilderConfig, BrandVoiceConfig, KnowledgeContext, SessionMemory, AgentDefinition, PolicyProfile } from './types.js';
2
+ import type { PromptTemplate, PromptBuilderConfig, BrandVoiceConfig, KnowledgeContext, SessionMemory, AgentIdentity, PolicyProfile } from './types.js';
3
3
  import { type PersonaConfig } from '../persona/index.js';
4
4
  export declare class PromptBuilder {
5
5
  private config;
@@ -10,7 +10,7 @@ export declare class PromptBuilder {
10
10
  */
11
11
  constructor(config?: PromptBuilderConfig | PromptTemplate);
12
12
  withTemplate(template: PromptTemplate): this;
13
- withAgentDefinition(definition: AgentDefinition): this;
13
+ withAgentIdentity(identity: AgentIdentity): this;
14
14
  withBrandVoice(brandVoice: BrandVoiceConfig): this;
15
15
  withPersona(persona: PersonaConfig): this;
16
16
  addPersona(persona: PersonaConfig): this;
@@ -19,7 +19,7 @@ export declare class PromptBuilder {
19
19
  withKnowledgeContext(context: KnowledgeContext): this;
20
20
  withPolicyProfile(profile: PolicyProfile): this;
21
21
  build(): string;
22
- private buildAgentDefinitionSections;
22
+ private buildAgentIdentitySections;
23
23
  private buildPersonaSections;
24
24
  private buildBrandVoiceSections;
25
25
  private buildKnowledgeSections;
@@ -22,8 +22,8 @@ export class PromptBuilder {
22
22
  this.config.template = template;
23
23
  return this;
24
24
  }
25
- withAgentDefinition(definition) {
26
- this.config.agentDefinition = definition;
25
+ withAgentIdentity(identity) {
26
+ this.config.agentIdentity = identity;
27
27
  return this;
28
28
  }
29
29
  withBrandVoice(brandVoice) {
@@ -63,8 +63,8 @@ export class PromptBuilder {
63
63
  immutable: true,
64
64
  });
65
65
  // Layer 1: Agent Definition
66
- if (this.config.agentDefinition) {
67
- sections.push(...this.buildAgentDefinitionSections());
66
+ if (this.config.agentIdentity) {
67
+ sections.push(...this.buildAgentIdentitySections());
68
68
  }
69
69
  if (this.config.persona) {
70
70
  sections.push(...this.buildPersonaSections());
@@ -100,8 +100,8 @@ export class PromptBuilder {
100
100
  const sorted = sections.sort((a, b) => (a.priority ?? 100) - (b.priority ?? 100));
101
101
  return sorted.map(s => this.formatSection(s)).join('\n\n');
102
102
  }
103
- buildAgentDefinitionSections() {
104
- const def = this.config.agentDefinition;
103
+ buildAgentIdentitySections() {
104
+ const def = this.config.agentIdentity;
105
105
  const sections = [];
106
106
  sections.push({
107
107
  type: 'identity',
@@ -1,4 +1,4 @@
1
- export type { PromptSection, PromptTemplate, ToolGuideline, PromptTemplateBuilderOptions, PromptSectionType, VoiceRulesConfig, VoiceRules, GlossaryTerm, GlossaryConfig, BrandVoiceConfig, KnowledgeContext, SessionMemory, AgentDefinition, PolicyProfile, PromptBuilderConfig, } from './types.js';
1
+ export type { PromptSection, PromptTemplate, ToolGuideline, PromptTemplateBuilderOptions, PromptSectionType, VoiceRulesConfig, VoiceRules, GlossaryTerm, GlossaryConfig, BrandVoiceConfig, KnowledgeContext, SessionMemory, AgentIdentity, PolicyProfile, PromptBuilderConfig, } from './types.js';
2
2
  export { PromptTemplateBuilder, createPromptTemplate, LAYER_PRIORITIES } from './types.js';
3
3
  export { PromptBuilder, createPrompt } from './PromptBuilder.js';
4
4
  export { SUPPORT_AGENT_TEMPLATE, SALES_AGENT_TEMPLATE, TRIAGE_AGENT_TEMPLATE, createSupportAgentTemplate, BUILTIN_TEMPLATES, DEFAULT_HANDOFF_INSTRUCTION, } from './templates.js';
@@ -52,14 +52,19 @@ export interface SessionMemory {
52
52
  /** Compact open-thread note projected from session.workingMemory.__goals (G5). */
53
53
  openGoalsPrompt?: string;
54
54
  }
55
- export interface AgentDefinition {
55
+ /**
56
+ * Who the agent is, rendered into the `identity` / `role` / `capabilities` prompt
57
+ * sections by `PromptBuilder`. A prompt fragment — not the agent itself, which is
58
+ * `AgentConfig` from `defineAgent`.
59
+ */
60
+ export interface AgentIdentity {
56
61
  identity: string;
57
62
  role: string;
58
63
  capabilities?: string[];
59
64
  }
60
65
  export interface PromptBuilderConfig {
61
66
  template?: PromptTemplate;
62
- agentDefinition?: AgentDefinition;
67
+ agentIdentity?: AgentIdentity;
63
68
  persona?: PersonaConfig;
64
69
  brandVoice?: BrandVoiceConfig;
65
70
  knowledgeContext?: KnowledgeContext;
@@ -1,4 +1,4 @@
1
- import type { KnowledgeRetrievalResult, RetrievalCacheAdapter } from '../types/voice.js';
1
+ import type { KnowledgeRetrievalResult, RetrievalCacheAdapter } from '../types/knowledge.js';
2
2
  /**
3
3
  * Zero-config, in-process session retrieval cache (G6). Keyed by the query
4
4
  * embedding: a lookup returns the cached results of the most-similar recent
@@ -12,7 +12,8 @@
12
12
  * The provider holds no mutable state itself — per-session cache state is
13
13
  * stored on RunContext.retrievalCache so it survives agent handoffs.
14
14
  */
15
- import type { KnowledgeProviderConfig, AgentKnowledgeOverrides, KnowledgeRetrievalResult, HarnessStreamPart, RetrievalCacheAdapter } from '../types/index.js';
15
+ import type { KnowledgeProviderConfig, AgentKnowledgeOverrides, KnowledgeRetrievalResult, RetrievalCacheAdapter } from '../types/index.js';
16
+ import type { StreamPart } from '../types/stream.js';
16
17
  export type { RetrievalCacheAdapter } from '../types/index.js';
17
18
  interface ResolvedKnowledgeConfig {
18
19
  compiledEnabled: boolean;
@@ -72,7 +73,7 @@ export declare class KnowledgeProvider {
72
73
  */
73
74
  retrieve(query: string, cache: RetrievalCacheAdapter | undefined, agentOverrides?: AgentKnowledgeOverrides, isVoice?: boolean): Promise<{
74
75
  results: KnowledgeRetrievalResult[];
75
- events: HarnessStreamPart[];
76
+ events: StreamPart[];
76
77
  }>;
77
78
  /**
78
79
  * Run quality check on retrieval results and optionally reformulate.
@@ -92,24 +92,33 @@ export class KnowledgeProvider {
92
92
  const cacheLatency = Date.now() - cacheStart;
93
93
  if (cached.length > 0) {
94
94
  events.push({
95
+ channel: 'internal',
95
96
  type: 'knowledge-cache-hit',
96
- query,
97
- resultCount: cached.length,
98
- latencyMs: cacheLatency,
97
+ payload: {
98
+ query,
99
+ resultCount: cached.length,
100
+ latencyMs: cacheLatency,
101
+ },
99
102
  });
100
103
  events.push({
104
+ channel: 'internal',
101
105
  type: 'knowledge-search',
102
- query,
103
- resultCount: cached.length,
104
- latencyMs: cacheLatency,
105
- layer: 'cache',
106
+ payload: {
107
+ query,
108
+ resultCount: cached.length,
109
+ latencyMs: cacheLatency,
110
+ layer: 'cache',
111
+ },
106
112
  });
107
113
  return { results: cached, events };
108
114
  }
109
115
  events.push({
116
+ channel: 'internal',
110
117
  type: 'knowledge-cache-miss',
111
- query,
112
- latencyMs: cacheLatency,
118
+ payload: {
119
+ query,
120
+ latencyMs: cacheLatency,
121
+ },
113
122
  });
114
123
  // Layer 3: Hybrid search (cache miss)
115
124
  const searchStart = Date.now();
@@ -121,11 +130,14 @@ export class KnowledgeProvider {
121
130
  });
122
131
  const searchLatency = Date.now() - searchStart;
123
132
  events.push({
133
+ channel: 'internal',
124
134
  type: 'knowledge-search',
125
- query,
126
- resultCount: results.length,
127
- latencyMs: searchLatency,
128
- layer: 'hybrid',
135
+ payload: {
136
+ query,
137
+ resultCount: results.length,
138
+ latencyMs: searchLatency,
139
+ layer: 'hybrid',
140
+ },
129
141
  });
130
142
  // Quality check + optional reformulation
131
143
  results = await this.runQualityCheck(query, results, events, isVoice, resolved);
@@ -144,11 +156,14 @@ export class KnowledgeProvider {
144
156
  });
145
157
  const searchLatency = Date.now() - searchStart;
146
158
  events.push({
159
+ channel: 'internal',
147
160
  type: 'knowledge-search',
148
- query,
149
- resultCount: results.length,
150
- latencyMs: searchLatency,
151
- layer: 'hybrid',
161
+ payload: {
162
+ query,
163
+ resultCount: results.length,
164
+ latencyMs: searchLatency,
165
+ layer: 'hybrid',
166
+ },
152
167
  });
153
168
  // Quality check + optional reformulation
154
169
  results = await this.runQualityCheck(query, results, events, isVoice, resolved);
@@ -182,12 +197,15 @@ export class KnowledgeProvider {
182
197
  quality = 'low';
183
198
  }
184
199
  events.push({
200
+ channel: 'internal',
185
201
  type: 'knowledge-quality-check',
186
- query,
187
- quality,
188
- topScore,
189
- avgScore,
190
- coverageEstimate,
202
+ payload: {
203
+ query,
204
+ quality,
205
+ topScore,
206
+ avgScore,
207
+ coverageEstimate,
208
+ },
191
209
  });
192
210
  // Only reformulate on low quality with a reformulate callback
193
211
  if (quality !== 'low' || !qc.reformulate)
@@ -195,11 +213,14 @@ export class KnowledgeProvider {
195
213
  if (isVoice) {
196
214
  // Voice: signal background reformulation, don't block
197
215
  events.push({
216
+ channel: 'internal',
198
217
  type: 'knowledge-reformulation',
199
- originalQuery: query,
200
- reformulatedQuery: '',
201
- trigger: 'background',
202
- latencyMs: 0,
218
+ payload: {
219
+ originalQuery: query,
220
+ reformulatedQuery: '',
221
+ trigger: 'background',
222
+ latencyMs: 0,
223
+ },
203
224
  });
204
225
  return results;
205
226
  }
@@ -209,11 +230,14 @@ export class KnowledgeProvider {
209
230
  const reformulatedQuery = await qc.reformulate(query, results);
210
231
  const reformulateLatency = Date.now() - reformulateStart;
211
232
  events.push({
233
+ channel: 'internal',
212
234
  type: 'knowledge-reformulation',
213
- originalQuery: query,
214
- reformulatedQuery,
215
- trigger: 'inline',
216
- latencyMs: reformulateLatency,
235
+ payload: {
236
+ originalQuery: query,
237
+ reformulatedQuery,
238
+ trigger: 'inline',
239
+ latencyMs: reformulateLatency,
240
+ },
217
241
  });
218
242
  // Re-retrieve with reformulated query (one attempt, no recursion)
219
243
  if (this.retriever) {
@@ -12,7 +12,7 @@ import type { SignalDelivery } from './durable/types.js';
12
12
  import type { ResolvedSelection } from '../types/selection.js';
13
13
  import type { ConversationOutcome, ConversationOutcomeMarkedBy } from '../outcomes/types.js';
14
14
  import type { classifyHostTarget, selectHostTarget } from './select.js';
15
- import type { KnowledgeProviderConfig } from '../types/voice.js';
15
+ import type { KnowledgeProviderConfig } from '../types/knowledge.js';
16
16
  import type { MemoryService as V1MemoryService } from '../memory/MemoryService.js';
17
17
  import type { PersistentMemoryStore } from '../memory/blocks/types.js';
18
18
  import { type CompactionConfig } from './compaction.js';
@@ -131,6 +131,8 @@ export declare class Runtime {
131
131
  getTrace(traceId: string): Promise<AgentTrace | null>;
132
132
  listTraces(sessionId: string): Promise<AgentTrace[]>;
133
133
  getTraceStore(): TraceStore | undefined;
134
+ /** The agent used when neither the caller nor persisted state names one. */
135
+ getDefaultAgentId(): string;
134
136
  getSessionStore(): SessionStore;
135
137
  deleteSession(sessionId: string): Promise<void>;
136
138
  abortSession(sessionId: string, reason?: string): void;
@@ -34,6 +34,7 @@ import { TraceRecorder } from './TraceRecorder.js';
34
34
  import { MemoryTraceStore } from '../tracing/MemoryTraceStore.js';
35
35
  import { mutateSessionWithRetry } from '../session/utils.js';
36
36
  import { isTraceStore } from '../tracing/TraceStore.js';
37
+ import { runHookSafely } from './runHookSafely.js';
37
38
  export class Runtime {
38
39
  config;
39
40
  agentsById;
@@ -72,6 +73,7 @@ export class Runtime {
72
73
  const recorder = this.shouldTrace(sessionId, opts.input)
73
74
  ? new TraceRecorder({
74
75
  sessionId,
76
+ agentId: opts.agentId ?? this.config.defaultAgentId,
75
77
  input: opts.input,
76
78
  onSpan: (span) => this.writeSpan(span),
77
79
  })
@@ -89,7 +91,7 @@ export class Runtime {
89
91
  if (part.type === 'done')
90
92
  this.flushTraceSinks();
91
93
  bus.emit(part);
92
- void this.hooks?.onStreamPart?.(runCtx, part);
94
+ void runHookSafely('onStreamPart', () => this.hooks?.onStreamPart?.(runCtx, part));
93
95
  };
94
96
  const opened = await openRun(this.agentsById, {
95
97
  sessionId,
@@ -106,6 +108,7 @@ export class Runtime {
106
108
  defaultAgentId: this.config.defaultAgentId,
107
109
  sessionStore: this.sessionStore,
108
110
  });
111
+ recorder?.setInitiatingAgent(opened.agent.id);
109
112
  const policies = resolveAgentPolicies(opened.agent);
110
113
  const knowledgeProvider = this.config.knowledge
111
114
  ? buildKnowledgeProvider(this.config.knowledge)
@@ -121,9 +124,16 @@ export class Runtime {
121
124
  agentId: opened.agent.id,
122
125
  onInterim: (message) => {
123
126
  const id = crypto.randomUUID();
124
- emit({ type: 'text-start', id });
125
- emit({ type: 'text-delta', id, delta: message });
126
- emit({ type: 'text-end', id });
127
+ emit({ channel: 'client', type: 'text-start', payload: { id } });
128
+ emit({ channel: 'client', type: 'text-delta', payload: { id, delta: message } });
129
+ emit({ channel: 'client', type: 'text-end', payload: { id } });
130
+ },
131
+ onChunk: (chunk, toolName, toolCallId) => {
132
+ emit({
133
+ channel: 'internal',
134
+ type: 'tool-result',
135
+ payload: { toolName, result: chunk, toolCallId, preliminary: true },
136
+ });
127
137
  },
128
138
  });
129
139
  const steps = await loadRecordedSteps(opened.runStore, opened.runState.runId);
@@ -170,9 +180,9 @@ export class Runtime {
170
180
  runCtx.skillPrompt = openingSurface.skillPrompt;
171
181
  runCtx.workingMemoryPrompt = appendGoalsPrompt(openingSurface.workingMemoryPrompt, opened.session.workingMemory);
172
182
  runCtx.workingMemoryTools = openingSurface.workingMemoryTools;
173
- await this.hooks?.onStart?.(runCtx);
183
+ await runHookSafely('onStart', () => this.hooks?.onStart?.(runCtx));
174
184
  if (opts.wake) {
175
- emit({ type: 'wake', reason: opts.wake.reason });
185
+ emit({ channel: 'internal', type: 'wake', payload: { reason: opts.wake.reason } });
176
186
  }
177
187
  const driver = opts.driver ?? new TextDriver();
178
188
  let activeAgent = opened.agent;
@@ -202,7 +212,11 @@ export class Runtime {
202
212
  }
203
213
  if (loopResult.kind === 'handoff') {
204
214
  if (this.terminalHandoffTargets.has(loopResult.to)) {
205
- emit({ type: 'handoff', targetAgent: loopResult.to, reason: loopResult.reason });
215
+ emit({
216
+ channel: 'internal',
217
+ type: 'handoff',
218
+ payload: { targetAgent: loopResult.to, reason: loopResult.reason },
219
+ });
206
220
  runCtx.runState.status = 'paused';
207
221
  await runCtx.runStore.putRunState(runCtx.runState);
208
222
  await this.dispatchEscalation(runCtx, activeAgent, { reason: loopResult.reason ?? 'handoff_to_human', category: loopResult.category }, emit, { setLatch: false });
@@ -285,9 +299,20 @@ export class Runtime {
285
299
  agentId: target.id,
286
300
  onInterim: (message) => {
287
301
  const id = crypto.randomUUID();
288
- emit({ type: 'text-start', id });
289
- emit({ type: 'text-delta', id, delta: message });
290
- emit({ type: 'text-end', id });
302
+ emit({ channel: 'client', type: 'text-start', payload: { id } });
303
+ emit({
304
+ channel: 'client',
305
+ type: 'text-delta',
306
+ payload: { id, delta: message },
307
+ });
308
+ emit({ channel: 'client', type: 'text-end', payload: { id } });
309
+ },
310
+ onChunk: (chunk, toolName, toolCallId) => {
311
+ emit({
312
+ channel: 'internal',
313
+ type: 'tool-result',
314
+ payload: { toolName, result: chunk, toolCallId, preliminary: true },
315
+ });
291
316
  },
292
317
  });
293
318
  await runCtx.runStore.putRunState(runCtx.runState);
@@ -314,14 +339,18 @@ export class Runtime {
314
339
  await this.applyCompaction(runCtx, activeAgent, emit, false);
315
340
  }
316
341
  catch (error) {
317
- await this.hooks?.onError?.(runCtx, error);
342
+ await runHookSafely('onError', () => this.hooks?.onError?.(runCtx, error));
318
343
  if (isDegradableRuntimeError(error)) {
319
344
  const message = error instanceof Error ? error.message : String(error);
320
- emit({ type: 'error', error: message });
345
+ emit({ channel: 'client', type: 'error', payload: { error: message } });
321
346
  const degradedId = crypto.randomUUID();
322
- emit({ type: 'text-start', id: degradedId });
323
- emit({ type: 'text-delta', id: degradedId, delta: SAFE_DEGRADED_MESSAGE });
324
- emit({ type: 'text-end', id: degradedId });
347
+ emit({ channel: 'client', type: 'text-start', payload: { id: degradedId } });
348
+ emit({
349
+ channel: 'client',
350
+ type: 'text-delta',
351
+ payload: { id: degradedId, delta: SAFE_DEGRADED_MESSAGE },
352
+ });
353
+ emit({ channel: 'client', type: 'text-end', payload: { id: degradedId } });
325
354
  runCtx.runState.messages = [
326
355
  ...runCtx.runState.messages,
327
356
  { role: 'assistant', content: SAFE_DEGRADED_MESSAGE },
@@ -354,11 +383,14 @@ export class Runtime {
354
383
  }
355
384
  },
356
385
  });
357
- await this.hooks?.onEnd?.(runCtx);
386
+ await runHookSafely('onEnd', () => this.hooks?.onEnd?.(runCtx));
358
387
  emit({
388
+ channel: 'client',
359
389
  type: 'done',
360
- sessionId: opened.session.id,
361
- usage: computeTurnTraceUsage(usageBaseline, runCtx.runState.state),
390
+ payload: {
391
+ sessionId: opened.session.id,
392
+ usage: computeTurnTraceUsage(usageBaseline, runCtx.runState.state),
393
+ },
362
394
  });
363
395
  }
364
396
  return { text: collectAssistantText(runCtx.runState.messages), toolResults: [] };
@@ -378,8 +410,13 @@ export class Runtime {
378
410
  run: gated,
379
411
  });
380
412
  }
381
- runOnce(opts) {
382
- return recordRunOnce(this, opts);
413
+ async runOnce(opts) {
414
+ const existing = opts.sessionId ? await this.sessionStore.get(opts.sessionId) : null;
415
+ // Caller's explicit agentId wins, matching run() (`opts.agentId ?? defaultAgentId`).
416
+ // Persisted state is the fallback, not an override — otherwise the two public
417
+ // entry points disagree about which agent handles the same turn.
418
+ const agentId = opts.agentId ?? existing?.activeAgentId ?? existing?.currentAgent ?? this.config.defaultAgentId;
419
+ return recordRunOnce(this, { ...opts, agentId });
383
420
  }
384
421
  stream(opts) {
385
422
  return this.run(opts);
@@ -398,6 +435,10 @@ export class Runtime {
398
435
  getTraceStore() {
399
436
  return this.traceStore;
400
437
  }
438
+ /** The agent used when neither the caller nor persisted state names one. */
439
+ getDefaultAgentId() {
440
+ return this.config.defaultAgentId;
441
+ }
401
442
  getSessionStore() {
402
443
  return this.sessionStore;
403
444
  }
@@ -506,7 +547,11 @@ export class Runtime {
506
547
  });
507
548
  if (!result.compacted) {
508
549
  if (force) {
509
- emit({ type: 'compaction-skipped', reason: result.reason });
550
+ emit({
551
+ channel: 'internal',
552
+ type: 'compaction-skipped',
553
+ payload: { reason: result.reason },
554
+ });
510
555
  }
511
556
  return false;
512
557
  }
@@ -518,10 +563,13 @@ export class Runtime {
518
563
  });
519
564
  runCtx.session.messages = [...result.messages];
520
565
  emit({
566
+ channel: 'internal',
521
567
  type: 'context-compacted',
522
- beforeTokens: result.beforeTokens,
523
- afterTokens: result.afterTokens,
524
- summarizedCount: result.summarizedCount,
568
+ payload: {
569
+ beforeTokens: result.beforeTokens,
570
+ afterTokens: result.afterTokens,
571
+ summarizedCount: result.summarizedCount,
572
+ },
525
573
  });
526
574
  return true;
527
575
  }
@@ -536,9 +584,12 @@ export class Runtime {
536
584
  runCtx.runState.messages = runCtx.session.messages;
537
585
  const compacted = await this.applyCompaction(runCtx, agent, emit, true);
538
586
  emit({
587
+ channel: 'internal',
539
588
  type: 'context-overflow-recovered',
540
- strippedCount: recovery.strippedCount,
541
- compacted,
589
+ payload: {
590
+ strippedCount: recovery.strippedCount,
591
+ compacted,
592
+ },
542
593
  });
543
594
  }
544
595
  async getConversationLength(sessionId) {
@@ -592,11 +643,14 @@ export class Runtime {
592
643
  });
593
644
  runCtx.session.metadata = latestSession.metadata;
594
645
  emit({
646
+ channel: 'internal',
595
647
  type: 'escalation',
596
- reason: info.reason,
597
- category: info.category,
598
- outcome: outcome.status,
599
- summary: request.summary,
648
+ payload: {
649
+ reason: info.reason,
650
+ category: info.category,
651
+ outcome: outcome.status,
652
+ summary: request.summary,
653
+ },
600
654
  });
601
655
  }
602
656
  /**