Nenda kwenye maudhui
KAMOUniverse

Mabadiliko

Nini kipya.

Kila kuboresha jukwaa, kama ni meli.

  1. · kamo-internal

    Uteuzi wa wingi unaongoza kwa mwanachama wa timu

    The grid already had multi-select checkboxes but nothing to do with a selection. Checking rows now reveals a Reassign action beside the other lead actions, gated on REASSIGN_LEADS_MANUALLY (the server re-checks it; this is convenience only). Uses checkRight rather than checkRole so god mode matches the backend's hasGod bypass — checkRole doesn't bypass and would diverge for god users. The dialog picks one destination member by search, takes an optional note, and says up front that the member will be emailed, since that's the point of the feature. Indigo/blue rather than Hot Reassign's orange/pink: this is a deliberate bulk admin action, not an urgent call transfer. The header checkbox selects every row in the client-side grid — thousands for a large org — so the 250 cap is enforced here too. Otherwise the headline "select all and reassign" flow would fail server-side only after the user had filled in the entire dialog, with an untranslated error. Selection is cleared through selectedIdsRef before reloading: loadLeads re-selects whatever that ref holds, so leaving it populated would re-check the rows just moved. The result message is composed rather than an else-if chain, because a batch can be both partial and unnotified and the chain reported only the first.

  2. · SecurityService

    Bulk-reassign endpoint, gated on REASSIGN_LEADS_MANUALLY

    A a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a Wajumbe na barua pepe ambazo wanachama mara moja kwa kila kikundi. Uidhinishaji hutumia REASSIGN LEADS MANUALLY (149) - haki iliyopewa jina hasa. ya hayo. Njia hii ni rahisi zaidi kuliko njia nyingine yoyote. checks ASSIGN LEADS; reassigning 100 inaongoza ni mlipuko tofauti radius Na kwa upande mmoja, na kwa upande mwingine, wana haki mbili. Pia, mfumo wa mizizi usio na mizizi unaweza kutumika hapa. Kujiandikisha ni kuonekana Jibu: Baada ya kuwaongoza ni kwa mwombaji anayesoma kama "Nimepewa", ambayo Inainua usomaji usio na saini 403 na inaruka mask ya kuwasiliana-info. Bila ya haya Angalia simu inayoshikilia 149 lakini sio VIEW UNASSIGNED LEADS inaweza kusababisha Wavuvi hao waliondolewa na kuondolewa kwenye vifusi vyao. Ski ya Inaongoza ripoti ya NOT FOUND - inayolingana na kile gridi yao ya taifa inaonyesha - kwa hivyo majibu Haiwezi kuhesabu maelekezo ya siri au ya kigeni. Si kila kitu ni cha bure, kila kitu ni bure. Shughuli na id mbaya inakuwa kuruka, kwa sababu kuacha tisa nzuri Taarifa juu ya kumi ni mbaya zaidi kuliko taarifa ambayo mtu hakuchukua. Capped katika 250 kwa wito kwa kufunga wote locks mstari na shabiki muda halisi. Notifier hutatua data yake katika shughuli fupi kupitia bean tofauti na kutuma baadaye, hivyo wito outbound na 30s kusoma timeout kamwe pins Uhusiano wa benki ya CRDB. Kuvuka mipaka ya bean ni nini kinachofanya @Transactional kutumia wakati wote - kujichochea kwa kimya bila shughuli yoyote na Kampuni ya mwenyeji wa wavuti ya LAZY itafungua.

  3. · EmailService

    Sample variables for the LEADS_ASSIGNED template

    Without a case here the admin template editor's Preview renders the new template with every placeholder blank, which reads as a broken template rather than an unfilled one. notesBlock is pre-rendered HTML because the renderer has no conditionals — the sender collapses it to "" when there is no note.

  4. · kamo-shared-library

    LEADS_ASSIGNED email template; harden assignLead for bulk use

    assignLead had zero callers and had never run in production. Before wiring the bulk reassignment path to it, give it the guarantees that path needs: - take orgId and verify BOTH the lead and the new assignee belong to it, so a reassignment can't reach across tenants (reported as "not found" rather than "forbidden" so the error can't be used to probe foreign lead ids) - lock the row with findByUidForUpdate: a manual reassignment and a concurrent pool-accept target the same lead and would otherwise interleave into a lost update - clear the pool flags, mirroring CreditLeadAssignmentService. A lead marked for auto-assignment otherwise stays in the pool after being claimed by hand and gets taken out from under its new owner - publish chat routing, as updateLead already does, so the borrower's open live chat follows the lead instead of staying with the previous officer Also add the LEADS_ASSIGNED canonical template. The key must be in CANONICAL_KEYS or it can never be seeded and can never self-heal, and every send returns a permanent 404.

  5. · kamo-shared-library

    Add MANAGE_ORG_BRANDING (174)

    Org branding endpoints (logos, colors, backgrounds, theme provisioning) were owner-or-god only, leaving no way to delegate branding without handing over ownership of the org. Adds the delegable right; owner checks stay as an implicit grant so existing owners keep working without being assigned it.

  6. · kamo-internal

    Ustahiki wa mwandishi matrices kutoka kwa jopo la catalog

    Bila matrix inayofunika kazi ya hali na kusudi, bei inarudi NO COVERAGE - Kwa hiyo, kabla ya hii, kununua tu ya makazi ya msingi inaweza kuwa bei. Waandishi wa A matrix na seli zake kwa aina ya kikomo cha kuchaguliwa, occupancy na kusudi, na seli ya kuongeza / kurejesha Kwa upande mwingine, pamoja na fomu ya lock-policy katika jopo moja. Kuacha bidhaa unset waandishi tumbo moja kwa bidhaa ACTIVE ya mwekezaji, kwa sababu Ukubwa wa bidhaa ya matrix sio NULL na haiwezi kuonyesha "bidhaa zote" kama mstari mmoja.

  7. · SecurityService

    Relay eligibility-matrix authoring; rebuild picks up the SUSPENDED resume

    Maelezo ya Post ****** kupitia maandishi ya sasa Msaada, kwa hivyo waandishi wa msimamizi hupanda tu kwa mpangaji wao. Msukumo huu pia unajenga dhidi ya mabadiliko ya pamoja yalib ambayo inaruhusu kurudi kwa mkopo. kamo-shared-library haina CI yake mwenyewe - kila clones huduma na hujenga kutoka chanzo - Ili kurekebisha huduma hii tu wakati huduma hii inajengwa.

  8. · kamo-internal

    Rebuild the agent studio as a full-width workspace

    Removing the width cap was not the fix; the layout itself needed to be designed for the space rather than tolerated in it. The studio is now three zones side by side: - **Outline rail** — the sections, with the current one highlighted as you scroll (IntersectionObserver, top-weighted so a section becomes current when its header reaches where attention actually is). Sections written by hand are marked, so a hand-written part is findable later without opening every one. - **Editor** — the sections themselves, tiling into as many columns as the viewport holds instead of one narrow ribbon. - **Live conversation** — a real column on a wide display, not a strip that collapses the content when opened. This is the edit-and-watch loop the studio exists for: change an instruction, see the answer change, without navigating. One TestDrivePanel instance, repositioned rather than duplicated — mounting it twice would start two throwaway sessions. Below xl it drops beneath the editor as a full-width row rather than squeezing a third column onto a display with no room for one, and the rail hides entirely on small screens.

  9. · kamo-internal

    Author lock policies — without one, no rate can be locked at all

    RateCommitmentService refuses a lock whenever the priced result carries no lockPolicyVersionId ("lock-policy version is required"), and a result only carries one if the investor has a published lock-policy version. No UI could publish one, so rate locking was unreachable for every tenant — while the endpoint itself was already built, org-gated and superseding correctly. Only the client method and this form were missing. The form takes the offered lock periods as an ordered list because the FIRST becomes the default, so it deliberately does not sort them; entries that are not a positive whole number of days are dropped rather than sent as a bad lock term.

  10. · kamo-internal

    Onyesha jinsi kila mfanyakazi anavyofanya

    Inaongeza sehemu ya utendaji juu ya studio ya wakala: mazungumzo, jinsi Mara nyingi mtu alichukua juu na nini kilichosababisha, matokeo ya kufikia, na gharama. Imeandikwa ili hakuna takwimu inaweza kupotosha: Zero hutoa kama neno "Hakuna", kamwe 0. - Kushiriki hutoa tu wakati kuna denominator; vinginevyo 'Hakuna mazungumzo Na badala yake jiepusheni navyo.” Hakuna kiwango cha chini cha tarakimu. Wakati hakuna kitu katika kipindi kilichobeba gharama, hakuna takwimu ya gharama iliyoonyeshwa kabisa - Taarifa hiyo ilieleza kuwa bei ya bidhaa hiyo ilipanda baada ya ajali hiyo. Sehemu ya Taarifa inaonyesha kiasi pamoja na jinsi majibu mengi ni kukosa kutoka. - Kuondolewa kwa ufikiaji kunawasilishwa kama kipengele ambacho ni: "Hizi zimehifadhiwa "Mawasiliano - ni rekodi yako ya kwa nini mtu hakuwasiliana." codes enum haijulikani degrade kusoma maandiko badala ya njia ya msingi. Ujumbe wa kupotosha na safu za mkono ziliondolewa: API haijumuishi Kwa mfano, wapo watu ambao wanabishana juu ya nani yupo Ilikuwa imepimwa. Mazungumzo peke yake kujibu nini meza ni kwa - ambayo kuokolewa Picha ya gari ambayo imebeba trafiki. Imewekwa kwenye hati ya kitabu cha sasa badala ya tab mpya, na Weka orodha ya wakala, ambapo alama 0 dhidi ya kila wakala itakuwa sahihi Kupuuza kunakatazwa.

  11. · AIService

    Per-agent scorecard

    Nini kila wakala kweli alifanya: mazungumzo, mara ngapi mtu alikuwa na kuchukua Na kwa nini, matokeo ya kufikia ikiwa ni pamoja na yale yaliyochukuliwa nyuma, na ni gharama gani. Kila data ni moja ambayo inaweza kusaidia. Mambo matatu kwa makusudi Sio hapa: * Hakuna maelezo ya jumla* Wao ni kweli juu ya njia ya kwenda na kurudi. Kwa mfano, katika aya ya 4 ya sura hii, kila kitu ni kamilifu. Majibu ya gharama swali la msingi, kwa sababu ni badala ya kufikiri ambapo Bei yake haijulikani. * Hakuna kiwango cha uharibifu au uharibifu* Haijalishi kama mazungumzo Mwisho mzuri, na "hakuna handoff kilichotokea" sio ushahidi wa mafanikio. * Hakuna ujumbe wa kupotosha au hesabu za mkono.* Hawa nao si wa kulaumiwa. Na kwa upande mwingine, ikiwa ni pamoja na 0, itakuwa na maana kwa ajili yao. Kiwango - kushindwa kwa usahihi screen hii ipo ili kuepuka. Gharama hubeba bendera iliyofuatiliwa wazi na kiasi cha null badala ya 0 wakati Hakuna kitu katika dirisha ilikuwa bei, hivyo org ambaye trafiki predates bei anaona "Haikuandikwa" badala ya $ 100. Bei za vyakula ni mamlaka ya kuliko jumla, hivyo zero halisi kutoka simu za bei nafuu bado kusoma kama ufuatiliaji. Tafsiri ya Transcript imefunguliwa kwenye VIEW SALES AGENT TRANSCRIPTS tofauti na hesabu - muhtasari wa mfano wa mgeni maalum ni maudhui ya mazungumzo, sio mita ya mraba. Wakala wasio na trafiki kurudi alama kamili ya alama: wakala kukosa kutoka orodha kusoma kama mdudu, wakala sasa na zeros kusoma kama ilivyo kweli. Na sasa, njia ya upatanisho ni njia ya upatanisho. Kwa hiyo, ushirikiano wa sababu zuliwa kwa wengine hauwezi drift kati ya mbili. Kuna aina 150 za mimea, kijani.

  12. · kamo-shared-library

    Grouped aggregate queries for the agent scorecard

    Twelve @Query aggregates across sessions, messages, usage records and outbound touches, so a scorecard is a handful of grouped queries rather than loading rows into memory. Two properties are enforced in the predicates rather than left to callers: - **isTest sessions are excluded in the query itself.** On a young agent the author's own test drives would otherwise be most of the data, and a caller who forgets to filter produces numbers that look real and are not. - **count(costEstimate) counts only NON-NULL costs.** That is what lets the scorecard distinguish 'nothing was priced' from 'it cost zero' - collapsing those would put a confident $0.00 in front of an org whose traffic simply predates pricing. Outbound touches are grouped by decision rather than filtered to sends. The refusals are the more interesting half: an agent whose touches are nearly all SUPPRESSED_QUIET_HOURS is misconfigured, and that is invisible if decoders are discarded.

  13. · kamo-internal

    Jinsi ya kufanya kila aina ya gharama

    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 - a blank means cost simply is not tracked for that model, which is better than a number that is confidently wrong. Copy tells people to check the seeded figures against their own bill rather than presenting them as authoritative. Fixes a display bug caught in review: the trailing-zero trim would have rendered a price of 10 as 1. It now strips zeros only after the decimal point.

  14. · AIService

    Model bei catalog, kuandika njia na nyuma

    Akaunti ya gharama haiwezi kufanya kazi: AiModel ina safu za bei, AiModelController Kusoma yao na ChatOrchestration Service kusoma yao kuhesabu gharama - lakini Hakuna aliyeandika popote. Ni kwa njia hii tu ndipo wataalamu wanapogundua kuwa Hakuna mtoa huduma wa API anarudi bei. 140 mifano, 0 bei, hakuna njia ambayo Inaweza kubadilika. Nguzo hizo zilikuwa za kimuundo zisizoweza kufutika. Sehemu tatu: - ModelPricingCatalog mbegu muuzaji LIST bei katika ugunduzi, vinavyolingana juu ya Kitambulisho cha kawaida na utawala wa prefix ya hyphen-boundary hivyo gpt-4 haiwezi kamwe Kwa mfano, gpt-4o. Mifano isiyo ya kuzungumza (TTS, embeddings, realtime) ni kukataliwa na Tumia tena ukaguzi wa modality - wanaondoa karatasi tofauti. - PatCH endpoint + UI hivyo org inaweza kurekebisha au kufuta bei. Org-scope kwa usahihi kama ilivyo sasa. Backfill inajaza safu tu za NULL, kwa safu kwa kujitegemea, na kamwe Inaandika juu ya kile org imeweka - vinginevyo kufanya bei kuhaririwa itakuwa ya uongo. Idempotent, na kufungwa kwa akaunti ya gharama haiwezi kamwe kuzuia boot. ** Mfano sisi si ujasiri juu ya kupata hakuna bei badala ya kubahatisha moja. ** GPT-5, o3, Mistral zaidi, DeepSeek, xAI, Cohere na Meta ni tupu kwa makusudi. OpenRouter na HuggingFace kamwe mechi kwa kubuni, kwa kuwa wao bill viwango vyao wenyewe. Na bei ya juu ya hisa itakuwa ni Sh. Bei mbaya husababisha Takwimu ya sura ya ankara ambayo ni sahihi kwa ujasiri - sababu hiyo bado ni gharama Wala hakuna njia ya mkato katika kuhesabu. Kubadilisha safu ya per-1k hutumia RoundingMode. Tarehe ya kuzaliwa: Bei Unahitaji zaidi ya vipande vya 6 kwenye darasa-init badala ya kuhifadhi kimya kimya Kwa sababu ya hii, na inaachwa wazi. Mradi huo una jumla ya majaribio 145, ya kijani.

  15. · kamo-internal

    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 not have to re-explain themselves to the person who picks up. The three degraded states are explicit and visible rather than silent: transcript unavailable, transcript truncated, and payload stripped in transit. An agent must never be left believing they have the full context when they do not. Visitor and agent share one STOMP topic, so the live frame arrives redacted (the AI's summary is its private assessment of the visitor and cannot go to their browser). Rather than telling the agent to reload, the card re-reads the full row once from its own authenticated endpoint. The re-read is validated before it is adopted - a response that came back still-stripped is rejected rather than used, so the warning can only ever clear when context was genuinely gained. Any failure falls back to the reload message.

  16. · APIService

    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: MediaService's endpoint hard-requires X-Internal-Auth, X-Public-Chat-Org-Id and X-Public-Chat-Key-Hash, which only this gateway injects, so the widget's POST 404'd here and never reached it. Carries the same conditional *** guard as createSupportSession. Handoff runs the full session-creation path, so proxying it bare would have left a ticket-creating route that bypasses the proof-of-work its sibling enforces.

  17. · MediaService

    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. Confidentiality is split by audience, which the first pass got backwards. The AI's summary and reasonDetail are its private assessment OF the visitor, and the full payload was reaching the visitor's own browser through two REST doors and the STOMP frame while the agent saw nothing. Redaction now applies at every visitor-facing path; the persisted row keeps the full payload for the agent. chat.session.{guid} is a single topic both audiences subscribe to, so the live frame is cut to what the visitor may see and the agent UI re-reads the full row from its own authenticated endpoint. Idempotency is keyed on aiSessionGuid, org-scoped, and checked BEFORE creating anything. Keying it on the session and checking after creation - the obvious shape - is useless precisely when it matters: a retry that lost its session token always passes the check and produces a duplicate ticket and a second agent page. transcriptAttached now reports what actually happened. It previously came back true even when the write had silently failed, which is the worst possible combination: the visitor is told their context came across, the agent's thread is empty, and neither party knows. Copy-on-handoff, not migration: AI turns stay where analytics reads them.

  18. · AIService

    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 model could only SAY it would fetch someone and nothing happened. - Synthetic kamo_request_human tool, described from the agent's own enabled escalation rule titles so the model sees identical trigger conditions in the prompt and the tool. Intercepted before MCP dispatch - it is a signal, not a real tool call - and the TOOL row it persists is what makes the reason durable and analytics-ready with zero new columns. - Attached ONLY when the channel actually has live support enabled. Handing an AI-only org a tool that promises a human who can never arrive is worse than having no tool: the widget has no Support tab, so the signal is dropped and the visitor is left waiting for someone who was never coming. - New internal endpoint returns the handoff reason, the AI's summary for whoever takes over, and the USER/ASSISTANT transcript. TOOL and SYSTEM rows are excluded - the human needs the conversation, not the machinery. - reasonDetail and summary are deliberately withheld from the visitor's browser: they are the model's private assessment OF the visitor. Only {requested, reason} crosses to the client; MediaService fetches the rest server-side. - AI turns are never moved or deleted. AiChatMessage stays the analytics system of record; the human side gets a copy. Also fixes a latent bug found on the way: the tools block ignored the per-model supportsToolUse flag, so a model explicitly flagged as not supporting tools was still sent them. 31 of 140 models are flagged false; ai_mcp_server_configs is empty cluster-wide, so today's blast radius is zero. Suite is 124 tests, green.

  19. · MediaService

    Kukubali kuingizwa kwa wakala katika thread ya kufungua

    Simu ya mpokeaji wa AIService. Bila ya yote haya Njia ya nje imefungwa imefungwa imefungwa katika 404 iliyorekodiwa - lango liliruhusu kugusa, Ujumbe uliandikwa, na hakukuwa na mahali pa kuiweka. Umiliki unakaa umegawanyika kwa makusudi: AIService huamua wapi kugusa inaweza kwenda nje Na kuandika maandiko, huduma hii inaiweka. Kuandika safu hizi kutoka kwa AI Service itazuia umiliki wa nakala kwa huduma ambayo haina chat Sindano au soketi. Kuna mambo mawili ambayo hawezi kufanya. Hakuna haja ya kuwa na mazungumzo ya moja kwa moja - kuwasiliana inaweza kuendelea. Thread mgeni tayari kufunguliwa, kamwe conjure dirisha chat katika mtu ambaye Haikuwa hivyo. Na kamwe hutavuka augs: uid kuongoza kutatua kwa tiketi nyingine ya org Angeweka wakala mmoja wa org ndani ya mazungumzo ya org, kwa hivyo org ni Kukagua tiketi badala ya kutegemea kutoka kwa mpiga simu. Ujumbe unahusishwa na mwanachama wa kikao, hasa kama ujumbe wa mgeni Hii ni - si kwa ajili ya mtu binafsi. Kwa mujibu wa taarifa iliyotolewa na Mhe. Ingawa mtu aitwaye, leseni aliandika ni nini utawala wa AI-disclosure upo kuzuia. kuhakikisha usajili kabla ya NATS kuchapisha kwa sababu watumiaji hutumia kutoa huduma. New: kuchapisha kwanza kutaendelea ujumbe lakini kuacha kutoka Kila mteja aliyeunganishwa. Inarudi id zote na ujumbe ili logi ya ukaguzi wa ufikiaji Ujumbe huu unahusu ujumbe badala ya thread. 404 wakati hakuna thread wazi Kwa hiyo mpiga simu ana rekodi ya kushindwa safi badala ya kuchukua utoaji.

  20. · AIService

    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 AIService via its own k8s/configmap.yaml (each Java service carries its own k8s dir; KlusterServices holds only cluster infra). JetStream is deliberately left OFF: NatsConfig asserts its own replication-factor against centrally-provisioned streams at startup, and AIService only subscribes to core NATS and publishes nothing, so enabling it would gain nothing and risk a second service asserting replica counts. - AgentOutboundConsumer subscribes security.leads.rt.> and consumes ONLY LEAD_CREATED/LEAD_UPDATED. The publisher also emits lock and stats events - reaching out to a person because a colleague took an edit lock on their record is not defensible. Ids arrive as strings from the publisher, so they are parsed as text rather than asLong(). - AgentOutboundScheduler evaluates schedule triggers under four bounds: org set derived from agents that actually have outreach on (capped), a thin sliding time slice so cost tracks new-lead rate rather than total leads, a per-tick row cap, and a re-evaluation damper so a lead crossing during quiet hours is retried once rather than every tick for a day. - Composition seeds textComplete with the PUBLISHED version's compiled prompt, never the draft, plus the trigger intent. Composition failure records FAILED; there is no canned fallback message. - WEB_CHAT dispatch continues an existing thread only. Outreach may resume a conversation the visitor opened; it may not conjure a chat window at someone who never opened one. - SMS/EMAIL/SOCIAL_DM route to a recorded FAILED naming the missing compliance plumbing, so an org pointing a trigger at SMS sees why in the outreach log immediately instead of nothing happening. 23 new tests; suite is 68 and green.

  21. · kamo-internal

    Mhariri wa maandishi unahitajika; dedupe AI mipangilio ya jumla; kurekebisha mfano wa kugeuza

    Inaongeza mhariri kwa maandishi ya kufungua / kufuta - mwandishi na Nguzo zilikuwepo lakini hakuna kitu kilichoweza kuwaweka, hivyo uwezo ulikuwa umekufa. Nakala ya nakala Anasema wazi kwamba mawakala hawawezi kuiondoa na kwamba kuokoa inatumika kwa kila kwa haraka, na ripoti ya toast inaonyesha jinsi mawakala wengi walichapishwa badala ya Ni zaidi ya "kuokoa" kwa sababu mawakala wa kuishi walibadilisha tu kile wanachosema. Vipeperushi viwili vya zamani vilipatikana njiani: Kubadilisha mfumo bora wa "Auto-select" haijawahi kufanya kazi. Upande wa mbele Soma data.autoSelectModel na kutuma autoSelectModel, lakini backend anarudi na Inatarajia autoModelEnabled - hivyo toggle daima imekuwa kweli na thamani yake ilikuwa Kuokoa kila kitu unachopata. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - AiGeneralSettings.tsx ilikuwa nambari ya wafu, haijawahi kuingizwa, wakati inline ya verbatim duplicate aliishi chini ya UsalamaModelsTab.tsx. Badala ya kutumia Nakala zinazohitajika mara mbili, duplicate imefutwa na SecurityModelsTab inaagiza sehemu ya pamoja. Pia inachukua nafasi ya vidokezo vya msaada wa mauzo, ambayo bado iliwaambia watumiaji kipengele hicho kilikuwa kuwasili hivi karibuni.

  22. · AIService

    Endelea kutumia maandishi yaliyohitajika na uyatumie mara moja

    AiOrgSettings kupata forcedPreamble/forcedFooter na SalesAgentCompiler tayari Inawaunganisha katika kila wakala, lakini mtawala wa mazingira hakusoma wala kuandika - Kwa hiyo uwezo ulikuwa umekufa: uokoaji ulionekana kufanikiwa na kurudi Bonyeza kwenye reload. Sasa rudisha maeneo yote mawili (ikiwa ni pamoja na kwenye defaults za mipangilio) na PUT Endelea nao, normalizing tupu kwa null hivyo kusafisha shamba kwa kweli Badala ya kuacha kamba tupu ili kukunja kama separator. Nakala zinazohitajika sasa inachukua athari mara moja, kwa kurekebisha na kuchapisha tena Kila mwanachama wa org. Kuruhusu kutumika kwenye kuchapishwa kwa kila wakala Alikuwa nafuu na ni mtego: admin ambaye anaongeza 'kila wakati anasema wewe ni automatiska Msaidizi 'ataamini ni hai, na wakala hakuna mtu kinachotokea kuchapisha tena Nitaendelea kuzungumza kwa muda usiojulikana. ambayo inahitaji utulivu wa hali ya juu ambayo inafanya Si mbaya zaidi kuliko kutoa moja. Kila mtu aliyeathirika aokolewa nakala imeandikwa na kwa nini, na majibu ripoti ni wangapi walikuwa kuchapishwa hivyo Unaweza kusema kile kilichotokea badala ya "kuokolewa".

  23. · kamo-internal

    Ukurasa kamili wa AI Sales Agent studio, kubadilisha modals

    Mhariri wa wakala alikuwa ~ 800px MUI Dialog ambaye uso wake wote ulikuwa na urefu wa futi 10 Nakala, kwenye tab moja ya AI ambayo ilitumia mazungumzo kabisa. Sasa ni wakati wa kujitolea Njia, na mfano wa uhariri nyuma yake ni muundo badala ya blob moja. - Mipangilio /ai / mauzo-umri / mpya - safu ya 720px, sio studio. Kadi za Tarot (Chama ni sekta, hivyo hakuna kushuka kwa sekta), kisha mashamba mawili: jina na sentensi moja kuhusu biashara. mtu anayefanya kazi chini ya dakika moja. -/settings/ai/sales-agents/[id] - upana kamili, hati moja ya scrolling na fimbo Kichwa cha sehemu, maudhui yaliyofungwa kwa 880px kwa hivyo pembejeo za mstari mmoja hazijawekwa Katika maonyesho ya 4K. Hakuna 240px nav reli: sehemu tisa ni kitabu-spy kazi, si Kazi ya Nav. Jaribu-nje ni toggle kichwa badala ya safu ya kudumu iliyohifadhiwa. Moja ya tupu chat pane kando ya brand-mpya wakala ni kupita nafasi kwamba kusoma kama kushindwa kwa mtumiaji. - Kusoma ni amri, kufukuzwa orodha ya nini inaweza kusaidia - si sehemu. Sehemu inasema mtu wanashindwa; orodha inawaambia nini cha kufanya baadaye. - Sheria zilizofungwa hufanya kufungwa na haiwezekani, na kuchukua sehemu kwa mkono Ni wakati wa kuwakumbusha wakati wa kujifungua. - Viongozi wanasema wazi kwamba hariri zinaathiri tu mazungumzo mapya, kwa sababu haraka ni snapshoted katika uumbaji kikao na watumiaji vinginevyo kuhitimisha Mabadiliko yao hayakufanya kazi. - outboundEnabled ni tu alimtuma wakati kweli iliyopita: server 403s wote Ikiwa shamba hilo liko bila MANAGE SALES OUTREACH, kwa hivyo ikiwa ni pamoja na Ni katika kila autosave itakuwa kuvunja studio kwa mtu yeyote kukosa haki hiyo. Pia huondoa sanduku la duplicate "mfumo wa AI haraka" kutoka kituo cha gumzo Mhariri. Ilikuwa ni nafasi ya pili, yenye nguvu ya kuandika kitu kimoja, bila Kuchapisha, hakuna sheria zilizofungwa na hakuna historia - chochote ambacho mhariri kilichotokea Kwa hiyo, ni muhimu kuamua nini wateja wako kusikia. Hatua za dharura bado zinaendelea; njia Kwa kutumia moja sasa kupata taarifa inayoonyesha mawakala. Nakala hubeba hakuna jargon ya AI kwa kubuni, na safu ya sekta ya Kiingereza ya hardcoded ni Kubadilishwa kwa maandiko yaliyotafsiriwa.

  24. · AIService

    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 - AgentConfig + SalesAgentCompiler: pure, deterministic compile of structured config into a sectioned prompt. Empty sections are omitted so a three-rule agent does not compile to a document that is mostly headings. - Section-level override ("write this part yourself") rather than a document-level raw-edit switch: an author gets full expressive power on one section while every other section keeps compiling, keeps its locked rules and keeps versioning. - That same mechanism makes migration byte-identical - a pre-config agent's prose is stored as a whole-document override and compiles back unchanged, so migration day is a no-op for agents already talking to customers. Proven by test. - PhraseBank is deliberately two dimensions, with the good prose on the TEMPLATE. A global bank keyed on every enum combination needs ~90 hand-written paragraphs, degenerates into stacked clauses, and would make every org open with the same sentence - which destroys the one thing an org is buying. - Six templates (front-desk and inbound-lead first: they are horizontal and cover any org whose vertical is not listed). Each ships locked compliance rules a model can never remove, verified by test. Lifecycle + authorization - Publish freezes {config, compiledPrompt, hash, model, provider}; rollback repoints and restores the draft so the studio can never show one thing while the agent serves another. - Controller is rights-gated for the first time. Previously ANY authenticated member of any org could rewrite what that org says to its customers. Falls back to MANAGE_AI_SETTINGS so no existing admin is locked out on deploy. - Public chat prefers the published version's frozen prompt over live trainingContext, and stamps salesAgentId/versionId on the session - the agent was already resolved there and was being discarded. - AI-assisted drafting: one sentence in, reviewable config out. Locked rules are carried over in code, never shown to the model, so a compliance line can never be deleted by instruction-following. Outreach gate (all 14 rules tested) - Opt-out beats every other check AND is reported as the reason, because the reason recorded against a refusal is itself the evidence. - SMS with no consent record is refused: under TCPA the burden of proof is on the sender, so absence of a record is absence of consent. - Quiet hours are judged where the CONTACT is, not where the business is. - Failed sends do not spend the touch budget; suppressed sends do not either, or one block would cascade into blocking everything after it. - The gate fails CLOSED - an outreach gate that errors open sends messages nobody authorized, the one failure here that cannot be undone. Fixes found along the way - Tool-call history replay was broken: the TOOL row persisted no content and the assistant tool_use turn was never persisted, so turn 2 sent a null-content blocks. Enabling tools would have failed every multi-turn conversation. - textComplete had no timeout (blocking .get(), pinning a thread on a slow provider) and recorded no usage, making every helper call invisible to billing. - System partition in context fitting was uncapped, so a verbose agent plus a RAG block could crowd out all history. - costEstimate is now populated on the sync path only, from real provider tokens. Streaming stays null: it fabricates tokens as content.length()/4 and multiplying that by a real price yields an invoice-shaped number that is wrong.

  25. · kamo-shared-library

    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 contact rather than only reply. - SalesAgent gains configJson (jsonb-as-String, matching WebChatIntegration .designConfig), hasConfig, publishedVersionId, audience and outboundEnabled. trainingContext is retained as the COMPILED OUTPUT so every existing consumer keeps working untouched. hasConfig is explicit rather than inferred from trainingContext being blank, because once it is compiled output it is never blank and any blankness test would be unreachable. - SalesAgentVersion freezes {configJson, compiledPrompt, compiledHash, modelId, providerId} per publish. The model is pinned alongside the prompt: freezing instructions while the model auto-routes would make the artifact a half-truth. - AiChatSession/AiUsageRecord gain salesAgentId + salesAgentVersionId. Previously "which agent handled this?" could only be answered by walking the mutable, nullable, non-FK WebChatIntegration.salesAgentId hop, so reassigning a channel silently re-attributed all history. - AiOrgSettings gains forcedPreamble/forcedFooter as NEW nullable columns rather than reusing defaultSystemPrompt, so concatenation is a no-op until an admin fills one in. Reusing the existing field would have changed behaviour for every org that already had one populated, on deploy day. - AgentContactState + AgentOutboundTouch: per-contact cross-channel suppression, explicit per-channel opt-out columns and timestamped consent. Opt-out is stored as real columns rather than JSON because "prove this number was suppressed on that date" must not depend on JSON path extraction. The touch log records REFUSALS as well as sends - a log of sends proves what you did, a log of decisions proves what you would not do. - Rights 168-173 split **************** off MANAGE_AI_SETTINGS(53), which previously gated none of this.

  26. · kamo-internal

    Wakala wa Uuzaji wa AI tab + kwa kazi ya wakala wa kati

    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 context themselves, then edit/enable/delete them. Chat channels (/settings/features/chat) can now each pick which agent drives that channel's AI, independently — the agent overrides the raw system prompt.

  27. · SecurityService

    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 state itself and whether we still need to ask for it. Reuses the SAFE-Act card's resolved data so the chat can never show a fabricated identity. Adds POST /portal/subject-state: when the lead has no property state yet, the borrower can set it from chat; it flows through patchEstimate (and its assignment pool re-entry) like any other claimed fact, which unlocks the license line.

  28. · MediaService

    Tuma wakala wa mauzo kwa kituo + ripoti LO upatikanaji

    - WebChatIntegration CRUD nyuzi mauzoAgentId (null wazi kazi) -Utangulizi sasa unarudisha upatikanaji wa wanachama pamoja na mtandao, hivyo widget inaweza kuonyesha hali halisi badala ya dot wazi. Uchunguzi wa shirika la msalaba waendelea Kurejea tu kwenye mtandao.

  29. · AIService

    Sales-agent CRUD, template mikopo, na wakala inayotokana chat prompt

    - AiSalesAgentController (/api/ai/sales-agents): org-scoped CRUD + GET /templates - SalesAgentTemplateRegistry: built-in starter templates, beginning with a mortgage-borrower assistant (compliance-aware: no binding rate quotes, no approval promises, defers to the licensed loan officer, asks for subject state) - PublicAiChatService: the assigned SalesAgent's trainingContext becomes the top tier of the prompt waterfall (agent -> integration prompt -> org -> generic)

  30. · kamo-shared-library

    SalesAgent chombo + kwa kazi ya wakala wa kati

    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), assignable to channels to drive that channel's AI. Kamo serves all industries — mortgage is just one template. - SalesAgent entity (dao/beans/ai) + SalesAgentRepository + SalesAgentDTO - WebChatIntegration.salesAgentId (nullable soft link) + DTO field

Ulimwengu wako unasubiri.

Kuanza bure katika dakika. Ongeza bidhaa wakati wowote wewe ni tayari - hakuna uhamiaji, hakuna logins mpya.

Bure milele - hakuna kadi ya mkopo inahitajika