@kuralle-agents/core 0.12.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 (210) hide show
  1. package/README.md +89 -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 +2 -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/collectDigression.d.ts +5 -2
  11. package/dist/flow/collectDigression.js +48 -10
  12. package/dist/flow/collectUntilComplete.js +13 -5
  13. package/dist/flow/degrade.js +8 -4
  14. package/dist/flow/emitInteractive.d.ts +2 -2
  15. package/dist/flow/emitInteractive.js +6 -3
  16. package/dist/flow/extraction.d.ts +3 -2
  17. package/dist/flow/extraction.js +14 -4
  18. package/dist/flow/reduceTransition.d.ts +2 -2
  19. package/dist/flow/reduceTransition.js +7 -3
  20. package/dist/flow/runFlow.js +97 -17
  21. package/dist/foundation/AgentStateController.d.ts +1 -1
  22. package/dist/foundation/ToolExecutor.d.ts +2 -2
  23. package/dist/foundation/index.d.ts +0 -11
  24. package/dist/foundation/index.js +0 -5
  25. package/dist/index.d.ts +15 -15
  26. package/dist/index.js +9 -6
  27. package/dist/outcomes/streamPart.d.ts +2 -2
  28. package/dist/outcomes/streamPart.js +2 -3
  29. package/dist/prompts/PromptBuilder.d.ts +3 -3
  30. package/dist/prompts/PromptBuilder.js +13 -6
  31. package/dist/prompts/index.d.ts +1 -1
  32. package/dist/prompts/types.d.ts +9 -2
  33. package/dist/runtime/InMemoryRetrievalCache.d.ts +25 -0
  34. package/dist/runtime/InMemoryRetrievalCache.js +59 -0
  35. package/dist/runtime/KnowledgeProvider.d.ts +3 -2
  36. package/dist/runtime/KnowledgeProvider.js +60 -31
  37. package/dist/runtime/Runtime.d.ts +47 -1
  38. package/dist/runtime/Runtime.js +273 -36
  39. package/dist/runtime/TokenAccumulator.d.ts +7 -0
  40. package/dist/runtime/TokenAccumulator.js +7 -0
  41. package/dist/runtime/TraceRecorder.d.ts +51 -0
  42. package/dist/runtime/TraceRecorder.js +326 -0
  43. package/dist/runtime/buildAgentToolSurface.js +1 -1
  44. package/dist/runtime/channels/TextDriver.js +57 -31
  45. package/dist/runtime/channels/executeModelTool.d.ts +14 -1
  46. package/dist/runtime/channels/executeModelTool.js +132 -3
  47. package/dist/runtime/channels/extractionTurn.js +1 -1
  48. package/dist/runtime/channels/index.d.ts +0 -3
  49. package/dist/runtime/channels/index.js +0 -6
  50. package/dist/runtime/channels/inputBuffer.d.ts +1 -0
  51. package/dist/runtime/channels/inputBuffer.js +9 -0
  52. package/dist/runtime/channels/streaming/hostControlSpeak.js +5 -1
  53. package/dist/runtime/channels/streaming/speakGated.js +24 -12
  54. package/dist/runtime/citations/index.d.ts +3 -3
  55. package/dist/runtime/closeRun.js +14 -10
  56. package/dist/runtime/compaction.d.ts +2 -0
  57. package/dist/runtime/compaction.js +3 -2
  58. package/dist/runtime/controlFlowSignal.d.ts +24 -0
  59. package/dist/runtime/controlFlowSignal.js +29 -0
  60. package/dist/runtime/ctx.d.ts +3 -4
  61. package/dist/runtime/ctx.js +147 -60
  62. package/dist/runtime/durable/RunStore.d.ts +16 -0
  63. package/dist/runtime/durable/RunStore.js +7 -1
  64. package/dist/runtime/durable/SessionRunStore.d.ts +7 -2
  65. package/dist/runtime/durable/SessionRunStore.js +136 -34
  66. package/dist/runtime/durable/idempotency.d.ts +1 -0
  67. package/dist/runtime/durable/idempotency.js +3 -0
  68. package/dist/runtime/durable/replay.js +7 -2
  69. package/dist/runtime/durable/types.d.ts +11 -0
  70. package/dist/runtime/goals.d.ts +18 -0
  71. package/dist/runtime/goals.js +158 -0
  72. package/dist/runtime/grounding/gather.d.ts +1 -1
  73. package/dist/runtime/grounding/inMemoryKnowledge.d.ts +1 -1
  74. package/dist/runtime/grounding/knowledge.d.ts +1 -1
  75. package/dist/runtime/grounding/knowledge.js +1 -1
  76. package/dist/runtime/handoffContinuation.d.ts +20 -0
  77. package/dist/runtime/handoffContinuation.js +30 -0
  78. package/dist/runtime/handoffOscillation.d.ts +6 -0
  79. package/dist/runtime/handoffOscillation.js +17 -0
  80. package/dist/runtime/hostLoop.js +37 -6
  81. package/dist/runtime/index.d.ts +4 -3
  82. package/dist/runtime/index.js +2 -1
  83. package/dist/runtime/openRun.d.ts +2 -0
  84. package/dist/runtime/openRun.js +46 -17
  85. package/dist/runtime/outcomeMarking.d.ts +2 -2
  86. package/dist/runtime/outcomeMarking.js +2 -1
  87. package/dist/runtime/policies/agentTurn.d.ts +1 -1
  88. package/dist/runtime/policies/limits.d.ts +1 -0
  89. package/dist/runtime/policies/limits.js +3 -0
  90. package/dist/runtime/runHookSafely.d.ts +3 -0
  91. package/dist/runtime/runHookSafely.js +19 -0
  92. package/dist/runtime/select.d.ts +5 -1
  93. package/dist/runtime/select.js +30 -1
  94. package/dist/runtime/turnTokenUsage.d.ts +28 -0
  95. package/dist/runtime/turnTokenUsage.js +70 -0
  96. package/dist/scheduler/index.d.ts +2 -2
  97. package/dist/scheduler/index.js +1 -1
  98. package/dist/services/TracingService.js +2 -3
  99. package/dist/session/SessionStore.d.ts +6 -0
  100. package/dist/session/SessionStore.js +12 -1
  101. package/dist/session/stores/MemoryStore.d.ts +1 -1
  102. package/dist/session/stores/MemoryStore.js +16 -2
  103. package/dist/session/testing.d.ts +6 -1
  104. package/dist/session/testing.js +34 -0
  105. package/dist/session/utils.d.ts +3 -0
  106. package/dist/session/utils.js +23 -0
  107. package/dist/skills/collectSkills.d.ts +11 -3
  108. package/dist/skills/collectSkills.js +51 -8
  109. package/dist/skills/compositeSkillStore.d.ts +26 -0
  110. package/dist/skills/compositeSkillStore.js +54 -0
  111. package/dist/skills/defineSkill.d.ts +21 -0
  112. package/dist/skills/defineSkill.js +26 -0
  113. package/dist/skills/fsSkillStore.d.ts +3 -0
  114. package/dist/skills/fsSkillStore.js +79 -0
  115. package/dist/skills/index.d.ts +4 -0
  116. package/dist/skills/index.js +4 -0
  117. package/dist/skills/parseSkillFrontmatter.d.ts +14 -0
  118. package/dist/skills/parseSkillFrontmatter.js +183 -0
  119. package/dist/skills/wireAgentSkills.d.ts +2 -1
  120. package/dist/skills/wireAgentSkills.js +2 -2
  121. package/dist/testing/mocks.d.ts +3 -3
  122. package/dist/testing/mocks.js +7 -3
  123. package/dist/tools/controlResults.d.ts +14 -0
  124. package/dist/tools/controlResults.js +15 -0
  125. package/dist/tools/effect/ToolExecutor.d.ts +6 -0
  126. package/dist/tools/effect/ToolExecutor.js +75 -36
  127. package/dist/tools/effect/defineTool.d.ts +11 -0
  128. package/dist/tools/effect/defineTool.js +3 -0
  129. package/dist/tools/effect/errors.d.ts +2 -5
  130. package/dist/tools/effect/errors.js +2 -5
  131. package/dist/tools/index.d.ts +0 -1
  132. package/dist/tools/index.js +0 -1
  133. package/dist/tracing/MemoryTraceStore.d.ts +16 -0
  134. package/dist/tracing/MemoryTraceStore.js +56 -0
  135. package/dist/tracing/OtelTraceSink.d.ts +127 -0
  136. package/dist/tracing/OtelTraceSink.js +101 -0
  137. package/dist/tracing/TraceStore.d.ts +19 -0
  138. package/dist/tracing/TraceStore.js +32 -0
  139. package/dist/tracing/index.d.ts +3 -0
  140. package/dist/tracing/index.js +3 -0
  141. package/dist/tracing/testing.d.ts +3 -0
  142. package/dist/tracing/testing.js +45 -0
  143. package/dist/types/agentConfig.d.ts +2 -1
  144. package/dist/types/channel.d.ts +14 -1
  145. package/dist/types/effectTool.d.ts +6 -0
  146. package/dist/types/flow.d.ts +1 -1
  147. package/dist/types/guardrails.d.ts +5 -0
  148. package/dist/types/hooks.d.ts +2 -2
  149. package/dist/types/index.d.ts +25 -15
  150. package/dist/types/index.js +8 -12
  151. package/dist/types/knowledge.d.ts +213 -0
  152. package/dist/types/processors.d.ts +0 -58
  153. package/dist/types/run-context.d.ts +16 -7
  154. package/dist/types/runtime.d.ts +3 -74
  155. package/dist/types/session.d.ts +11 -1
  156. package/dist/types/skills.d.ts +15 -1
  157. package/dist/types/stream.d.ts +138 -68
  158. package/dist/types/stream.js +34 -1
  159. package/dist/types/trace.d.ts +52 -0
  160. package/guides/AGENTS.md +3 -3
  161. package/guides/EXAMPLE_VERIFICATION.md +4 -4
  162. package/guides/FLOWS.md +1 -1
  163. package/guides/GETTING_STARTED.md +1 -1
  164. package/guides/RUNTIME.md +20 -15
  165. package/guides/TOOLS.md +1 -1
  166. package/package.json +13 -14
  167. package/dist/foundation/AgentDefinition.d.ts +0 -17
  168. package/dist/foundation/ConversationEventLog.d.ts +0 -71
  169. package/dist/foundation/ConversationState.d.ts +0 -33
  170. package/dist/foundation/ConversationState.js +0 -1
  171. package/dist/foundation/DefaultConversationEventLog.d.ts +0 -27
  172. package/dist/foundation/DefaultConversationEventLog.js +0 -205
  173. package/dist/foundation/DefaultConversationState.d.ts +0 -36
  174. package/dist/foundation/DefaultConversationState.js +0 -103
  175. package/dist/foundation/DefaultToolExecutor.d.ts +0 -57
  176. package/dist/foundation/DefaultToolExecutor.js +0 -132
  177. package/dist/foundation/createFoundation.d.ts +0 -32
  178. package/dist/foundation/createFoundation.js +0 -33
  179. package/dist/hooks/HookRunner.d.ts +0 -37
  180. package/dist/hooks/HookRunner.js +0 -111
  181. package/dist/hooks/builtin/logging.d.ts +0 -5
  182. package/dist/hooks/builtin/logging.js +0 -98
  183. package/dist/hooks/builtin/metrics.d.ts +0 -7
  184. package/dist/hooks/builtin/metrics.js +0 -60
  185. package/dist/hooks/builtin/observability.d.ts +0 -20
  186. package/dist/hooks/builtin/observability.js +0 -572
  187. package/dist/hooks/helpers.d.ts +0 -22
  188. package/dist/hooks/helpers.js +0 -183
  189. package/dist/hooks/index.d.ts +0 -8
  190. package/dist/hooks/index.js +0 -6
  191. package/dist/realtime/RealtimeAudioClient.d.ts +0 -166
  192. package/dist/realtime/RealtimeAudioClient.js +0 -14
  193. package/dist/realtime/RealtimeSessionHandle.d.ts +0 -6
  194. package/dist/realtime/RealtimeSessionHandle.js +0 -1
  195. package/dist/realtime/index.d.ts +0 -2
  196. package/dist/realtime/index.js +0 -1
  197. package/dist/runtime/channels/VoiceDriver.d.ts +0 -31
  198. package/dist/runtime/channels/VoiceDriver.js +0 -321
  199. package/dist/runtime/channels/voiceTools.d.ts +0 -9
  200. package/dist/runtime/channels/voiceTools.js +0 -51
  201. package/dist/tools/errorHandling.d.ts +0 -35
  202. package/dist/tools/errorHandling.js +0 -145
  203. package/dist/types/voice.d.ts +0 -517
  204. package/dist/types/voice.js +0 -14
  205. package/dist/utils/isRecord.d.ts +0 -1
  206. package/dist/utils/isRecord.js +0 -3
  207. package/dist/utils/messageNormalization.d.ts +0 -2
  208. package/dist/utils/messageNormalization.js +0 -137
  209. /package/dist/{foundation/AgentDefinition.js → types/knowledge.js} +0 -0
  210. /package/dist/{foundation/ConversationEventLog.js → types/trace.js} +0 -0
