mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-15 00:04:58 +02:00
* MUL-5765 feat(chat): starter cards under Mika's onboarding opening Replace the LLM quick-action chips on Mika's onboarding opening with three product-fixed starter cards (board / delegate / digest), so a new member never starts from a blank canvas. Clicking a card sends its fixed prompt as a visible member message through the existing quick-action path; cards follow the chips' disabled rule while a task runs and stay clickable in history. Older clients keep the LLM chips untouched. The multica-onboarding skill gains matching starter plays (one-question budget each) and a digest-only exception to the no-autopilot rule. Co-authored-by: multica-agent <github@multica.ai> (cherry picked from commit32364cea89) * MUL-5765 refactor(chat): drop pre-release compatibility around starter cards The onboarding flow has not shipped, so no old client exists to protect (per review): the server now skips the quick-actions pass for the opening turn (new TaskHasOnboardingKickoffInput gate) instead of generating chips the new client would hide, and the multica-onboarding opening points at the cards directly — beat 4 is the mock's bridge line again. Co-authored-by: multica-agent <github@multica.ai> (cherry picked from commit26e5242d0b) * MUL-5765 fix(chat): stamp the onboarding opening so starter cards actually render The cards never showed in the field: the client detected the opening by finding the hidden kickoff row, but visibleChatMessages strips that row from list responses — and the client zod schema coerced unknown message kinds to 'message' anyway, so the signal died twice before reaching the detector. The opening now self-describes: writeChatCompletionOutcome stamps the reply to a kickoff-input task with message_kind 'onboarding_opening', the schema and type unions carry the new kind, and the client keys the cards off it directly — pagination-proof, and the hidden kickoff stays hidden. The explicit quick-actions eligibility gate is gone: a non-'message' kind already skips the pass at both call sites. The kickoff prompt also forbids pre-reply narration ('I'll load the onboarding skill first.' leaked into the field opening). Co-authored-by: multica-agent <github@multica.ai> (cherry picked from commitffacd3d02c) * MUL-5765 fix(chat): stamp the opening on the input owner, not the retry clone The kickoff check asked TaskHasOnboardingKickoffInput about task.ID. An auto-retry clone gets a fresh id while inheriting the root's chat_input_task_id (MUL-4351), and the kickoff user row stays bound to the root -- so the child answered false. An opening that only succeeded after a retriable failure (provider_network, runtime recovery) therefore persisted as a plain 'message': no starter cards, and a chips pass generated for a turn whose copy invites the member to pick one of the cards that never rendered. Keyed on chatInputOwnerID now, which exists for exactly this provenance question. The query doc states that its argument is the input-owning id, so the next caller does not reintroduce task.ID. The regression test drives the real completion write with child.ID != child.ChatInputTaskID; it fails on the old call site with kind "message". Co-authored-by: multica-agent <github@multica.ai> * MUL-5765 fix(onboarding): give the digest schedule a timezone to name The digest starter play proposed "every morning at 09:00" while the kickoff profile carried only workspace name, role and use case. `autopilot trigger-add` defaults an absent --timezone to UTC (DefaultAutopilotTriggerTimezone, and the flag's own help), so a member outside UTC could confirm a morning summary and receive an afternoon one -- a wrong assumption that recurs daily. The member's IANA timezone now travels in the profile block, stated as a value either way and emitted before the skipped-questionnaire early return: the digest card is clickable whether or not the questionnaire was answered, and "unknown" is the case the skill has to handle rather than paper over. What to do with it lives in the skill, since that block declares itself data and never a command. The digest play must now quote the whole time ("09:00 Asia/Shanghai") and pass --timezone; when the zone is unknown it spends the one allowed question there instead of falling back to UTC silently. Co-authored-by: multica-agent <github@multica.ai> --------- Co-authored-by: Lambda <lambda@multica.ai> Co-authored-by: multica-agent <github@multica.ai>