feat(workflows): add RAG publishing and startup reconciliation

This commit is contained in:
2026-09-03 06:03:06 -04:00
parent ad95d530ad
commit d58be9613f
27 changed files with 1516 additions and 2487 deletions
View File
+43 -3
View File
@@ -13,7 +13,7 @@
href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600&family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="style.css?v=20260826001" />
<link rel="stylesheet" href="style.css?v=20260902001" />
</head>
<!--
`booting` disables transitions/animations until the first paint commits.
@@ -42,6 +42,9 @@
<button id="tools-btn" class="icon-btn" title="Tools" aria-label="Tools">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
</button>
<button id="rag-btn" class="icon-btn" title="Custom RAG context" aria-label="Custom RAG context">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/></svg>
</button>
<button id="chat-btn" class="icon-btn" title="Conversation history" aria-label="Conversation history">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
<span id="chat-badge" class="chat-badge" aria-hidden="true"></span>
@@ -263,7 +266,7 @@
<label class="field">
<span>Instructions</span>
<textarea id="instructions" rows="5" placeholder="You are a friendly voice assistant..."></textarea>
<textarea id="instructions" rows="5" placeholder="You are Vocero, a friendly voice assistant for the company Aquachile..."></textarea>
<small id="primary-prompt-meta" hidden></small>
</label>
@@ -337,6 +340,43 @@
</div>
</dialog>
<dialog id="rag-modal" class="modal">
<div class="modal-content">
<header class="modal-header">
<h2>Custom RAG context</h2>
<button id="rag-close" class="icon-btn" aria-label="Close">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</header>
<p class="tools-intro">
Incolla qui testo, documenti, o estratti RAG che vuoi siano disponibili
per la sessione vocale corrente. Il testo viene aggiunto sia alle
istruzioni del LLM sia al campo <code>user_context</code> del body
<code>/api/reasoning</code>.
</p>
<label class="field">
<span>RAG context (testo libero, puro)</span>
<textarea
id="rag-textarea"
rows="12"
spellcheck="false"
placeholder="Incolla o scrivi qui il contesto RAG che il modello deve usare durante la risposta. Es: dati cliente, policy, estratti documentali, ecc."
></textarea>
<small id="rag-hint" class="tool-hint">
Nessun RAG context caricato. Premi &quot;Invia nella sessione&quot; per applicare le modifiche.
</small>
</label>
<footer class="modal-footer">
<button id="rag-clear" class="btn secondary" type="button" value="clear">Svuota</button>
<div style="flex: 1"></div>
<button id="rag-submit" class="btn primary" type="button" value="submit">Invia nella sessione</button>
</footer>
</div>
</dialog>
<!-- Shown when the per-day conversation budget is spent (mid-call or at
start). Title / message / CTA / note are filled per tier by
ui/account.js. The hero is the HF mark — a friendly smiling face. -->
@@ -355,6 +395,6 @@
</div>
</dialog>
<script type="module" src="main.js?v=20260826001"></script>
<script type="module" src="main.js?v=20260902001"></script>
</body>
</html>
@@ -262,7 +262,7 @@
<label class="field">
<span>Instructions</span>
<textarea id="instructions" rows="5" placeholder="You are a friendly voice assistant..."></textarea>
<textarea id="instructions" rows="5" placeholder="You are Vocero, a friendly voice assistant for the company Aquachile..."></textarea>
<small id="primary-prompt-meta" hidden></small>
</label>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -666,7 +666,7 @@ export class S2sWsRealtimeClient extends EventTarget {
toolNames = names.join(",");
}
console.debug(
`[Vocero MCP WS] session.updated tool_choice=${event.session?.tool_choice ?? ""} ` +
`[Vocero WS] session.updated tool_choice=${event.session?.tool_choice ?? ""} ` +
`tool_count=${Array.isArray(event.session?.tools) ? event.session.tools.length : 0} ` +
`tools=${toolNames || "none"}`
);
@@ -711,7 +711,7 @@ export class S2sWsRealtimeClient extends EventTarget {
// #endregion
if (this._debug) {
console.debug(
`[Vocero MCP WS] response.created id=${event.response?.id ?? event.response_id ?? ""} ` +
`[Vocero WS] response.created id=${event.response?.id ?? event.response_id ?? ""} ` +
`status=${event.response?.status ?? ""}`
);
}
@@ -812,7 +812,7 @@ export class S2sWsRealtimeClient extends EventTarget {
});
// #endregion
console.debug(
`[Vocero MCP WS] function_call_arguments.done name=${name || "unknown"} ` +
`[Vocero WS] function_call_arguments.done name=${name || "unknown"} ` +
`callId=${JSON.stringify(callId)} args=${args}`
);
if (name) {
@@ -1067,7 +1067,7 @@ export class S2sWsRealtimeClient extends EventTarget {
if (!callId) return; // Can't target a result without the call id.
if (this._debug) {
console.debug(
`[Vocero MCP WS] function_call_output callId=${JSON.stringify(callId)} ` +
`[Vocero WS] function_call_output callId=${JSON.stringify(callId)} ` +
`outputLength=${(output || "").length}`
);
}
@@ -1181,7 +1181,7 @@ export class S2sWsRealtimeClient extends EventTarget {
if (opts.image) this.sendUserImage(opts.image);
this._createInFlight = true;
if (this._debug) {
console.debug(`[Vocero MCP WS] response.create image=${!!opts.image} openResponses=${this._openResponses}`);
console.debug(`[Vocero WS] response.create image=${!!opts.image} openResponses=${this._openResponses}`);
}
this._send({ type: "response.create" });
}
@@ -1342,7 +1342,7 @@ export class S2sWsRealtimeClient extends EventTarget {
}
if (this._debug && (event.type === "session.update" || event.type === "conversation.item.create")) {
const preview = (payload || JSON.stringify(event)).slice(0, 400);
console.debug(`[Vocero MCP WS OUT] type=${event.type} payload=${preview}`);
console.debug(`[Vocero WS OUT] type=${event.type} payload=${preview}`);
}
this._ws.send(payload || JSON.stringify(event));
}