@kuralle-agents/core 0.13.0 → 0.15.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 (160) 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 +30 -7
  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 +21 -2
  15. package/dist/flow/extraction.js +62 -7
  16. package/dist/flow/reduceTransition.d.ts +2 -2
  17. package/dist/flow/reduceTransition.js +7 -3
  18. package/dist/flow/runFlow.d.ts +11 -0
  19. package/dist/flow/runFlow.js +68 -12
  20. package/dist/foundation/AgentStateController.d.ts +1 -1
  21. package/dist/foundation/ToolExecutor.d.ts +2 -2
  22. package/dist/foundation/index.d.ts +0 -11
  23. package/dist/foundation/index.js +0 -5
  24. package/dist/index.d.ts +9 -14
  25. package/dist/index.js +5 -6
  26. package/dist/outcomes/streamPart.d.ts +2 -2
  27. package/dist/outcomes/streamPart.js +2 -3
  28. package/dist/prompts/PromptBuilder.d.ts +3 -3
  29. package/dist/prompts/PromptBuilder.js +6 -6
  30. package/dist/prompts/index.d.ts +1 -1
  31. package/dist/prompts/types.d.ts +7 -2
  32. package/dist/runtime/InMemoryRetrievalCache.d.ts +1 -1
  33. package/dist/runtime/KnowledgeProvider.d.ts +3 -2
  34. package/dist/runtime/KnowledgeProvider.js +54 -30
  35. package/dist/runtime/Runtime.d.ts +9 -1
  36. package/dist/runtime/Runtime.js +123 -30
  37. package/dist/runtime/TraceRecorder.d.ts +22 -4
  38. package/dist/runtime/TraceRecorder.js +65 -29
  39. package/dist/runtime/buildAgentToolSurface.js +1 -1
  40. package/dist/runtime/channels/TextDriver.js +12 -9
  41. package/dist/runtime/channels/executeModelTool.d.ts +6 -0
  42. package/dist/runtime/channels/executeModelTool.js +70 -10
  43. package/dist/runtime/channels/extractionTurn.js +1 -1
  44. package/dist/runtime/channels/index.d.ts +0 -3
  45. package/dist/runtime/channels/index.js +0 -6
  46. package/dist/runtime/channels/streaming/hostControlSpeak.js +5 -1
  47. package/dist/runtime/channels/streaming/speakGated.js +33 -12
  48. package/dist/runtime/citations/index.d.ts +3 -3
  49. package/dist/runtime/closeRun.js +3 -2
  50. package/dist/runtime/controlFlowSignal.d.ts +24 -0
  51. package/dist/runtime/controlFlowSignal.js +29 -0
  52. package/dist/runtime/ctx.d.ts +3 -4
  53. package/dist/runtime/ctx.js +39 -5
  54. package/dist/runtime/durable/RunStore.js +1 -1
  55. package/dist/runtime/grounding/gather.d.ts +1 -1
  56. package/dist/runtime/grounding/inMemoryKnowledge.d.ts +1 -1
  57. package/dist/runtime/grounding/knowledge.d.ts +1 -1
  58. package/dist/runtime/hostLoop.js +39 -10
  59. package/dist/runtime/index.d.ts +1 -2
  60. package/dist/runtime/index.js +1 -1
  61. package/dist/runtime/outcomeMarking.d.ts +2 -2
  62. package/dist/runtime/outcomeMarking.js +2 -1
  63. package/dist/runtime/policies/agentTurn.d.ts +1 -1
  64. package/dist/runtime/runHookSafely.d.ts +3 -0
  65. package/dist/runtime/runHookSafely.js +19 -0
  66. package/dist/scheduler/index.d.ts +2 -2
  67. package/dist/scheduler/index.js +1 -1
  68. package/dist/services/TracingService.js +2 -3
  69. package/dist/skills/collectSkills.d.ts +11 -3
  70. package/dist/skills/collectSkills.js +51 -8
  71. package/dist/skills/compositeSkillStore.d.ts +26 -0
  72. package/dist/skills/compositeSkillStore.js +54 -0
  73. package/dist/skills/defineSkill.d.ts +21 -0
  74. package/dist/skills/defineSkill.js +26 -0
  75. package/dist/skills/fsSkillStore.d.ts +3 -0
  76. package/dist/skills/fsSkillStore.js +79 -0
  77. package/dist/skills/index.d.ts +4 -0
  78. package/dist/skills/index.js +4 -0
  79. package/dist/skills/parseSkillFrontmatter.d.ts +14 -0
  80. package/dist/skills/parseSkillFrontmatter.js +183 -0
  81. package/dist/skills/wireAgentSkills.d.ts +2 -1
  82. package/dist/skills/wireAgentSkills.js +2 -2
  83. package/dist/testing/mocks.d.ts +3 -3
  84. package/dist/testing/mocks.js +7 -3
  85. package/dist/tools/controlResults.d.ts +14 -0
  86. package/dist/tools/controlResults.js +15 -0
  87. package/dist/tools/effect/ToolExecutor.d.ts +6 -0
  88. package/dist/tools/effect/ToolExecutor.js +71 -35
  89. package/dist/tools/effect/defineTool.d.ts +9 -0
  90. package/dist/tools/effect/defineTool.js +1 -0
  91. package/dist/tools/effect/errors.d.ts +2 -5
  92. package/dist/tools/effect/errors.js +2 -5
  93. package/dist/tools/fs/createFsTool.js +2 -1
  94. package/dist/tools/index.d.ts +0 -1
  95. package/dist/tools/index.js +0 -1
  96. package/dist/types/effectTool.d.ts +2 -0
  97. package/dist/types/flow.d.ts +1 -1
  98. package/dist/types/guardrails.d.ts +5 -0
  99. package/dist/types/hooks.d.ts +2 -2
  100. package/dist/types/index.d.ts +25 -16
  101. package/dist/types/index.js +8 -13
  102. package/dist/types/knowledge.d.ts +213 -0
  103. package/dist/types/processors.d.ts +0 -58
  104. package/dist/types/run-context.d.ts +3 -7
  105. package/dist/types/runtime.d.ts +3 -74
  106. package/dist/types/session.d.ts +1 -1
  107. package/dist/types/skills.d.ts +15 -1
  108. package/dist/types/stream.d.ts +133 -71
  109. package/dist/types/stream.js +34 -1
  110. package/dist/types/trace.d.ts +2 -0
  111. package/guides/AGENTS.md +3 -3
  112. package/guides/FLOWS.md +1 -1
  113. package/guides/GETTING_STARTED.md +1 -1
  114. package/guides/RUNTIME.md +20 -15
  115. package/guides/TOOLS.md +1 -1
  116. package/package.json +3 -13
  117. package/dist/foundation/AgentDefinition.d.ts +0 -17
  118. package/dist/foundation/ConversationEventLog.d.ts +0 -71
  119. package/dist/foundation/ConversationEventLog.js +0 -1
  120. package/dist/foundation/ConversationState.d.ts +0 -33
  121. package/dist/foundation/ConversationState.js +0 -1
  122. package/dist/foundation/DefaultConversationEventLog.d.ts +0 -27
  123. package/dist/foundation/DefaultConversationEventLog.js +0 -205
  124. package/dist/foundation/DefaultConversationState.d.ts +0 -36
  125. package/dist/foundation/DefaultConversationState.js +0 -103
  126. package/dist/foundation/DefaultToolExecutor.d.ts +0 -57
  127. package/dist/foundation/DefaultToolExecutor.js +0 -132
  128. package/dist/foundation/createFoundation.d.ts +0 -32
  129. package/dist/foundation/createFoundation.js +0 -33
  130. package/dist/hooks/HookRunner.d.ts +0 -37
  131. package/dist/hooks/HookRunner.js +0 -111
  132. package/dist/hooks/builtin/logging.d.ts +0 -5
  133. package/dist/hooks/builtin/logging.js +0 -98
  134. package/dist/hooks/builtin/metrics.d.ts +0 -7
  135. package/dist/hooks/builtin/metrics.js +0 -60
  136. package/dist/hooks/builtin/observability.d.ts +0 -20
  137. package/dist/hooks/builtin/observability.js +0 -572
  138. package/dist/hooks/helpers.d.ts +0 -22
  139. package/dist/hooks/helpers.js +0 -183
  140. package/dist/hooks/index.d.ts +0 -8
  141. package/dist/hooks/index.js +0 -6
  142. package/dist/realtime/RealtimeAudioClient.d.ts +0 -166
  143. package/dist/realtime/RealtimeAudioClient.js +0 -14
  144. package/dist/realtime/RealtimeSessionHandle.d.ts +0 -6
  145. package/dist/realtime/RealtimeSessionHandle.js +0 -1
  146. package/dist/realtime/index.d.ts +0 -2
  147. package/dist/realtime/index.js +0 -1
  148. package/dist/runtime/channels/VoiceDriver.d.ts +0 -31
  149. package/dist/runtime/channels/VoiceDriver.js +0 -321
  150. package/dist/runtime/channels/voiceTools.d.ts +0 -9
  151. package/dist/runtime/channels/voiceTools.js +0 -51
  152. package/dist/tools/errorHandling.d.ts +0 -35
  153. package/dist/tools/errorHandling.js +0 -145
  154. package/dist/types/voice.d.ts +0 -517
  155. package/dist/types/voice.js +0 -14
  156. package/dist/utils/isRecord.d.ts +0 -1
  157. package/dist/utils/isRecord.js +0 -3
  158. package/dist/utils/messageNormalization.d.ts +0 -2
  159. package/dist/utils/messageNormalization.js +0 -137
  160. /package/dist/{foundation/AgentDefinition.js → types/knowledge.js} +0 -0
