81 lines
5.7 KiB
PHP
81 lines
5.7 KiB
PHP
<?php
|
|
|
|
/** Audio is deliberately OFF until the synthetic short/15m/1h gate passes for the current app. */
|
|
return [
|
|
// Human-reviewed business operation; does not claim complete model accuracy certification.
|
|
'manual_review_enabled' => filter_var(env('followup_audio.MANUAL_REVIEW_ENABLED', false), FILTER_VALIDATE_BOOLEAN),
|
|
'preview_only' => filter_var(env('followup_audio.PREVIEW_ONLY', false), FILTER_VALIDATE_BOOLEAN),
|
|
// Parse strictly at the gate; empty/malformed diagnosis lists never grant preview access.
|
|
'test_diagnosis_ids' => env('followup_audio.TEST_DIAGNOSIS_IDS', ''),
|
|
'test_admin_ids' => env('followup_audio.TEST_ADMIN_IDS', ''),
|
|
'enabled' => filter_var(env('followup_audio.ENABLED', false), FILTER_VALIDATE_BOOLEAN),
|
|
'audio_verified' => filter_var(env('followup_audio.AUDIO_VERIFIED', false), FILTER_VALIDATE_BOOLEAN),
|
|
// Each selected application must separately pass all three synthetic fixtures.
|
|
'verified_profiles' => array_values(array_intersect(['qwen', 'openai'], array_filter(array_map('trim',
|
|
explode(',', (string) env('followup_audio.VERIFIED_PROFILES', '')))))),
|
|
// LLM-suggested media offsets are not reliable ASR alignment; leave off until separately verified.
|
|
'timestamp_verified' => false,
|
|
'profile' => (string) env('followup_audio.PROFILE', 'qwen'),
|
|
'max_bytes' => 524288000,
|
|
'max_seconds' => 3600,
|
|
'chunk_bytes' => 2097152,
|
|
'retention_days' => 90,
|
|
'lease_seconds' => 600,
|
|
'http_transport' => (string) env('followup_audio.HTTP_TRANSPORT', 'curl'),
|
|
'request_timeout' => (int) env('followup_audio.REQUEST_TIMEOUT', 240),
|
|
'concurrency' => max(1, min(8, (int) env('followup_audio.CONCURRENCY', 1))),
|
|
// Keep one stable key across web/worker nodes; empty reuses the existing prescription AI key.
|
|
'encryption_key' => (string) env('followup_audio.ENCRYPTION_KEY', ''),
|
|
'private_dir' => runtime_path() . 'private/followup_audio',
|
|
// Original upload stays <=500 MiB. The same Dify app receives at most this private processing copy.
|
|
'upstream_max_bytes' => (int) env('followup_audio.UPSTREAM_MAX_BYTES', 20971520),
|
|
'normalize_timeout' => (int) env('followup_audio.NORMALIZE_TIMEOUT', 120),
|
|
'ffmpeg' => (string) env('followup_audio.FFMPEG', 'ffmpeg'),
|
|
'ffprobe' => (string) env('followup_audio.FFPROBE', 'ffprobe'),
|
|
'max_response_bytes' => 8388608,
|
|
'asr_stereo_chunk_seconds' => (int) env('followup_audio.ASR_STEREO_CHUNK_SECONDS', 15),
|
|
'asr_chunk_seconds' => (int) env('followup_audio.ASR_CHUNK_SECONDS', 120),
|
|
'asr_max_chunk_bytes' => 4194304,
|
|
'asr_request_timeout' => (int) env('followup_audio.ASR_REQUEST_TIMEOUT', 240),
|
|
'extraction_request_timeout' => (int) env('followup_audio.EXTRACTION_REQUEST_TIMEOUT', 240),
|
|
// HTTP is permitted only for explicitly acknowledged synthetic probes, never patient requests.
|
|
'allow_insecure_synthetic' => filter_var(env('followup_audio.ALLOW_INSECURE_SYNTHETIC', false), FILTER_VALIDATE_BOOLEAN),
|
|
// Stable logical slots preserve task schema. No model identifier or supplier is hardcoded.
|
|
'providers' => array_combine(['qwen', 'openai'], array_map(static function (string $profile): array {
|
|
$prefix = 'followup_audio.' . strtoupper($profile) . '_';
|
|
return [
|
|
'driver' => (string) env($prefix . 'DRIVER', 'dify'),
|
|
// Only the dify driver may reuse empty base/key fields from prescription_ai.
|
|
'base_url' => (string) env($prefix . 'BASE_URL', ''),
|
|
'api_key' => (string) env($prefix . 'API_KEY', ''),
|
|
'model' => (string) env($prefix . 'MODEL', ''),
|
|
'label' => (string) env($prefix . 'LABEL', $profile),
|
|
// Explicit server-only two-stage identities; no fallback to prescription_ai or another slot.
|
|
'allow_loopback_tunnel' => filter_var(env($prefix . 'ALLOW_LOOPBACK_TUNNEL', false), FILTER_VALIDATE_BOOLEAN),
|
|
'asr' => [
|
|
'protocol' => (string) env($prefix . 'ASR_PROTOCOL', 'openai'),
|
|
'binding_revision' => (string) env($prefix . 'ASR_BINDING_REVISION', ''),
|
|
'base_url' => (string) env($prefix . 'ASR_BASE_URL', ''),
|
|
'api_key' => (string) env($prefix . 'ASR_API_KEY', ''),
|
|
'model' => (string) env($prefix . 'ASR_MODEL', ''),
|
|
],
|
|
'extraction' => [
|
|
'protocol' => (string) env($prefix . 'EXTRACTION_PROTOCOL', 'openai'),
|
|
// Empty by default; operator-authorized exact HTTP text endpoint only, never ASR.
|
|
'http_base_opt_in' => (string) env($prefix . 'EXTRACTION_HTTP_BASE_OPT_IN', ''),
|
|
'binding_revision' => (string) env($prefix . 'EXTRACTION_BINDING_REVISION', ''),
|
|
'base_url' => (string) env($prefix . 'EXTRACTION_BASE_URL', ''),
|
|
'api_key' => (string) env($prefix . 'EXTRACTION_API_KEY', ''),
|
|
'model' => (string) env($prefix . 'EXTRACTION_MODEL', ''),
|
|
'response_format' => (string) env($prefix . 'EXTRACTION_RESPONSE_FORMAT', 'json_schema'),
|
|
'max_tokens' => (int) env($prefix . 'EXTRACTION_MAX_TOKENS', 8192),
|
|
// Unset is portable; explicit true/false opts into the provider's Qwen chat-template extension.
|
|
'enable_thinking' => env($prefix . 'EXTRACTION_ENABLE_THINKING', null) === null ? null
|
|
: (filter_var(env($prefix . 'EXTRACTION_ENABLE_THINKING'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? 'invalid'),
|
|
],
|
|
'preview_verified_fingerprint' => (string) env($prefix . 'PREVIEW_VERIFIED_FINGERPRINT', ''),
|
|
'verified_fingerprint' => (string) env($prefix . 'VERIFIED_FINGERPRINT', ''),
|
|
];
|
|
}, ['qwen', 'openai'])),
|
|
];
|