@kuralle-agents/core 0.3.11 → 0.3.12
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/dist/runtime/Runtime.js +1 -0
- package/dist/runtime/channels/TextDriver.js +3 -3
- package/dist/runtime/channels/VoiceDriver.js +3 -2
- package/dist/runtime/channels/extractionTurn.js +8 -1
- package/dist/runtime/ctx.d.ts +1 -0
- package/dist/runtime/ctx.js +1 -0
- package/dist/runtime/hostLoop.js +1 -1
- package/dist/runtime/select.js +1 -0
- package/dist/types/agentConfig.d.ts +4 -0
- package/dist/types/run-context.d.ts +2 -0
- package/package.json +2 -2
package/dist/runtime/Runtime.js
CHANGED
|
@@ -109,8 +109,7 @@ export class TextDriver {
|
|
|
109
109
|
// voice are identical). The model's prose is discarded; the user-facing
|
|
110
110
|
// question is emitted deterministically by the flow engine (CollectNode.ask).
|
|
111
111
|
runExtraction(node, ctx) {
|
|
112
|
-
|
|
113
|
-
return runSilentExtraction(node, ctx, model, resolveMaxSteps(ctx.limits, this.maxSteps));
|
|
112
|
+
return runSilentExtraction(node, ctx, ctx.controlModel, resolveMaxSteps(ctx.limits, this.maxSteps));
|
|
114
113
|
}
|
|
115
114
|
async runStructured(node, ctx) {
|
|
116
115
|
const base = composeSystem(ctx.baseInstructions, resolveInstructions(node.instructions, ctx.runState.state), ctx.runState.state);
|
|
@@ -125,10 +124,11 @@ export class TextDriver {
|
|
|
125
124
|
.join(', ')}. Respond with only the chosen id, nothing else.`
|
|
126
125
|
: base;
|
|
127
126
|
const { object } = await generateObject({
|
|
128
|
-
model: ctx.
|
|
127
|
+
model: ctx.controlModel,
|
|
129
128
|
schema,
|
|
130
129
|
system,
|
|
131
130
|
messages: ctx.runState.messages,
|
|
131
|
+
temperature: 0,
|
|
132
132
|
abortSignal: ctx.abortSignal,
|
|
133
133
|
});
|
|
134
134
|
return object;
|
|
@@ -75,10 +75,11 @@ export class VoiceDriver {
|
|
|
75
75
|
.join(', ')}. Respond with only the chosen id, nothing else.`
|
|
76
76
|
: base;
|
|
77
77
|
const { object } = await generateObject({
|
|
78
|
-
model: ctx.
|
|
78
|
+
model: ctx.controlModel,
|
|
79
79
|
schema,
|
|
80
80
|
system,
|
|
81
81
|
messages: ctx.runState.messages,
|
|
82
|
+
temperature: 0,
|
|
82
83
|
abortSignal: ctx.abortSignal,
|
|
83
84
|
});
|
|
84
85
|
return object;
|
|
@@ -89,7 +90,7 @@ export class VoiceDriver {
|
|
|
89
90
|
// behavior to TextDriver — voice and text emit the same structural events; the
|
|
90
91
|
// user-facing question is the deterministic CollectNode.ask, synthesized after.
|
|
91
92
|
runExtraction(node, ctx) {
|
|
92
|
-
return runSilentExtraction(node, ctx, ctx.
|
|
93
|
+
return runSilentExtraction(node, ctx, ctx.controlModel, resolveMaxSteps(ctx.limits, this.maxSteps));
|
|
93
94
|
}
|
|
94
95
|
async awaitUser(ctx) {
|
|
95
96
|
if (this.pendingBargeInInput != null) {
|
|
@@ -20,7 +20,14 @@ export async function runSilentExtraction(node, ctx, model, maxSteps) {
|
|
|
20
20
|
const aiTools = resolveExtractionTools(node);
|
|
21
21
|
const out = { text: '', toolResults: [] };
|
|
22
22
|
for (let step = 0; step < maxSteps; step += 1) {
|
|
23
|
-
const result = streamText({
|
|
23
|
+
const result = streamText({
|
|
24
|
+
model,
|
|
25
|
+
system,
|
|
26
|
+
messages,
|
|
27
|
+
tools: aiTools,
|
|
28
|
+
temperature: 0,
|
|
29
|
+
abortSignal: ctx.abortSignal,
|
|
30
|
+
});
|
|
24
31
|
for await (const part of result.fullStream) {
|
|
25
32
|
// Intentionally NOT handling 'text-delta' — extraction never speaks.
|
|
26
33
|
if (part.type === 'error') {
|
package/dist/runtime/ctx.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export interface CtxDeps {
|
|
|
20
20
|
toolExecutor: EffectToolExecutor;
|
|
21
21
|
hookRunner?: HookRunner;
|
|
22
22
|
model: LanguageModel;
|
|
23
|
+
controlModel?: LanguageModel;
|
|
23
24
|
refinementPolicies?: RefinementCapability[];
|
|
24
25
|
validationPolicies?: ValidationCapability[];
|
|
25
26
|
inputProcessors?: InputProcessor[];
|
package/dist/runtime/ctx.js
CHANGED
|
@@ -99,6 +99,7 @@ function makeCtx(deps) {
|
|
|
99
99
|
toolExecutor: deps.toolExecutor,
|
|
100
100
|
hookRunner: deps.hookRunner ?? {},
|
|
101
101
|
model: deps.model,
|
|
102
|
+
controlModel: deps.controlModel ?? deps.model,
|
|
102
103
|
refinementPolicies: deps.refinementPolicies ?? [],
|
|
103
104
|
validationPolicies: deps.validationPolicies ?? [],
|
|
104
105
|
inputProcessors: deps.inputProcessors ?? [],
|
package/dist/runtime/hostLoop.js
CHANGED
|
@@ -21,7 +21,7 @@ export async function hostLoop(options) {
|
|
|
21
21
|
const selection = await select({
|
|
22
22
|
agent,
|
|
23
23
|
run,
|
|
24
|
-
model: agent.routing?.model ??
|
|
24
|
+
model: agent.routing?.model ?? ctx.controlModel,
|
|
25
25
|
alwaysRoute,
|
|
26
26
|
});
|
|
27
27
|
if (selection.kind === 'enterFlow') {
|
package/dist/runtime/select.js
CHANGED
|
@@ -33,6 +33,7 @@ export async function selectHostTarget(options) {
|
|
|
33
33
|
const { object } = await generateObject({
|
|
34
34
|
model,
|
|
35
35
|
schema: selectionSchema,
|
|
36
|
+
temperature: 0,
|
|
36
37
|
system: 'You are an internal routing classifier. Choose exactly one action. ' +
|
|
37
38
|
'Output schema fields only — never user-facing prose. ' +
|
|
38
39
|
'Prefer route when a route condition clearly matches; else enterFlow when a flow description matches an uncompleted flow; else keep. Never re-enter a completed flow.',
|
|
@@ -14,6 +14,10 @@ export interface AgentConfig {
|
|
|
14
14
|
description?: string;
|
|
15
15
|
instructions?: Instructions;
|
|
16
16
|
model?: LanguageModel;
|
|
17
|
+
/** Optional model for the control path (routing, decide, extraction), run at
|
|
18
|
+
* temperature 0 for determinism. Defaults to `model` (the speaker) when unset.
|
|
19
|
+
* Set this to pin control to a reliable provider independent of the speaker. */
|
|
20
|
+
controlModel?: LanguageModel;
|
|
17
21
|
tools?: ToolSet;
|
|
18
22
|
effectTools?: Record<string, AnyTool>;
|
|
19
23
|
/** Safe, always-available tools made model-visible in EVERY speaking node turn
|
|
@@ -51,6 +51,8 @@ export interface RunContext {
|
|
|
51
51
|
toolExecutor: EffectToolExecutor;
|
|
52
52
|
hookRunner: HookRunner;
|
|
53
53
|
model: LanguageModel;
|
|
54
|
+
/** Control-path model (routing, decide, extraction) at temperature 0. */
|
|
55
|
+
controlModel: LanguageModel;
|
|
54
56
|
refinementPolicies: RefinementCapability[];
|
|
55
57
|
validationPolicies: ValidationCapability[];
|
|
56
58
|
inputProcessors: InputProcessor[];
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"url": "git+https://github.com/kuralle/kuralle-agents.git",
|
|
7
7
|
"directory": "packages/kuralle-core"
|
|
8
8
|
},
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.12",
|
|
10
10
|
"description": "A framework for structured conversational AI agents",
|
|
11
11
|
"publishConfig": {
|
|
12
12
|
"access": "public"
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"dotenv": "^16.4.0",
|
|
98
98
|
"typescript": "^5.3.0",
|
|
99
99
|
"zod": "^3.23.0",
|
|
100
|
-
"@kuralle-agents/realtime-audio": "0.3.
|
|
100
|
+
"@kuralle-agents/realtime-audio": "0.3.12"
|
|
101
101
|
},
|
|
102
102
|
"dependencies": {
|
|
103
103
|
"chrono-node": "^2.6.0",
|