Merge main into feat/voice-core

Keeps the voice-core prompt rules and adds main's world-query and
vessels-vs-visuals rules; the tool catalog wraps the deixis-aware runner.

Also fixes two things the branch had before the merge:
- Live voice could not start: OpenAI rejects track_entity's top-level
  anyOf. Model-facing tools now omit top-level combinators; the runner
  and benchmark still require a query or a referent.
- The Contacts-centred analyst answer dropped the viewport coverage note.
This commit is contained in:
Bilawal Sidhu committed 2026-10-03 23:30:02 -07:00
commit e7cb9b02b5
191 files changed
+20005 -1450

No files matched your search

+5 -4
View File
@@ -1,4 +1,4 @@
import { enforceOptInRateLimit, openAiRateLimiter } from './rate-limit.js';
import { enforceRateLimit, openAiRateLimiter } from './rate-limit.js';
import {
resolveVoiceModel,
isKnownVoiceTier,
@@ -21,6 +21,7 @@ function createRealtimeTokenHandler({
fetchImpl = (...args) => fetch(...args),
resolveApiKey = () => process.env.OPENAI_API_KEY,
models = {},
tools = GEV_REALTIME_TOOLS,
} = {}) {
return async (req, res) => {
res.setHeader('Cache-Control', 'no-store');
@@ -31,8 +32,8 @@ function createRealtimeTokenHandler({
return;
}
// Opt-in per-IP throttle (GEV_RATELIMIT_OPENAI_PER_MIN). No-op when unset.
if (!enforceOptInRateLimit(openAiRateLimiter(), req, res)) return;
// Per-IP throttle (GEV_RATELIMIT_OPENAI_PER_MIN). On by default; 0 disables.
if (!enforceRateLimit(openAiRateLimiter(), req, res)) return;
const apiKey = resolveApiKey();
if (!apiKey) {
@@ -123,7 +124,7 @@ function createRealtimeTokenHandler({
output: { voice },
},
instructions: realtimeInstructions(annotationGuidance),
tools: GEV_REALTIME_TOOLS,
tools,
tool_choice: 'auto',
},
};