@@ -0,0 +1,19 @@
1
+ import type { AgentSpan, AgentTrace } from '../types/trace.js';
2
+ export interface TraceListWindow {
3
+ from?: Date;
4
+ to?: Date;
5
+ limit?: number;
6
+ }
7
+ export interface TraceSink {
8
+ write(span: AgentSpan): void | Promise<void>;
9
+ flush?(): Promise<void>;
10
+ }
11
+ export interface TraceStore extends TraceSink {
12
+ putSpan(span: AgentSpan): void | Promise<void>;
13
+ getTrace(traceId: string): Promise<AgentTrace | null>;
14
+ listTraces(sessionId: string, window?: TraceListWindow): Promise<AgentTrace[]>;
15
+ cleanup?(maxAgeMs: number): Promise<number>;
16
+ }
17
+ export declare function isTraceStore(sink: TraceSink): sink is TraceStore;
18
+ export declare function traceFromSpans(spans: AgentSpan[]): AgentTrace | null;
19
+ export declare function cloneSpan(span: AgentSpan): AgentSpan;
@@ -0,0 +1,32 @@
1
+ export function isTraceStore(sink) {
2
+ const value = sink;
3
+ return typeof value.putSpan === 'function' &&
4
+ typeof value.getTrace === 'function' &&
5
+ typeof value.listTraces === 'function';
6
+ }
7
+ export function traceFromSpans(spans) {
8
+ if (spans.length === 0)
9
+ return null;
10
+ const ordered = spans.map(cloneSpan).sort((a, b) => a.startTime - b.startTime);
11
+ const root = ordered.find((span) => span.kind === 'turn') ?? ordered[0];
12
+ const tools = ordered.filter((span) => span.kind === 'tool');
13
+ return {
14
+ traceId: root.traceId,
15
+ sessionId: root.attributes.sessionId,
16
+ spans: ordered,
17
+ answer: typeof root.attributes.output === 'string' ? root.attributes.output : '',
18
+ usedTool: tools.length > 0,
19
+ toolCalls: tools.map((span) => ({
20
+ name: span.attributes.toolName ?? span.name,
21
+ args: span.attributes.input ?? null,
22
+ })),
23
+ toolResults: tools
24
+ .filter((span) => span.attributes.output !== undefined)
25
+ .map((span) => ({ name: span.attributes.toolName ?? span.name, result: span.attributes.output })),
26
+ startedAt: root.startTime,
27
+ ...(root.endTime !== undefined ? { endedAt: root.endTime } : {}),
28
+ };
29
+ }
30
+ export function cloneSpan(span) {
31
+ return structuredClone(span);
32
+ }
@@ -0,0 +1,3 @@
1
+ export { MemoryTraceStore, type MemoryTraceStoreOptions } from './MemoryTraceStore.js';
2
+ export { isTraceStore, traceFromSpans, type TraceListWindow, type TraceSink, type TraceStore, } from './TraceStore.js';
3
+ export { OtelTraceSink, langfuseSink, otelSink, toOtlpPayload, type LangfuseSinkOptions, type OtelTraceSinkOptions, } from './OtelTraceSink.js';
@@ -0,0 +1,3 @@
1
+ export { MemoryTraceStore } from './MemoryTraceStore.js';
2
+ export { isTraceStore, traceFromSpans, } from './TraceStore.js';
3
+ export { OtelTraceSink, langfuseSink, otelSink, toOtlpPayload, } from './OtelTraceSink.js';
@@ -0,0 +1,3 @@
1
+ import type { TraceStore } from './TraceStore.js';
2
+ export type TraceStoreFactory = () => TraceStore | Promise<TraceStore>;
3
+ export declare function runTraceStoreContract(factory: TraceStoreFactory): void;
@@ -0,0 +1,45 @@
1
+ /// <reference types="bun-types" />
2
+ import { beforeEach, describe, expect, test } from 'bun:test';
3
+ export function runTraceStoreContract(factory) {
4
+ describe('TraceStore contract', () => {
5
+ let store;
6
+ beforeEach(async () => { store = await factory(); });
7
+ test('writes spans and reconstructs a JSON-safe trace', async () => {
8
+ await store.putSpan(span('trace-a', 'session-a', 'root', 10, 'turn'));
9
+ await store.putSpan(span('trace-a', 'session-a', 'tool', 11, 'tool'));
10
+ const trace = await store.getTrace('trace-a');
11
+ expect(trace?.spans.map((entry) => entry.spanId)).toEqual(['root', 'tool']);
12
+ expect(trace?.sessionId).toBe('session-a');
13
+ expect(() => JSON.stringify(trace)).not.toThrow();
14
+ });
15
+ test('returns null for a missing trace', async () => {
16
+ expect(await store.getTrace('missing')).toBeNull();
17
+ });
18
+ test('lists newest traces for only the requested session and window', async () => {
19
+ await store.putSpan(span('old', 'session-a', 'old-root', 10, 'turn'));
20
+ await store.putSpan(span('new', 'session-a', 'new-root', 30, 'turn'));
21
+ await store.putSpan(span('other', 'session-b', 'other-root', 40, 'turn'));
22
+ const traces = await store.listTraces('session-a', { from: new Date(20), limit: 1 });
23
+ expect(traces.map((trace) => trace.traceId)).toEqual(['new']);
24
+ });
25
+ test('upserts a span by trace and span id', async () => {
26
+ const root = span('trace-a', 'session-a', 'root', 10, 'turn');
27
+ await store.write(root);
28
+ await store.putSpan({ ...root, endTime: 25 });
29
+ expect((await store.getTrace('trace-a'))?.spans).toHaveLength(1);
30
+ expect((await store.getTrace('trace-a'))?.endedAt).toBe(25);
31
+ });
32
+ });
33
+ }
34
+ function span(traceId, sessionId, spanId, startTime, kind) {
35
+ return {
36
+ traceId,
37
+ spanId,
38
+ name: kind,
39
+ kind,
40
+ startTime,
41
+ endTime: startTime + 5,
42
+ status: 'ok',
43
+ attributes: { sessionId },
44
+ };
45
+ }
@@ -50,7 +50,8 @@ export interface AgentConfig {
50
50
  /** Pre-turn refinement policies. Default: none. */
51
51
  refine?: RefinementCapability[];
52
52
  experimental?: {
53
- /** Flow reply nodes: silo flow-transition control tools + deterministic evaluator (ADR 0003 H1). Default OFF. */
53
+ /** Flow reply nodes: silo flow-transition control tools + deterministic evaluator (ADR 0003 H1).
54
+ * Default ON when the agent declares `flows`; OFF for answering-only agents. Override explicitly to opt out. */
54
55
  outOfBandControl?: boolean;
55
56
  };
56
57
  /** Portable workspace filesystem; auto-registers the durable `workspace` tool when set.
@@ -1,4 +1,4 @@
1
- import type { ToolSet } from 'ai';
1
+ import type { ModelMessage, ToolSet } from 'ai';
2
2
  import type { UserInputContent } from '../runtime/userInput.js';
3
3
  import type { RunContext } from './run-context.js';
4
4
  import type { FlowNode } from './flow.js';
@@ -34,6 +34,14 @@ export interface ChannelDriver {
34
34
  * back to runAgentTurn, whose text the engine then discards. */
35
35
  runExtraction?(node: ResolvedNode, ctx: RunContext): Promise<TurnResult>;
36
36
  }
