@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,5 +1,6 @@
1
1
  import { popFlowPark, runCollectDigression } from './collectDigression.js';
2
2
  import { parseConfirmation } from './confirmParse.js';
3
+ import { inferRequiredFields } from './extraction.js';
3
4
  import { hasPendingUserInput, setPendingUserInput } from '../runtime/channels/inputBuffer.js';
4
5
  import { userInputToText } from '../runtime/userInput.js';
5
6
  import { collectUntilComplete } from './collectUntilComplete.js';
@@ -11,8 +12,7 @@ import { evaluateReplyControl } from './controlEvaluator.js';
11
12
  import { runNodeVerify, VerifyBlockedError } from './verify.js';
12
13
  import { loadRecordedSteps } from '../runtime/durable/replay.js';
13
14
  import { persistTurnUsageFromTurn } from '../runtime/turnTokenUsage.js';
14
- import { SuspendError } from '../runtime/durable/RunStore.js';
15
- import { ToolApprovalDeniedError } from '../tools/effect/errors.js';
15
+ import { isApprovalDenial, isControlFlowSignal } from '../runtime/controlFlowSignal.js';
16
16
  import { emitInteractiveOnNodeEnter } from './emitInteractive.js';
17
17
  import { appendConversationAudit } from '../audit/record.js';
18
18
  import { appendSafeAssistantMessage, degradeFlowError, findEscalateNode, } from './degrade.js';
@@ -254,6 +254,27 @@ async function dispatchNode(node, run, driver, ctx, agent, flow) {
254
254
  }
255
255
  throw new Error(`Unknown node kind: ${node.kind}`);
256
256
  }