@@ -1,135 +1,197 @@
1
1
  import type { ConversationOutcome } from '../outcomes/types.js';
2
2
  import type { ChoiceOption } from './selection.js';
3
3
  import type { EscalationReason } from '../escalation/types.js';
4
- /**
5
- * Authoritative runtime stream union (`runFlow` / `Runtime` emit).
6
- * `types/voice.ts` defines a separate voice/realtime union that intentionally
7
- * does not include `{ type: 'interactive' }`.
8
- */
9
- export type HarnessStreamPart = {
10
- type: 'text-start';
4
+ export type StreamChannel = 'client' | 'internal';
5
+ export interface StreamPartBase<Channel extends StreamChannel = StreamChannel> {
6
+ channel: Channel;
7
+ }
8
+ export interface TextStartPayload {
11
9
  id: string;
12
- } | {
13
- type: 'text-delta';
10
+ }
11
+ export interface TextDeltaPayload {
14
12
  id: string;
15
13
  delta: string;
16
- } | {
17
- type: 'text-end';
14
+ }
15
+ export interface TextEndPayload {
18
16
  id: string;
19
- } | {
20
- type: 'text-cancel';
17
+ }
18
+ export interface TextCancelPayload {
21
19
  id: string;
22
20
  reason: string;
23
- } | {
24
- type: 'tool-call';
21
+ }
22
+ export interface ToolCallPayload {
25
23
  toolName: string;
26
24
  args: unknown;
27
25
  toolCallId?: string;
28
- } | {
29
- type: 'tool-result';
26
+ }
27
+ export interface ToolResultPayload {
30
28
  toolName: string;
31
29
  result: unknown;
32
30
  toolCallId?: string;
33
- } | {
34
- type: 'flow-enter';
31
+ /** A chunk from a still-running async-iterable tool. The final result follows without it. */
32
+ preliminary?: boolean;
33
+ }
34
+ export interface FlowEnterPayload {
35
35
  flow: string;
36
- } | {
37
- type: 'flow-end';
36
+ }
37
+ export interface FlowEndPayload {
38
38
  flow: string;
39
39
  reason: string;
40
- } | {
41
- type: 'node-enter';
40
+ }
41
+ export interface NodeEnterPayload {
42
42
  nodeName: string;
43
- } | {
44
- type: 'node-exit';
43
+ }
44
+ export interface NodeExitPayload {
45
45
  nodeName: string;
46
- } | {
47
- type: 'flow-transition';
46
+ }
47
+ export interface FlowTransitionPayload {
48
48
  from: string;
49
49
  to: string;
50
- } | {
51
- type: 'handoff';
50
+ }
51
+ export interface HandoffPayload {
52
52
  targetAgent: string;
53
53
  reason?: string;
54
- } | {
55
- type: 'interrupted';
54
+ }
55
+ export interface InterruptedPayload {
56
56
  reason: string;
57
57
  lastStep: number;
58
- } | {
59
- type: 'paused';
58
+ }
59
+ export interface PausedPayload {
60
60
  waitingFor: string;
61
- } | {
62
- type: 'conversation-outcome';
61
+ }
62
+ export interface ConversationOutcomePayload {
63
63
  outcome: ConversationOutcome;
64
- } | {
65
- type: 'interactive';
64
+ }
65
+ export interface InteractivePayload {
66
66
  nodeId: string;
67
67
  options: ChoiceOption[];
68
68
  prompt: string;
69
- } | {
70
- type: 'turn-end';
71
- } | {
72
- type: 'pipeline-validation-block';
69
+ }
70
+ export interface TurnEndPayload {
71
+ }
72
+ export interface PipelineValidationBlockPayload {
73
73
  rationale: string;
74
74
  userFacingMessage?: string;
75
- } | {
76
- type: 'safety-blocked';
75
+ }
76
+ export interface SafetyBlockedPayload {
77
77
  moderator: string;
78
78
  rationale: string;
79
79
  userFacingMessage: string;
80
80
  handlerOutcome?: 'queued' | 'connected' | 'failed';
81
- } | {
82
- /** An agent-initiated (scheduled wake) turn — there is no new user message. */
83
- type: 'wake';
81
+ }
82
+ export interface WakePayload {
84
83
  reason: string;
85
- } | {
86
- type: 'escalation';
84
+ }
85
+ export interface EscalationPayload {
87
86
  reason: string;
88
87
  category?: EscalationReason;
89
- /** Result of the configured escalation handler. */
90
88
  outcome: 'queued' | 'connected' | 'failed';
91
- /** The LLM handoff brief included in the request, when generated. */
92
89
  summary?: string;
93
- } | {
94
- type: 'context-compacted';
95
- /** Estimated history tokens before/after compaction. */
90
+ }
91
+ export interface ContextCompactedPayload {
96
92
  beforeTokens: number;
97
93
  afterTokens: number;
98
- /** Number of older messages folded into the summary. */
99
94
  summarizedCount: number;
100
- } | {
101
- type: 'compaction-skipped';
95
+ }
96
+ export interface CompactionSkippedPayload {
102
97
  reason: string;
103
- } | {
104
- type: 'context-overflow-recovered';
105
- /** Partial assistant/tool messages stripped from the failed turn. */
98
+ }
99
+ export interface ContextOverflowRecoveredPayload {
106
100
  strippedCount: number;
107
- /** Whether the forced post-recovery compaction actually compacted. */
108
101
  compacted: boolean;
109
- } | {
110
- type: 'error';
102
+ }
103
+ export interface ErrorPayload {
111
104
  error: string;
112
- } | {
113
- type: 'custom';
105
+ }
106
+ export interface CustomPayload {
114
107
  name: string;
115
108
  data: unknown;
116
- } | {
117
- type: 'done';
109
+ }
110
+ export interface DonePayload {
118
111
  sessionId: string;
119
- /** Per-turn token usage: `inputTokens`/`outputTokens` are THIS turn's
120
- * consumption (deltas, for cost attribution); `contextTokens` is the current
121
- * context-window occupancy (last prompt tokens, a snapshot). */
122
112
  usage?: {
123
113
  inputTokens?: number;
124
114
  outputTokens?: number;
125
115
  contextTokens?: number;
126
116
  };
127
- };
117
+ }
118
+ export interface KnowledgeCacheHitPayload {
119
+ query: string;
120
+ resultCount: number;
121
+ latencyMs: number;
122
+ }
123
+ export interface KnowledgeCacheMissPayload {
124
+ query: string;
125
+ latencyMs: number;
126
+ }
127
+ export interface KnowledgeSearchPayload {
128
+ query: string;
129
+ resultCount: number;
130
+ latencyMs: number;
131
+ layer: 'cache' | 'hybrid';
132
+ }
133
+ export interface KnowledgeQualityCheckPayload {
134
+ query: string;
135
+ quality: 'high' | 'medium' | 'low';
136
+ topScore: number;
137
+ avgScore: number;
138
+ coverageEstimate: number;
139
+ }
140
+ export interface KnowledgeReformulationPayload {
141
+ originalQuery: string;
142
+ reformulatedQuery: string;
143
+ trigger: 'inline' | 'background';
144
+ latencyMs: number;
145
+ }
146
+ interface StreamPayloadMap {
147
+ 'text-start': TextStartPayload;
148
+ 'text-delta': TextDeltaPayload;
149
+ 'text-end': TextEndPayload;
150
+ 'text-cancel': TextCancelPayload;
151
+ 'tool-call': ToolCallPayload;
152
+ 'tool-result': ToolResultPayload;
153
+ 'flow-enter': FlowEnterPayload;
154
+ 'flow-end': FlowEndPayload;
155
+ 'node-enter': NodeEnterPayload;
156
+ 'node-exit': NodeExitPayload;
157
+ 'flow-transition': FlowTransitionPayload;
158
+ handoff: HandoffPayload;
159
+ interrupted: InterruptedPayload;
160
+ paused: PausedPayload;
161
+ 'conversation-outcome': ConversationOutcomePayload;
162
+ interactive: InteractivePayload;
163
+ 'turn-end': TurnEndPayload;
164
+ 'pipeline-validation-block': PipelineValidationBlockPayload;
165
+ 'safety-blocked': SafetyBlockedPayload;
166
+ wake: WakePayload;
167
+ escalation: EscalationPayload;
168
+ 'context-compacted': ContextCompactedPayload;
169
+ 'compaction-skipped': CompactionSkippedPayload;
170
+ 'context-overflow-recovered': ContextOverflowRecoveredPayload;
171
+ error: ErrorPayload;
172
+ custom: CustomPayload;
173
+ done: DonePayload;
174
+ 'knowledge-cache-hit': KnowledgeCacheHitPayload;
175
+ 'knowledge-cache-miss': KnowledgeCacheMissPayload;
176
+ 'knowledge-search': KnowledgeSearchPayload;
177
+ 'knowledge-quality-check': KnowledgeQualityCheckPayload;
178
+ 'knowledge-reformulation': KnowledgeReformulationPayload;
179
+ }
180
+ type ClientStreamPartType = 'text-start' | 'text-delta' | 'text-end' | 'text-cancel' | 'conversation-outcome' | 'error' | 'done';
181
+ type ChannelFor<Type extends keyof StreamPayloadMap> = Type extends ClientStreamPartType ? 'client' : 'internal';
182
+ export type StreamPart = {
183
+ [Type in keyof StreamPayloadMap]: StreamPartBase<ChannelFor<Type>> & {
184
+ type: Type;
185
+ payload: StreamPayloadMap[Type];
186
+ };
187
+ }[keyof StreamPayloadMap];
188
+ export declare const PART_CHANNEL: Record<StreamPart['type'], StreamChannel>;
128
189
  export interface TurnHandle extends Promise<import('./channel.js').TurnResult> {
129
- readonly events: AsyncIterable<HarnessStreamPart>;
190
+ readonly events: AsyncIterable<StreamPart>;
130
191
  toResponseStream(format?: 'sse' | 'ndjson'): ReadableStream;
131
192
  toUIMessageStreamResponse(opts?: {
132
193
  sessionId?: string;
133
194
  }): Response;
134
195
  cancel(reason?: string): void;
135
196
  }
