Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/eval-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mod report;
mod submissions;

use hypr_eval::{
DEFAULT_MODELS, EvalResult, Executor, ExecutorProgress, OpenRouterClient, parse_config,
parse_config, EvalResult, Executor, ExecutorProgress, OpenRouterClient, DEFAULT_MODELS,
};
use report::{render_json, render_results};
use submissions::{all_cases, filter_cases};
Expand Down Expand Up @@ -179,7 +179,7 @@ fn list_cases() {

fn generate_completion(shell: Shell) {
use clap::CommandFactory;
use clap_complete::{Shell as ClapShell, generate};
use clap_complete::{generate, Shell as ClapShell};

let mut cmd = Cli::command();
let shell = match shell {
Expand Down
2 changes: 1 addition & 1 deletion apps/eval-cli/src/report.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use comfy_table::{Cell, Color, ContentArrangement, Table, presets::UTF8_FULL_CONDENSED};
use comfy_table::{presets::UTF8_FULL_CONDENSED, Cell, Color, ContentArrangement, Table};

use hypr_eval::EvalResult;

Expand Down
4 changes: 2 additions & 2 deletions apps/eval-cli/src/submissions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use hypr_eval::{
ChatMessage, CheckResult, EvalCase, GraderSpec, RubricSpec, find_headings, find_lists, grade,
is_non_empty,
find_headings, find_lists, grade, is_non_empty, ChatMessage, CheckResult, EvalCase, GraderSpec,
RubricSpec,
};
use hypr_template_eval::{MdgenSystem, Template};

Expand Down
16 changes: 10 additions & 6 deletions crates/audio-device/src/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl MacOSBackend {
.unwrap_or(TransportType::Unknown);

let is_default = default_device_id
.map(|id| device.0.0 == id)
.map(|id| device.0 .0 == id)
.unwrap_or(false);

let mut audio_device = AudioDevice {
Expand Down Expand Up @@ -102,7 +102,11 @@ impl MacOSBackend {
})
});

if detected { Some(true) } else { None }
if detected {
Some(true)
} else {
None
}
}

fn is_external_from_device(device: Option<ca::Device>) -> bool {
Expand All @@ -120,8 +124,8 @@ impl AudioDeviceBackend for MacOSBackend {
let ca_devices =
ca::System::devices().map_err(|e| Error::EnumerationFailed(format!("{:?}", e)))?;

let default_input_id = ca::System::default_input_device().ok().map(|d| d.0.0);
let default_output_id = ca::System::default_output_device().ok().map(|d| d.0.0);
let default_input_id = ca::System::default_input_device().ok().map(|d| d.0 .0);
let default_output_id = ca::System::default_output_device().ok().map(|d| d.0 .0);

let mut devices = Vec::new();

Expand Down Expand Up @@ -161,7 +165,7 @@ impl AudioDeviceBackend for MacOSBackend {
Ok(Self::create_audio_device(
&ca_device,
AudioDirection::Input,
Some(ca_device.0.0),
Some(ca_device.0 .0),
))
}

Expand All @@ -178,7 +182,7 @@ impl AudioDeviceBackend for MacOSBackend {
Ok(Self::create_audio_device(
&ca_device,
AudioDirection::Output,
Some(ca_device.0.0),
Some(ca_device.0 .0),
))
}

Expand Down
8 changes: 4 additions & 4 deletions crates/audio-device/src/windows.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::{AudioDevice, AudioDeviceBackend, AudioDirection, DeviceId, Error, TransportType};
use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt;
use windows::core::{Interface, GUID, PCWSTR, PWSTR};
use windows::Win32::Devices::FunctionDiscovery::PKEY_Device_FriendlyName;
use windows::Win32::Media::Audio::Endpoints::IAudioEndpointVolume;
use windows::Win32::Media::Audio::{
DEVICE_STATE_ACTIVE, IMMDevice, IMMDeviceEnumerator, MMDeviceEnumerator, eAll, eCapture,
eConsole, eRender,
eAll, eCapture, eConsole, eRender, IMMDevice, IMMDeviceEnumerator, MMDeviceEnumerator,
DEVICE_STATE_ACTIVE,
};
use windows::Win32::System::Com::{
CLSCTX_ALL, COINIT_MULTITHREADED, CoCreateInstance, CoInitializeEx, CoUninitialize, STGM_READ,
CoCreateInstance, CoInitializeEx, CoUninitialize, CLSCTX_ALL, COINIT_MULTITHREADED, STGM_READ,
};
use windows::Win32::UI::Shell::PropertiesSystem::IPropertyStore;
use windows::core::{GUID, Interface, PCWSTR, PWSTR};

pub struct WindowsBackend;

Expand Down
2 changes: 1 addition & 1 deletion crates/eval/src/format.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use markdown::mdast::{Heading, List, ListItem, Node};
use markdown::{ParseOptions, to_mdast};
use markdown::{to_mdast, ParseOptions};

#[derive(Debug, Clone)]
pub struct CheckResult {
Expand Down
22 changes: 11 additions & 11 deletions crates/eval/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,23 @@ pub use testing::*;

// Re-export core types at root for convenience
pub use client::{
ChatCompleter, ChatCompletionRequest, ChatCompletionResponse, ChatMessage, ClientError,
GraderResponse, OpenRouterClient, Usage, UsageResolver, generate_chat_multi_with_generation_id,
generate_chat_with_generation_id, generate_structured_grader_response,
generate_structured_grader_response_multi, generate_text_multi_with_generation_id,
generate_text_with_generation_id,
generate_chat_multi_with_generation_id, generate_chat_with_generation_id,
generate_structured_grader_response, generate_structured_grader_response_multi,
generate_text_multi_with_generation_id, generate_text_with_generation_id, ChatCompleter,
ChatCompletionRequest, ChatCompletionResponse, ChatMessage, ClientError, GraderResponse,
OpenRouterClient, Usage, UsageResolver,
};
pub use config::{Config, parse_config};
pub use config::{parse_config, Config};
pub use constants::*;
pub use format::{
CheckResult, GradeResult, Rule, count_list_items_in_section, extract_text, find_headings,
find_list_items, find_lists, first_inline_child, grade, split_by_headings,
count_list_items_in_section, extract_text, find_headings, find_list_items, find_lists,
first_inline_child, grade, split_by_headings, CheckResult, GradeResult, Rule,
};
pub use models::{fetch_openrouter_models, filter_models};
pub use rubric::{Score, grade_with_func, grade_with_llm, is_non_empty};
pub use rubric::{grade_with_func, grade_with_llm, is_non_empty, Score};
pub use stats::{
AggregatedGraderResponse, ConfidenceInterval, PassStats, aggregate_grader_responses,
calc_pass_stats,
aggregate_grader_responses, calc_pass_stats, AggregatedGraderResponse, ConfidenceInterval,
PassStats,
};
pub use submission::{
EvalCase, EvalResult, Executor, ExecutorProgress, ExecutorProgressCallback, GraderSpec,
Expand Down
4 changes: 2 additions & 2 deletions crates/eval/src/rubric.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::collections::HashMap;

use crate::{
ChatCompleter, ConfidenceInterval, aggregate_grader_responses,
generate_structured_grader_response, generate_structured_grader_response_multi,
aggregate_grader_responses, generate_structured_grader_response,
generate_structured_grader_response_multi, ChatCompleter, ConfidenceInterval,
};

/// Score represents the result of evaluating output against a rubric.
Expand Down
2 changes: 1 addition & 1 deletion crates/eval/src/submission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex};
use rayon::prelude::*;

use crate::constants::DEFAULT_GRADER_MODEL;
use crate::{ChatCompleter, ChatMessage, Score, Usage, parse_config};
use crate::{parse_config, ChatCompleter, ChatMessage, Score, Usage};

pub type ValidatorFn = fn(&str) -> (bool, String);
pub type ValidatorFnWithMeta = fn(&str, &HashMap<String, serde_json::Value>) -> (bool, String);
Expand Down
89 changes: 87 additions & 2 deletions crates/owhisper-client/src/adapter/openai/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,18 @@ impl RealtimeSttAdapter for OpenAIAdapter {
false
}

fn build_ws_url(&self, api_base: &str, _params: &ListenParams, _channels: u8) -> url::Url {
let (mut url, existing_params) = Self::build_ws_url_from_base(api_base);
fn build_ws_url(&self, api_base: &str, params: &ListenParams, _channels: u8) -> url::Url {
// Detect Azure from the base URL and store flag for initial_message
if let Ok(parsed) = api_base.parse::<url::Url>() {
if let Some(host) = parsed.host_str() {
if Self::is_azure_host(host) {
self.set_azure(true);
}
}
}

let model = params.model.as_deref();
let (mut url, existing_params) = Self::build_ws_url_from_base_with_model(api_base, model);

if !existing_params.is_empty() {
let mut query_pairs = url.query_pairs_mut();
Expand Down Expand Up @@ -78,6 +88,11 @@ impl RealtimeSttAdapter for OpenAIAdapter {
None => default,
};

// Use the Azure flag set during build_ws_url (detected from api_base URL)
if self.is_azure() {
return self.build_azure_initial_message(model, language);
}

let session_config = SessionUpdateEvent {
event_type: "session.update".to_string(),
session: SessionConfig {
Expand Down Expand Up @@ -211,6 +226,76 @@ impl RealtimeSttAdapter for OpenAIAdapter {
}
}

impl OpenAIAdapter {
/// Build Azure OpenAI-specific initial message
/// Azure uses a different session update format: transcription_session.update
fn build_azure_initial_message(
&self,
model: &str,
language: Option<String>,
) -> Option<Message> {
let session_update = AzureTranscriptionSessionUpdate {
event_type: "transcription_session.update".to_string(),
session: AzureSessionConfig {
input_audio_format: "pcm16".to_string(),
input_audio_transcription: AzureTranscriptionConfig {
model: model.to_string(),
prompt: None,
language,
},
turn_detection: Some(AzureTurnDetection {
detection_type: VAD_DETECTION_TYPE.to_string(),
threshold: Some(VAD_THRESHOLD),
prefix_padding_ms: Some(VAD_PREFIX_PADDING_MS),
silence_duration_ms: Some(VAD_SILENCE_DURATION_MS),
}),
},
};

let json = serde_json::to_string(&session_update).ok()?;
tracing::debug!(payload = %json, "azure_openai_session_update_payload");
Some(Message::Text(json.into()))
}
}

// Azure OpenAI specific session message types

#[derive(Debug, Serialize)]
struct AzureTranscriptionSessionUpdate {
#[serde(rename = "type")]
event_type: String,
session: AzureSessionConfig,
}

#[derive(Debug, Serialize)]
struct AzureSessionConfig {
input_audio_format: String,
input_audio_transcription: AzureTranscriptionConfig,
#[serde(skip_serializing_if = "Option::is_none")]
turn_detection: Option<AzureTurnDetection>,
}

#[derive(Debug, Serialize)]
struct AzureTranscriptionConfig {
model: String,
#[serde(skip_serializing_if = "Option::is_none")]
prompt: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
language: Option<String>,
}

#[derive(Debug, Serialize)]
struct AzureTurnDetection {
#[serde(rename = "type")]
detection_type: String,
#[serde(skip_serializing_if = "Option::is_none")]
threshold: Option<f32>,
#[serde(skip_serializing_if = "Option::is_none")]
prefix_padding_ms: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
silence_duration_ms: Option<u32>,
}

#[derive(Debug, Serialize)]
struct SessionUpdateEvent {
#[serde(rename = "type")]
Expand Down
Loading