@fonoster/autopilot 0.27.0 → 0.31.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 +15 -52
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -5
- package/dist/knowledge/AbstractKnowledgeBase.d.ts +3 -2
- package/dist/knowledge/AbstractKnowledgeBase.js +2 -7
- package/dist/knowledge/FilesKnowledgeBase.d.ts +1 -1
- package/dist/knowledge/MeteredEmbeddings.d.ts +47 -0
- package/dist/knowledge/MeteredEmbeddings.js +58 -0
- package/dist/knowledge/types.d.ts +1 -1
- package/dist/models/LanguageModelFactory.d.ts +5 -24
- package/dist/models/LanguageModelFactory.js +0 -1
- package/dist/models/createLanguageModel.d.ts +2 -2
- package/dist/models/createLanguageModel.js +2 -2
- package/dist/models/evaluations/createEvalEffectiveConfig.d.ts +10 -106
- package/dist/models/evaluations/createEvalEffectiveConfig.js +47 -7
- package/dist/models/evaluations/createEvaluateIntelligence.d.ts +21 -20
- package/dist/models/evaluations/createEvaluateIntelligence.js +53 -23
- package/dist/models/evaluations/createTestTextSimilarity.d.ts +7 -1
- package/dist/models/evaluations/createTestTextSimilarity.js +19 -1
- package/dist/models/evaluations/evalTestCases.d.ts +2 -2
- package/dist/models/evaluations/evalTestCases.js +7 -7
- package/dist/models/evaluations/evaluateScenario.js +2 -2
- package/dist/models/evaluations/evaluateStep.d.ts +1 -1
- package/dist/models/evaluations/evaluateStep.js +2 -2
- package/dist/models/evaluations/extractAiResponse.d.ts +2 -3
- package/dist/models/evaluations/extractAiResponse.js +3 -3
- package/dist/models/evaluations/index.d.ts +1 -0
- package/dist/models/evaluations/index.js +1 -0
- package/dist/models/evaluations/runEval.d.ts +2 -20
- package/dist/models/evaluations/runEval.js +7 -7
- package/dist/models/evaluations/session/EvalSession.d.ts +73 -0
- package/dist/models/evaluations/session/EvalSession.js +134 -0
- package/dist/models/evaluations/session/evaluateSessionScenario.d.ts +58 -0
- package/dist/models/evaluations/session/evaluateSessionScenario.js +182 -0
- package/dist/{vad → models/evaluations/session}/index.d.ts +3 -2
- package/dist/{vad → models/evaluations/session}/index.js +3 -2
- package/dist/models/evaluations/session/runSessionEval.d.ts +20 -0
- package/dist/models/evaluations/session/runSessionEval.js +59 -0
- package/dist/models/evaluations/textSimilaryPrompt.d.ts +1 -1
- package/dist/models/evaluations/textSimilaryPrompt.js +1 -1
- package/dist/models/evaluations/types.d.ts +7 -6
- package/dist/models/types.d.ts +19 -1
- package/dist/session/Agent.d.ts +173 -0
- package/dist/session/Agent.js +548 -0
- package/dist/{loadAssistantFromAPI.d.ts → session/AsyncQueue.d.ts} +12 -7
- package/dist/session/AsyncQueue.js +67 -0
- package/dist/{machine/guards/index.d.ts → session/config.d.ts} +2 -2
- package/dist/session/config.js +27 -0
- package/dist/session/createAutopilot.d.ts +48 -0
- package/dist/session/createAutopilot.js +151 -0
- package/dist/session/hosted.d.ts +454 -0
- package/dist/session/hosted.js +501 -0
- package/dist/{assistants → session}/index.d.ts +11 -2
- package/dist/{machine/actors → session}/index.js +11 -3
- package/dist/{machine/actions/appendSpeech.js → session/knowledge.d.ts} +14 -17
- package/dist/session/knowledge.js +10 -0
- package/dist/session/llm.d.ts +113 -0
- package/dist/session/llm.js +127 -0
- package/dist/session/machine.d.ts +206 -0
- package/dist/session/machine.js +126 -0
- package/dist/session/main.js +45 -0
- package/dist/session/meteredThink.d.ts +45 -0
- package/dist/session/meteredThink.js +125 -0
- package/dist/session/sentences.d.ts +5 -0
- package/dist/session/sentences.js +53 -0
- package/dist/session/telemetry.d.ts +34 -0
- package/dist/session/telemetry.js +55 -0
- package/dist/{machine/actors/index.d.ts → session/think.d.ts} +2 -3
- package/dist/{machine/actions/announceSystemError.js → session/think.js} +8 -10
- package/dist/session/tools.d.ts +22 -0
- package/dist/session/tools.js +83 -0
- package/dist/tools/builtin/transferToolDefinition.js +1 -1
- package/dist/voice/index.d.ts +0 -1
- package/dist/voice/index.js +0 -1
- package/dist/voice/types.d.ts +5 -18
- package/package.json +15 -16
- package/dist/Autopilot.d.ts +0 -14
- package/dist/Autopilot.js +0 -133
- package/dist/assistants/index.js +0 -36
- package/dist/assistants/loadAndValidateAssistant.d.ts +0 -3
- package/dist/assistants/loadAndValidateAssistant.js +0 -49
- package/dist/assistants/types.d.ts +0 -24
- package/dist/assistants/types.js +0 -2
- package/dist/envs.d.ts +0 -15
- package/dist/envs.js +0 -78
- package/dist/handleVoiceRequest.d.ts +0 -3
- package/dist/handleVoiceRequest.js +0 -167
- package/dist/loadAssistantConfigFromFile.d.ts +0 -3
- package/dist/loadAssistantConfigFromFile.js +0 -68
- package/dist/loadAssistantFromAPI.js +0 -98
- package/dist/machine/actions/announceSystemError.d.ts +0 -4
- package/dist/machine/actions/appendSpeech.d.ts +0 -1
- package/dist/machine/actions/cleanSpeech.d.ts +0 -1
- package/dist/machine/actions/cleanSpeech.js +0 -23
- package/dist/machine/actions/goodbye.d.ts +0 -4
- package/dist/machine/actions/goodbye.js +0 -31
- package/dist/machine/actions/increaseIdleTimeoutCount.d.ts +0 -1
- package/dist/machine/actions/increaseIdleTimeoutCount.js +0 -31
- package/dist/machine/actions/index.d.ts +0 -26
- package/dist/machine/actions/index.js +0 -37
- package/dist/machine/actions/interruptPlayback.d.ts +0 -4
- package/dist/machine/actions/interruptPlayback.js +0 -43
- package/dist/machine/actions/resetIdleTimeoutCount.d.ts +0 -1
- package/dist/machine/actions/resetIdleTimeoutCount.js +0 -31
- package/dist/machine/actions/resetState.d.ts +0 -1
- package/dist/machine/actions/resetState.js +0 -32
- package/dist/machine/actors/doAnnounceIdleTimeout.d.ts +0 -4
- package/dist/machine/actors/doAnnounceIdleTimeout.js +0 -41
- package/dist/machine/actors/doGreetUser.d.ts +0 -4
- package/dist/machine/actors/doGreetUser.js +0 -45
- package/dist/machine/actors/doProcessUserRequest.d.ts +0 -4
- package/dist/machine/actors/doProcessUserRequest.js +0 -75
- package/dist/machine/context.d.ts +0 -52
- package/dist/machine/context.js +0 -28
- package/dist/machine/delays.d.ts +0 -30
- package/dist/machine/delays.js +0 -37
- package/dist/machine/guards/hasSpeechResult.d.ts +0 -4
- package/dist/machine/guards/hasSpeechResult.js +0 -30
- package/dist/machine/guards/idleTimeoutCountExceedsMax.d.ts +0 -4
- package/dist/machine/guards/idleTimeoutCountExceedsMax.js +0 -31
- package/dist/machine/guards/index.js +0 -25
- package/dist/machine/index.d.ts +0 -19
- package/dist/machine/index.js +0 -23
- package/dist/machine/machine.d.ts +0 -408
- package/dist/machine/machine.js +0 -206
- package/dist/machine/setup.d.ts +0 -328
- package/dist/machine/setup.js +0 -116
- package/dist/machine/types.d.ts +0 -54
- package/dist/machine/types.js +0 -2
- package/dist/sendConversationEndedEvent.d.ts +0 -32
- package/dist/sendConversationEndedEvent.js +0 -66
- package/dist/sendConversationStartedEvent.d.ts +0 -6
- package/dist/sendConversationStartedEvent.js +0 -63
- package/dist/server.d.ts +0 -2
- package/dist/server.js +0 -25
- package/dist/types.d.ts +0 -40
- package/dist/types.js +0 -8
- package/dist/vad/SileroVad.d.ts +0 -18
- package/dist/vad/SileroVad.js +0 -40
- package/dist/vad/SileroVadModel.d.ts +0 -14
- package/dist/vad/SileroVadModel.js +0 -83
- package/dist/vad/chunkToFloat32Array.d.ts +0 -20
- package/dist/vad/chunkToFloat32Array.js +0 -34
- package/dist/vad/createVad.d.ts +0 -3
- package/dist/vad/createVad.js +0 -126
- package/dist/vad/types.d.ts +0 -60
- package/dist/vad/types.js +0 -2
- package/dist/vadWorker.js +0 -36
- package/dist/voice/Voice.d.ts +0 -61
- package/dist/voice/Voice.js +0 -96
- package/dist/voiceServerSetup.d.ts +0 -2
- package/dist/voiceServerSetup.js +0 -29
- /package/dist/{vadWorker.d.ts → session/main.d.ts} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Agent, Recorder } from "./Agent";
|
|
2
|
+
import { SessionAgent } from "./config";
|
|
3
|
+
import { KnowledgePort } from "./knowledge";
|
|
4
|
+
import { LlmResolver } from "./llm";
|
|
5
|
+
import { UsageSink } from "./meteredThink";
|
|
6
|
+
import { Think, ThinkProvider } from "./think";
|
|
7
|
+
import { ToolPort } from "./tools";
|
|
8
|
+
import type { Session } from "@fonoster/voice";
|
|
9
|
+
/** What the hosted Autopilot knows about the app a session belongs to. */
|
|
10
|
+
export type LoadedAgent = {
|
|
11
|
+
agent: unknown;
|
|
12
|
+
/** The workspace that owns the app: scope for its own keys (BYOK) and knowledge. */
|
|
13
|
+
workspaceRef?: string;
|
|
14
|
+
};
|
|
15
|
+
export type AutopilotOptions = {
|
|
16
|
+
/** The agent for a session (validated with the session agent schema). */
|
|
17
|
+
agent?: unknown | ((session: Session) => Promise<unknown> | unknown);
|
|
18
|
+
/**
|
|
19
|
+
* The hosted path: loads the app's agent and workspace for a session; undefined means the
|
|
20
|
+
* app has no agent (the call is ended).
|
|
21
|
+
*/
|
|
22
|
+
load?: (session: Session) => Promise<LoadedAgent | undefined>;
|
|
23
|
+
/** Language models through the provider registry (task 3.1). */
|
|
24
|
+
llm?: LlmResolver;
|
|
25
|
+
/** Language model endpoints by provider name (the stand-in used before the registry). */
|
|
26
|
+
providers?: Record<string, ThinkProvider>;
|
|
27
|
+
think?: Think;
|
|
28
|
+
tools?: ToolPort;
|
|
29
|
+
/**
|
|
30
|
+
* Private destinations HTTP tools may call (host names, IPs, CIDRs); defaults to
|
|
31
|
+
* FONOSTER_ALLOWED_DESTINATIONS. Everything else must be public (RV-B2).
|
|
32
|
+
*/
|
|
33
|
+
allowedDestinations?: string[];
|
|
34
|
+
/** Finds what is relevant to the caller's question (the knowledge port). */
|
|
35
|
+
knowledge?: KnowledgePort;
|
|
36
|
+
/** Builds the knowledge port for an agent (operator wiring, task 4.1). */
|
|
37
|
+
knowledgeFor?: (agent: SessionAgent, scope: {
|
|
38
|
+
workspaceRef?: string;
|
|
39
|
+
}, usage?: UsageSink) => KnowledgePort | undefined;
|
|
40
|
+
recorder?: Recorder;
|
|
41
|
+
/** Called with each session's Agent, for tests and observability. */
|
|
42
|
+
onAgent?: (agent: Agent) => void;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Autopilot as an ordinary application (rework-autopilot A2): returns a VoiceServer handler that
|
|
46
|
+
* runs the state machine on the session's public messages only.
|
|
47
|
+
*/
|
|
48
|
+
export declare function createAutopilotHandler(options: AutopilotOptions): (session: Session) => Promise<void>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAutopilotHandler = createAutopilotHandler;
|
|
4
|
+
/**
|
|
5
|
+
* Copyright (C) 2025 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const logger_1 = require("@fonoster/logger");
|
|
23
|
+
const xstate_1 = require("xstate");
|
|
24
|
+
const Agent_1 = require("./Agent");
|
|
25
|
+
const config_1 = require("./config");
|
|
26
|
+
const llm_1 = require("./llm");
|
|
27
|
+
const machine_1 = require("./machine");
|
|
28
|
+
const meteredThink_1 = require("./meteredThink");
|
|
29
|
+
const telemetry_1 = require("./telemetry");
|
|
30
|
+
const think_1 = require("./think");
|
|
31
|
+
const tools_1 = require("./tools");
|
|
32
|
+
const logger = (0, logger_1.getLogger)({ service: "autopilot", filePath: __filename });
|
|
33
|
+
/**
|
|
34
|
+
* Autopilot as an ordinary application (rework-autopilot A2): returns a VoiceServer handler that
|
|
35
|
+
* runs the state machine on the session's public messages only.
|
|
36
|
+
*/
|
|
37
|
+
function createAutopilotHandler(options) {
|
|
38
|
+
const run = createSessionRunner(options);
|
|
39
|
+
return async (session) => {
|
|
40
|
+
// The session span joins the call's trace when AppBridge sent a traceparent.
|
|
41
|
+
const span = telemetry_1.telemetry.startCall(session.callRef, "autopilot.session", {
|
|
42
|
+
"fonoster.app_ref": session.appRef,
|
|
43
|
+
"fonoster.session_ref": session.sessionRef
|
|
44
|
+
}, session.traceparent);
|
|
45
|
+
try {
|
|
46
|
+
await run(session);
|
|
47
|
+
span.end();
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
span.end({}, e.message);
|
|
51
|
+
throw e;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function createSessionRunner(options) {
|
|
56
|
+
return async (session) => {
|
|
57
|
+
// Listen before any await: turn events that arrive while the agent and model load are
|
|
58
|
+
// held and delivered once the machine runs.
|
|
59
|
+
const early = [];
|
|
60
|
+
let deliver = (event) => early.push(event);
|
|
61
|
+
session.on("turn.user_started", () => deliver({ type: "TURN_USER_STARTED" }));
|
|
62
|
+
session.on("turn.likely_ended", (e) => deliver({ type: "TURN_LIKELY_ENDED", text: e.text }));
|
|
63
|
+
session.on("turn.resumed", () => deliver({ type: "TURN_RESUMED" }));
|
|
64
|
+
// A turn with no words (line noise, an abandoned start) is not an answer: no reply, and the
|
|
65
|
+
// idle count is kept, so a silent call still ends.
|
|
66
|
+
session.on("turn.ended", (e) => {
|
|
67
|
+
if (e.text.trim())
|
|
68
|
+
deliver({ type: "TURN_ENDED", text: e.text });
|
|
69
|
+
});
|
|
70
|
+
session.on("turn.backchannel", () => deliver({ type: "TURN_BACKCHANNEL" }));
|
|
71
|
+
// Open drains of interrupted replies stop with the session: their usage can no longer
|
|
72
|
+
// reach the call (add-usage-metering D6).
|
|
73
|
+
const closed = new AbortController();
|
|
74
|
+
const ended = new Promise((resolve) => session.on("end", () => {
|
|
75
|
+
closed.abort();
|
|
76
|
+
deliver({ type: "SESSION_END" });
|
|
77
|
+
resolve();
|
|
78
|
+
}));
|
|
79
|
+
const loaded = options.load
|
|
80
|
+
? await options.load(session)
|
|
81
|
+
: {
|
|
82
|
+
agent: typeof options.agent === "function"
|
|
83
|
+
? await options.agent(session)
|
|
84
|
+
: options.agent
|
|
85
|
+
};
|
|
86
|
+
if (!loaded) {
|
|
87
|
+
logger.warn("no agent for this app; ending the call", {
|
|
88
|
+
appRef: session.appRef,
|
|
89
|
+
callRef: session.callRef
|
|
90
|
+
});
|
|
91
|
+
await session.hangup().catch(() => undefined);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const agentConfig = config_1.sessionAgentSchema.parse(loaded.agent);
|
|
95
|
+
const scope = { workspaceRef: loaded.workspaceRef };
|
|
96
|
+
const recorder = options.recorder ?? (0, Agent_1.sessionRecorder)(session);
|
|
97
|
+
const settings = {
|
|
98
|
+
temperature: agentConfig.languageModel.temperature,
|
|
99
|
+
maxTokens: agentConfig.languageModel.maxTokens
|
|
100
|
+
};
|
|
101
|
+
const sink = {
|
|
102
|
+
usage: (lines) => recorder.usage?.(lines),
|
|
103
|
+
missing: (catalogId) => {
|
|
104
|
+
telemetry_1.telemetry.count("fonoster.usage.missing", 1, { catalog_id: catalogId });
|
|
105
|
+
recorder.note({ type: "usage_missing", catalogId });
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
let think = options.think;
|
|
109
|
+
if (!think && options.llm) {
|
|
110
|
+
try {
|
|
111
|
+
const resolved = await options.llm.resolve(agentConfig.languageModel.model, settings, scope);
|
|
112
|
+
think = (0, meteredThink_1.meteredThink)(resolved.think, { catalogId: resolved.id, keySource: resolved.keySource }, sink, { closed: closed.signal });
|
|
113
|
+
if (resolved.event)
|
|
114
|
+
recorder.note(resolved.event);
|
|
115
|
+
}
|
|
116
|
+
catch (e) {
|
|
117
|
+
// A model the registry cannot serve: apologise and end the call, never a silent line.
|
|
118
|
+
logger.error(`autopilot cannot reach its language model: ${e.message}`);
|
|
119
|
+
recorder.note({
|
|
120
|
+
type: "llm.unavailable",
|
|
121
|
+
reason: e instanceof llm_1.KeyUnavailableError ? e.reason : e.message
|
|
122
|
+
});
|
|
123
|
+
await session
|
|
124
|
+
.say(agentConfig.conversationSettings.systemErrorMessage, {
|
|
125
|
+
interruptible: false
|
|
126
|
+
})
|
|
127
|
+
.catch(() => undefined);
|
|
128
|
+
await session.hangup().catch(() => undefined);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
think ?? (think = (0, meteredThink_1.meteredThink)((0, think_1.resolveThink)(agentConfig.languageModel.model, options.providers ?? {}, settings), { catalogId: agentConfig.languageModel.model, keySource: "platform" }, sink, { closed: closed.signal }));
|
|
133
|
+
const agent = new Agent_1.Agent(session, agentConfig, think, options.tools ??
|
|
134
|
+
new tools_1.HttpToolPort(agentConfig.languageModel.tools, {
|
|
135
|
+
allow: options.allowedDestinations
|
|
136
|
+
}), recorder, options.knowledge ?? options.knowledgeFor?.(agentConfig, scope, sink));
|
|
137
|
+
options.onAgent?.(agent);
|
|
138
|
+
const actor = (0, xstate_1.createActor)(machine_1.autopilotMachine, { input: { agent } });
|
|
139
|
+
agent.send = (event) => actor.send(event);
|
|
140
|
+
actor.subscribe((state) => logger.verbose("autopilot state", {
|
|
141
|
+
callRef: session.callRef,
|
|
142
|
+
state: state.value
|
|
143
|
+
}));
|
|
144
|
+
actor.start();
|
|
145
|
+
deliver = (event) => actor.send(event);
|
|
146
|
+
for (const event of early.splice(0))
|
|
147
|
+
actor.send(event);
|
|
148
|
+
await ended;
|
|
149
|
+
actor.stop();
|
|
150
|
+
};
|
|
151
|
+
}
|
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
import { CellSecrets, Registry } from "@fonoster/common";
|
|
2
|
+
import { Session, VoiceServer } from "@fonoster/voice";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { SessionAgent } from "./config";
|
|
5
|
+
import { AutopilotOptions, LoadedAgent } from "./createAutopilot";
|
|
6
|
+
import { KnowledgePort } from "./knowledge";
|
|
7
|
+
import { CredentialSource } from "./llm";
|
|
8
|
+
import { UsageSink } from "./meteredThink";
|
|
9
|
+
export declare const hostedConfigSchema: z.ZodObject<{
|
|
10
|
+
host: z.ZodDefault<z.ZodString>;
|
|
11
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
12
|
+
/**
|
|
13
|
+
* Private destinations HTTP tools may call (host names, IPs, CIDRs; RV-B2); defaults to
|
|
14
|
+
* FONOSTER_ALLOWED_DESTINATIONS.
|
|
15
|
+
*/
|
|
16
|
+
allowedDestinations: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
17
|
+
/** The secret AppBridge signs Autopilot sessions with (one for every Autopilot app). */
|
|
18
|
+
signingSecret: z.ZodUnion<[z.ZodObject<{
|
|
19
|
+
env: z.ZodString;
|
|
20
|
+
}, "strict", z.ZodTypeAny, {
|
|
21
|
+
env?: string;
|
|
22
|
+
}, {
|
|
23
|
+
env?: string;
|
|
24
|
+
}>, z.ZodObject<{
|
|
25
|
+
value: z.ZodString;
|
|
26
|
+
}, "strict", z.ZodTypeAny, {
|
|
27
|
+
value?: string;
|
|
28
|
+
}, {
|
|
29
|
+
value?: string;
|
|
30
|
+
}>]>;
|
|
31
|
+
/**
|
|
32
|
+
* The URL Autopilot apps point to, exactly as the apps have it (the apiserver's
|
|
33
|
+
* `apps.autopilotUrl`, e.g. ws://autopilot:3000), or several. Signatures are checked against
|
|
34
|
+
* it, never against the request's Host header.
|
|
35
|
+
*/
|
|
36
|
+
publicUrl: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
37
|
+
/**
|
|
38
|
+
* Apps and their agents: a file `{apps: {<appRef>: {workspaceRef?, agent}}}` (JSON or
|
|
39
|
+
* YAML), or `database`: the apps' Intelligence rows, cached for `cacheMs` (CP-B11).
|
|
40
|
+
*/
|
|
41
|
+
agents: z.ZodUnion<[z.ZodObject<{
|
|
42
|
+
file: z.ZodString;
|
|
43
|
+
}, "strict", z.ZodTypeAny, {
|
|
44
|
+
file?: string;
|
|
45
|
+
}, {
|
|
46
|
+
file?: string;
|
|
47
|
+
}>, z.ZodObject<{
|
|
48
|
+
source: z.ZodLiteral<"database">;
|
|
49
|
+
cacheMs: z.ZodDefault<z.ZodNumber>;
|
|
50
|
+
}, "strict", z.ZodTypeAny, {
|
|
51
|
+
source?: "database";
|
|
52
|
+
cacheMs?: number;
|
|
53
|
+
}, {
|
|
54
|
+
source?: "database";
|
|
55
|
+
cacheMs?: number;
|
|
56
|
+
}>]>;
|
|
57
|
+
/** The provider registry's catalog: the JSON file fonoster-registry writes, or the tables. */
|
|
58
|
+
registry: z.ZodUnion<[z.ZodObject<{
|
|
59
|
+
file: z.ZodString;
|
|
60
|
+
}, "strict", z.ZodTypeAny, {
|
|
61
|
+
file?: string;
|
|
62
|
+
}, {
|
|
63
|
+
file?: string;
|
|
64
|
+
}>, z.ZodObject<{
|
|
65
|
+
source: z.ZodLiteral<"database">;
|
|
66
|
+
refreshMs: z.ZodDefault<z.ZodNumber>;
|
|
67
|
+
}, "strict", z.ZodTypeAny, {
|
|
68
|
+
source?: "database";
|
|
69
|
+
refreshMs?: number;
|
|
70
|
+
}, {
|
|
71
|
+
source?: "database";
|
|
72
|
+
refreshMs?: number;
|
|
73
|
+
}>]>;
|
|
74
|
+
/** Platform keys by credentialRef. */
|
|
75
|
+
credentials: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{
|
|
76
|
+
env: z.ZodString;
|
|
77
|
+
}, "strict", z.ZodTypeAny, {
|
|
78
|
+
env?: string;
|
|
79
|
+
}, {
|
|
80
|
+
env?: string;
|
|
81
|
+
}>, z.ZodObject<{
|
|
82
|
+
value: z.ZodString;
|
|
83
|
+
}, "strict", z.ZodTypeAny, {
|
|
84
|
+
value?: string;
|
|
85
|
+
}, {
|
|
86
|
+
value?: string;
|
|
87
|
+
}>]>>>;
|
|
88
|
+
/**
|
|
89
|
+
* Workspace Secrets (bring your own key): a JSON file by workspace and credentialRef, or
|
|
90
|
+
* `database`: the workspace's vendor keys (workspace_provider_keys).
|
|
91
|
+
*/
|
|
92
|
+
workspaceSecrets: z.ZodOptional<z.ZodUnion<[z.ZodObject<{
|
|
93
|
+
file: z.ZodString;
|
|
94
|
+
}, "strict", z.ZodTypeAny, {
|
|
95
|
+
file?: string;
|
|
96
|
+
}, {
|
|
97
|
+
file?: string;
|
|
98
|
+
}>, z.ZodObject<{
|
|
99
|
+
source: z.ZodLiteral<"database">;
|
|
100
|
+
}, "strict", z.ZodTypeAny, {
|
|
101
|
+
source?: "database";
|
|
102
|
+
}, {
|
|
103
|
+
source?: "database";
|
|
104
|
+
}>, z.ZodObject<{
|
|
105
|
+
cellSecrets: z.ZodObject<{
|
|
106
|
+
file: z.ZodOptional<z.ZodString>;
|
|
107
|
+
dir: z.ZodOptional<z.ZodString>;
|
|
108
|
+
keyEnv: z.ZodOptional<z.ZodString>;
|
|
109
|
+
}, "strict", z.ZodTypeAny, {
|
|
110
|
+
file?: string;
|
|
111
|
+
dir?: string;
|
|
112
|
+
keyEnv?: string;
|
|
113
|
+
}, {
|
|
114
|
+
file?: string;
|
|
115
|
+
dir?: string;
|
|
116
|
+
keyEnv?: string;
|
|
117
|
+
}>;
|
|
118
|
+
}, "strict", z.ZodTypeAny, {
|
|
119
|
+
cellSecrets?: {
|
|
120
|
+
file?: string;
|
|
121
|
+
dir?: string;
|
|
122
|
+
keyEnv?: string;
|
|
123
|
+
};
|
|
124
|
+
}, {
|
|
125
|
+
cellSecrets?: {
|
|
126
|
+
file?: string;
|
|
127
|
+
dir?: string;
|
|
128
|
+
keyEnv?: string;
|
|
129
|
+
};
|
|
130
|
+
}>]>>;
|
|
131
|
+
/**
|
|
132
|
+
* The control-plane database (the apiserver's), for any `source: database`. The URL comes
|
|
133
|
+
* from this file only, usually as a placeholder: `url: "${APISERVER_DATABASE_URL}"`.
|
|
134
|
+
*/
|
|
135
|
+
database: z.ZodOptional<z.ZodObject<{
|
|
136
|
+
url: z.ZodString;
|
|
137
|
+
/** A client generated from the apiserver schema (default `@prisma/client`). */
|
|
138
|
+
clientModule: z.ZodOptional<z.ZodString>;
|
|
139
|
+
}, "strict", z.ZodTypeAny, {
|
|
140
|
+
url?: string;
|
|
141
|
+
clientModule?: string;
|
|
142
|
+
}, {
|
|
143
|
+
url?: string;
|
|
144
|
+
clientModule?: string;
|
|
145
|
+
}>>;
|
|
146
|
+
/** Endpoint overrides by provider or adapter id (e.g. a local ollama); the catalog's otherwise. */
|
|
147
|
+
endpoints: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
148
|
+
/** The S3 + Unstructured knowledge bases; keys by credentialRef (task 4.1). */
|
|
149
|
+
knowledge: z.ZodOptional<z.ZodObject<{
|
|
150
|
+
s3: z.ZodObject<{
|
|
151
|
+
endpoint: z.ZodString;
|
|
152
|
+
region: z.ZodDefault<z.ZodString>;
|
|
153
|
+
accessKeyIdRef: z.ZodString;
|
|
154
|
+
secretAccessKeyRef: z.ZodString;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
endpoint?: string;
|
|
157
|
+
region?: string;
|
|
158
|
+
accessKeyIdRef?: string;
|
|
159
|
+
secretAccessKeyRef?: string;
|
|
160
|
+
}, {
|
|
161
|
+
endpoint?: string;
|
|
162
|
+
region?: string;
|
|
163
|
+
accessKeyIdRef?: string;
|
|
164
|
+
secretAccessKeyRef?: string;
|
|
165
|
+
}>;
|
|
166
|
+
unstructured: z.ZodObject<{
|
|
167
|
+
url: z.ZodString;
|
|
168
|
+
apiKeyRef: z.ZodString;
|
|
169
|
+
}, "strip", z.ZodTypeAny, {
|
|
170
|
+
url?: string;
|
|
171
|
+
apiKeyRef?: string;
|
|
172
|
+
}, {
|
|
173
|
+
url?: string;
|
|
174
|
+
apiKeyRef?: string;
|
|
175
|
+
}>;
|
|
176
|
+
embeddings: z.ZodObject<{
|
|
177
|
+
apiKeyRef: z.ZodString;
|
|
178
|
+
}, "strip", z.ZodTypeAny, {
|
|
179
|
+
apiKeyRef?: string;
|
|
180
|
+
}, {
|
|
181
|
+
apiKeyRef?: string;
|
|
182
|
+
}>;
|
|
183
|
+
}, "strip", z.ZodTypeAny, {
|
|
184
|
+
s3?: {
|
|
185
|
+
endpoint?: string;
|
|
186
|
+
region?: string;
|
|
187
|
+
accessKeyIdRef?: string;
|
|
188
|
+
secretAccessKeyRef?: string;
|
|
189
|
+
};
|
|
190
|
+
unstructured?: {
|
|
191
|
+
url?: string;
|
|
192
|
+
apiKeyRef?: string;
|
|
193
|
+
};
|
|
194
|
+
embeddings?: {
|
|
195
|
+
apiKeyRef?: string;
|
|
196
|
+
};
|
|
197
|
+
}, {
|
|
198
|
+
s3?: {
|
|
199
|
+
endpoint?: string;
|
|
200
|
+
region?: string;
|
|
201
|
+
accessKeyIdRef?: string;
|
|
202
|
+
secretAccessKeyRef?: string;
|
|
203
|
+
};
|
|
204
|
+
unstructured?: {
|
|
205
|
+
url?: string;
|
|
206
|
+
apiKeyRef?: string;
|
|
207
|
+
};
|
|
208
|
+
embeddings?: {
|
|
209
|
+
apiKeyRef?: string;
|
|
210
|
+
};
|
|
211
|
+
}>>;
|
|
212
|
+
/**
|
|
213
|
+
* The apiserver's encryption key (fonoster.yaml `encryption.key`; vendor keys are encrypted
|
|
214
|
+
* Secrets). Usually "${ENCRYPTION_KEY}".
|
|
215
|
+
*/
|
|
216
|
+
encryption: z.ZodOptional<z.ZodObject<{
|
|
217
|
+
key: z.ZodString;
|
|
218
|
+
}, "strict", z.ZodTypeAny, {
|
|
219
|
+
key?: string;
|
|
220
|
+
}, {
|
|
221
|
+
key?: string;
|
|
222
|
+
}>>;
|
|
223
|
+
/** OTLP export (empty = off): `otlpEndpoint: "${OTEL_EXPORTER_OTLP_ENDPOINT:-}"`. */
|
|
224
|
+
telemetry: z.ZodOptional<z.ZodObject<{
|
|
225
|
+
otlpEndpoint: z.ZodOptional<z.ZodString>;
|
|
226
|
+
}, "strip", z.ZodTypeAny, {
|
|
227
|
+
otlpEndpoint?: string;
|
|
228
|
+
}, {
|
|
229
|
+
otlpEndpoint?: string;
|
|
230
|
+
}>>;
|
|
231
|
+
}, "strict", z.ZodTypeAny, {
|
|
232
|
+
registry?: {
|
|
233
|
+
file?: string;
|
|
234
|
+
} | {
|
|
235
|
+
source?: "database";
|
|
236
|
+
refreshMs?: number;
|
|
237
|
+
};
|
|
238
|
+
host?: string;
|
|
239
|
+
port?: number;
|
|
240
|
+
allowedDestinations?: string[];
|
|
241
|
+
signingSecret?: {
|
|
242
|
+
env?: string;
|
|
243
|
+
} | {
|
|
244
|
+
value?: string;
|
|
245
|
+
};
|
|
246
|
+
publicUrl?: string | string[];
|
|
247
|
+
agents?: {
|
|
248
|
+
file?: string;
|
|
249
|
+
} | {
|
|
250
|
+
source?: "database";
|
|
251
|
+
cacheMs?: number;
|
|
252
|
+
};
|
|
253
|
+
database?: {
|
|
254
|
+
url?: string;
|
|
255
|
+
clientModule?: string;
|
|
256
|
+
};
|
|
257
|
+
credentials?: Record<string, {
|
|
258
|
+
env?: string;
|
|
259
|
+
} | {
|
|
260
|
+
value?: string;
|
|
261
|
+
}>;
|
|
262
|
+
workspaceSecrets?: {
|
|
263
|
+
file?: string;
|
|
264
|
+
} | {
|
|
265
|
+
source?: "database";
|
|
266
|
+
} | {
|
|
267
|
+
cellSecrets?: {
|
|
268
|
+
file?: string;
|
|
269
|
+
dir?: string;
|
|
270
|
+
keyEnv?: string;
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
endpoints?: Record<string, string>;
|
|
274
|
+
knowledge?: {
|
|
275
|
+
s3?: {
|
|
276
|
+
endpoint?: string;
|
|
277
|
+
region?: string;
|
|
278
|
+
accessKeyIdRef?: string;
|
|
279
|
+
secretAccessKeyRef?: string;
|
|
280
|
+
};
|
|
281
|
+
unstructured?: {
|
|
282
|
+
url?: string;
|
|
283
|
+
apiKeyRef?: string;
|
|
284
|
+
};
|
|
285
|
+
embeddings?: {
|
|
286
|
+
apiKeyRef?: string;
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
encryption?: {
|
|
290
|
+
key?: string;
|
|
291
|
+
};
|
|
292
|
+
telemetry?: {
|
|
293
|
+
otlpEndpoint?: string;
|
|
294
|
+
};
|
|
295
|
+
}, {
|
|
296
|
+
registry?: {
|
|
297
|
+
file?: string;
|
|
298
|
+
} | {
|
|
299
|
+
source?: "database";
|
|
300
|
+
refreshMs?: number;
|
|
301
|
+
};
|
|
302
|
+
host?: string;
|
|
303
|
+
port?: number;
|
|
304
|
+
allowedDestinations?: string[];
|
|
305
|
+
signingSecret?: {
|
|
306
|
+
env?: string;
|
|
307
|
+
} | {
|
|
308
|
+
value?: string;
|
|
309
|
+
};
|
|
310
|
+
publicUrl?: string | string[];
|
|
311
|
+
agents?: {
|
|
312
|
+
file?: string;
|
|
313
|
+
} | {
|
|
314
|
+
source?: "database";
|
|
315
|
+
cacheMs?: number;
|
|
316
|
+
};
|
|
317
|
+
database?: {
|
|
318
|
+
url?: string;
|
|
319
|
+
clientModule?: string;
|
|
320
|
+
};
|
|
321
|
+
credentials?: Record<string, {
|
|
322
|
+
env?: string;
|
|
323
|
+
} | {
|
|
324
|
+
value?: string;
|
|
325
|
+
}>;
|
|
326
|
+
workspaceSecrets?: {
|
|
327
|
+
file?: string;
|
|
328
|
+
} | {
|
|
329
|
+
source?: "database";
|
|
330
|
+
} | {
|
|
331
|
+
cellSecrets?: {
|
|
332
|
+
file?: string;
|
|
333
|
+
dir?: string;
|
|
334
|
+
keyEnv?: string;
|
|
335
|
+
};
|
|
336
|
+
};
|
|
337
|
+
endpoints?: Record<string, string>;
|
|
338
|
+
knowledge?: {
|
|
339
|
+
s3?: {
|
|
340
|
+
endpoint?: string;
|
|
341
|
+
region?: string;
|
|
342
|
+
accessKeyIdRef?: string;
|
|
343
|
+
secretAccessKeyRef?: string;
|
|
344
|
+
};
|
|
345
|
+
unstructured?: {
|
|
346
|
+
url?: string;
|
|
347
|
+
apiKeyRef?: string;
|
|
348
|
+
};
|
|
349
|
+
embeddings?: {
|
|
350
|
+
apiKeyRef?: string;
|
|
351
|
+
};
|
|
352
|
+
};
|
|
353
|
+
encryption?: {
|
|
354
|
+
key?: string;
|
|
355
|
+
};
|
|
356
|
+
telemetry?: {
|
|
357
|
+
otlpEndpoint?: string;
|
|
358
|
+
};
|
|
359
|
+
}>;
|
|
360
|
+
export type HostedConfig = z.infer<typeof hostedConfigSchema>;
|
|
361
|
+
/** Where Autopilot looks for its file when none is named (autopilot.yaml, then the older name). */
|
|
362
|
+
export declare const AUTOPILOT_CONFIG_DIRS: string[];
|
|
363
|
+
/** The file `loadHostedConfig` reads without `--config`: the first one found, or undefined. */
|
|
364
|
+
export declare function findHostedConfig(): string | undefined;
|
|
365
|
+
/**
|
|
366
|
+
* Loads the hosted Autopilot's file the apiserver's way (unify-config-placeholders): `${VAR}`
|
|
367
|
+
* placeholders from the container environment, `secret://` references, strict validation.
|
|
368
|
+
*/
|
|
369
|
+
export declare function loadHostedConfig(file: string, env?: Record<string, string | undefined>): HostedConfig;
|
|
370
|
+
/** Apps and agents from a file (a stand-in until agents come from the control plane). */
|
|
371
|
+
export declare class FileAgentSource {
|
|
372
|
+
private readonly file;
|
|
373
|
+
constructor(file: string);
|
|
374
|
+
get(appRef: string): Promise<LoadedAgent | undefined>;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Agents from the control plane: an Autopilot app's Intelligence row holds its agent
|
|
378
|
+
* (CP-B3). Each app is cached for `cacheMs` (misses too), so edits show up within seconds.
|
|
379
|
+
*/
|
|
380
|
+
export declare class PrismaAgentSource {
|
|
381
|
+
private readonly prisma;
|
|
382
|
+
private readonly options;
|
|
383
|
+
private cache;
|
|
384
|
+
constructor(prisma: any, options?: {
|
|
385
|
+
cacheMs?: number;
|
|
386
|
+
now?: () => number;
|
|
387
|
+
});
|
|
388
|
+
get(appRef: string): Promise<LoadedAgent | undefined>;
|
|
389
|
+
}
|
|
390
|
+
/** Workspace vendor keys from the database, looked up by the credentialRef's providers. */
|
|
391
|
+
export declare class DatabaseWorkspaceSecrets implements CredentialSource {
|
|
392
|
+
private readonly keys;
|
|
393
|
+
private readonly providers;
|
|
394
|
+
constructor(keys: Registry.PrismaWorkspaceKeys, providers: () => {
|
|
395
|
+
id: string;
|
|
396
|
+
credentialRef: string;
|
|
397
|
+
}[]);
|
|
398
|
+
get(ref: string, scope: {
|
|
399
|
+
workspaceRef?: string;
|
|
400
|
+
}): Promise<string>;
|
|
401
|
+
}
|
|
402
|
+
/** A private region's cell secrets (PR-4): keys never leave the cell. */
|
|
403
|
+
export declare class CellSecretCredentials implements CredentialSource {
|
|
404
|
+
private readonly keys;
|
|
405
|
+
private readonly providers;
|
|
406
|
+
constructor(keys: CellSecrets.CellSecretKeys, providers: () => {
|
|
407
|
+
id: string;
|
|
408
|
+
credentialRef: string;
|
|
409
|
+
}[]);
|
|
410
|
+
get(ref: string): string;
|
|
411
|
+
}
|
|
412
|
+
/** Workspace Secrets from a JSON file: `{<workspaceRef>: {<credentialRef>: value}}`. */
|
|
413
|
+
export declare class FileWorkspaceSecrets implements CredentialSource {
|
|
414
|
+
private readonly file;
|
|
415
|
+
constructor(file: string);
|
|
416
|
+
get(ref: string, scope: {
|
|
417
|
+
workspaceRef?: string;
|
|
418
|
+
}): string;
|
|
419
|
+
}
|
|
420
|
+
type KnowledgeBaseLike = {
|
|
421
|
+
load(): Promise<void>;
|
|
422
|
+
queryKnowledgeBase(query: string, k?: number): Promise<string>;
|
|
423
|
+
};
|
|
424
|
+
/**
|
|
425
|
+
* Builds the knowledge port for an agent from the operator's S3 + Unstructured settings,
|
|
426
|
+
* with keys from the credential source (never Autopilot's environment). The bucket is the
|
|
427
|
+
* workspace's, as today. `make` is the knowledge base constructor (the S3 one by default).
|
|
428
|
+
*/
|
|
429
|
+
export declare function s3Knowledge(config: NonNullable<HostedConfig["knowledge"]>, credentials: CredentialSource, make?: (params: Record<string, unknown>) => KnowledgeBaseLike): (agent: SessionAgent, scope: {
|
|
430
|
+
workspaceRef?: string;
|
|
431
|
+
}, usage?: UsageSink) => Promise<KnowledgePort | undefined>;
|
|
432
|
+
/** The handler options the hosted Autopilot runs with, built from its config. */
|
|
433
|
+
export declare function hostedOptions(config: HostedConfig, deps?: {
|
|
434
|
+
prisma?: any;
|
|
435
|
+
}): AutopilotOptions;
|
|
436
|
+
/**
|
|
437
|
+
* One knowledge port per call, built eagerly; a lookup waits for it (and gives up after 800 ms
|
|
438
|
+
* like any). A port that fails to build is logged and answers nothing: the eager promise always
|
|
439
|
+
* has a handler, so a failure never becomes an unhandled rejection (RV-B5).
|
|
440
|
+
*/
|
|
441
|
+
export declare function eagerKnowledge(build: (agent: SessionAgent, scope: {
|
|
442
|
+
workspaceRef?: string;
|
|
443
|
+
}, usage?: UsageSink) => Promise<KnowledgePort | undefined>): (agent: SessionAgent, scope: {
|
|
444
|
+
workspaceRef?: string;
|
|
445
|
+
}, usage?: UsageSink) => KnowledgePort;
|
|
446
|
+
/**
|
|
447
|
+
* The app's agent only when the app belongs to the workspace AppBridge signed for: one
|
|
448
|
+
* secret serves every Autopilot app, so a session is bound to its app and workspace
|
|
449
|
+
* (voice-session, "Connection requests are bound to the app").
|
|
450
|
+
*/
|
|
451
|
+
export declare function signedWorkspaceOnly(session: Pick<Session, "appRef" | "signedFor">, loaded: LoadedAgent | undefined): LoadedAgent | undefined;
|
|
452
|
+
/** Starts the hosted Autopilot. */
|
|
453
|
+
export declare function startHostedAutopilot(config: HostedConfig): Promise<VoiceServer>;
|
|
454
|
+
export {};
|