197
+ export {};
@@ -1 +1,34 @@
1
- export {};
1
+ export const PART_CHANNEL = {
2
+ 'text-start': 'client',
3
+ 'text-delta': 'client',
4
+ 'text-end': 'client',
5
+ 'text-cancel': 'client',
6
+ 'tool-call': 'internal',
7
+ 'tool-result': 'internal',
8
+ 'flow-enter': 'internal',
9
+ 'flow-end': 'internal',
10
+ 'node-enter': 'internal',
11
+ 'node-exit': 'internal',
12
+ 'flow-transition': 'internal',
13
+ handoff: 'internal',
14
+ interrupted: 'internal',
15
+ paused: 'internal',
16
+ 'conversation-outcome': 'client',
17
+ interactive: 'internal',
18
+ 'turn-end': 'internal',
19
+ 'pipeline-validation-block': 'internal',
20
+ 'safety-blocked': 'internal',
21
+ wake: 'internal',
22
+ escalation: 'internal',
23
+ 'context-compacted': 'internal',
24
+ 'compaction-skipped': 'internal',
25
+ 'context-overflow-recovered': 'internal',
26
+ error: 'client',
27
+ custom: 'internal',
28
+ done: 'client',
29
+ 'knowledge-cache-hit': 'internal',
30
+ 'knowledge-cache-miss': 'internal',
31
+ 'knowledge-search': 'internal',
32
+ 'knowledge-quality-check': 'internal',
33
+ 'knowledge-reformulation': 'internal',
34
+ };
@@ -15,6 +15,8 @@ export interface AgentSpan {
15
15
  }>;