257
+ /**
258
+ * Drop everything a previous run of `flow` collected. Namespaced cache keys AND the
259
+ * un-namespaced copies `reduceTransition` promotes onto `run.state` via Object.assign.
260
+ *
261
+ * Clearing only the cache was not enough. The promoted fields are a plain merge, and
262
+ * `projectCollectData` omits any field the new extraction did not supply — so an optional
263
+ * field answered on report #1 (say `accessNotes: "key under the mat"`) and left blank on
264
+ * report #2 survives the merge and is read by the next action node as if it belonged to
265
+ * report #2. A work order then ships another unit's access instructions.
266
+ */
267
+ export function clearFlowCollectCache(state, flow) {
268
+ for (const node of flow.nodes) {
269
+ if (node.kind !== 'collect')
270
+ continue;
271
+ delete state[`__collect_${node.id}`];
272
+ delete state[`__collectTurns_${node.id}`];
273
+ for (const field of inferRequiredFields(node.schema)) {
274
+ delete state[field];
275
+ }
276
+ }
277
+ }
257
278
  export async function runFlow(flow, run, driver, ctx, agent) {
258
279
  const registry = buildNodeRegistry(flow);
259
280
  const startNode = resolveStartNode(flow);
@@ -263,10 +284,22 @@ export async function runFlow(flow, run, driver, ctx, agent) {
263
284
  throw new Error(`Unknown active node "${initialNodeId}" in flow "${flow.name}"`);
264
285
  }
265
286
  if (!run.activeNode) {
287
+ // Fresh entry, not a resume. A collect node caches its extraction under
288
+ // `__collect_<nodeId>` and that cache is SUPPOSED to survive turn boundaries — it is how
289
+ // fields accumulate across several user turns mid-flow. But it must not survive the flow
290
+ // itself: re-entering a completed flow found the previous run's cache already complete,
291
+ // finished instantly with those values, and the action node acted on them.
292
+ //
293
+ // Observed live: three maintenance reports for three different units produced three
294
+ // copies of the FIRST work order; the units actually reported were never touched.
295
+ //
296
+ // Cleared here rather than on completion so mid-flow accumulation is untouched — which
297
+ // is what `continuity.test.ts` and the G14 slot-correction test encode.
298
+ clearFlowCollectCache(run.state, flow);
266
299
  run.activeNode = node.id;
267
300
  run.activeFlow = flow.name;
268
- ctx.emit({ type: 'flow-enter', flow: flow.name });
269
- ctx.emit({ type: 'node-enter', nodeName: node.id });
301
+ ctx.emit({ channel: 'internal', type: 'flow-enter', payload: { flow: flow.name } });
302
+ ctx.emit({ channel: 'internal', type: 'node-enter', payload: { nodeName: node.id } });
270
303
  emitInteractiveOnNodeEnter(node, run.state, ctx.emit);
271
304
  }
272
305
  const edgeCounts = new Map();
@@ -277,11 +310,14 @@ export async function runFlow(flow, run, driver, ctx, agent) {
277
310
  transition = await dispatchNode(node, run, driver, ctx, agent, flow);
278
311
  }
279
312
  catch (error) {
280
- if (error instanceof SuspendError || error instanceof ToolApprovalDeniedError) {
313
+ // Neither is a malfunction, so neither may reach degradeFlowError and be reported to
314
+ // the user as "something went wrong on my side". A suspend resumes later; a denial is
315
+ // the action node author's to handle, since they chose to call the tool.
316
+ if (isControlFlowSignal(error) || isApprovalDenial(error)) {
281
317
  throw error;
282
318
  }
283
319
  const message = error instanceof Error ? error.message : String(error);
284
- ctx.emit({ type: 'error', error: message });
320
+ ctx.emit({ channel: 'client', type: 'error', payload: { error: message } });
285
321
  return degradeFlowError(flow, registry, run, driver, ctx, (n, r, d, c) => dispatchNode(n, r, d, c, agent, flow));
286
322
  }
287
323
  if (transition.kind === 'switchFlow') {
@@ -298,15 +334,27 @@ export async function runFlow(flow, run, driver, ctx, agent) {
298
334
  run.activeFlow = park.flow;
299
335
  run.activeNode = park.node;
300
336
  await ctx.runStore.putRunState(run);
301
- ctx.emit({ type: 'flow-end', flow: flow.name, reason: transition.reason });
337
+ ctx.emit({
338
+ channel: 'internal',
339
+ type: 'flow-end',
340
+ payload: { flow: flow.name, reason: transition.reason },
341
+ });
302
342
  return runFlow(parkedFlow, run, driver, ctx, agent);
303
343
  }
304
344
  }
305
- ctx.emit({ type: 'flow-end', flow: flow.name, reason: transition.reason });
345
+ ctx.emit({
346
+ channel: 'internal',
347
+ type: 'flow-end',
348
+ payload: { flow: flow.name, reason: transition.reason },
349
+ });
306
350
  return { kind: 'ended', reason: transition.reason };
307
351
  }
308
352
  if (transition.kind === 'handoff') {
309
- ctx.emit({ type: 'handoff', targetAgent: transition.to, reason: transition.reason });
353
+ ctx.emit({
354
+ channel: 'internal',
355
+ type: 'handoff',
356
+ payload: { targetAgent: transition.to, reason: transition.reason },
357
+ });
310
358
  return { kind: 'handoff', to: transition.to, reason: transition.reason };
311
359
  }
312
360
  if (transition.kind === 'escalate') {
@@ -337,14 +385,18 @@ export async function runFlow(flow, run, driver, ctx, agent) {
337
385
  }
338
386
  catch (error) {
339
387
  if (error instanceof VerifyBlockedError) {
340
- ctx.emit({ type: 'error', error: error.message });
388
+ ctx.emit({ channel: 'client', type: 'error', payload: { error: error.message } });
341
389
  return { kind: 'awaitingUser' };
342
390
  }
343
391
  throw error;
344
392
  }
345
393
  const oscillation = bumpOscillation(edgeCounts, node.id, target.id);
346
394
  if (oscillation > maxOscillations) {
347
- ctx.emit({ type: 'error', error: `Flow oscillation blocked: ${node.id} -> ${target.id}` });
395
+ ctx.emit({
396
+ channel: 'client',
397
+ type: 'error',
398
+ payload: { error: `Flow oscillation blocked: ${node.id} -> ${target.id}` },
399
+ });
348
400
  const escalateNode = findEscalateNode(registry);
349
401
  if (escalateNode) {
350
402
  appendSafeAssistantMessage(run, ctx);
@@ -363,7 +415,11 @@ export async function runFlow(flow, run, driver, ctx, agent) {
363
415
  continue;
364
416
  }
365
417
  appendSafeAssistantMessage(run, ctx);
366
- ctx.emit({ type: 'flow-end', flow: flow.name, reason: 'error_degraded' });
418
+ ctx.emit({
419
+ channel: 'internal',
420
+ type: 'flow-end',
421
+ payload: { flow: flow.name, reason: 'error_degraded' },
422
+ });
367
423
  return { kind: 'ended', reason: 'error_degraded' };
368
424
  }
369
425
  await reduceTransition({
@@ -1,7 +1,7 @@
1
1
  import type { Session } from '../types/index.js';
2
2
  /**
3
3
  * Manages active agent resolution, handoff recording, and agent state.
4
- * Shared by Runtime and VoiceEngine.
4
+ * Used by Runtime.
5
5
  */
6
6
  export interface AgentStateController {
7
7
  /** Resolve the active agent ID, falling back to the provided default. */
@@ -1,7 +1,7 @@
1
1
  import type { Session, ToolCallRecord } from '../types/index.js';
2
2
  /**
3
3
  * Minimal tool shape required by the executor.
4
- * Compatible with AI SDK `Tool`, VoiceToolDef, and plain `{ execute }` objects.
4
+ * Compatible with AI SDK `Tool` and plain `{ execute }` objects.
5
5
  */
6
6
  export interface ExecutableTool {
7
7
  execute: (args: unknown, options?: unknown) => Promise<unknown>;
@@ -9,7 +9,7 @@ export interface ExecutableTool {
9
9
  }
10
10
  /**
11
11
  * Encapsulates tool execution with enforcement, idempotency, and context enrichment.
12
- * Shared by Runtime (text path) and VoiceEngine (audio path).
12
+ * Used by Runtime.
13
13
  */
14
14
  export interface ToolExecutor {
15
15
  /**
@@ -1,14 +1,3 @@
1
- export type { AgentDefinition } from './AgentDefinition.js';
2
1
  export type { ToolExecutor, ExecutableTool } from './ToolExecutor.js';
3
- export type { ConversationState } from './ConversationState.js';
4
- export type { ConversationEventLog, ConversationEvent } from './ConversationEventLog.js';
5
2
  export type { AgentStateController } from './AgentStateController.js';
6
- export { DefaultToolExecutor, ToolTimeoutError } from './DefaultToolExecutor.js';
7
- export type { DefaultToolExecutorConfig } from './DefaultToolExecutor.js';
8
- export { DefaultConversationState } from './DefaultConversationState.js';
9
- export type { DefaultConversationStateConfig } from './DefaultConversationState.js';
10
- export { DefaultConversationEventLog } from './DefaultConversationEventLog.js';
11
- export type { DefaultConversationEventLogConfig } from './DefaultConversationEventLog.js';
12
3
  export { DefaultAgentStateController } from './DefaultAgentStateController.js';
13
- export { createFoundation } from './createFoundation.js';
14
- export type { Foundation, FoundationConfig } from './createFoundation.js';
@@ -1,7 +1,2 @@
1
1
  // Default implementations
2
- export { DefaultToolExecutor, ToolTimeoutError } from './DefaultToolExecutor.js';
3
- export { DefaultConversationState } from './DefaultConversationState.js';
4
- export { DefaultConversationEventLog } from './DefaultConversationEventLog.js';
5
2
  export { DefaultAgentStateController } from './DefaultAgentStateController.js';
6
- // Factory
7
- export { createFoundation } from './createFoundation.js';
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';
@@ -21,6 +21,12 @@ import type { WakeOptions } from '../scheduler/index.js';
21
21
  import type { HandoffInputFilter } from './handoffFilters.js';
22
22
  import type { AgentSpan, AgentTrace } from '../types/trace.js';
23
23
  import { type TraceSink, type TraceStore } from '../tracing/TraceStore.js';
24
+ /**
25
+ * What the user is told when the run hands off to a human and the app has not configured an
26
+ * escalation handler to say something better. Silence is the wrong default: an escalation
27
+ * that emits no text is indistinguishable from the agent having crashed.
28
+ */
29
+ export declare const HANDOFF_TO_HUMAN_MESSAGE = "I'm bringing a colleague into this \u2014 they'll pick it up from here.";
24
30
  export interface TracingConfig {
25
31
  enabled?: boolean;
26
32
  store?: TraceStore;
@@ -131,6 +137,8 @@ export declare class Runtime {
131
137
  getTrace(traceId: string): Promise<AgentTrace | null>;
132
138
  listTraces(sessionId: string): Promise<AgentTrace[]>;
133
139
  getTraceStore(): TraceStore | undefined;
140
+ /** The agent used when neither the caller nor persisted state names one. */
141
+ getDefaultAgentId(): string;
134
142
  getSessionStore(): SessionStore;
135
143
  deleteSession(sessionId: string): Promise<void>;
136
144
  abortSession(sessionId: string, reason?: string): void;