Mount the live per-host cert instead of the expired wildcard secret
The cert-converter init container built its PKCS12 keystore from wildcard-kamocrm-com, a legacy multi-SAN secret that cert-manager orphaned when its Certificate...
Stop pinning the expired wildcard-kamocrm-com secret
wildcard-kamocrm-com was a legacy multi-SAN secret that cert-manager orphaned when its Certificate was repointed at a per-host secret. Nothing renewed it and it...
Stop pinning the expired wildcard-kamocrm-com secret
wildcard-kamocrm-com was a legacy multi-SAN secret that cert-manager orphaned when its Certificate was repointed at a per-host secret. Nothing renewed it and it...
Stop pinning the expired wildcard-kamocrm-com secret
wildcard-kamocrm-com was a legacy multi-SAN secret that cert-manager orphaned when its Certificate was repointed at a per-host secret. Nothing renewed it and it...
Stop pinning the expired wildcard-kamocrm-com secret
wildcard-kamocrm-com was a legacy multi-SAN secret that cert-manager orphaned when its Certificate was repointed at a per-host secret. Nothing renewed it and it...
Stop expired/orphaned secrets shadowing live per-host certs
update_tls_store() rebuilt the TLSStore from a plain Secret listing, bucketed only on name prefix and type, with no check that a Certificate still owned the sec...
Edit what each model costs
Adds per-model price editing to the provider setup screen. Prices are seeded from each vendor's published list price where we know it, and blank where we do not...
Model pricing catalog, write path and backfill
Cost accounting could never work: AiModel has price columns, AiModelController reads them and ChatOrchestrationService reads them to compute costEstimate - but ...
Show the AI handoff context to the agent taking over
Renders an AI_HANDOFF system event as a card with the reason, the AI's summary, and a collapsible transcript of the conversation so far - so the borrower does n...
Proxy the public AI->human handoff route
Adds POST **************** proxied to MediaService alongside its createSupportSession sibling. Without this the handoff feature was dead on arrival: MediaServi...
Carry the AI conversation into the human thread on handoff
Creates or reuses the support session, copies the AI transcript in as one system event, routes it, and tells the visitor honestly what happens next. Confidenti...
Agent-initiated handoff to a human, with context
The AI could not previously ask for a person: escalation rules reached the model via the compiled prompt, but there was no machine-readable signal back, so the ...
Accept agent-authored outreach into an open borrower thread
The counterpart AIService's outreach dispatcher calls. Without it the whole outbound path terminated in a recorded 404 - the gate authorized a touch, the messag...
Outbound triggers, scheduler and web-chat dispatch
Makes the outreach spine actually fire. The gate, contact state, consent and audit already existed; nothing caused a touch to be evaluated. - NATS enabled for ...
Required-text editor; dedupe AI general settings; fix model toggle
Adds an editor for org-wide required opening/closing text - the compiler and columns existed but nothing could set them, so the capability was dead. Copy states...
Persist org-wide required text and apply it immediately
AiOrgSettings gained forcedPreamble/forcedFooter and SalesAgentCompiler already folds them into every agent, but the settings controller neither read nor wrote ...
Reject cross-org sales agents; widen bootstrap cache busting
salesAgentId was persisted from the request body unchecked, so a cross-org or dangling agent id could be stored on a WebChatIntegration. It failed safe only bec...
Anthropic dropped every system message but the last
buildRequestBody assigned rather than accumulated the system field, so with more than one system message only the final one reached the model. In practice that ...
Full-page AI Sales Agent studio, replacing the modals
The agent editor was a ~800px MUI Dialog whose entire surface was a 10-row textarea, on the one AI tab that used a dialog at all. It is now a dedicated route, a...
Locked rules survive a section or whole-document override
An author taking over a rule section by hand replaced the entire section body, which silently discarded the locked pack rules inside it - so 'never quote a rate...
Stamp the borrower quote's actor from the session
The quote requires createdByMemberId and the browser must never supply it. memberId(req) is hoisted out of the party-check branch so it resolves for stewards to...
Sales-agent compiler, versioning, outreach gate; fix tool replay
Structured agent config compiles to the system prompt, freezes per published version, and gains the gate an agent must pass before initiating contact. Compiler...
Structured sales-agent config, version spine and outreach state
Replaces the single training-context blob with a structured, versionable agent model, and adds the per-contact spine an agent needs before it may initiate conta...
Correct the CATALOG_SOURCE ordinal — every rate-sheet upload was rejected
ImageAssocType.CATALOG_SOURCE is id 14 but ordinal 12: the ids skip 6, so id is not ordinal+1 past SYSTEM_WIDE. The panel sent 13, which is out of range for a 1...
AI Sales Agents tab + per-channel agent assignment
Builds out /settings/ai?tab=sales-agents (was a stub): orgs create agents for their sales industry, either from a built-in template or by writing the training c...
Enrich borrower chat routing + capture subject-property state
chat-routing now returns the assigned officer's NMLS, title, photo, phone, email and whether they hold a valid license for the subject-property state, plus the ...
Assign a sales agent per channel + report LO availability
- WebChatIntegration CRUD threads salesAgentId (null clears the assignment) - lo-presence now returns the member's availabilityStatus alongside online, so the ...
Sales-agent CRUD, mortgage template, and agent-driven chat prompt
- AiSalesAgentController (/api/ai/sales-agents): org-scoped CRUD + GET /templates - SalesAgentTemplateRegistry: built-in starter templates, beginning with a m...
SalesAgent entity + per-channel agent assignment
Org-configurable AI sales agents: a named agent for a sales industry, programmed with a training context the org authors (from a template or by hand), assignabl...
Translate the steward console panels; drop the label escape hatch
Catalog, Identifiers, Ingestion, Loan Sale Desk and the Pipeline table rendered hardcoded English inside a console whose other screens were fully translated. Al...
Streamed replies were dropped, persisting blank assistant messages
Every successful chat completion came back as an EMPTY assistant bubble. The assistant rows were being saved with content_len=0 and is_error=false, so there was...
Send AIService the secret it actually validates
The vision-capability proxy authenticated with internal.auth.secret, but AIService validates **************** — a different secret. Confirmed live: the console ...
LoanTransactionService ctor gained LeadRealtimePublisher param
assignLoanOfficer now publishes the chat-routing event, so the service ctor takes a 10th arg (LeadRealtimePublisher). Update the unit test's direct instantiatio...
Resolve the k1m1 npm registry host inside the build container
kamo-internal has not deployed since 2026-07-16: every build died in npm ci with ENOTFOUND k1m1 while fetching the private @kamo/* packages, which package-lock....
Auto-provision platform-managed MLOS chat + serve site key by host
- ManagedChatIntegrationService: lazily mint the org's platform-managed SPECIFIC_AGENT WebChatIntegration on first access. KamoMLOS is first-party: org resolv...
Verify routing token, persist leadUid, reassign chat on lead move
- createSupportSession takes a signed routingToken (not preferredAgentMemberId); verified via ChatRoutingTokenCodec + cluster internal.auth.secret, enforces ...
Signed agent-routing token + lead-reassignment propagation
Foundation for making the reusable public-chat widget handle the KamoMLOS borrower->loan-officer variant securely, and for propagating lead reassignment into an...
Try the next model when a vision model rejects the image
Probing production again after the modality fix, routing moved from a text-to-speech model to o3-mini — an o-series reasoning model that also takes no image inp...
Stop routing vision to text-to-speech models
Found by probing production: org 1188756624575266822's vision calls resolved to gpt-4o-mini-tts-2025-03-20 — a TEXT-TO-SPEECH model — so every vision call retur...
Use next-intl keys for the Mobile Devices strings
Swaps the literal labels added with the Devices sub-tabs for **************** and .mobileDevices.* keys, now published in the translation dictionary (CI fans th...
Fold Document QC into Documents & Conditions; PDF ingest notices
Document QC had its own steward screen for work that is the same documents, on the same loans, done by the same reviewer. Splitting it across two tabs made some...
Expose vision capability so the console can explain a missing provider
PDF rate sheets are read by the org's configured vision provider. When none is configured the AI call fails the same way a model error does, so the console had ...
Inline image vision + tier fallback that prefers stronger over weaker
Two limits made org-configured vision unusable for whole classes of caller. 1. Vision was URL-ONLY. Every caller had to stand up public, provider-fetchable ser...
Split Devices into "Phone System(s) Devices" + "Mobile Devices"
The Devices tab now has two sub-tabs. The existing PBX/softphone hardware table moves under "Phone System(s) Devices" unchanged; the new "Mobile Devices" tab M...
Org-admin endpoints for mobile device policy + enrolled devices
Backs the new "Mobile Devices" sub-tab under Settings → Features → Phone → Devices (its sibling "Phone System(s) Devices" stays on VOIPService and covers - GET...
Ingestion panel accepts spreadsheets, not just CSV
The extractor now reads .xlsx/.xls and sniffs the format from the file itself, so the picker no longer restricts to CSV and the copy says plainly what is readab...
Steward Ingestion tab + the Catalog/Identifier proxy routes that were missing
Rate-sheet ingestion existed end-to-end in the backend and none of it was reachable. This adds the one surface that walks the whole chain: upload an investor's ...
A bad assocType index is a 400, not a 500
The upload/register paths indexed ImageAssocType.values() with the client's raw index, so an out-of-range value surfaced as an ArrayIndexOutOfBoundsException (5...
CATALOG_SOURCE assoc type for MLOS catalog source documents
Investor rate sheets / LLPA + eligibility matrices / lock policies need somewhere to live: the ingest extracts from the blob, and the published rate-sheet versi...
Gateway for candidate review + rate-sheet promotion
Exposes the two new catalog promotion writes to the steward console under the existing MLOS steward gate, with organizationId server-stamped from the operator s...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
