@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.
- package/README.md +4 -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 +1 -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/collectUntilComplete.js +30 -7
- 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 +21 -2
- package/dist/flow/extraction.js +62 -7
- package/dist/flow/reduceTransition.d.ts +2 -2
- package/dist/flow/reduceTransition.js +7 -3
- package/dist/flow/runFlow.d.ts +11 -0
- package/dist/flow/runFlow.js +68 -12
- 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 +9 -14
- package/dist/index.js +5 -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 +6 -6
- package/dist/prompts/index.d.ts +1 -1
- package/dist/prompts/types.d.ts +7 -2
- package/dist/runtime/InMemoryRetrievalCache.d.ts +1 -1
- package/dist/runtime/KnowledgeProvider.d.ts +3 -2
- package/dist/runtime/KnowledgeProvider.js +54 -30
- package/dist/runtime/Runtime.d.ts +9 -1
- package/dist/runtime/Runtime.js +123 -30
- package/dist/runtime/TraceRecorder.d.ts +22 -4
- package/dist/runtime/TraceRecorder.js +65 -29
- package/dist/runtime/buildAgentToolSurface.js +1 -1
- package/dist/runtime/channels/TextDriver.js +12 -9
- package/dist/runtime/channels/executeModelTool.d.ts +6 -0
- package/dist/runtime/channels/executeModelTool.js +70 -10
- 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/streaming/hostControlSpeak.js +5 -1
- package/dist/runtime/channels/streaming/speakGated.js +33 -12
- package/dist/runtime/citations/index.d.ts +3 -3
- package/dist/runtime/closeRun.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 +39 -5
- package/dist/runtime/durable/RunStore.js +1 -1
- 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/hostLoop.js +39 -10
- package/dist/runtime/index.d.ts +1 -2
- package/dist/runtime/index.js +1 -1
- 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/runHookSafely.d.ts +3 -0
- package/dist/runtime/runHookSafely.js +19 -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/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 +71 -35
- package/dist/tools/effect/defineTool.d.ts +9 -0
- package/dist/tools/effect/defineTool.js +1 -0
- package/dist/tools/effect/errors.d.ts +2 -5
- package/dist/tools/effect/errors.js +2 -5
- package/dist/tools/fs/createFsTool.js +2 -1
- package/dist/tools/index.d.ts +0 -1
- package/dist/tools/index.js +0 -1
- package/dist/types/effectTool.d.ts +2 -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 -16
- package/dist/types/index.js +8 -13
- package/dist/types/knowledge.d.ts +213 -0
- package/dist/types/processors.d.ts +0 -58
- package/dist/types/run-context.d.ts +3 -7
- package/dist/types/runtime.d.ts +3 -74
- package/dist/types/session.d.ts +1 -1
- package/dist/types/skills.d.ts +15 -1
- package/dist/types/stream.d.ts +133 -71
- package/dist/types/stream.js +34 -1
- package/dist/types/trace.d.ts +2 -0
- package/guides/AGENTS.md +3 -3
- 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 +3 -13
- package/dist/foundation/AgentDefinition.d.ts +0 -17
- package/dist/foundation/ConversationEventLog.d.ts +0 -71
- package/dist/foundation/ConversationEventLog.js +0 -1
- 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
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import crypto from 'node:crypto';
|
|
2
|
-
import { isRecord } from '../utils/isRecord.js';
|
|
3
|
-
/** Working memory key for the runtime event log array. */
|
|
4
|
-
const EVENT_LOG_KEY = 'runtimeEventLog';
|
|
5
|
-
/** Working memory key for accumulated assistant text between flushes. */
|
|
6
|
-
const ASSISTANT_TEXT_KEY = '__ariaAssistantText';
|
|
7
|
-
/** Working memory key for turn tracking. */
|
|
8
|
-
const SESSION_TURN_KEY = '__ariaSessionTurn';
|
|
9
|
-
/** Max event entries before oldest are evicted. */
|
|
10
|
-
const MAX_ENTRIES = 2000;
|
|
11
|
-
/** Stream part types that trigger a checkpoint save. */
|
|
12
|
-
const CHECKPOINT_TYPES = new Set([
|
|
13
|
-
'tool-result',
|
|
14
|
-
'tool-error',
|
|
15
|
-
'flow-transition',
|
|
16
|
-
]);
|
|
17
|
-
/**
|
|
18
|
-
* Default conversation event log extracted from SessionEventManager + Runtime checkpoint logic.
|
|
19
|
-
*
|
|
20
|
-
* Handles:
|
|
21
|
-
* - Recording stream parts into session working memory
|
|
22
|
-
* - Text-delta accumulation and flush on terminal events
|
|
23
|
-
* - Value truncation at depth 5 for safe serialization
|
|
24
|
-
* - Checkpoint determination and persistence
|
|
25
|
-
*/
|
|
26
|
-
export class DefaultConversationEventLog {
|
|
27
|
-
sessionStore;
|
|
28
|
-
constructor(config) {
|
|
29
|
-
this.sessionStore = config.sessionStore;
|
|
30
|
-
}
|
|
31
|
-
record(context, part) {
|
|
32
|
-
// Fast path: text-delta only accumulates text — no UUID, no base object
|
|
33
|
-
if (part.type === 'text-delta') {
|
|
34
|
-
const prevRaw = context.session.workingMemory[ASSISTANT_TEXT_KEY];
|
|
35
|
-
const prev = typeof prevRaw === 'string' ? prevRaw : '';
|
|
36
|
-
context.session.workingMemory[ASSISTANT_TEXT_KEY] = prev + part.delta;
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
const base = {
|
|
40
|
-
id: crypto.randomUUID(),
|
|
41
|
-
sessionId: context.session.id,
|
|
42
|
-
agentId: context.agentId,
|
|
43
|
-
turn: this.getSessionTurn(context.session),
|
|
44
|
-
timestamp: new Date().toISOString(),
|
|
45
|
-
};
|
|
46
|
-
switch (part.type) {
|
|
47
|
-
case 'input':
|
|
48
|
-
this.appendEvent(context, { ...base, type: 'user', text: part.text, userId: part.userId });
|
|
49
|
-
return;
|
|
50
|
-
case 'tool-call':
|
|
51
|
-
this.appendEvent(context, {
|
|
52
|
-
...base,
|
|
53
|
-
type: 'tool_call',
|
|
54
|
-
toolCallId: part.toolCallId,
|
|
55
|
-
toolName: part.toolName,
|
|
56
|
-
args: this.toEventLogValue(part.args),
|
|
57
|
-
});
|
|
58
|
-
return;
|
|
59
|
-
case 'tool-result':
|
|
60
|
-
this.appendEvent(context, {
|
|
61
|
-
...base,
|
|
62
|
-
type: 'tool_result',
|
|
63
|
-
toolCallId: part.toolCallId,
|
|
64
|
-
toolName: part.toolName,
|
|
65
|
-
result: this.toEventLogValue(part.result),
|
|
66
|
-
});
|
|
67
|
-
return;
|
|
68
|
-
case 'tool-error':
|
|
69
|
-
this.appendEvent(context, {
|
|
70
|
-
...base,
|
|
71
|
-
type: 'tool_error',
|
|
72
|
-
toolCallId: part.toolCallId,
|
|
73
|
-
toolName: part.toolName,
|
|
74
|
-
error: part.error,
|
|
75
|
-
});
|
|
76
|
-
return;
|
|
77
|
-
case 'flow-transition':
|
|
78
|
-
this.appendEvent(context, {
|
|
79
|
-
...base,
|
|
80
|
-
type: 'transition',
|
|
81
|
-
kind: 'flow',
|
|
82
|
-
from: part.from,
|
|
83
|
-
to: part.to,
|
|
84
|
-
});
|
|
85
|
-
return;
|
|
86
|
-
case 'handoff':
|
|
87
|
-
this.appendEvent(context, {
|
|
88
|
-
...base,
|
|
89
|
-
type: 'transition',
|
|
90
|
-
kind: 'handoff',
|
|
91
|
-
from: part.from,
|
|
92
|
-
to: part.to,
|
|
93
|
-
reason: part.reason,
|
|
94
|
-
});
|
|
95
|
-
return;
|
|
96
|
-
case 'turn-end':
|
|
97
|
-
this.flushAssistantText(context, 'turn-end');
|
|
98
|
-
return;
|
|
99
|
-
case 'done':
|
|
100
|
-
this.flushAssistantText(context, 'done');
|
|
101
|
-
return;
|
|
102
|
-
case 'error':
|
|
103
|
-
this.flushAssistantText(context, 'error');
|
|
104
|
-
return;
|
|
105
|
-
case 'text-clear':
|
|
106
|
-
delete context.session.workingMemory[ASSISTANT_TEXT_KEY];
|
|
107
|
-
return;
|
|
108
|
-
default:
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
async checkpoint(session) {
|
|
113
|
-
const now = new Date();
|
|
114
|
-
session.updatedAt = now;
|
|
115
|
-
if (session.metadata) {
|
|
116
|
-
session.metadata.lastActiveAt = now;
|
|
117
|
-
}
|
|
118
|
-
// Strip non-serializable pending extraction promises before save —
|
|
119
|
-
// they can't survive JSON.stringify (Redis/Postgres) or structuredClone (cache).
|
|
120
|
-
const pending = session.__pendingExtractions;
|
|
121
|
-
delete session.__pendingExtractions;
|
|
122
|
-
await this.sessionStore.save(session);
|
|
123
|
-
// Restore so in-process turn tracking continues
|
|
124
|
-
if (pending?.length) {
|
|
125
|
-
session.__pendingExtractions = pending;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
shouldCheckpoint(part) {
|
|
129
|
-
return CHECKPOINT_TYPES.has(part.type);
|
|
130
|
-
}
|
|
131
|
-
cleanup(session) {
|
|
132
|
-
delete session.workingMemory[ASSISTANT_TEXT_KEY];
|
|
133
|
-
}
|
|
134
|
-
// --- Private helpers (extracted from SessionEventManager) ---
|
|
135
|
-
getSessionTurn(session) {
|
|
136
|
-
const value = session.workingMemory[SESSION_TURN_KEY];
|
|
137
|
-
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
138
|
-
}
|
|
139
|
-
appendEvent(context, entry) {
|
|
140
|
-
const current = context.session.workingMemory[EVENT_LOG_KEY];
|
|
141
|
-
let events;
|
|
142
|
-
if (Array.isArray(current)) {
|
|
143
|
-
events = current;
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
events = [];
|
|
147
|
-
context.session.workingMemory[EVENT_LOG_KEY] = events;
|
|
148
|
-
}
|
|
149
|
-
events.push(entry);
|
|
150
|
-
if (events.length > MAX_ENTRIES) {
|
|
151
|
-
events.splice(0, events.length - MAX_ENTRIES);
|
|
152
|
-
}
|
|
153
|
-
// Touch session
|
|
154
|
-
const now = new Date();
|
|
155
|
-
context.session.updatedAt = now;
|
|
156
|
-
if (context.session.metadata) {
|
|
157
|
-
context.session.metadata.lastActiveAt = now;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
flushAssistantText(context, trigger) {
|
|
161
|
-
const textRaw = context.session.workingMemory[ASSISTANT_TEXT_KEY];
|
|
162
|
-
const text = (typeof textRaw === 'string' ? textRaw : '').trim();
|
|
163
|
-
if (text.length > 0) {
|
|
164
|
-
this.appendEvent(context, {
|
|
165
|
-
id: crypto.randomUUID(),
|
|
166
|
-
sessionId: context.session.id,
|
|
167
|
-
agentId: context.agentId,
|
|
168
|
-
turn: this.getSessionTurn(context.session),
|
|
169
|
-
type: 'assistant_final',
|
|
170
|
-
trigger,
|
|
171
|
-
text,
|
|
172
|
-
timestamp: new Date().toISOString(),
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
delete context.session.workingMemory[ASSISTANT_TEXT_KEY];
|
|
176
|
-
}
|
|
177
|
-
toEventLogValue(value, depth = 0) {
|
|
178
|
-
if (value === null || value === undefined) {
|
|
179
|
-
return value;
|
|
180
|
-
}
|
|
181
|
-
if (depth >= 5) {
|
|
182
|
-
return '[truncated]';
|
|
183
|
-
}
|
|
184
|
-
if (value instanceof Date) {
|
|
185
|
-
return value.toISOString();
|
|
186
|
-
}
|
|
187
|
-
if (value instanceof Error) {
|
|
188
|
-
return { name: value.name, message: value.message };
|
|
189
|
-
}
|
|
190
|
-
if (Array.isArray(value)) {
|
|
191
|
-
return value.slice(0, 50).map(item => this.toEventLogValue(item, depth + 1));
|
|
192
|
-
}
|
|
193
|
-
if (typeof value === 'function') {
|
|
194
|
-
return '[function]';
|
|
195
|
-
}
|
|
196
|
-
if (isRecord(value)) {
|
|
197
|
-
const out = {};
|
|
198
|
-
for (const [k, v] of Object.entries(value).slice(0, 50)) {
|
|
199
|
-
out[k] = this.toEventLogValue(v, depth + 1);
|
|
200
|
-
}
|
|
201
|
-
return out;
|
|
202
|
-
}
|
|
203
|
-
return value;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { ModelMessage } from 'ai';
|
|
2
|
-
import type { ChannelId, Session, WorkingMemory } from '../types/index.js';
|
|
3
|
-
import type { SessionStore } from '../session/SessionStore.js';
|
|
4
|
-
import type { ConversationState } from './ConversationState.js';
|
|
5
|
-
export interface DefaultConversationStateConfig {
|
|
6
|
-
sessionStore: SessionStore;
|
|
7
|
-
defaultAgentId: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Default conversation state implementation extracted from Runtime.
|
|
11
|
-
*
|
|
12
|
-
* Handles:
|
|
13
|
-
* - Session load/create/save/delete via SessionStore
|
|
14
|
-
* - Message appending with normalization
|
|
15
|
-
* - Turn counting
|
|
16
|
-
* - Working memory access
|
|
17
|
-
*/
|
|
18
|
-
export declare class DefaultConversationState implements ConversationState {
|
|
19
|
-
private sessionStore;
|
|
20
|
-
private defaultAgentId;
|
|
21
|
-
constructor(config: DefaultConversationStateConfig);
|
|
22
|
-
load(sessionId: string, userId?: string): Promise<Session>;
|
|
23
|
-
save(session: Session): Promise<void>;
|
|
24
|
-
delete(sessionId: string): Promise<void>;
|
|
25
|
-
workingMemory(session: Session): WorkingMemory;
|
|
26
|
-
appendUserMessage(session: Session, text: string): void;
|
|
27
|
-
appendAssistantMessage(session: Session, text: string): void;
|
|
28
|
-
appendMessage(session: Session, message: ModelMessage): void;
|
|
29
|
-
getSessionTurn(session: Session): number;
|
|
30
|
-
bumpSessionTurn(session: Session): number;
|
|
31
|
-
touchSession(session: Session): void;
|
|
32
|
-
createSession(id: string, defaultAgentId: string, userId?: string, opts?: {
|
|
33
|
-
channelId?: ChannelId;
|
|
34
|
-
conversationId?: string;
|
|
35
|
-
}): Session;
|
|
36
|
-
}
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { SessionWorkingMemory } from '../runtime/WorkingMemory.js';
|
|
2
|
-
import { normalizeModelMessage } from '../utils/messageNormalization.js';
|
|
3
|
-
/** Internal working memory key for turn tracking. */
|
|
4
|
-
const SESSION_TURN_KEY = '__ariaSessionTurn';
|
|
5
|
-
/**
|
|
6
|
-
* Default conversation state implementation extracted from Runtime.
|
|
7
|
-
*
|
|
8
|
-
* Handles:
|
|
9
|
-
* - Session load/create/save/delete via SessionStore
|
|
10
|
-
* - Message appending with normalization
|
|
11
|
-
* - Turn counting
|
|
12
|
-
* - Working memory access
|
|
13
|
-
*/
|
|
14
|
-
export class DefaultConversationState {
|
|
15
|
-
sessionStore;
|
|
16
|
-
defaultAgentId;
|
|
17
|
-
constructor(config) {
|
|
18
|
-
this.sessionStore = config.sessionStore;
|
|
19
|
-
this.defaultAgentId = config.defaultAgentId;
|
|
20
|
-
}
|
|
21
|
-
async load(sessionId, userId) {
|
|
22
|
-
const existing = await this.sessionStore.get(sessionId);
|
|
23
|
-
if (existing) {
|
|
24
|
-
return existing;
|
|
25
|
-
}
|
|
26
|
-
return this.createSession(sessionId, this.defaultAgentId, userId);
|
|
27
|
-
}
|
|
28
|
-
async save(session) {
|
|
29
|
-
this.touchSession(session);
|
|
30
|
-
await this.sessionStore.save(session);
|
|
31
|
-
}
|
|
32
|
-
async delete(sessionId) {
|
|
33
|
-
await this.sessionStore.delete(sessionId);
|
|
34
|
-
}
|
|
35
|
-
workingMemory(session) {
|
|
36
|
-
return new SessionWorkingMemory(session);
|
|
37
|
-
}
|
|
38
|
-
appendUserMessage(session, text) {
|
|
39
|
-
const message = {
|
|
40
|
-
role: 'user',
|
|
41
|
-
content: [{ type: 'text', text }],
|
|
42
|
-
};
|
|
43
|
-
this.appendMessage(session, message);
|
|
44
|
-
}
|
|
45
|
-
appendAssistantMessage(session, text) {
|
|
46
|
-
const message = {
|
|
47
|
-
role: 'assistant',
|
|
48
|
-
content: [{ type: 'text', text }],
|
|
49
|
-
};
|
|
50
|
-
this.appendMessage(session, message);
|
|
51
|
-
}
|
|
52
|
-
appendMessage(session, message) {
|
|
53
|
-
const normalized = normalizeModelMessage(message);
|
|
54
|
-
if (normalized) {
|
|
55
|
-
session.messages.push(normalized);
|
|
56
|
-
this.touchSession(session);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
getSessionTurn(session) {
|
|
60
|
-
const value = session.workingMemory[SESSION_TURN_KEY];
|
|
61
|
-
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
62
|
-
}
|
|
63
|
-
bumpSessionTurn(session) {
|
|
64
|
-
const next = this.getSessionTurn(session) + 1;
|
|
65
|
-
session.workingMemory[SESSION_TURN_KEY] = next;
|
|
66
|
-
this.touchSession(session);
|
|
67
|
-
return next;
|
|
68
|
-
}
|
|
69
|
-
touchSession(session) {
|
|
70
|
-
const now = new Date();
|
|
71
|
-
session.updatedAt = now;
|
|
72
|
-
if (session.metadata) {
|
|
73
|
-
session.metadata.lastActiveAt = now;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
createSession(id, defaultAgentId, userId, opts) {
|
|
77
|
-
const now = new Date();
|
|
78
|
-
const channelId = opts?.channelId ?? 'web';
|
|
79
|
-
const conversationId = opts?.conversationId ?? id;
|
|
80
|
-
return {
|
|
81
|
-
id,
|
|
82
|
-
conversationId,
|
|
83
|
-
channelId,
|
|
84
|
-
userId,
|
|
85
|
-
messages: [],
|
|
86
|
-
createdAt: now,
|
|
87
|
-
updatedAt: now,
|
|
88
|
-
workingMemory: {},
|
|
89
|
-
currentAgent: defaultAgentId,
|
|
90
|
-
activeAgentId: defaultAgentId,
|
|
91
|
-
state: {},
|
|
92
|
-
metadata: {
|
|
93
|
-
createdAt: now,
|
|
94
|
-
lastActiveAt: now,
|
|
95
|
-
totalTokens: 0,
|
|
96
|
-
totalSteps: 0,
|
|
97
|
-
handoffHistory: [],
|
|
98
|
-
},
|
|
99
|
-
agentStates: {},
|
|
100
|
-
handoffHistory: [],
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import type { Session, ToolCallRecord } from '../types/index.js';
|
|
2
|
-
import type { ToolExecutor, ExecutableTool } from './ToolExecutor.js';
|
|
3
|
-
import type { ToolEnforcer } from '../guards/ToolEnforcer.js';
|
|
4
|
-
import type { HookRunner } from '../hooks/HookRunner.js';
|
|
5
|
-
import type { MemoryService } from '../memory/MemoryService.js';
|
|
6
|
-
export interface DefaultToolExecutorConfig {
|
|
7
|
-
enforcer: ToolEnforcer;
|
|
8
|
-
hookRunner: HookRunner;
|
|
9
|
-
memoryService?: MemoryService;
|
|
10
|
-
/** Default timeout in milliseconds for tool execution. Defaults to 30000 (30s). */
|
|
11
|
-
defaultToolTimeoutMs?: number;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Error thrown when a tool execution exceeds the configured timeout.
|
|
15
|
-
*/
|
|
16
|
-
export declare class ToolTimeoutError extends Error {
|
|
17
|
-
readonly toolName: string;
|
|
18
|
-
readonly timeoutMs: number;
|
|
19
|
-
constructor(toolName: string, timeoutMs: number);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Default tool executor extracted from Runtime.wrapToolsWithEnforcement().
|
|
23
|
-
*
|
|
24
|
-
* Handles:
|
|
25
|
-
* - Enforcement checks via ToolEnforcer
|
|
26
|
-
* - Idempotency key generation
|
|
27
|
-
* - Context enrichment (experimental_context)
|
|
28
|
-
* - Error propagation via HookRunner
|
|
29
|
-
*/
|
|
30
|
-
export declare class DefaultToolExecutor implements ToolExecutor {
|
|
31
|
-
private enforcer;
|
|
32
|
-
private hookRunner;
|
|
33
|
-
private memoryService?;
|
|
34
|
-
private defaultToolTimeoutMs?;
|
|
35
|
-
constructor(config: DefaultToolExecutorConfig);
|
|
36
|
-
execute(args: {
|
|
37
|
-
session: Session;
|
|
38
|
-
userId?: string;
|
|
39
|
-
agentId: string;
|
|
40
|
-
toolName: string;
|
|
41
|
-
tool: ExecutableTool;
|
|
42
|
-
input: unknown;
|
|
43
|
-
toolCallId?: string;
|
|
44
|
-
abortSignal?: AbortSignal;
|
|
45
|
-
step?: number;
|
|
46
|
-
turn?: number;
|
|
47
|
-
toolCallHistory?: ToolCallRecord[];
|
|
48
|
-
}): Promise<unknown>;
|
|
49
|
-
buildIdempotencyKey(args: {
|
|
50
|
-
sessionId: string;
|
|
51
|
-
agentId: string;
|
|
52
|
-
step: number;
|
|
53
|
-
toolName: string;
|
|
54
|
-
toolCallId: string;
|
|
55
|
-
}): string;
|
|
56
|
-
private withToolExecutionMetadata;
|
|
57
|
-
}
|
|
@@ -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 {};
|