8 Commits
Author SHA1 Message Date
KellyvvandClaude Opus 4.6 779be78843 refactor: split MLX service, introduce skill type & runtime budgets
Major restructuring of the agent stack to support content-type skills,
data-driven runtime budgets, and the new translate skill.

LLM/MLX/
- Split MLXLocalLLMService.swift (1500 → 700 lines) into Core/, Gemma4/,
  Installation/ subdirectories
- New BundledModel: LinearBudgetFormula replaces tier tables, model
  parameters fully data-driven via ModelRuntimeProfile
- New RuntimeBudgets: pure functions for text/thinking/multimodal budgets,
  zero hardcoded model IDs
- Drop adjustedTextOutputTokens prepared-subtraction (chunked prefill made
  it obsolete and triggered false-positive truncation on long prompts)

Skills/
- Add SkillType (.device / .content) metadata, parsed from SKILL.md
  frontmatter
- New translate skill (type: content, no tools) with anaphora handling
- Trim translate (4563→1804), device (2357→1680), calendar (2169→1790)
- contacts SKILL.md adds multi-turn disambiguation + cancel guidance,
  semantics owned by body not framework
- SkillRegistry validates allowed-tools against ToolRegistry at load time

Agent/
- ToolCallParser becomes registry-aware: drops tool_call names not in
  ToolRegistry or protocol set (load_skill / list_skills); ToolRegistry
  is now the single white list, validation moves to parser boundary
- Router sticky routing uses semantic user-turn boundary instead of
  fixed suffix(4); correctly handles long agent loops
- AgentEngine system prompt template differentiates device vs content
  skills with explicit invocation rules
- SYSPROMPT.md auto-migration: old single-placeholder template backed up
  to .bak when new dual-placeholder is detected
- PromptBuilder.buildLoadedSkillPrompt receives availableTools list,
  explicitly tells model which tools (or none) are callable

Tools/
- ToolRegistry split into Helpers/Stores/AppPermissions/Handlers/* for
  separation of concerns
- Mark Tools/Handlers/* with explicit allowed argument signatures

UI/
- Add long-press copy contextMenu on user and assistant bubbles
- Enable .textSelection on user bubble

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 09:22:20 +08:00
Kellyvv 446d216088 feat: improve on-device model download flow 2026-04-07 16:19:56 +08:00
Kellyvv 69c4b32248 feat: ship shell app and chat session polish 2026-04-07 11:13:35 +08:00
271ac8c1dc feat(ui): show download progress bar in model picker
Replace the plain "下载中 X/Y" badge with a small progress bar that
visualises file-count progress while a model is downloading. UI-only
change — does not touch the download path itself.

Inspired by @gclsoft's PR #3.

Co-Authored-By: Peter <gclsoft@qq.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-07 02:42:06 +08:00
Kellyvv 0d223ae373 feat: add audio input and stabilize gemma 4 inference 2026-04-07 01:50:29 +08:00
Kellyvv c81625aff8 Stabilize local skills and keep shell install default 2026-04-06 16:05:56 +08:00
Kellyvv 95553ee653 feat: major agent upgrade — multi-model, calendar/reminders/contacts skills
Agent:
- Rewrite load_skill follow-up: inject skill instructions into system
  block (buildLoadedSkillPrompt) instead of appending as user message
- Add auto tool-call shortcut for single no-arg skills
  (autoToolCallForLoadedSkills) — skips second LLM round
- Add Chinese date parsing (parseBasicChineseDate, detectDateInQuestion)
- Add heuristic argument inference (heuristicArgumentsForTool)
- Add looksLikePromptEcho / looksLikeStructuredIntermediateOutput filters
- Add renderToolResultLocally for zero-inference result formatting
- Add permission management API (AppPermissionKind, permissionStatuses,
  requestPermission)
- Add applyModelSelection() for runtime model switching

PromptBuilder:
- Replace buildFollowUp+buildForcedSkillContinuation with:
  buildLoadedSkillPrompt (skill in system block, cleaner prefill)
  buildToolAnswerPrompt (minimal tool-result answer prompt)
- Add extractSystemBlock / injectIntoSystemBlock helpers

MLXLocalLLMService:
- Add BundledModelOption struct
- Support multiple models (E2B + E4B) via availableModels array
- modelPath now dynamic based on selectedModel

ToolRegistry:
- Add calendar-create-event (EventKit, write-only access)
- Add reminders-create (EventKit, full access, EKAlarm for notifications)
  - ensureWritableReminderCalendar: auto-creates reminder list if needed
- Add contacts-upsert (Contacts, dedup by phone number)
- Fix: CNContacts .limited case treated as .granted
- Fix: reminders EKAlarm required for notification to fire

SkillLoader:
- Add calendar, reminders, contacts default SKILL.md entries

Info.plist:
- Add NSCalendarsWriteOnlyAccessUsageDescription
- Add NSCalendarsUsageDescription
- Add NSRemindersFullAccessUsageDescription
- Add NSRemindersUsageDescription
- Add NSContactsUsageDescription

ConfigurationsView:
- Add model picker (E2B / E4B)
- Add permissions panel (AppPermissionKind list with request support)
2026-04-06 03:49:21 +08:00
Kellyvv 0f146d4e8f refactor: flatten structure + remove dead code
- Move PhoneClaw/ contents to project root (no more nesting)
- Delete PhoneClawMac/ (nested SPM package, duplicated iOS code)
- Delete LLM/LocalLLMService.swift (dead MediaPipe implementation)
- Delete llm_inference_engine.h + PhoneClaw-Bridging-Header.h (unused)
- Delete Sources/ (empty dir), phoneclaw.code-workspace, TECH_PATH_ANALYSIS.md, project.yml
- Fix project.pbxproj: update INFOPLIST_FILE, CODE_SIGN_ENTITLEMENTS paths
- Fix project.pbxproj: remove SWIFT_OBJC_BRIDGING_HEADER setting
- Fix project.pbxproj: remove LocalLLMService.swift file reference
- Fix project.pbxproj: PhoneClaw group now uses name= instead of path=
2026-04-06 01:33:10 +08:00