16
16
  attributes: {
17
17
  sessionId: string;
18
+ /** Agent active when the span opened; a turn span keeps its initiating agent across handoffs. */
19
+ agentId?: string;
18
20
  activeFlow?: string;
19
21
  nodeId?: string;
20
22
  toolName?: string;
package/guides/AGENTS.md CHANGED
@@ -43,7 +43,7 @@ const runtime = createRuntime({
43
43
 
44
44
  const handle = runtime.run({ input: 'Hello', sessionId: 'demo' });
45
45
  for await (const part of handle.events) {
46
- if (part.type === 'text-delta') process.stdout.write(part.delta);
46
+ if (part.type === 'text-delta') process.stdout.write(part.payload.delta);
47
47
  }
48
48
  await handle;
49
49
  ```
@@ -221,7 +221,7 @@ const handle = runtime.run({
221
221
  sessionId: 'demo',
222
222
  });
223
223
  for await (const part of handle.events) {
224
- if (part.type === 'text-delta') process.stdout.write(part.delta);
224
+ if (part.type === 'text-delta') process.stdout.write(part.payload.delta);
225
225
  }
226
226
  await handle;
227
227
  ```
@@ -260,7 +260,7 @@ See [standalone-agent.ts](../examples/agents/standalone-agent.ts) (Example 4) fo
260
260
  - `AgentConfig` — Agent configuration returned by `defineAgent`
261
261
  - `Route`, `RoutingPolicy` — Routing declarations on an agent
262
262
  - `Flow`, `FlowNode` — Flow graph types from `defineFlow` and node builders
263
- - `HarnessStreamPart` — Stream event union (`text-delta`, `handoff`, `flow-transition`, etc.)
263
+ - `StreamPart` — Stream event union (`text-delta`, `handoff`, `flow-transition`, etc.)
264
264
  - `TurnHandle` — Return value of `runtime.run`; async iterable via `.events`
265
265
  - `ToolExecutionOptions`, `ToolExecutionContext` — Tool execution context
266
266
  - `getRuntimeFromContext()` — Read runtime from tool context when available
package/guides/FLOWS.md CHANGED
@@ -57,7 +57,7 @@ const agent = defineAgent({
57
57
  const runtime = createRuntime({ agents: [agent], defaultAgentId: 'booking' });
58
58
  const handle = runtime.run({ input: 'Hi', sessionId: 'demo' });
59
59
  for await (const part of handle.events) {
60
- if (part.type === 'text-delta') process.stdout.write(part.delta);
60
+ if (part.type === 'text-delta') process.stdout.write(part.payload.delta);
61
61
  }
62
62
  await handle;
63
63
  ```
@@ -52,7 +52,7 @@ const runtime = createRuntime({
52
52
 
53
53
  const handle = runtime.run({ input: 'Hello there', sessionId: 'demo' });
54
54
  for await (const part of handle.events) {
55
- if (part.type === 'text-delta') process.stdout.write(part.delta);
55
+ if (part.type === 'text-delta') process.stdout.write(part.payload.delta);
56
56
  }
57
57
  await handle;
58
58
  ```
package/guides/RUNTIME.md CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
  ## Stream Events
13
13
 
14
- `runtime.run()` returns a `TurnHandle` with an `.events` async iterable of `HarnessStreamPart` items.
14
+ `runtime.run()` returns a `TurnHandle` with an `.events` async iterable of `StreamPart` items.
15
15
 
16
16
  ### Web UI (AI SDK native, 0.5.0+)
17
17
 
@@ -24,29 +24,29 @@ return handle.toUIMessageStreamResponse({ sessionId });
24
24
 
25
25
  Kuralle orchestration events map to typed `data-kuralle-*` parts (see `docs/adr/0005-ai-sdk-native-uimessage-default.md`). Import `KuralleUIMessage` for compile-time-safe `message.parts`.
26
26
 
27
- With `@kuralle-agents/hono-server`, `POST /api/chat/sse` defaults to this native wire. Append `?format=raw` for legacy `HarnessStreamPart` JSON-SSE.
27
+ With `@kuralle-agents/hono-server`, `POST /api/chat/sse` defaults to this native wire. Append `?format=raw` for legacy `StreamPart` JSON-SSE.
28
28
 
29
- ### Direct `HarnessStreamPart` consumption
29
+ ### Direct `StreamPart` consumption
30
30
 
31
- For CLI scripts, cascaded voice, messaging, or custom transports, iterate `handle.events` directly. Typical usage renders `text-delta` chunks via `part.delta`.
31
+ For CLI scripts, messaging, or custom transports, iterate `handle.events` directly. Every part has `{ channel, type, payload }`; render `text-delta` chunks via `part.payload.delta`.
32
32
 
33
33
  Common types:
34
- - `text-delta`
35
- - `tool-call`, `tool-result`, `tool-error`
34
+ - `text-start`, `text-delta`, `text-end`, `text-cancel`
35
+ - `tool-call`, `tool-result`
36
36
  - `handoff`
37
- - `node-enter`, `flow-transition`, `flow-end`
37
+ - `flow-enter`, `node-enter`, `node-exit`, `flow-transition`, `flow-end`
38
38
  - `custom` (flow/runtime emitted app events)
39
- - `agent-start`, `agent-end`
40
39
  - `turn-end`, `done`, `error`
40
+ - `knowledge-cache-hit`, `knowledge-cache-miss`, `knowledge-search`, `knowledge-quality-check`, `knowledge-reformulation`
41
41
 
42
- Internal events can expose operational details. Treat them as privileged data.
42
+ Use `PART_CHANNEL` or the envelope's `channel` field to distinguish client events from privileged internal events.
43
43
 
44
44
  ## Stream Callback (Persistence Defaults)
45
45
 
46
46
  Use `streamCallback` when sending runtime events to file/webhook/DB/queue sinks.
47
47
 
48
48
  Default behavior is message-oriented:
49
- - emits: `input`, `done`, `error`, `tripwire`, `tool-call`, `tool-result`, `tool-error`, `flow-transition`, `handoff`
49
+ - emits terminal events plus configured tool and transition events
50
50
  - does not emit `text-delta` tokens unless enabled
51
51
  - attaches final assistant text as `fullText` on terminal events
52
52
  - if no sink is configured, adapter is a no-op
@@ -95,7 +95,6 @@ To prevent internal runtime state from leaking into the model's context window:
95
95
 
96
96
  Runtime checkpoints session state automatically on critical events:
97
97
  - `tool-result`
98
- - `tool-error`
99
98
  - `flow-transition`
100
99
  - handoff state updates (after `activeAgentId` mutation)
101
100
 
@@ -135,21 +134,27 @@ const runtime = createRuntime({
135
134
  ],
136
135
  hooks: {
137
136
  onStreamPart: async (ctx, part) => {
138
- if (part.type === 'error') console.error(part.error);
137
+ if (part.type === 'error') console.error(part.payload.error);
139
138
  },
140
139
  },
141
140
  });
142
141
  ```
143
142
 
144
- ## Hooks
143
+ ## Tracing
145
144
 
146
- Use hooks for logging, metrics, and audit trails without polluting prompts.
145
+ Use a trace sink for logging, metrics, and audit trails without polluting prompts.
147
146
 
148
147
  ```ts
148
+ const loggingSink: TraceSink = {
149
+ write(span) {
150
+ console.log(JSON.stringify(span));
151
+ },
152
+ };
153
+
149
154
  const runtime = createRuntime({
150
155
  agents,
151
156
  defaultAgentId: 'router',
152
- hooks: loggingHooks(),
157
+ tracing: { sinks: [loggingSink] },
153
158
  });
154
159
  ```
155
160
 
package/guides/TOOLS.md CHANGED
@@ -152,7 +152,7 @@ const handle = runtime.run({
152
152
  sessionId: 'demo',
153
153
  });
154
154
  for await (const part of handle.events) {
155
- if (part.type === 'text-delta') process.stdout.write(part.delta);
155
+ if (part.type === 'text-delta') process.stdout.write(part.payload.delta);
156
156
  }
157
157
  await handle;
158
158
  ```
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "url": "git+https://github.com/kuralle/kuralle-agents.git",
7
7
  "directory": "packages/core"
8
8
  },
9
- "version": "0.13.0",
9
+ "version": "0.15.0",
10
10
  "description": "A framework for structured conversational AI agents",
11
11
  "publishConfig": {
12
12
  "access": "public"
@@ -32,10 +32,6 @@
32
32
  "types": "./dist/runtime/index.d.ts",
33
33
  "default": "./dist/runtime/index.js"
34
34
  },
35
- "./hooks": {
36
- "types": "./dist/hooks/index.d.ts",
37
- "default": "./dist/hooks/index.js"
38
- },
39
35
  "./guards": {
40
36
  "types": "./dist/guards/index.d.ts",
41
37
  "default": "./dist/guards/index.js"
@@ -91,10 +87,6 @@
91
87
  "./capabilities": {
92
88
  "types": "./dist/capabilities/index.d.ts",
93
89
  "default": "./dist/capabilities/index.js"
94
- },
95
- "./realtime": {
96
- "types": "./dist/realtime/index.d.ts",
97
- "default": "./dist/realtime/index.js"
98
90
  }
99
91
  },
100
92
  "peerDependencies": {
@@ -111,8 +103,7 @@
111
103
  "typescript": "^5.3.0",
112
104
  "vitest": "^3.2.4",
113
105
  "zod": "^4.0.0",
114
- "@kuralle-agents/fs": "0.13.0",
115
- "@kuralle-agents/realtime-audio": "0.13.0"
106
+ "@kuralle-agents/fs": "0.14.1"
116
107
  },
117
108
  "dependencies": {
118
109
  "chrono-node": "^2.6.0"
@@ -131,7 +122,6 @@
131
122
  "smoke:flow": "bun test ./test/core-flow/flow.smoke.ts",
132
123
  "smoke:agent": "bun test ./test/core-agent/agent.smoke.ts",
133
124
  "smoke:approval": "bun test ./test/core-policy/approval.smoke.ts",
134
- "smoke:knowledge": "bun test ./test/core-grounding/knowledge.smoke.ts",
135
- "smoke:realtime": "bun test ./test/core-voice/realtime.smoke.ts"
125
+ "smoke:knowledge": "bun test ./test/core-grounding/knowledge.smoke.ts"
136
126
  }
137
127
  }
@@ -1,17 +0,0 @@
1
- import type { PromptTemplate } from '../prompts/types.js';
2
- import type { AgentPrompt } from '../prompts/AgentPrompt.js';
3
- /**
4
- * Shared agent definition — the minimal shape every engine needs.
5
- * Both Runtime (text) and VoiceEngine (audio) extend this.
6
- *
7
- * Define agents once against this interface, then spread into
8
- * engine-specific configs to add model, voice, processors, etc.
9
- */
10
- export interface AgentDefinition {
11
- id: string;
12
- name: string;
13
- description?: string;
14
- /** Agent prompt — a plain string, PromptTemplate, or structured AgentPrompt. */
15
- prompt?: string | PromptTemplate | AgentPrompt;
16
- tools?: Record<string, unknown>;
17
- }
@@ -1,71 +0,0 @@
1
- import type { HarnessStreamPart, RunContext, Session } from '../types/index.js';
2
- /**
3
- * Discriminated union of conversation-level events for the runtime event log.
4
- * Stored in session workingMemory for observability.
5
- */
6
- export type ConversationEvent = {
7
- type: 'user';
8
- text: string;
9
- userId?: string;
10
- timestamp: Date;
11
- } | {
12
- type: 'assistant';
13
- text: string;
14
- timestamp: Date;
15
- } | {
16
- type: 'tool-call';
17
- toolCallId: string;
18
- toolName: string;
19
- args: unknown;
20
- timestamp: Date;
21
- } | {
22
- type: 'tool-result';
23
- toolCallId: string;
24
- toolName: string;
25
- result: unknown;
26
- timestamp: Date;
27
- } | {
28
- type: 'tool-error';
29
- toolCallId: string;
30
- toolName: string;
31
- error: string;
32
- timestamp: Date;
33
- } | {
34
- type: 'handoff';
35
- from: string;
36
- to: string;
37
- reason?: string;
38
- timestamp: Date;
39
- } | {
40
- type: 'flow-transition';
41
- from: string;
42
- to: string;
43
- timestamp: Date;
44
- } | {
45
- type: 'error';
46
- error: string;
47
- timestamp: Date;
48
- };
49
- /**
50
- * Records conversation events into session working memory and manages checkpointing.
51
- * Shared by Runtime and VoiceEngine.
52
- */
53
- export interface ConversationEventLog {
54
- /**
55
- * Record a stream part into the session's runtime event log.
56
- * Text-deltas are accumulated; terminal events flush the assistant text.
57
- */
58
- record(context: RunContext, part: HarnessStreamPart): void;
59
- /**
60
- * Persist the session as a checkpoint (called after significant events).
61
- */
62
- checkpoint(session: Session): Promise<void>;
63
- /**
64
- * Whether a given stream part type should trigger a checkpoint save.
65
- */
66
- shouldCheckpoint(part: HarnessStreamPart): boolean;
67
- /**
68
- * Clean up transient state (e.g., accumulated assistant text) from the session.
69
- */
70
- cleanup(session: Session): void;
71
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,33 +0,0 @@
1
- import type { ChannelId, Session, WorkingMemory } from '../types/index.js';
2
- import type { ModelMessage } from 'ai';
3
- /**
4
- * Manages session lifecycle: load, save, delete, message append, turn counting.
5
- * Shared by Runtime and VoiceEngine.
6
- */
7
- export interface ConversationState {
8
- /** Load an existing session or create a new one. */
9
- load(sessionId: string, userId?: string): Promise<Session>;
10
- /** Persist session to the backing store. */
11
- save(session: Session): Promise<void>;
12
- /** Delete a session from the backing store. */
13
- delete(sessionId: string): Promise<void>;
14
- /** Get a WorkingMemory wrapper for the session. */
15
- workingMemory(session: Session): WorkingMemory;
16
- /** Append a user message to the session history. */
17
- appendUserMessage(session: Session, text: string): void;
18
- /** Append an assistant message to the session history. */
19
- appendAssistantMessage(session: Session, text: string): void;
20
- /** Append a raw ModelMessage to the session history. */
21
- appendMessage(session: Session, message: ModelMessage): void;
22
- /** Get the current turn number for the session. */
23
- getSessionTurn(session: Session): number;
24
- /** Increment and return the new turn number. */
25
- bumpSessionTurn(session: Session): number;
26
- /** Update the session's updatedAt timestamp. */
27
- touchSession(session: Session): void;
28
- /** Create a fresh session with defaults. */
29
- createSession(id: string, defaultAgentId: string, userId?: string, opts?: {
30
- channelId?: ChannelId;
31
- conversationId?: string;
32
- }): Session;
33
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,27 +0,0 @@
1
- import type { HarnessStreamPart, RunContext, Session } from '../types/index.js';
2
- import type { SessionStore } from '../session/SessionStore.js';
3
- import type { ConversationEventLog } from './ConversationEventLog.js';
4
- export interface DefaultConversationEventLogConfig {
5
- sessionStore: SessionStore;
6
- }
7
- /**
8
- * Default conversation event log extracted from SessionEventManager + Runtime checkpoint logic.
9
- *
10
- * Handles:
11
- * - Recording stream parts into session working memory
12
- * - Text-delta accumulation and flush on terminal events
13
- * - Value truncation at depth 5 for safe serialization
14
- * - Checkpoint determination and persistence
15
- */
16
- export declare class DefaultConversationEventLog implements ConversationEventLog {
17
- private sessionStore;
18
- constructor(config: DefaultConversationEventLogConfig);
19
- record(context: RunContext, part: HarnessStreamPart): void;
20
- checkpoint(session: Session): Promise<void>;
21
- shouldCheckpoint(part: HarnessStreamPart): boolean;
22
- cleanup(session: Session): void;
23
- private getSessionTurn;
24
- private appendEvent;
25
- private flushAssistantText;
26
- private toEventLogValue;
27
- }