@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.
- package/README.md +89 -4
- package/dist/ai-sdk/uiMessageStream.d.ts +2 -2
- package/dist/ai-sdk/uiMessageStream.js +42 -29
- package/dist/capabilities/LivePromptAssembler.d.ts +1 -1
- package/dist/capabilities/LivePromptAssembler.js +2 -1
- package/dist/capabilities/index.d.ts +1 -1
- package/dist/eval/EvalRunner.js +4 -4
- package/dist/eval/simulation.js +4 -3
- package/dist/events/TurnHandle.d.ts +3 -3
- package/dist/flow/collectDigression.d.ts +5 -2
- package/dist/flow/collectDigression.js +48 -10
- package/dist/flow/collectUntilComplete.js +13 -5
- package/dist/flow/degrade.js +8 -4
- package/dist/flow/emitInteractive.d.ts +2 -2
- package/dist/flow/emitInteractive.js +6 -3
- package/dist/flow/extraction.d.ts +3 -2
- package/dist/flow/extraction.js +14 -4
- package/dist/flow/reduceTransition.d.ts +2 -2
- package/dist/flow/reduceTransition.js +7 -3
- package/dist/flow/runFlow.js +97 -17
- package/dist/foundation/AgentStateController.d.ts +1 -1
- package/dist/foundation/ToolExecutor.d.ts +2 -2
- package/dist/foundation/index.d.ts +0 -11
- package/dist/foundation/index.js +0 -5
- package/dist/index.d.ts +15 -15
- package/dist/index.js +9 -6
- package/dist/outcomes/streamPart.d.ts +2 -2
- package/dist/outcomes/streamPart.js +2 -3
- package/dist/prompts/PromptBuilder.d.ts +3 -3
- package/dist/prompts/PromptBuilder.js +13 -6
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/types.d.ts +9 -2
- package/dist/runtime/InMemoryRetrievalCache.d.ts +25 -0
- package/dist/runtime/InMemoryRetrievalCache.js +59 -0
- package/dist/runtime/KnowledgeProvider.d.ts +3 -2
- package/dist/runtime/KnowledgeProvider.js +60 -31
- package/dist/runtime/Runtime.d.ts +47 -1
- package/dist/runtime/Runtime.js +273 -36
- package/dist/runtime/TokenAccumulator.d.ts +7 -0
- package/dist/runtime/TokenAccumulator.js +7 -0
- package/dist/runtime/TraceRecorder.d.ts +51 -0
- package/dist/runtime/TraceRecorder.js +326 -0
- package/dist/runtime/buildAgentToolSurface.js +1 -1
- package/dist/runtime/channels/TextDriver.js +57 -31
- package/dist/runtime/channels/executeModelTool.d.ts +14 -1
- package/dist/runtime/channels/executeModelTool.js +132 -3
- package/dist/runtime/channels/extractionTurn.js +1 -1
- package/dist/runtime/channels/index.d.ts +0 -3
- package/dist/runtime/channels/index.js +0 -6
- package/dist/runtime/channels/inputBuffer.d.ts +1 -0
- package/dist/runtime/channels/inputBuffer.js +9 -0
- package/dist/runtime/channels/streaming/hostControlSpeak.js +5 -1
- package/dist/runtime/channels/streaming/speakGated.js +24 -12
- package/dist/runtime/citations/index.d.ts +3 -3
- package/dist/runtime/closeRun.js +14 -10
- package/dist/runtime/compaction.d.ts +2 -0
- package/dist/runtime/compaction.js +3 -2
- package/dist/runtime/controlFlowSignal.d.ts +24 -0
- package/dist/runtime/controlFlowSignal.js +29 -0
- package/dist/runtime/ctx.d.ts +3 -4
- package/dist/runtime/ctx.js +147 -60
- package/dist/runtime/durable/RunStore.d.ts +16 -0
- package/dist/runtime/durable/RunStore.js +7 -1
- package/dist/runtime/durable/SessionRunStore.d.ts +7 -2
- package/dist/runtime/durable/SessionRunStore.js +136 -34
- package/dist/runtime/durable/idempotency.d.ts +1 -0
- package/dist/runtime/durable/idempotency.js +3 -0
- package/dist/runtime/durable/replay.js +7 -2
- package/dist/runtime/durable/types.d.ts +11 -0
- package/dist/runtime/goals.d.ts +18 -0
- package/dist/runtime/goals.js +158 -0
- package/dist/runtime/grounding/gather.d.ts +1 -1
- package/dist/runtime/grounding/inMemoryKnowledge.d.ts +1 -1
- package/dist/runtime/grounding/knowledge.d.ts +1 -1
- package/dist/runtime/grounding/knowledge.js +1 -1
- package/dist/runtime/handoffContinuation.d.ts +20 -0
- package/dist/runtime/handoffContinuation.js +30 -0
- package/dist/runtime/handoffOscillation.d.ts +6 -0
- package/dist/runtime/handoffOscillation.js +17 -0
- package/dist/runtime/hostLoop.js +37 -6
- package/dist/runtime/index.d.ts +4 -3
- package/dist/runtime/index.js +2 -1
- package/dist/runtime/openRun.d.ts +2 -0
- package/dist/runtime/openRun.js +46 -17
- package/dist/runtime/outcomeMarking.d.ts +2 -2
- package/dist/runtime/outcomeMarking.js +2 -1
- package/dist/runtime/policies/agentTurn.d.ts +1 -1
- package/dist/runtime/policies/limits.d.ts +1 -0
- package/dist/runtime/policies/limits.js +3 -0
- package/dist/runtime/runHookSafely.d.ts +3 -0
- package/dist/runtime/runHookSafely.js +19 -0
- package/dist/runtime/select.d.ts +5 -1
- package/dist/runtime/select.js +30 -1
- package/dist/runtime/turnTokenUsage.d.ts +28 -0
- package/dist/runtime/turnTokenUsage.js +70 -0
- package/dist/scheduler/index.d.ts +2 -2
- package/dist/scheduler/index.js +1 -1
- package/dist/services/TracingService.js +2 -3
- package/dist/session/SessionStore.d.ts +6 -0
- package/dist/session/SessionStore.js +12 -1
- package/dist/session/stores/MemoryStore.d.ts +1 -1
- package/dist/session/stores/MemoryStore.js +16 -2
- package/dist/session/testing.d.ts +6 -1
- package/dist/session/testing.js +34 -0
- package/dist/session/utils.d.ts +3 -0
- package/dist/session/utils.js +23 -0
- package/dist/skills/collectSkills.d.ts +11 -3
- package/dist/skills/collectSkills.js +51 -8
- package/dist/skills/compositeSkillStore.d.ts +26 -0
- package/dist/skills/compositeSkillStore.js +54 -0
- package/dist/skills/defineSkill.d.ts +21 -0
- package/dist/skills/defineSkill.js +26 -0
- package/dist/skills/fsSkillStore.d.ts +3 -0
- package/dist/skills/fsSkillStore.js +79 -0
- package/dist/skills/index.d.ts +4 -0
- package/dist/skills/index.js +4 -0
- package/dist/skills/parseSkillFrontmatter.d.ts +14 -0
- package/dist/skills/parseSkillFrontmatter.js +183 -0
- package/dist/skills/wireAgentSkills.d.ts +2 -1
- package/dist/skills/wireAgentSkills.js +2 -2
- package/dist/testing/mocks.d.ts +3 -3
- package/dist/testing/mocks.js +7 -3
- package/dist/tools/controlResults.d.ts +14 -0
- package/dist/tools/controlResults.js +15 -0
- package/dist/tools/effect/ToolExecutor.d.ts +6 -0
- package/dist/tools/effect/ToolExecutor.js +75 -36
- package/dist/tools/effect/defineTool.d.ts +11 -0
- package/dist/tools/effect/defineTool.js +3 -0
- package/dist/tools/effect/errors.d.ts +2 -5
- package/dist/tools/effect/errors.js +2 -5
- package/dist/tools/index.d.ts +0 -1
- package/dist/tools/index.js +0 -1
- package/dist/tracing/MemoryTraceStore.d.ts +16 -0
- package/dist/tracing/MemoryTraceStore.js +56 -0
- package/dist/tracing/OtelTraceSink.d.ts +127 -0
- package/dist/tracing/OtelTraceSink.js +101 -0
- package/dist/tracing/TraceStore.d.ts +19 -0
- package/dist/tracing/TraceStore.js +32 -0
- package/dist/tracing/index.d.ts +3 -0
- package/dist/tracing/index.js +3 -0
- package/dist/tracing/testing.d.ts +3 -0
- package/dist/tracing/testing.js +45 -0
- package/dist/types/agentConfig.d.ts +2 -1
- package/dist/types/channel.d.ts +14 -1
- package/dist/types/effectTool.d.ts +6 -0
- package/dist/types/flow.d.ts +1 -1
- package/dist/types/guardrails.d.ts +5 -0
- package/dist/types/hooks.d.ts +2 -2
- package/dist/types/index.d.ts +25 -15
- package/dist/types/index.js +8 -12
- package/dist/types/knowledge.d.ts +213 -0
- package/dist/types/processors.d.ts +0 -58
- package/dist/types/run-context.d.ts +16 -7
- package/dist/types/runtime.d.ts +3 -74
- package/dist/types/session.d.ts +11 -1
- package/dist/types/skills.d.ts +15 -1
- package/dist/types/stream.d.ts +138 -68
- package/dist/types/stream.js +34 -1
- package/dist/types/trace.d.ts +52 -0
- package/guides/AGENTS.md +3 -3
- package/guides/EXAMPLE_VERIFICATION.md +4 -4
- package/guides/FLOWS.md +1 -1
- package/guides/GETTING_STARTED.md +1 -1
- package/guides/RUNTIME.md +20 -15
- package/guides/TOOLS.md +1 -1
- package/package.json +13 -14
- package/dist/foundation/AgentDefinition.d.ts +0 -17
- package/dist/foundation/ConversationEventLog.d.ts +0 -71
- package/dist/foundation/ConversationState.d.ts +0 -33
- package/dist/foundation/ConversationState.js +0 -1
- package/dist/foundation/DefaultConversationEventLog.d.ts +0 -27
- package/dist/foundation/DefaultConversationEventLog.js +0 -205
- package/dist/foundation/DefaultConversationState.d.ts +0 -36
- package/dist/foundation/DefaultConversationState.js +0 -103
- package/dist/foundation/DefaultToolExecutor.d.ts +0 -57
- package/dist/foundation/DefaultToolExecutor.js +0 -132
- package/dist/foundation/createFoundation.d.ts +0 -32
- package/dist/foundation/createFoundation.js +0 -33
- package/dist/hooks/HookRunner.d.ts +0 -37
- package/dist/hooks/HookRunner.js +0 -111
- package/dist/hooks/builtin/logging.d.ts +0 -5
- package/dist/hooks/builtin/logging.js +0 -98
- package/dist/hooks/builtin/metrics.d.ts +0 -7
- package/dist/hooks/builtin/metrics.js +0 -60
- package/dist/hooks/builtin/observability.d.ts +0 -20
- package/dist/hooks/builtin/observability.js +0 -572
- package/dist/hooks/helpers.d.ts +0 -22
- package/dist/hooks/helpers.js +0 -183
- package/dist/hooks/index.d.ts +0 -8
- package/dist/hooks/index.js +0 -6
- package/dist/realtime/RealtimeAudioClient.d.ts +0 -166
- package/dist/realtime/RealtimeAudioClient.js +0 -14
- package/dist/realtime/RealtimeSessionHandle.d.ts +0 -6
- package/dist/realtime/RealtimeSessionHandle.js +0 -1
- package/dist/realtime/index.d.ts +0 -2
- package/dist/realtime/index.js +0 -1
- package/dist/runtime/channels/VoiceDriver.d.ts +0 -31
- package/dist/runtime/channels/VoiceDriver.js +0 -321
- package/dist/runtime/channels/voiceTools.d.ts +0 -9
- package/dist/runtime/channels/voiceTools.js +0 -51
- package/dist/tools/errorHandling.d.ts +0 -35
- package/dist/tools/errorHandling.js +0 -145
- package/dist/types/voice.d.ts +0 -517
- package/dist/types/voice.js +0 -14
- package/dist/utils/isRecord.d.ts +0 -1
- package/dist/utils/isRecord.js +0 -3
- package/dist/utils/messageNormalization.d.ts +0 -2
- package/dist/utils/messageNormalization.js +0 -137
- /package/dist/{foundation/AgentDefinition.js → types/knowledge.js} +0 -0
- /package/dist/{foundation/ConversationEventLog.js → types/trace.js} +0 -0
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import { isRecord } from '../utils/isRecord.js';
|
|
3
|
-
/**
|
|
4
|
-
* Error thrown when a tool execution exceeds the configured timeout.
|
|
5
|
-
*/
|
|
6
|
-
export class ToolTimeoutError extends Error {
|
|
7
|
-
toolName;
|
|
8
|
-
timeoutMs;
|
|
9
|
-
constructor(toolName, timeoutMs) {
|
|
10
|
-
super(`Tool "${toolName}" timeout after ${timeoutMs}ms`);
|
|
11
|
-
this.name = 'ToolTimeoutError';
|
|
12
|
-
this.toolName = toolName;
|
|
13
|
-
this.timeoutMs = timeoutMs;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Default tool executor extracted from Runtime.wrapToolsWithEnforcement().
|
|
18
|
-
*
|
|
19
|
-
* Handles:
|
|
20
|
-
* - Enforcement checks via ToolEnforcer
|
|
21
|
-
* - Idempotency key generation
|
|
22
|
-
* - Context enrichment (experimental_context)
|
|
23
|
-
* - Error propagation via HookRunner
|
|
24
|
-
*/
|
|
25
|
-
export class DefaultToolExecutor {
|
|
26
|
-
enforcer;
|
|
27
|
-
hookRunner;
|
|
28
|
-
memoryService;
|
|
29
|
-
defaultToolTimeoutMs;
|
|
30
|
-
constructor(config) {
|
|
31
|
-
this.enforcer = config.enforcer;
|
|
32
|
-
this.hookRunner = config.hookRunner;
|
|
33
|
-
this.memoryService = config.memoryService;
|
|
34
|
-
this.defaultToolTimeoutMs = config.defaultToolTimeoutMs;
|
|
35
|
-
}
|
|
36
|
-
async execute(args) {
|
|
37
|
-
const { session, agentId, toolName, tool, input, step = 0, turn = 0, toolCallHistory = [], } = args;
|
|
38
|
-
const toolCallId = args.toolCallId ?? crypto.randomUUID();
|
|
39
|
-
const idempotencyKey = this.buildIdempotencyKey({
|
|
40
|
-
sessionId: session.id,
|
|
41
|
-
agentId,
|
|
42
|
-
step,
|
|
43
|
-
toolName,
|
|
44
|
-
toolCallId,
|
|
45
|
-
});
|
|
46
|
-
const callRecord = {
|
|
47
|
-
toolCallId,
|
|
48
|
-
toolName,
|
|
49
|
-
args: input,
|
|
50
|
-
idempotencyKey,
|
|
51
|
-
success: true,
|
|
52
|
-
timestamp: Date.now(),
|
|
53
|
-
};
|
|
54
|
-
// Enforcement check
|
|
55
|
-
const enforcement = await this.enforcer.check(callRecord, {
|
|
56
|
-
previousCalls: toolCallHistory,
|
|
57
|
-
currentStep: step,
|
|
58
|
-
sessionState: session.state ?? {},
|
|
59
|
-
});
|
|
60
|
-
if (!enforcement.allowed) {
|
|
61
|
-
const reason = enforcement.reason ?? 'Tool call blocked by enforcement';
|
|
62
|
-
callRecord.success = false;
|
|
63
|
-
callRecord.error = new Error(reason);
|
|
64
|
-
toolCallHistory.push(callRecord);
|
|
65
|
-
const runContext = {
|
|
66
|
-
session,
|
|
67
|
-
agentId,
|
|
68
|
-
stepCount: step,
|
|
69
|
-
totalTokens: 0,
|
|
70
|
-
handoffStack: [],
|
|
71
|
-
startTime: Date.now(),
|
|
72
|
-
consecutiveErrors: 0,
|
|
73
|
-
toolCallHistory,
|
|
74
|
-
};
|
|
75
|
-
await this.hookRunner.onToolError(runContext, callRecord, callRecord.error);
|
|
76
|
-
throw callRecord.error;
|
|
77
|
-
}
|
|
78
|
-
// Build enriched options for the tool's execute function
|
|
79
|
-
if (!('execute' in tool) || typeof tool.execute !== 'function') {
|
|
80
|
-
throw new Error(`Tool "${toolName}" does not have an execute function`);
|
|
81
|
-
}
|
|
82
|
-
const enrichedOptions = this.withToolExecutionMetadata(undefined, { session, agentId, step, turn, toolName, toolCallId, idempotencyKey });
|
|
83
|
-
try {
|
|
84
|
-
const timeoutMs = tool.timeout ??
|
|
85
|
-
this.defaultToolTimeoutMs ??
|
|
86
|
-
30_000;
|
|
87
|
-
const exec = tool.execute.bind(tool);
|
|
88
|
-
const result = await Promise.race([
|
|
89
|
-
exec(input, enrichedOptions),
|
|
90
|
-
new Promise((_, reject) => {
|
|
91
|
-
const timer = setTimeout(() => reject(new ToolTimeoutError(toolName, timeoutMs)), timeoutMs);
|
|
92
|
-
if (typeof timer === 'object' && timer !== null && 'unref' in timer) {
|
|
93
|
-
timer.unref();
|
|
94
|
-
}
|
|
95
|
-
}),
|
|
96
|
-
]);
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
console.error(`[ToolExecutor] Tool execution failed for ${toolName}:`, error);
|
|
101
|
-
throw error;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
buildIdempotencyKey(args) {
|
|
105
|
-
return `${args.sessionId}:${args.agentId}:${args.step}:${args.toolName}:${args.toolCallId}`;
|
|
106
|
-
}
|
|
107
|
-
withToolExecutionMetadata(options, ctx) {
|
|
108
|
-
const baseOptions = options ?? {
|
|
109
|
-
toolCallId: ctx.toolCallId,
|
|
110
|
-
messages: [],
|
|
111
|
-
};
|
|
112
|
-
const existingContext = isRecord(baseOptions.experimental_context)
|
|
113
|
-
? baseOptions.experimental_context
|
|
114
|
-
: {};
|
|
115
|
-
return {
|
|
116
|
-
...baseOptions,
|
|
117
|
-
toolCallId: ctx.toolCallId,
|
|
118
|
-
experimental_context: {
|
|
119
|
-
...existingContext,
|
|
120
|
-
session: ctx.session,
|
|
121
|
-
sessionId: ctx.session.id,
|
|
122
|
-
agentId: ctx.agentId,
|
|
123
|
-
step: ctx.step,
|
|
124
|
-
turn: ctx.turn,
|
|
125
|
-
toolName: ctx.toolName,
|
|
126
|
-
toolCallId: ctx.toolCallId,
|
|
127
|
-
idempotencyKey: ctx.idempotencyKey,
|
|
128
|
-
memoryService: this.memoryService,
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { SessionStore } from '../session/SessionStore.js';
|
|
2
|
-
import type { MemoryService } from '../memory/MemoryService.js';
|
|
3
|
-
import type { EnforcementRule, HarnessHooks } from '../types/index.js';
|
|
4
|
-
import type { ToolExecutor } from './ToolExecutor.js';
|
|
5
|
-
import type { ConversationState } from './ConversationState.js';
|
|
6
|
-
import type { ConversationEventLog } from './ConversationEventLog.js';
|
|
7
|
-
import type { AgentStateController } from './AgentStateController.js';
|
|
8
|
-
/**
|
|
9
|
-
* Configuration for creating a foundation service bundle.
|
|
10
|
-
*/
|
|
11
|
-
export interface FoundationConfig {
|
|
12
|
-
sessionStore?: SessionStore;
|
|
13
|
-
defaultAgentId?: string;
|
|
14
|
-
enforcementRules?: EnforcementRule[];
|
|
15
|
-
hooks?: HarnessHooks;
|
|
16
|
-
memoryService?: MemoryService;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Bundle of all foundation services. Both Runtime and VoiceEngine
|
|
20
|
-
* compose this to share operational logic.
|
|
21
|
-
*/
|
|
22
|
-
export interface Foundation {
|
|
23
|
-
toolExecutor: ToolExecutor;
|
|
24
|
-
conversationState: ConversationState;
|
|
25
|
-
eventLog: ConversationEventLog;
|
|
26
|
-
agentState: AgentStateController;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Create a foundation service bundle with default implementations.
|
|
30
|
-
* Services can be individually overridden if needed.
|
|
31
|
-
*/
|
|
32
|
-
export declare function createFoundation(config?: FoundationConfig): Foundation;
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { DefaultToolExecutor } from './DefaultToolExecutor.js';
|
|
2
|
-
import { DefaultConversationState } from './DefaultConversationState.js';
|
|
3
|
-
import { DefaultConversationEventLog } from './DefaultConversationEventLog.js';
|
|
4
|
-
import { DefaultAgentStateController } from './DefaultAgentStateController.js';
|
|
5
|
-
import { ToolEnforcer } from '../guards/ToolEnforcer.js';
|
|
6
|
-
import { defaultEnforcementRules } from '../guards/rules.js';
|
|
7
|
-
import { HookRunner } from '../hooks/HookRunner.js';
|
|
8
|
-
import { MemoryStore } from '../session/stores/MemoryStore.js';
|
|
9
|
-
/**
|
|
10
|
-
* Create a foundation service bundle with default implementations.
|
|
11
|
-
* Services can be individually overridden if needed.
|
|
12
|
-
*/
|
|
13
|
-
export function createFoundation(config = {}) {
|
|
14
|
-
const sessionStore = config.sessionStore ?? new MemoryStore();
|
|
15
|
-
const defaultAgentId = config.defaultAgentId ?? 'default';
|
|
16
|
-
const enforcer = new ToolEnforcer(config.enforcementRules ?? defaultEnforcementRules);
|
|
17
|
-
const hookRunner = new HookRunner(config.hooks);
|
|
18
|
-
return {
|
|
19
|
-
toolExecutor: new DefaultToolExecutor({
|
|
20
|
-
enforcer,
|
|
21
|
-
hookRunner,
|
|
22
|
-
memoryService: config.memoryService,
|
|
23
|
-
}),
|
|
24
|
-
conversationState: new DefaultConversationState({
|
|
25
|
-
sessionStore,
|
|
26
|
-
defaultAgentId,
|
|
27
|
-
}),
|
|
28
|
-
eventLog: new DefaultConversationEventLog({
|
|
29
|
-
sessionStore,
|
|
30
|
-
}),
|
|
31
|
-
agentState: new DefaultAgentStateController(),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { HarnessHooks, RunContext, StepResult, ToolCallRecord, HarnessStreamPart, Session, TurnUsage, ConversationOutcomeRecord, TurnEndHookResult, TurnSummary } from '../types/index.js';
|
|
2
|
-
import type { SessionEndMetadata } from '../types/telemetry.js';
|
|
3
|
-
import type { ModelMessage } from 'ai';
|
|
4
|
-
type HookErrorHandler = (hookName: string, error: Error) => void;
|
|
5
|
-
export declare class HookRunner {
|
|
6
|
-
private hooks;
|
|
7
|
-
private errorHandler;
|
|
8
|
-
constructor(hooks?: HarnessHooks, errorHandler?: HookErrorHandler);
|
|
9
|
-
/** Check if a specific hook is configured. */
|
|
10
|
-
has(hookName: string): boolean;
|
|
11
|
-
run<K extends keyof HarnessHooks>(hookName: K, ...args: NonNullable<HarnessHooks[K]> extends (...args: infer P) => unknown ? P : never): Promise<void>;
|
|
12
|
-
onStart(context: RunContext): Promise<void>;
|
|
13
|
-
onEnd(context: RunContext, result: {
|
|
14
|
-
success: boolean;
|
|
15
|
-
error?: Error;
|
|
16
|
-
}): Promise<void>;
|
|
17
|
-
onStepStart(context: RunContext, step: number): Promise<void>;
|
|
18
|
-
onStepEnd(context: RunContext, step: number, result: StepResult): Promise<void>;
|
|
19
|
-
onTokensUpdate(context: RunContext, turn: TurnUsage): Promise<void>;
|
|
20
|
-
onToolCall(context: RunContext, call: ToolCallRecord): Promise<void>;
|
|
21
|
-
onToolResult(context: RunContext, call: ToolCallRecord): Promise<void>;
|
|
22
|
-
onToolError(context: RunContext, call: ToolCallRecord, error: Error): Promise<void>;
|
|
23
|
-
onTurnEnd(context: RunContext, summary: TurnSummary): Promise<TurnEndHookResult | void>;
|
|
24
|
-
onAgentStart(context: RunContext, agentId: string): Promise<void>;
|
|
25
|
-
onAgentEnd(context: RunContext, agentId: string): Promise<void>;
|
|
26
|
-
onHandoff(context: RunContext, from: string, to: string, reason: string): Promise<void>;
|
|
27
|
-
onError(context: RunContext, error: Error): Promise<void>;
|
|
28
|
-
onMessage(context: RunContext, message: ModelMessage): Promise<void>;
|
|
29
|
-
onStreamPart(context: RunContext, part: HarnessStreamPart): Promise<void>;
|
|
30
|
-
onSessionEnd(session: Session, metadata: SessionEndMetadata): Promise<void>;
|
|
31
|
-
onConversationEnd(session: Session, outcome: ConversationOutcomeRecord): Promise<void>;
|
|
32
|
-
merge(additionalHooks: HarnessHooks): void;
|
|
33
|
-
setHooks(hooks: HarnessHooks): void;
|
|
34
|
-
getHooks(): HarnessHooks;
|
|
35
|
-
}
|
|
36
|
-
export declare function createHookRunner(hooks?: HarnessHooks, errorHandler?: HookErrorHandler): HookRunner;
|
|
37
|
-
export {};
|
package/dist/hooks/HookRunner.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
const defaultErrorHandler = (hookName, error) => {
|
|
2
|
-
console.error(`[HookRunner] Hook "${hookName}" failed:`, error.message);
|
|
3
|
-
};
|
|
4
|
-
export class HookRunner {
|
|
5
|
-
hooks;
|
|
6
|
-
errorHandler;
|
|
7
|
-
constructor(hooks = {}, errorHandler) {
|
|
8
|
-
this.hooks = hooks;
|
|
9
|
-
this.errorHandler = errorHandler ?? defaultErrorHandler;
|
|
10
|
-
}
|
|
11
|
-
/** Check if a specific hook is configured. */
|
|
12
|
-
has(hookName) {
|
|
13
|
-
return Boolean(this.hooks[hookName]);
|
|
14
|
-
}
|
|
15
|
-
async run(hookName, ...args) {
|
|
16
|
-
const hook = this.hooks[hookName];
|
|
17
|
-
if (!hook)
|
|
18
|
-
return;
|
|
19
|
-
try {
|
|
20
|
-
await hook(...args);
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
this.errorHandler(String(hookName), error);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
async onStart(context) {
|
|
27
|
-
await this.run('onStart', context);
|
|
28
|
-
}
|
|
29
|
-
async onEnd(context, result) {
|
|
30
|
-
await this.run('onEnd', context, result);
|
|
31
|
-
}
|
|
32
|
-
async onStepStart(context, step) {
|
|
33
|
-
await this.run('onStepStart', context, step);
|
|
34
|
-
}
|
|
35
|
-
async onStepEnd(context, step, result) {
|
|
36
|
-
await this.run('onStepEnd', context, step, result);
|
|
37
|
-
}
|
|
38
|
-
async onTokensUpdate(context, turn) {
|
|
39
|
-
await this.run('onTokensUpdate', context, turn);
|
|
40
|
-
}
|
|
41
|
-
async onToolCall(context, call) {
|
|
42
|
-
await this.run('onToolCall', context, call);
|
|
43
|
-
}
|
|
44
|
-
async onToolResult(context, call) {
|
|
45
|
-
await this.run('onToolResult', context, call);
|
|
46
|
-
}
|
|
47
|
-
async onToolError(context, call, error) {
|
|
48
|
-
await this.run('onToolError', context, call, error);
|
|
49
|
-
}
|
|
50
|
-
async onTurnEnd(context, summary) {
|
|
51
|
-
const hook = this.hooks.onTurnEnd;
|
|
52
|
-
if (!hook)
|
|
53
|
-
return;
|
|
54
|
-
try {
|
|
55
|
-
return await hook(context, summary);
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
this.errorHandler('onTurnEnd', error);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async onAgentStart(context, agentId) {
|
|
62
|
-
await this.run('onAgentStart', context, agentId);
|
|
63
|
-
}
|
|
64
|
-
async onAgentEnd(context, agentId) {
|
|
65
|
-
await this.run('onAgentEnd', context, agentId);
|
|
66
|
-
}
|
|
67
|
-
async onHandoff(context, from, to, reason) {
|
|
68
|
-
await this.run('onHandoff', context, from, to, reason);
|
|
69
|
-
}
|
|
70
|
-
async onError(context, error) {
|
|
71
|
-
await this.run('onError', context, error);
|
|
72
|
-
}
|
|
73
|
-
async onMessage(context, message) {
|
|
74
|
-
await this.run('onMessage', context, message);
|
|
75
|
-
}
|
|
76
|
-
async onStreamPart(context, part) {
|
|
77
|
-
await this.run('onStreamPart', context, part);
|
|
78
|
-
}
|
|
79
|
-
async onSessionEnd(session, metadata) {
|
|
80
|
-
await this.run('onSessionEnd', session, metadata);
|
|
81
|
-
}
|
|
82
|
-
async onConversationEnd(session, outcome) {
|
|
83
|
-
await this.run('onConversationEnd', session, outcome);
|
|
84
|
-
}
|
|
85
|
-
merge(additionalHooks) {
|
|
86
|
-
const hooks = this.hooks;
|
|
87
|
-
for (const [key, hook] of Object.entries(additionalHooks)) {
|
|
88
|
-
const existing = hooks[key];
|
|
89
|
-
if (!hook)
|
|
90
|
-
continue;
|
|
91
|
-
if (existing) {
|
|
92
|
-
hooks[key] = (async (...args) => {
|
|
93
|
-
await existing(...args);
|
|
94
|
-
await hook(...args);
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
hooks[key] = hook;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
setHooks(hooks) {
|
|
103
|
-
this.hooks = hooks;
|
|
104
|
-
}
|
|
105
|
-
getHooks() {
|
|
106
|
-
return { ...this.hooks };
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
export function createHookRunner(hooks, errorHandler) {
|
|
110
|
-
return new HookRunner(hooks, errorHandler);
|
|
111
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { HarnessHooks } from '../../types/index.js';
|
|
2
|
-
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
3
|
-
export declare const loggingHooks: HarnessHooks;
|
|
4
|
-
export declare function createLoggingHooks(logFn: (level: LogLevel, message: string, data?: Record<string, unknown>) => void): HarnessHooks;
|
|
5
|
-
export {};
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
function log(level, message, context, data) {
|
|
2
|
-
const entry = {
|
|
3
|
-
timestamp: new Date().toISOString(),
|
|
4
|
-
level,
|
|
5
|
-
component: 'kuralle',
|
|
6
|
-
message,
|
|
7
|
-
traceId: context?.session.id,
|
|
8
|
-
data,
|
|
9
|
-
};
|
|
10
|
-
console.log(JSON.stringify(entry));
|
|
11
|
-
}
|
|
12
|
-
export const loggingHooks = {
|
|
13
|
-
onStart: async (context) => {
|
|
14
|
-
log('info', 'Agent run started', context, {
|
|
15
|
-
sessionId: context.session.id,
|
|
16
|
-
agentId: context.agentId,
|
|
17
|
-
userId: context.session.userId,
|
|
18
|
-
});
|
|
19
|
-
},
|
|
20
|
-
onEnd: async (context, result) => {
|
|
21
|
-
const duration = Date.now() - context.startTime;
|
|
22
|
-
log('info', 'Agent run completed', context, {
|
|
23
|
-
success: result.success,
|
|
24
|
-
error: result.error?.message,
|
|
25
|
-
duration,
|
|
26
|
-
steps: context.stepCount,
|
|
27
|
-
tokens: context.totalTokens,
|
|
28
|
-
handoffs: context.handoffStack.length,
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
onStepStart: async (context, step) => {
|
|
32
|
-
log('debug', `Step ${step} started`, context, { step, agentId: context.agentId });
|
|
33
|
-
},
|
|
34
|
-
onStepEnd: async (context, step, result) => {
|
|
35
|
-
log('debug', `Step ${step} completed`, context, {
|
|
36
|
-
step,
|
|
37
|
-
finishReason: result.finishReason,
|
|
38
|
-
toolCalls: result.toolCalls.length,
|
|
39
|
-
tokens: result.tokensUsed,
|
|
40
|
-
});
|
|
41
|
-
},
|
|
42
|
-
onToolCall: async (context, call) => {
|
|
43
|
-
log('info', `Tool called: ${call.toolName}`, context, {
|
|
44
|
-
toolCallId: call.toolCallId,
|
|
45
|
-
toolName: call.toolName,
|
|
46
|
-
args: call.args,
|
|
47
|
-
});
|
|
48
|
-
},
|
|
49
|
-
onToolResult: async (context, call) => {
|
|
50
|
-
log('debug', `Tool completed: ${call.toolName}`, context, {
|
|
51
|
-
toolCallId: call.toolCallId,
|
|
52
|
-
toolName: call.toolName,
|
|
53
|
-
success: call.success,
|
|
54
|
-
durationMs: call.durationMs,
|
|
55
|
-
resultPreview: JSON.stringify(call.result)?.slice(0, 200),
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
onToolError: async (context, call, error) => {
|
|
59
|
-
log('error', `Tool failed: ${call.toolName}`, context, {
|
|
60
|
-
toolCallId: call.toolCallId,
|
|
61
|
-
toolName: call.toolName,
|
|
62
|
-
error: error.message,
|
|
63
|
-
stack: error.stack,
|
|
64
|
-
});
|
|
65
|
-
},
|
|
66
|
-
onHandoff: async (context, from, to, reason) => {
|
|
67
|
-
log('info', `Agent handoff: ${from} -> ${to}`, context, { from, to, reason });
|
|
68
|
-
},
|
|
69
|
-
onError: async (context, error) => {
|
|
70
|
-
log('error', 'Agent error', context, {
|
|
71
|
-
error: error.message,
|
|
72
|
-
stack: error.stack,
|
|
73
|
-
step: context.stepCount,
|
|
74
|
-
});
|
|
75
|
-
},
|
|
76
|
-
onAgentStart: async (context, agentId) => {
|
|
77
|
-
log('info', `Agent started: ${agentId}`, context, { agentId });
|
|
78
|
-
},
|
|
79
|
-
onAgentEnd: async (context, agentId) => {
|
|
80
|
-
log('info', `Agent ended: ${agentId}`, context, { agentId });
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
export function createLoggingHooks(logFn) {
|
|
84
|
-
const customLog = (level, message, context, data) => {
|
|
85
|
-
logFn(level, message, {
|
|
86
|
-
...data,
|
|
87
|
-
traceId: context?.session.id,
|
|
88
|
-
timestamp: new Date().toISOString(),
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
return {
|
|
92
|
-
onStart: async (ctx) => customLog('info', 'Agent started', ctx, { agentId: ctx.agentId }),
|
|
93
|
-
onEnd: async (ctx, r) => customLog('info', 'Agent ended', ctx, { success: r.success }),
|
|
94
|
-
onToolCall: async (ctx, c) => customLog('info', `Tool: ${c.toolName}`, ctx, { args: c.args }),
|
|
95
|
-
onHandoff: async (ctx, f, t, r) => customLog('info', `Handoff: ${f}->${t}`, ctx, { reason: r }),
|
|
96
|
-
onError: async (ctx, e) => customLog('error', 'Error', ctx, { error: e.message }),
|
|
97
|
-
};
|
|
98
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { HarnessHooks } from '../../types/index.js';
|
|
2
|
-
import type { Metrics } from '../../types/index.js';
|
|
3
|
-
import { InMemoryMetricsService } from '../../services/MetricsService.js';
|
|
4
|
-
export { Metrics };
|
|
5
|
-
export declare class InMemoryMetrics extends InMemoryMetricsService implements Metrics {
|
|
6
|
-
}
|
|
7
|
-
export declare function createMetricsHooks(metrics: Metrics): HarnessHooks;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { InMemoryMetricsService } from '../../services/MetricsService.js';
|
|
2
|
-
// Re-export as alias for compatibility
|
|
3
|
-
export class InMemoryMetrics extends InMemoryMetricsService {
|
|
4
|
-
}
|
|
5
|
-
export function createMetricsHooks(metrics) {
|
|
6
|
-
const toolStartTimes = new Map();
|
|
7
|
-
return {
|
|
8
|
-
onStart: async (context) => {
|
|
9
|
-
metrics.increment('agent.starts', 1, { agent: context.agentId });
|
|
10
|
-
metrics.gauge('agent.active', 1);
|
|
11
|
-
},
|
|
12
|
-
onEnd: async (context, result) => {
|
|
13
|
-
const duration = Date.now() - context.startTime;
|
|
14
|
-
metrics.increment(result.success ? 'agent.success' : 'agent.failure');
|
|
15
|
-
metrics.gauge('agent.active', -1);
|
|
16
|
-
metrics.timing('agent.duration', duration);
|
|
17
|
-
metrics.histogram('agent.steps', context.stepCount);
|
|
18
|
-
metrics.histogram('agent.tokens', context.totalTokens);
|
|
19
|
-
metrics.histogram('agent.handoffs', context.handoffStack.length);
|
|
20
|
-
},
|
|
21
|
-
onToolCall: async (_context, call) => {
|
|
22
|
-
metrics.increment('tool.calls', 1, { tool: call.toolName });
|
|
23
|
-
toolStartTimes.set(call.toolCallId, Date.now());
|
|
24
|
-
},
|
|
25
|
-
onToolResult: async (_context, call) => {
|
|
26
|
-
const startTime = toolStartTimes.get(call.toolCallId);
|
|
27
|
-
if (startTime) {
|
|
28
|
-
metrics.timing('tool.duration', Date.now() - startTime, { tool: call.toolName });
|
|
29
|
-
toolStartTimes.delete(call.toolCallId);
|
|
30
|
-
}
|
|
31
|
-
metrics.increment('tool.success', 1, { tool: call.toolName });
|
|
32
|
-
},
|
|
33
|
-
onToolError: async (_context, call) => {
|
|
34
|
-
const startTime = toolStartTimes.get(call.toolCallId);
|
|
35
|
-
if (startTime) {
|
|
36
|
-
metrics.timing('tool.duration', Date.now() - startTime, { tool: call.toolName });
|
|
37
|
-
toolStartTimes.delete(call.toolCallId);
|
|
38
|
-
}
|
|
39
|
-
metrics.increment('tool.errors', 1, { tool: call.toolName });
|
|
40
|
-
},
|
|
41
|
-
onHandoff: async (_context, from, to) => {
|
|
42
|
-
metrics.increment('agent.handoffs', 1, { from, to });
|
|
43
|
-
},
|
|
44
|
-
onError: async () => {
|
|
45
|
-
metrics.increment('agent.errors');
|
|
46
|
-
},
|
|
47
|
-
onStreamPart: async (_context, part) => {
|
|
48
|
-
// Capture flow-level metrics emitted as custom stream events
|
|
49
|
-
if (part.type === 'custom' && typeof part.name === 'string' && part.name.startsWith('flow.')) {
|
|
50
|
-
const data = part.data;
|
|
51
|
-
if (data && typeof data.durationMs === 'number') {
|
|
52
|
-
metrics.timing(part.name, data.durationMs);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
metrics.increment(part.name);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { HarnessHooks } from '../../types/index.js';
|
|
2
|
-
import type { Metrics, SessionTrace, TraceStreamEvent } from '../../types/telemetry.js';
|
|
3
|
-
export interface ObservabilityConfig {
|
|
4
|
-
/** Where to send the final SessionTrace. Default: console. */
|
|
5
|
-
exporter?: 'console' | 'json' | ((trace: SessionTrace) => Promise<void>);
|
|
6
|
-
/** Output file for `json` exporter. Default: `./.kuralle-traces/session-<id>.json` */
|
|
7
|
-
outputPath?: string;
|
|
8
|
-
/** Include message text in span events (PII risk). Default: false. */
|
|
9
|
-
includeContent?: boolean;
|
|
10
|
-
/** Optional metrics service for timings alongside spans. */
|
|
11
|
-
metrics?: Metrics;
|
|
12
|
-
/** Service name stored on spans. */
|
|
13
|
-
serviceName?: string;
|
|
14
|
-
/**
|
|
15
|
-
* Optional live trace stream (e.g. Kuralle Studio WebSocket). Fire-and-forget;
|
|
16
|
-
* keep handlers synchronous or schedule async work without blocking the harness.
|
|
17
|
-
*/
|
|
18
|
-
traceStream?: (event: TraceStreamEvent) => void;
|
|
19
|
-
}
|
|
20
|
-
export declare function createObservabilityHooks(config?: ObservabilityConfig): HarnessHooks;
|