CHANGELOG.md
## 2026-05-29 - GoSeek AI Workbench + aiepyc01 ### Added - aiepyc01: New Ubuntu 24.04 VM on EPYC ESXi, 60 vCPU, 280GB RAM - aiepyc01: Ollama 0.24.0 installed, listening on 10.133.133.2:11434 - aiepyc01: llama3.3:70b and llama3.2:3b models installed - jfmsrv01: Second NIC (ens192) added, 10.133.133.1/24, direct link to aiepyc01 - GoSeek: New Laravel/Filament AI workbench at /var/www/goseek port 8090 - GoSeek: 10 AI providers configured (Ollama, Anthropic, OpenAI, Google, Deepseek, Kimi, Groq, Mistral, xAI, Cohere) - GoSeek: Tool engine (read files, run commands, logs, database queries, Ollama management) - GoSeek: Groq API key configured and working (248ms response time) - GoSeek: AI Provider management UI with encrypted key storage - GoSeek: Full screen chat interface ### Architecture - Direct 10.133.133.x network for AI traffic bypasses Untangle - API keys encrypted with Laravel encrypt() - never plaintext in DB ## 2026-05-30 - Repair GoSeek AI Provider form namespace ### Fixed - Repaired GoSeek AI Provider Filament resource after the API key save patch caused a class namespace error. - Form input components such as `TextInput` now use the Filament Forms component namespace instead of the Filament Schemas namespace. - Confirmed Groq's existing API key remains stored and reports as encrypted without exposing the key value. ### Changed - Confirmed this server now uses the generic `/opt/jfmsrv01/scripts/` handover workflow, not the old `/opt/legaltranscribe/scripts/` path. ## 2026-05-30 - Fix GoSeek external provider key saving and selection ### Fixed - GoSeek `AiProvider` model now supports a virtual `api_key_input` attribute that encrypts into `api_key`. - AI Provider create/edit pages now preserve existing keys when the field is blank and pass new key input to the model mutator. - API key input is dehydrated only when filled, preventing blank edits from wiping existing keys. - Provider selector now returns enabled providers that are local or have a stored key. ### Security - API keys are still never pre-filled into the browser. - Verification reports only `empty`, `encrypted`, or `legacy_or_invalid`; it does not print key values. ## 2026-05-30 - Fix GoSeek OpenAI provider save using real api_key field ### Fixed - Replaced the virtual AI Provider key input save path with the real `api_key` model field. - `AiProvider::setApiKeyAttribute()` now encrypts raw browser input and preserves already encrypted values. - Edit form blanks the API key field before display so stored keys are never sent back to the browser. - Blank key field on edit keeps the existing encrypted key. - Provider selector continues to list only enabled providers that are local or have a stored key. ### Validation - Model save was tested inside a rolled-back transaction. - The test confirmed `enabled=yes`, encrypted key status, and successful decrypt match without persisting or printing a real key. ## 2026-05-30 - Add OpenAI model options for GoSeek selector ### Fixed - Added selectable OpenAI model options when the OpenAI provider has no models configured. - Updated GoSeek provider API output to return enabled local providers or enabled keyed external providers with model lists. - Updated `AiProviderSeeder` so OpenAI is no longer reseeded with an empty model list. ### Validation - `/chat-api/providers` was checked after cache clear. - Verification output reports provider visibility and model counts only; it does not print API keys. ## 2026-05-30 - Complete GoSeek provider dropdown loading fix ### Fixed - Completed the provider dropdown repair after the first patch script stopped on a Python regex escaping error. - Patched `ChatController::models()` safely. - Ensured `ProviderRouter::all()` uses normalised model options. - Normalised existing provider model data so `/chat-api/providers` no longer fails when models are stored as strings. ### Validation - PHP lint passed. - Direct `ProviderRouter::all()` was checked. - `/chat-api/providers` was checked for HTTP 200. ## 2026-05-30 - Fix GoSeek provider classification and OpenAI visibility ### Fixed - Normalised GoSeek provider records so only Ollama is treated as local. - Cloud providers are now classified as cloud/external. - OpenAI is enabled automatically when a saved key is present. - Provider API now strictly returns Ollama as local and keyed external providers as cloud. - Confirmed provider API returns JSON after cache clear. ### Security - No API key values are printed or published; checks only show key status. ## 2026-05-30 - Securely set GoSeek OpenAI provider ### Fixed - OpenAI provider was not visible in the GoSeek selector because it was not passing the enabled/keyed provider filter. - OpenAI provider was securely set using a hidden terminal prompt. - OpenAI is now classified as cloud, enabled, keyed, and configured with selectable models. ### Security - The OpenAI API key was not printed to the terminal, handover, changelog, or chat. - Verification output reports only key status, not key value. ## 2026-05-30 - Refresh jfmsrv01 handoff and publish PHP source - Replaced stale transcribe01/legaltranscribe wording with current jfmsrv01 generic server layout. - Updated workflow paths to /opt/jfmsrv01/scripts. - Documented mainsite, admin, GoSeek and handoff portal. - Published first-party PHP source browsers for active development inspection. - Excluded .env, vendor, node_modules, storage logs/cache, sessions and private files. ## 2026-05-30 - Fix handoff aliases and add fresh run publishing ### Fixed - Non-slug aliases such as /server/HANDOVER.html now read from the canonical slug tree instead of stale root-level files. - Added no-cache headers to the handoff HTTPS vhost. - Redirected the accidental missing-v slug to the canonical slug. ### Added - Added /opt/jfmsrv01/scripts/publish_fresh_handoff_run.sh. - Each fresh publish creates /runs/<timestamp>/ so ChatGPT/browser inspection can use a new URL and avoid stale cache. ## 20260530-160357 - Publish fresh handoff run ### Changed - Published unique cache-busting handoff run: runs/20260530-160357/ - Updated latest-run pointers. - Added fresh run links to the canonical handoff index. ### URLs - https://vqngx6j8dc9q1lvt7g2a7a646q2t.jfmcommunications.com.au/vqngx6j8dc9q1lvt7g2a7a646q2t/runs/20260530-160357/ - https://vqngx6j8dc9q1lvt7g2a7a646q2t.jfmcommunications.com.au/vqngx6j8dc9q1lvt7g2a7a646q2t/runs/20260530-160357/server/HANDOVER.html - https://vqngx6j8dc9q1lvt7g2a7a646q2t.jfmcommunications.com.au/vqngx6j8dc9q1lvt7g2a7a646q2t/runs/20260530-160357/source/goseek/index.html ## 2026-05-30 - Fix GoSeek AI Provider API key saving through the UI ### Fixed - AiProviderResource api_key field declared dehydrated() twice; the trailing dehydrated(false) won, so the field was stripped from the form payload and the Create/Edit page mutators never received it. No API key entered in the UI was ever persisted. - api_key now dehydrates only when filled; blank-on-edit preserves the existing encrypted key via the page mutators. This also restores cloud provider visibility in the chat selector, since ProviderRouter::all() requires a key. ### Security - API keys remain encrypted at rest and are never pre-filled into the browser, printed, logged, or published.