37
+ export interface TurnUsageSnapshot {
38
+ inputTokens: number;
39
+ outputTokens: number;
40
+ totalTokens: number;
41
+ cacheReadTokens?: number;
42
+ /** Input tokens on the final model call, i.e. current context-window occupancy. */
43
+ contextTokens?: number;
44
+ }
37
45
  export interface TurnResult {
38
46
  text: string;
39
47
  toolResults: ToolResultRecord[];
@@ -43,6 +51,11 @@ export interface TurnResult {
43
51
  confidence?: number;
44
52
  /** Native realtime post-hoc gate: provider audio already played; gate is advisory only. */
45
53
  gateScope?: 'advisory';
54
+ /** AI-SDK tool round-trip messages (assistant tool-call + tool-result) produced this turn,
55
+ * so the host loop can persist them to history in free conversation (G18). */
56
+ toolMessages?: ModelMessage[];
57
+ /** Real token usage from the AI SDK when the driver captured it. */
58
+ usage?: TurnUsageSnapshot;
46
59
  }
47
60
  export type UserSignal = {
48
61
  type: 'message';
@@ -12,7 +12,13 @@ export interface Tool<TInput = unknown, TOutput = unknown> {
12
12
  timeoutMs?: number;
13
13
  /** When false, the durable journal always re-executes this tool instead of returning a cached step result — for observation/mutation tools (fs, shell) whose result must be fresh. Default true. */
14
14
  replay?: boolean;
15
+ /** When true, the tool may run concurrently with other parallel-safe tools in the same model turn. */
16
+ parallelSafe?: boolean;
17
+ /** Override the auto-derived effect key (`idempotencyKey(logicalRunId, callsite, {name,args})`). Use when args are not a stable identity (e.g. a nonce). */
18
+ idempotencyKey?: (args: TInput) => string;
15
19
  execute: (args: TInput, ctx?: ToolContext) => Promise<TOutput> | AsyncIterable<TOutput>;
20
+ /** Recover from a thrown error by returning a result the model can act on. Not called for timeouts, aborts, schema violations, or control-flow signals. */
21
+ onError?: (error: Error, args: TInput) => Promise<TOutput> | TOutput;
16
22
  }
17
23
  export type AnyTool = Tool<any, any>;
18
24
  export { defineTool } from '../tools/effect/defineTool.js';
@@ -1,6 +1,6 @@
1
1
  import type { LanguageModel, ModelMessage, ToolSet } from 'ai';
2
2
  import type { Instructions } from './agentConfig.js';
3
- import type { AgentKnowledgeOverrides } from './voice.js';
3
+ import type { AgentKnowledgeOverrides } from './knowledge.js';
4
4
  import type { StandardSchemaV1 } from './standard-schema.js';
5
5
  import type { ContextStrategy } from './context.js';
6
6
  import type { TurnResult } from './channel.js';
@@ -11,4 +11,9 @@ export interface Limits {
11
11
  maxSteps?: number;
12
12
  toolMaxSteps?: number;
13
13
  maxOscillations?: number;
14
+ /**
15
+ * Ceiling on parallel-safe tools executing at once within one model-emitted batch.
16
+ * Unset means unbounded — the model's batch size decides how many run concurrently.
17
+ */
18
+ maxToolConcurrency?: number;
14
19
  }
@@ -1,11 +1,11 @@
1
1
  import type { ConversationOutcomeRecord } from '../outcomes/types.js';
2
- import type { HarnessStreamPart } from './stream.js';
2
+ import type { StreamPart } from './stream.js';
3
3
  import type { RunContext } from './run-context.js';
4
4
  import type { Session } from './session.js';
5
5
  import type { TurnUsage } from './telemetry.js';
6
6
  export interface Hooks {
7
7
  onStart?: (ctx: RunContext) => void | Promise<void>;
8
- onStreamPart?: (ctx: RunContext, part: HarnessStreamPart) => void | Promise<void>;
8
+ onStreamPart?: (ctx: RunContext, part: StreamPart) => void | Promise<void>;
9
9
  onEnd?: (ctx: RunContext) => void | Promise<void>;
10
10
  onConversationEnd?: (args: {
11
11
  session: Session;
@@ -1,15 +1,25 @@
1
- export * from './selection.js';
2
- export * from './telemetry.js';
3
- export * from './processors.js';
4
- export * from './agentConfig.js';
5
- export * from './filesystem.js';
6
- export * from './skills.js';
7
- export * from './flow.js';
8
- export * from './session.js';
9
- export * from './tool.js';
10
- export * from './effectTool.js';
11
- export * from './voice.js';
12
- export * from './runtime.js';
13
- export type * from '../audit/types.js';
14
- export type * from '../outcomes/index.js';
15
- export type * from '../channels/index.js';
1
+ export type { ChoiceOption, ResolvedSelection } from './selection.js';
2
+ export type { TurnUsage, TraceStreamEvent, TracingConfig, Span, SpanEvent, MetricsConfig, ObservabilityMetrics, Metrics, SessionTelemetry, SessionEndMetadata, SessionTrace, } from './telemetry.js';
3
+ export type { ProcessorAction, FlowPromptContext, ProcessorContext, InputProcessorResult, OutputProcessorResult, InputProcessor, OutputProcessor, HandoffInputData, HandoffInputResult, HandoffInputFilter, AgentRoute, RouteCondition, AgentCapabilityDescriptor, } from './processors.js';
4
+ export { defineAgent } from './agentConfig.js';
5
+ export type { AgentWorkspaceConfig, Instructions, AgentConfig } from './agentConfig.js';
6
+ export { fsErrorCode } from './filesystem.js';
7
+ export type { FileSystemEntryType, BufferEncoding, FileContent, FsStat, FileSystemDirent, MkdirOptions, RmOptions, CpOptions, FileSystem, ReadFileOptions, WriteFileOptions, FileEntry, DirectoryEntry, SymlinkEntry, LazyFileEntry, FsEntry, FileInit, LazyFileProvider, InitialFiles, FsError, } from './filesystem.js';
8
+ export type { SkillMeta, SkillLike, SkillStoreLike, SkillSource } from './skills.js';
9
+ export { reply, collect, action, decide, confirmGate, defineFlow } from './flow.js';
10
+ export type { FlowState, Flow, FlowNode, NodeGrounding, Transition, ReplyNode, CollectNode, ActionNode, ConfirmGate, DecideNode, } from './flow.js';
11
+ export type { ChannelId, GoalStatus, TrackedGoal, WorkingMemory, AgentContext, Session, SessionMetadata, AgentState, HandoffRecord, ToolCallRecord, RunContext, } from './session.js';
12
+ export type { ToolSet, ToolPolicy, EnforcementContext, EnforcementResult, EnforcementRule, InjectionPriority, InjectionLevel, Injection, } from './tool.js';
13
+ export { defineTool } from './effectTool.js';
14
+ export type { Tool, AnyTool } from './effectTool.js';
15
+ export type { KnowledgeProviderConfig, AgentKnowledgeOverrides, KnowledgeRetrieverAdapter, KnowledgeEmbedderAdapter, SourceRef, KnowledgeRetrievalResult, KnowledgeChunk, RetrievalCacheAdapter, HttpCallbackConfig, StreamCallbackPayload, StreamCallbackSink, StreamCallbackConfig, } from './knowledge.js';
16
+ export { PART_CHANNEL } from './stream.js';
17
+ 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 './stream.js';
18
+ export { isAbortSignal } from './runtime.js';
19
+ export type { RefinementStageResult, ValidationStageResult, Hook, StopConditionResult, StopCondition, StreamOptions, AbortOptions, InterruptionEvent, CancellationReason, } from './runtime.js';
20
+ export type { SpanKind, AgentSpan, AgentTrace } from './trace.js';
21
+ export type { AuditEntryBase, AuditEscalationReason, ConversationAuditEntry, ConversationAuditLog, AuditEntryType, AuditListOptions, AuditReplayOptions, AuditConfig, } from '../audit/types.js';
22
+ export { toConversationOutcomeStreamPart, buildMarkOutcomeTool, OUTCOMES_MARK_TOOL_NAME } from '../outcomes/index.js';
23
+ export type { ConversationOutcome, ConversationOutcomeMarkedBy, ConversationOutcomeRecord, CsatRecord, MarkOutcomeToolResult, } from '../outcomes/index.js';
24
+ export { DEFAULT_CHANNEL_POLICIES, getDefaultChannelPolicy, applyChannelPolicy, resolveChannelPolicy } from '../channels/index.js';
25
+ export type { ChannelPolicy, ChannelPolicyChange, ChannelPolicyResult } from '../channels/index.js';
@@ -1,12 +1,8 @@
1
- export * from './selection.js';
2
- export * from './telemetry.js';
3
- export * from './processors.js';
4
- export * from './agentConfig.js';
5
- export * from './filesystem.js';
6
- export * from './skills.js';
7
- export * from './flow.js';
8
- export * from './session.js';
9
- export * from './tool.js';
10
- export * from './effectTool.js';
11
- export * from './voice.js';
12
- export * from './runtime.js';
1
+ export { defineAgent } from './agentConfig.js';
2
+ export { fsErrorCode } from './filesystem.js';
3
+ export { reply, collect, action, decide, confirmGate, defineFlow } from './flow.js';
4
+ export { defineTool } from './effectTool.js';
5
+ export { PART_CHANNEL } from './stream.js';
6
+ export { isAbortSignal } from './runtime.js';
7
+ export { toConversationOutcomeStreamPart, buildMarkOutcomeTool, OUTCOMES_MARK_TOOL_NAME } from '../outcomes/index.js';
8
+ export { DEFAULT_CHANNEL_POLICIES, getDefaultChannelPolicy, applyChannelPolicy, resolveChannelPolicy } from '../channels/index.js';
@@ -0,0 +1,213 @@
1
+ import type { StreamPart } from './stream.js';
2
+ /**
3
+ * Runtime-level knowledge configuration. Configured once on the Runtime,
4
+ * inherited by all agents. Per-agent overrides via `AgentKnowledgeOverrides`
5
+ * can only reduce capabilities (e.g., disable compiled knowledge, restrict
6
+ * topK, filter by metadata).
7
+ */
8
+ export interface KnowledgeProviderConfig {
9
+ /**
10
+ * Retriever for hybrid search (Layer 3). Any object implementing the
11
+ * Retriever interface from `@kuralle-agents/rag`. When not provided,
12
+ * only compiled knowledge and cache are available.
13
+ */
14
+ retriever?: KnowledgeRetrieverAdapter;
15
+ /**
16
+ * Embedder for cache similarity lookup. Required when `retriever` is
17
+ * provided (needed for cache population and query embedding).
18
+ */
19
+ embedder?: KnowledgeEmbedderAdapter;
20
+ /**
21
+ * Pre-compiled knowledge content (Layer 1). Injected into the system
22
+ * prompt every turn with zero search latency. Produced offline by
23
+ * KnowledgeCompiler.
24
+ */
25
+ compiled?: string;
26
+ /**
27
+ * Retrieval cache configuration. When omitted, a default configuration
28
+ * is used (maxEntries: 256, ttlMs: 300000, similarityThreshold: 0.85).
29
+ */
30
+ cache?: {
31
+ /** Maximum entries in the LRU cache. Default: 256. */
32
+ maxEntries?: number;
33
+ /** Cache entry TTL in milliseconds. Default: 300000 (5 minutes). */
34
+ ttlMs?: number;
35
+ /** Minimum cosine similarity for a cache hit. Default: 0.85. */
36
+ similarityThreshold?: number;
37
+ };
38
+ /**
39
+ * Predictive pre-fetch configuration. When enabled, the system
40
+ * predicts follow-up topics from the conversation window and
41
+ * pre-fetches relevant content into the session cache.
42
+ */
43
+ prefetch?: {
44
+ /** Enable predictive pre-fetching. Default: false. */
45
+ enabled?: boolean;
46
+ /** Number of keywords to extract per prediction. Default: 3. */
47
+ maxKeywords?: number;
48
+ /** Number of recent messages to analyze. Default: 5. */
49
+ conversationWindow?: number;
50
+ };
51
+ /**
52
+ * Default retrieval options applied to all agents unless overridden.
53
+ */
54
+ defaults?: {
55
+ /** Maximum results from Layer 3 search. Default: 5. */
56
+ topK?: number;
57
+ /** Maximum tokens for retrieval context in the system prompt. Default: 2000. */
58
+ maxOutputTokens?: number;
59
+ /** Whether to include embedding vectors in results (for cache writeback). Default: true. */
60
+ includeEmbeddings?: boolean;
61
+ };
62
+ /**
63
+ * Retrieval quality checking configuration. When configured, retrieval
64
+ * results are evaluated using score distribution (sub-millisecond).
65
+ * For text agents, low-quality results trigger inline reformulation.
66
+ * For voice agents, low-quality results trigger background reformulation
67
+ * via the pre-fetcher.
68
+ */
69
+ qualityCheck?: {
70
+ /** Minimum top-result score to consider quality "high". Default: 0.5. */
71
+ highThreshold?: number;
72
+ /** Minimum top-result score to consider quality "medium". Default: 0.3. */
73
+ mediumThreshold?: number;
74
+ /**
75
+ * Query reformulator callback. When provided and quality is "low",
76
+ * the system rewrites the query and re-retrieves.
77
+ */
78
+ reformulate?: (query: string, results: KnowledgeRetrievalResult[]) => Promise<string>;
79
+ };
80
+ /**
81
+ * How retrieved source references should be rendered into the model prompt.
82
+ * Defaults to 'footnotes'.
83
+ */
84
+ renderCitations?: 'inline' | 'footnotes' | 'off';
85
+ }
86
+ /**
87
+ * Per-agent knowledge overrides. Can only reduce capabilities — cannot
88
+ * add a retriever that doesn't exist at the Runtime level.
89
+ */
90
+ export interface AgentKnowledgeOverrides {
91
+ /** Disable compiled knowledge injection for this agent. */
92
+ compiledEnabled?: boolean;
93
+ /** Disable retrieval tool for this agent. */
94
+ toolEnabled?: boolean;
95
+ /** Override topK (must be <= Runtime default). */
96
+ topK?: number;
97
+ /** Override max output tokens (must be <= Runtime default). */
98
+ maxOutputTokens?: number;
99
+ /** Metadata filter restricting which documents this agent can access. */
100
+ filter?: Record<string, unknown>;
101
+ }
102
+ /**
103
+ * Adapter interface for retrievers used by KnowledgeProvider.
104
+ * Mirrors the Retriever interface from `@kuralle-agents/rag` without
105
+ * creating a dependency from core → rag.
106
+ */
107
+ export interface KnowledgeRetrieverAdapter {
108
+ retrieve(query: string, options?: {
109
+ topK?: number;
110
+ filter?: Record<string, unknown>;
111
+ queryEmbedding?: readonly number[];
112
+ includeEmbeddings?: boolean;
113
+ }): Promise<KnowledgeRetrievalResult[]>;
114
+ }
115
+ /**
116
+ * Adapter interface for embedders used by KnowledgeProvider.
117
+ * Mirrors the Embedder interface from `@kuralle-agents/rag`.
118
+ */
119
+ export interface KnowledgeEmbedderAdapter {
120
+ embed(text: string): Promise<readonly number[]>;
121
+ }
122
+ export interface SourceRef {
123
+ readonly id: string;
124
+ readonly title?: string;
125
+ readonly url?: string;
126
+ readonly lastModified?: string;
127
+ readonly score?: number;
128
+ }
129
+ /**
130
+ * A single result from knowledge retrieval, used across the pipeline.
131
+ */
132
+ export interface KnowledgeRetrievalResult {
133
+ id: string;
134
+ text: string;
135
+ sourceId: string;
136
+ score?: number;
137
+ relevanceScore?: number;
138
+ snippet?: string;
139
+ metadata?: Record<string, unknown>;
140
+ embedding?: readonly number[];
141
+ }
142
+ export type KnowledgeChunk = KnowledgeRetrievalResult;
143
+ /**
144
+ * Interface for the session-level retrieval cache. Implemented by
145
+ * `RetrievalCache` from `@kuralle-agents/rag`. Defined here so
146
+ * `RunContext.retrievalCache` can be properly typed without core
147
+ * depending on rag.
148
+ */
149
+ export interface RetrievalCacheAdapter {
150
+ lookup(queryEmbedding: readonly number[], topK?: number): KnowledgeRetrievalResult[];
151
+ populate(results: KnowledgeRetrievalResult[], queryEmbedding?: readonly number[]): void;
152
+ readonly size: number;
153
+ }
154
+ export interface HttpCallbackConfig {
155
+ url: string;
156
+ method?: 'POST' | 'PUT';
157
+ headers?: Record<string, string>;
158
+ allowList?: string[];
159
+ denyList?: string[];
160
+ includeFullText?: boolean;
161
+ timeoutMs?: number;
162
+ }
163
+ export interface StreamCallbackPayload {
164
+ sessionId: string;
165
+ agentId: string;
166
+ timestamp: string;
167
+ part: StreamPart;
168
+ fullText?: string;
169
+ }
170
+ export interface StreamCallbackSink {
171
+ name?: string;
172
+ write: (payload: StreamCallbackPayload) => Promise<void>;
173
+ close?: () => Promise<void>;
174
+ }
175
+ export interface StreamCallbackConfig {
176
+ sinks?: StreamCallbackSink[];
177
+ /**
178
+ * Events to emit when no explicit allowList is provided.
179
+ * - message: emit terminal events plus tool/transition events per toggles
180
+ * - all: emit every runtime event
181
+ * Default: message
182
+ */
183
+ eventMode?: 'message' | 'all';
184
+ /**
185
+ * Emit streaming text-delta events.
186
+ * Default: false (final text is emitted on terminal events via fullText)
187
+ */
188
+ emitTextDeltas?: boolean;
189
+ /**
190
+ * Emit tool lifecycle events (tool-call/tool-result) in message mode.
191
+ * Default: true
192
+ */
193
+ emitToolEvents?: boolean;
194
+ /**
195
+ * Emit transition lifecycle events (flow-transition/handoff) in message mode.
196
+ * Default: true
197
+ */
198
+ emitTransitionEvents?: boolean;
199
+ /**
200
+ * Attach accumulated assistant text as fullText on terminal events.
201
+ * Default: true
202
+ */
203
+ emitFinalText?: boolean;
204
+ allowList?: string[];
205
+ denyList?: string[];
206
+ includeFullText?: boolean;
207
+ maxQueueSize?: number;
208
+ dropPolicy?: 'drop_oldest' | 'drop_newest';
209
+ logDroppedEvents?: boolean;
210
+ /** If true, wait for sink queue drain when a stream call ends. Default: false. */
211
+ flushOnEnd?: boolean;
212
+ flushTimeoutMs?: number;
213
+ }
@@ -70,61 +70,3 @@ export interface AgentCapabilityDescriptor {
70
70
  handlesIntents?: string[];
71
71
  doesNotHandle?: string[];
72
72
  }
73
- export type AgentStreamPart = {
74
- type: 'text-start';
75
- id: string;
76
- } | {
77
- type: 'text-delta';
78
- id: string;
79
- delta: string;
80
- } | {
81
- type: 'text-end';
82
- id: string;
83
- } | {
84
- type: 'text-cancel';
85
- id: string;
86
- reason: string;
87
- } | {
88
- type: 'tool-call';
89
- toolName: string;
90
- args: unknown;
91
- toolCallId?: string;
92
- } | {
93
- type: 'tool-result';
94
- toolName: string;
95
- result: unknown;
96
- toolCallId?: string;
97
- } | {
98
- type: 'tool-error';
99
- toolName: string;
100
- error: string;
101
- toolCallId?: string;
102
- } | {
103
- type: 'handoff';
104
- targetAgent: string;
105
- reason?: string;
106
- } | {
107
- type: 'node-enter';
108
- nodeName: string;
109
- } | {
110
- type: 'node-exit';
111
- nodeName: string;
112
- } | {
113
- type: 'flow-transition';
114
- from: string;
115
- to: string;
116
- } | {
117
- type: 'flow-end';
118
- reason: string;
119
- } | {
120
- type: 'custom';
121
- name: string;
122
- data: unknown;
123
- timestamp?: Date;
124
- } | {
125
- type: 'turn-end';
126
- metadata?: Record<string, unknown>;
127
- } | {
128
- type: 'error';
129
- error: string;
130
- };
@@ -3,14 +3,14 @@ import type { Session } from './session.js';
3
3
  import type { InputProcessor, OutputProcessor } from './processors.js';
4
4
  import type { RunState } from '../runtime/durable/types.js';
5
5
  import type { RunStore } from '../runtime/durable/RunStore.js';
6
- import type { HarnessStreamPart } from './stream.js';
6
+ import type { StreamPart } from './stream.js';
7
7
  import type { RefinementCapability } from '../capabilities/RefinementCapability.js';
8
8
  import type { ValidationCapability } from '../capabilities/ValidationCapability.js';
9
9
  import type { Limits } from './guardrails.js';
10
10
  import type { AnyTool } from './effectTool.js';
11
11
  import type { FileSystem } from './filesystem.js';
12
12
  import type { Instructions } from './agentConfig.js';
13
- import type { AgentKnowledgeOverrides, SourceRef } from './voice.js';
13
+ import type { AgentKnowledgeOverrides, SourceRef, RetrievalCacheAdapter } from './knowledge.js';
14
14
  export interface GatherScope {
15
15
  query?: string;
16
16
  knowledge?: AgentKnowledgeOverrides & {
@@ -45,16 +45,12 @@ export interface MemoryService {
45
45
  preload?(ctx: RunContext, scope?: GatherScope): Promise<string | undefined>;
46
46
  ingest?(ctx: RunContext): Promise<void>;
47
47
  }
48
- export interface HookRunner {
49
- onStreamPart?(ctx: RunContext, part: HarnessStreamPart): void | Promise<void>;
50
- }
51
48
  export interface RunContext {
52
49
  session: Session;
53
50
  runState: RunState;
54
51
  runStore: RunStore;
55
- emit: (part: HarnessStreamPart) => void;
52
+ emit: (part: StreamPart) => void;
56
53
  toolExecutor: EffectToolExecutor;
57
- hookRunner: HookRunner;
58
54
  model: LanguageModel;
59
55
  /** Control-path model (routing, decide, extraction) at temperature 0. */
60
56
  controlModel: LanguageModel;
@@ -80,6 +76,13 @@ export interface RunContext {
80
76
  turnInputConsumed?: boolean;
81
77
  /** Citations from the latest gather-phase retrieval on this turn. */
82
78
  lastRetrievalCitations?: SourceRef[];
79
+ /**
80
+ * Session retrieval cache (G6): created once per run by the KnowledgeProvider,
81
+ * persists across in-session agent handoffs (this RunContext survives the
82
+ * handoff branch). Keyed by query embedding; RAG-only, undefined without a
83
+ * configured knowledge provider + embedder.
84
+ */
85
+ retrievalCache?: RetrievalCacheAdapter;
83
86
  /** Agent base layer (ADR 0001), set when entering a flow. `baseInstructions`
84
87
  * is composed as a prefix into every node turn's system prompt (persona /
85
88
  * safety / grounding floor); `globalTools` are safe tools made model-visible
@@ -98,6 +101,10 @@ export interface RunContext {
98
101
  toolCallId?: string;
99
102
  def?: AnyTool;
100
103
  toolCtx?: ToolContext;
104
+ /** Pre-reserved callsite ordinal for parallel-safe tool batches (G9). */
105
+ callsite?: string;
106
+ /** Pre-reserved journal index for parallel-safe tool batches (G9). */
107
+ index?: number;
101
108
  }): Promise<unknown>;
102
109
  approve(req: {
103
110
  title: string;
@@ -116,6 +123,8 @@ export interface RunContext {
116
123
  * a flow's durable callsites are anchored to the flow — identical on fresh entry
117
124
  * (after an answering turn) and on resume (where that turn does not re-run). */
118
125
  resetCallsites(): void;
126
+ /** Reserve N contiguous effect callsite ordinals for parallel-safe tool batches (G9). */
127
+ reserveCallsites(count: number): string[];
119
128
  }
120
129
  export type ActionContext = Pick<RunContext, 'tool' | 'approve' | 'signal' | 'now' | 'uuid' | 'emit' | 'fs'>;
121
130
  export type ToolContext = Pick<RunContext, 'session' | 'runState' | 'tool' | 'now' | 'uuid' | 'emit' | 'fs' | 'abortSignal'>;