Files
openhuman/src-tauri/src
fb4a88867a feat: self evolving skills (#150)
* feat(skills): extend GenerateSkillSpec with full_index_js and update generator

- Add optional `full_index_js` field to GenerateSkillSpec so LLM-generated
  JS source can be written verbatim instead of using the default template
- Change generate_alphahuman() return type from PathBuf to Vec<PathBuf>
  (returns both manifest.json and index.js paths for audit logging)
- Add UnifiedSkillRegistry::skills_dir() and engine() helper accessors
  needed by the self-evolve orchestrator

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(skills): add isolated QuickJS skill tester with mock bridge globals

Introduces SkillTester::run_isolated() which spins up a fresh rquickjs
context (no shared state), injects no-op mock globals for all bridge APIs
(db, net, state, platform, cron, skills), loads index.js, and calls
init/start plus each tool's execute() with empty args.

The test passes only if every exported tool returns without throwing and
produces valid output. Used by the self-evolve loop to validate generated
code before registering it into the live registry.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(skills): add LLM code generator using Anthropic Claude API

Introduces LlmGenerator with two methods:
- generate_spec(task): first-pass generation from a natural-language task
  description; produces a complete GenerateSkillSpec including full_index_js
- fix_spec(task, prev_code, error): retry pass that feeds the previous
  code and the test error back to the model for correction

Uses claude-3-5-haiku-20241022 via direct reqwest POST to the Anthropic
messages API. System prompt teaches the model the exact QuickJS index.js
format, available bridge globals, and synchronous net.fetch semantics.
Strips markdown code fences from the response before use.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(skills): add self-evolve orchestrator with iteration loop and audit log

Introduces SkillEvolver::evolve() which implements the full pipeline:
  1. LLM generates a GenerateSkillSpec from a task description
  2. generator::generate_alphahuman() writes manifest.json + index.js
  3. SkillTester::run_isolated() validates the code in a fresh sandbox
  4. On failure: feed error back to LLM and regenerate (up to max_iterations)
  5. On success: discover_skills() + start_skill() to register live, then
     execute() to run the real task and capture final output
  6. Returns SelfEvolveResult with full audit log, files_created, and
     the final UnifiedSkillResult

Wraps the entire evolve() call in tokio::time::timeout (default 120s).
Cleans up written skill directory on permanent failure so no partial
skill is left registered.

Key types:
  SelfEvolveRequest  — task_description, max_iterations, timeout_secs,
                       optional anthropic_api_key override
  SelfEvolveResult   — skill_id, success, iterations_used, audit_log,
                       files_created, final_result, failure_reason
  IterationLog       — per-iteration code, test output, pass/fail flag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(tauri): register unified_self_evolve_skill command with progress events

Adds unified_self_evolve_skill Tauri command that:
- Accepts a SelfEvolveRequest (task_description + optional limits)
- Emits skill:evolve:progress event after each iteration so the frontend
  can show live progress without polling
- Delegates to SkillEvolver::evolve() and returns SelfEvolveResult
- Mobile stub returns an informative error (feature requires desktop runtime)

Registers the command in generate_handler![] in lib.rs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(ui): add SelfEvolveModal and Auto-Generate button to SkillsGrid

SelfEvolveModal (src/components/skills/SelfEvolveModal.tsx):
- createPortal modal with 4 states: idle / running / success / failed
- Text input for natural-language task description
- Calls unified_self_evolve_skill via invoke() on submit
- Subscribes to skill:evolve:progress Tauri events to show live iteration
  updates (iteration number, pass/fail indicator)
- On success: displays audit log accordion with per-iteration code,
  test output, and final task result
- On failure: shows failure reason and full audit trail for debugging
- Calls onSkillCreated() callback to trigger grid refresh

SkillsGrid changes:
- Add selfEvolveOpen state + "Auto-Generate" button in the toolbar
- Extract refreshSkills as a named async function reused by both the
  initial load and the SelfEvolveModal's onSkillCreated callback
- Add activeSkillType state so SkillSetupModal shows the correct badge
  when opened from either the Connect or Manage flow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(skills): fix alphahuman skill template and generation pipeline

- generator.rs: use bare `tools = []` (not const) for globalThis access,
  add `execute: async function(args)` method, fix `input_schema` casing
- mod.rs: call start_skill() after generate() so skills are immediately executable
- llm_generator.rs: update model to claude-haiku-4-5-20251001, sync system prompt

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(skills): fix tools not loading for generated skills and add robustness fixes

- llm_generator: require 'var tools = [...]' in system prompt (const/let are
  block-scoped and do not attach to globalThis, causing extract_tools() to find
  an empty array in the production QuickJS engine)
- llm_generator: add smart_name() — deterministic display name from task
  description (strips preambles + lead fillers + stop words, title-cases 3
  tokens); replaces brittle LLM-dependent naming
- llm_generator: improve sandbox testing rules in system prompt so placeholder
  values prevent test failures when net.fetch returns empty JSON
- skill_tester: detect {error: '...'} return values as test failures (both sync
  and Promise paths) so the iteration loop attempts a fix instead of treating
  them as success
- manager.ts: dispatch setSkillSetupComplete(true) for skills without a setup
  flow so deriveConnectionStatus() returns "connected" instead of "connecting"

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 19:58:42 +04:00
..
2026-02-20 13:03:15 +04:00
2026-02-26 19:55:53 +04:00
2026-02-20 13:03:15 +04:00
2026-02-03 15:26:38 +05:30
2026-02-05 19:29:21 +05:30
2026-02-26 19:58:42 +04:00