@agentprojectcontext/apx 1.81.0 → 1.89.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -8
- package/skills/apc-context/SKILL.md +14 -7
- package/skills/apx/SKILL.md +62 -2
- package/skills/apx-mcp/SKILL.md +42 -15
- package/src/core/agent/a2a/peers.js +161 -0
- package/src/core/agent/a2a/reply.js +379 -27
- package/src/core/agent/abort.js +25 -0
- package/src/core/agent/agent-model.js +58 -0
- package/src/core/agent/agent-tools.js +101 -0
- package/src/core/agent/author-line.js +110 -0
- package/src/core/agent/build-agent-system.js +52 -18
- package/src/core/agent/channels/voice-context.js +17 -2
- package/src/core/agent/closing-floor.js +117 -0
- package/src/core/agent/constants.js +119 -11
- package/src/core/agent/engine-call.js +56 -0
- package/src/core/agent/group/run-group-turn.js +218 -0
- package/src/core/agent/group/turn-resolver.js +165 -0
- package/src/core/agent/judge.js +138 -11
- package/src/core/agent/loop/side-effects.js +106 -3
- package/src/core/agent/memory.js +31 -18
- package/src/core/agent/model-capabilities.js +47 -0
- package/src/core/agent/model-router.js +11 -40
- package/src/core/agent/prompt-builder.js +47 -0
- package/src/core/agent/prompts/channels/a2a.md +12 -0
- package/src/core/agent/prompts/channels/code.md +3 -1
- package/src/core/agent/prompts/channels/telegram.md +2 -0
- package/src/core/agent/prompts/channels/web_code.md +1 -1
- package/src/core/agent/prompts/channels/whatsapp.md +37 -0
- package/src/core/agent/prompts/core/agent-base.md +2 -0
- package/src/core/agent/prompts/discipline/action.md +1 -0
- package/src/core/agent/prompts/discipline/two-segment.md +2 -1
- package/src/core/agent/prompts/modes/mobility.md +36 -0
- package/src/core/agent/retry.js +42 -0
- package/src/core/agent/run-agent.js +322 -25
- package/src/core/agent/run-turn.js +253 -0
- package/src/core/agent/self-memory.js +18 -52
- package/src/core/agent/skills/agent-skills.js +118 -0
- package/src/core/agent/skills/catalog.js +1 -1
- package/src/core/agent/skills/declared.js +13 -0
- package/src/core/agent/skills/index-store.js +8 -1
- package/src/core/agent/skills/inspector.js +20 -3
- package/src/core/agent/skills/loader.js +18 -3
- package/src/core/agent/skills/media.js +121 -0
- package/src/core/agent/skills/origin.js +61 -0
- package/src/core/agent/skills/sections.js +136 -0
- package/src/core/agent/super-agent.js +54 -14
- package/src/core/agent/tools/handlers/_calendar.js +50 -0
- package/src/core/agent/tools/handlers/add-mcp.js +103 -0
- package/src/core/agent/tools/handlers/asana-create-task.js +3 -1
- package/src/core/agent/tools/handlers/attach-media.js +56 -0
- package/src/core/agent/tools/handlers/calendar-create-event.js +38 -0
- package/src/core/agent/tools/handlers/calendar-find-slot.js +39 -0
- package/src/core/agent/tools/handlers/calendar-list-events.js +39 -0
- package/src/core/agent/tools/handlers/calendar-update-event.js +35 -0
- package/src/core/agent/tools/handlers/call-agent.js +14 -6
- package/src/core/agent/tools/handlers/call-runtime.js +27 -49
- package/src/core/agent/tools/handlers/comment-task.js +78 -0
- package/src/core/agent/tools/handlers/complete-task.js +60 -0
- package/src/core/agent/tools/handlers/configure-agent.js +70 -0
- package/src/core/agent/tools/handlers/create-agent.js +68 -0
- package/src/core/agent/tools/handlers/create-task.js +41 -3
- package/src/core/agent/tools/handlers/import-agent.js +5 -5
- package/src/core/agent/tools/handlers/list-mcp-tools.js +83 -0
- package/src/core/agent/tools/handlers/list-routines.js +46 -0
- package/src/core/agent/tools/handlers/list-tasks.js +8 -1
- package/src/core/agent/tools/handlers/mark-commitment.js +57 -0
- package/src/core/agent/tools/handlers/read-skill.js +64 -0
- package/src/core/agent/tools/handlers/remember-routine.js +2 -8
- package/src/core/agent/tools/handlers/remember.js +82 -6
- package/src/core/agent/tools/handlers/remove-agent.js +42 -0
- package/src/core/agent/tools/handlers/run-routine.js +94 -0
- package/src/core/agent/tools/handlers/run-shell.js +44 -2
- package/src/core/agent/tools/handlers/send-telegram.js +41 -19
- package/src/core/agent/tools/handlers/set-agent-prompt.js +44 -0
- package/src/core/agent/tools/handlers/view-media.js +69 -0
- package/src/core/agent/tools/handlers/write-agent-memory.js +52 -0
- package/src/core/agent/tools/helpers.js +36 -4
- package/src/core/agent/tools/names.js +64 -0
- package/src/core/agent/tools/registry-bridge.js +24 -1
- package/src/core/agent/tools/registry.js +79 -0
- package/src/core/agent/tools/tool-call-parser.js +136 -13
- package/src/core/agent/vision-bridge.js +69 -0
- package/src/core/apc/agent-identity.js +74 -0
- package/src/core/apc/agent-rename-refs.js +187 -0
- package/src/core/apc/agent-write.js +312 -0
- package/src/core/apc/agents-vault.js +1 -1
- package/src/core/apc/blob-keys.js +42 -0
- package/src/core/apc/frontmatter.js +166 -10
- package/src/core/apc/parser.js +33 -83
- package/src/core/apc/paths.js +4 -6
- package/src/core/apc/project-memory.js +44 -0
- package/src/core/apc/projects-helpers.js +33 -0
- package/src/core/apc/scaffold.js +36 -16
- package/src/core/channels/telegram/ask-callbacks.js +103 -0
- package/src/core/channels/telegram/dispatch.js +154 -30
- package/src/core/channels/telegram/helpers.js +59 -7
- package/src/core/channels/telegram/inbound/audio.js +26 -30
- package/src/core/channels/telegram/inbound/file.js +22 -32
- package/src/core/channels/telegram/inbound/photo.js +24 -28
- package/src/core/channels/telegram/progress-gate.js +76 -0
- package/src/core/channels/telegram/reply.js +151 -43
- package/src/core/channels/telegram/voice-note.js +150 -0
- package/src/core/config/index.js +53 -54
- package/src/core/config/paths.js +117 -31
- package/src/core/config/redact.js +89 -4
- package/src/core/config/secret-values.js +2 -4
- package/src/core/constants/actors.js +5 -0
- package/src/core/constants/channels.js +3 -1
- package/src/core/constants/task-categories.js +73 -0
- package/src/core/constants/task-fields.js +28 -0
- package/src/core/engines/_globs.js +33 -0
- package/src/core/engines/anthropic.js +19 -1
- package/src/core/engines/catalog.js +20 -0
- package/src/core/engines/gemini.js +84 -16
- package/src/core/engines/index.js +19 -3
- package/src/core/engines/mock.js +145 -1
- package/src/core/engines/openai-compatible.js +150 -15
- package/src/core/engines/presets.js +36 -9
- package/src/core/engines/zen.js +131 -0
- package/src/core/events/bus.js +140 -0
- package/src/core/events/mascot-notify.js +156 -0
- package/src/core/http-tools/browser.js +366 -36
- package/src/core/http-tools/catalog.js +206 -22
- package/src/core/http-tools/grep.js +62 -7
- package/src/core/http-tools/registry.js +3 -1
- package/src/core/i18n/en.js +34 -3
- package/src/core/i18n/es.js +36 -4
- package/src/core/i18n/index.js +5 -5
- package/src/core/i18n/pt.js +32 -3
- package/src/core/identity/self.js +14 -1
- package/src/core/images/engines/a1111.js +219 -0
- package/src/core/images/engines/index.js +187 -0
- package/src/core/images/engines/mock.js +74 -0
- package/src/core/images/engines/openai.js +130 -0
- package/src/core/images/engines/sdcpp.js +204 -0
- package/src/core/images/engines/shared.js +218 -0
- package/src/core/images/generate.js +260 -0
- package/src/core/integrations/catalog.js +8 -3
- package/src/core/integrations/plugins/_google-oauth.js +179 -0
- package/src/core/integrations/plugins/asana.js +7 -3
- package/src/core/integrations/plugins/calendar.js +404 -0
- package/src/core/integrations/store.js +2 -0
- package/src/core/memory/broker.js +16 -1
- package/src/core/memory/compactor.js +19 -3
- package/src/core/memory/consolidate.js +2 -2
- package/src/core/memory/dated-log.js +66 -0
- package/src/core/memory/embed-engines/custom.js +59 -0
- package/src/core/memory/embed-engines/gemini.js +9 -3
- package/src/core/memory/embed-engines/index.js +87 -15
- package/src/core/memory/embeddings.js +52 -24
- package/src/core/memory/index.js +13 -3
- package/src/core/memory/indexer.js +83 -27
- package/src/core/memory/prune.js +182 -0
- package/src/core/memory/store.js +22 -0
- package/src/core/memory/summarizer.js +72 -8
- package/src/core/mobility/answer.js +80 -0
- package/src/core/mobility/geofence.js +667 -0
- package/src/core/mobility/osm-route.js +282 -0
- package/src/core/mobility/preferences.js +91 -0
- package/src/core/mobility/state.js +245 -0
- package/src/core/mobility/trip-event.js +384 -0
- package/src/core/net/tailscale.js +168 -0
- package/src/core/profiles/bundled/secretary/PROFILE.md +32 -42
- package/src/core/profiles/bundled/secretary/config.schema.es.json +68 -0
- package/src/core/profiles/bundled/secretary/config.schema.json +30 -2
- package/src/core/profiles/bundled/secretary/profile.json +3 -1
- package/src/core/profiles/bundled/secretary/routines/a2a-sweep.json +20 -0
- package/src/core/profiles/bundled/secretary/routines/day-close.json +4 -1
- package/src/core/profiles/bundled/secretary/routines/day-open.json +7 -1
- package/src/core/profiles/bundled/secretary/routines/watch.json +13 -2
- package/src/core/profiles/lifecycle.js +243 -19
- package/src/core/profiles/paths.js +12 -0
- package/src/core/profiles/store.js +47 -0
- package/src/core/routines/active-runs.js +213 -0
- package/src/core/routines/delivery.js +612 -0
- package/src/core/routines/header.js +88 -0
- package/src/core/routines/index.js +26 -0
- package/src/core/routines/run-log.js +78 -0
- package/src/core/routines/runner.js +629 -66
- package/src/core/routines/signals.js +75 -0
- package/src/core/runtime-skills/apc-context/SKILL.md +14 -7
- package/src/core/runtime-skills/apx/SKILL.md +93 -1
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +2 -2
- package/src/core/runtime-skills/apx-agent/SKILL.md +134 -19
- package/src/core/runtime-skills/apx-commitment/SKILL.md +21 -11
- package/src/core/runtime-skills/apx-image/SKILL.md +60 -0
- package/src/core/runtime-skills/apx-integrations/SKILL.md +82 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +45 -14
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +4 -4
- package/src/core/runtime-skills/apx-profile/SKILL.md +27 -2
- package/src/core/runtime-skills/apx-project/SKILL.md +23 -2
- package/src/core/runtime-skills/apx-routine/SKILL.md +40 -17
- package/src/core/runtime-skills/apx-runtime/SKILL.md +124 -14
- package/src/core/runtime-skills/apx-sessions/SKILL.md +7 -6
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +15 -13
- package/src/core/runtime-skills/apx-task/SKILL.md +79 -26
- package/src/core/runtime-skills/apx-telegram/SKILL.md +12 -12
- package/src/core/runtime-skills/apx-transcribe/SKILL.md +56 -0
- package/src/core/runtime-skills/apx-voice/SKILL.md +27 -8
- package/src/core/runtime-skills/claude-code/SKILL.md +8 -0
- package/src/core/runtime-skills/openrouter/SKILL.md +8 -2
- package/src/core/runtimes/_spawn.js +9 -1
- package/src/core/runtimes/claude-code.js +11 -2
- package/src/core/runtimes/codex.js +44 -10
- package/src/core/runtimes/index.js +17 -2
- package/src/core/runtimes/opencode.js +88 -9
- package/src/core/runtimes/outcome.js +119 -0
- package/src/core/sessions/index.js +193 -1
- package/src/core/stores/agent-inbox.js +109 -23
- package/src/core/stores/code-sessions.js +21 -0
- package/src/core/stores/commitments.js +27 -3
- package/src/core/stores/conversations.js +220 -20
- package/src/core/stores/deliveries.js +177 -0
- package/src/core/stores/media-archive.js +228 -0
- package/src/core/stores/messages.js +1096 -112
- package/src/core/stores/organization.js +34 -0
- package/src/core/stores/project-memory.js +71 -0
- package/src/core/stores/routine-memory.js +16 -8
- package/src/core/stores/routines.js +27 -49
- package/src/core/stores/sessions.js +4 -8
- package/src/core/stores/tasks.js +212 -18
- package/src/core/stores/turn-record.js +209 -0
- package/src/core/tasks/columns.js +136 -0
- package/src/core/tasks/comment-turn.js +258 -0
- package/src/core/util/time.js +13 -0
- package/src/core/voice/engines/index.js +54 -1
- package/src/core/voice/engines/openai.js +50 -4
- package/src/core/voice/opus.js +67 -0
- package/src/core/voice/pronounceable.js +43 -0
- package/src/core/voice/transcription.js +4 -0
- package/src/core/voice/tts.js +114 -24
- package/src/host/daemon/active-turns.js +188 -0
- package/src/host/daemon/api/admin-config.js +9 -0
- package/src/host/daemon/api/agents.js +99 -90
- package/src/host/daemon/api/artifact-preview.js +7 -6
- package/src/host/daemon/api/artifacts.js +3 -2
- package/src/host/daemon/api/code.js +55 -9
- package/src/host/daemon/api/commitments.js +11 -0
- package/src/host/daemon/api/confirm.js +3 -2
- package/src/host/daemon/api/conversations.js +543 -35
- package/src/host/daemon/api/deck.js +9 -8
- package/src/host/daemon/api/deliveries.js +33 -0
- package/src/host/daemon/api/desktop.js +5 -4
- package/src/host/daemon/api/embeddings.js +15 -6
- package/src/host/daemon/api/engines.js +59 -8
- package/src/host/daemon/api/exec.js +437 -121
- package/src/host/daemon/api/groups.js +215 -0
- package/src/host/daemon/api/images.js +107 -0
- package/src/host/daemon/api/inbox.js +123 -2
- package/src/host/daemon/api/integrations.js +64 -2
- package/src/host/daemon/api/mcps.js +7 -6
- package/src/host/daemon/api/media.js +283 -0
- package/src/host/daemon/api/mobility.js +177 -0
- package/src/host/daemon/api/net.js +182 -0
- package/src/host/daemon/api/pairing.js +38 -5
- package/src/host/daemon/api/profiles.js +30 -2
- package/src/host/daemon/api/routines.js +36 -4
- package/src/host/daemon/api/runtimes.js +74 -39
- package/src/host/daemon/api/sessions-search.js +7 -2
- package/src/host/daemon/api/sessions.js +44 -2
- package/src/host/daemon/api/shared.js +127 -20
- package/src/host/daemon/api/skills.js +11 -4
- package/src/host/daemon/api/super-agent.js +384 -53
- package/src/host/daemon/api/tasks.js +180 -10
- package/src/host/daemon/api/telegram.js +11 -10
- package/src/host/daemon/api/thread-faces.js +159 -0
- package/src/host/daemon/api/top-level.js +3 -3
- package/src/host/daemon/api/transcribe.js +11 -10
- package/src/host/daemon/api/tts.js +97 -4
- package/src/host/daemon/api/turn-abort.js +23 -0
- package/src/host/daemon/api/turns.js +49 -0
- package/src/host/daemon/api/voice.js +5 -4
- package/src/host/daemon/api/web.js +98 -0
- package/src/host/daemon/api.js +39 -0
- package/src/host/daemon/delivery-sweep.js +58 -0
- package/src/host/daemon/desktop-ws.js +5 -23
- package/src/host/daemon/events-ws.js +273 -0
- package/src/host/daemon/index.js +59 -15
- package/src/host/daemon/plugins/desktop/index.js +17 -4
- package/src/host/daemon/plugins/telegram/index.js +78 -40
- package/src/host/daemon/pty-bridge.py +99 -0
- package/src/host/daemon/routines-scheduler.js +1 -0
- package/src/host/daemon/smoke.js +1 -2
- package/src/host/daemon/terminal-ws.js +132 -0
- package/src/host/daemon/tts-keepwarm.js +87 -0
- package/src/host/daemon/wakeup.js +11 -6
- package/src/host/daemon/whisper-server.js +44 -0
- package/src/host/daemon/whisper-server.py +70 -13
- package/src/host/daemon/ws-auth.js +28 -0
- package/src/interfaces/android/app/build.gradle +42 -0
- package/src/interfaces/android/app/proguard-rules.pro +4 -0
- package/src/interfaces/android/app/src/main/AndroidManifest.xml +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AlertScreen.java +139 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/AndroidAutoDetector.java +106 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxCarAppService.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ApxPreferences.java +165 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarAlertStore.java +84 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageActionReceiver.java +47 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/CarMessageNotification.java +152 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonAddress.java +35 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DaemonClient.java +339 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/DeviceLocation.java +38 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ErrandScreen.java +127 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MainActivity.java +872 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationDetector.java +63 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsNavigationListenerService.java +453 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MapsShareIntentParser.java +93 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotBlobCatalog.java +66 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotOverlayService.java +448 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MascotView.java +249 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/MessageFrameParser.java +240 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/NotifyChannels.java +69 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityActionReceiver.java +78 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/ProximityNotification.java +161 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/StartupReceiver.java +57 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelEventGate.java +62 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TravelStatusBanner.java +116 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripLocationService.java +272 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripPlacesSheet.java +203 -0
- package/src/interfaces/android/app/src/main/java/dev/agentprojectcontext/apx/TripScreen.java +182 -0
- package/src/interfaces/android/app/src/main/res/drawable/app_background.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_app.xml +10 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_launcher_foreground.xml +12 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_apx_notification.xml +22 -0
- package/src/interfaces/android/app/src/main/res/drawable/ic_trip_car.xml +37 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/apx_logo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_amatista.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_aqua.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_brasa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_campana.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_caracol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_carbon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cobalto.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cometa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_coral.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_cubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_eclipse.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_faro.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_gajo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_iris.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_kiwi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_laguna.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_lila.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_menta.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_nimbo.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_noche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_onyx.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_orbita.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_ovni.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_papa.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_parche.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_peon.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_perla.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_pino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_quad.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_rubi.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_saturno.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trebol.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_trino.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_volcan.png +0 -0
- package/src/interfaces/android/app/src/main/res/drawable-nodpi/mascot_zafiro.png +0 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- package/src/interfaces/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +5 -0
- package/src/interfaces/android/app/src/main/res/raw/apx_notification.mp3 +0 -0
- package/src/interfaces/android/app/src/main/res/values/colors.xml +4 -0
- package/src/interfaces/android/app/src/main/res/values/strings.xml +25 -0
- package/src/interfaces/android/app/src/main/res/values/styles.xml +10 -0
- package/src/interfaces/android/app/src/main/res/values-v31/styles.xml +14 -0
- package/src/interfaces/android/app/src/main/res/xml/automotive_app_desc.xml +9 -0
- package/src/interfaces/android/app/src/main/res/xml/network_security_config.xml +10 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/AndroidAutoDetectorTest.java +85 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/CarAlertStoreTest.java +104 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/DaemonAddressTest.java +23 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsNavigationDetectorTest.java +69 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MapsShareIntentParserTest.java +31 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/MessageFrameParserTest.java +180 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TravelEventGateTest.java +64 -0
- package/src/interfaces/android/app/src/test/java/dev/agentprojectcontext/apx/TripPlacesSheetTest.java +66 -0
- package/src/interfaces/android/build.gradle +3 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/src/interfaces/android/gradle/wrapper/gradle-wrapper.properties +9 -0
- package/src/interfaces/android/gradle.properties +3 -0
- package/src/interfaces/android/gradlew +248 -0
- package/src/interfaces/android/gradlew.bat +82 -0
- package/src/interfaces/android/settings.gradle +18 -0
- package/src/interfaces/cli/commands/a2a.js +145 -4
- package/src/interfaces/cli/commands/agent.js +247 -22
- package/src/interfaces/cli/commands/code.js +1 -1
- package/src/interfaces/cli/commands/commitment.js +5 -0
- package/src/interfaces/cli/commands/config.js +85 -6
- package/src/interfaces/cli/commands/exec.js +90 -1
- package/src/interfaces/cli/commands/image.js +314 -0
- package/src/interfaces/cli/commands/mcp.js +87 -23
- package/src/interfaces/cli/commands/memory.js +35 -22
- package/src/interfaces/cli/commands/panel.js +94 -0
- package/src/interfaces/cli/commands/profile.js +14 -0
- package/src/interfaces/cli/commands/project.js +29 -0
- package/src/interfaces/cli/commands/routine.js +45 -10
- package/src/interfaces/cli/commands/runtime.js +30 -7
- package/src/interfaces/cli/commands/session.js +90 -38
- package/src/interfaces/cli/commands/sessions.js +35 -2
- package/src/interfaces/cli/commands/skills.js +15 -9
- package/src/interfaces/cli/commands/status.js +2 -3
- package/src/interfaces/cli/commands/task.js +54 -5
- package/src/interfaces/cli/commands/telegram.js +12 -4
- package/src/interfaces/cli/commands/transcribe.js +177 -0
- package/src/interfaces/cli/help/index.js +311 -72
- package/src/interfaces/cli/http.js +61 -13
- package/src/interfaces/cli/index.js +1 -1
- package/src/interfaces/cli/routes/agent.js +5 -4
- package/src/interfaces/cli/routes/commitment.js +3 -2
- package/src/interfaces/cli/routes/config.js +7 -2
- package/src/interfaces/cli/routes/image.js +11 -0
- package/src/interfaces/cli/routes/index.js +2 -0
- package/src/interfaces/cli/routes/log.js +1 -1
- package/src/interfaces/cli/routes/memory.js +3 -2
- package/src/interfaces/cli/routes/panel.js +15 -2
- package/src/interfaces/cli/routes/profile.js +3 -2
- package/src/interfaces/cli/routes/transcribe.js +10 -0
- package/src/interfaces/cli/stdin.js +29 -0
- package/src/interfaces/desktop/assets/blobs/amatista.png +0 -0
- package/src/interfaces/desktop/assets/blobs/aqua.png +0 -0
- package/src/interfaces/desktop/assets/blobs/brasa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/campana.png +0 -0
- package/src/interfaces/desktop/assets/blobs/caracol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/carbon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cobalto.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cometa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/coral.png +0 -0
- package/src/interfaces/desktop/assets/blobs/cubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/eclipse.png +0 -0
- package/src/interfaces/desktop/assets/blobs/faro.png +0 -0
- package/src/interfaces/desktop/assets/blobs/gajo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/iris.png +0 -0
- package/src/interfaces/desktop/assets/blobs/kiwi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/laguna.png +0 -0
- package/src/interfaces/desktop/assets/blobs/lila.png +0 -0
- package/src/interfaces/desktop/assets/blobs/menta.png +0 -0
- package/src/interfaces/desktop/assets/blobs/nimbo.png +0 -0
- package/src/interfaces/desktop/assets/blobs/noche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/onyx.png +0 -0
- package/src/interfaces/desktop/assets/blobs/orbita.png +0 -0
- package/src/interfaces/desktop/assets/blobs/ovni.png +0 -0
- package/src/interfaces/desktop/assets/blobs/papa.png +0 -0
- package/src/interfaces/desktop/assets/blobs/parche.png +0 -0
- package/src/interfaces/desktop/assets/blobs/peon.png +0 -0
- package/src/interfaces/desktop/assets/blobs/perla.png +0 -0
- package/src/interfaces/desktop/assets/blobs/pino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/quad.png +0 -0
- package/src/interfaces/desktop/assets/blobs/rubi.png +0 -0
- package/src/interfaces/desktop/assets/blobs/saturno.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trebol.png +0 -0
- package/src/interfaces/desktop/assets/blobs/trino.png +0 -0
- package/src/interfaces/desktop/assets/blobs/volcan.png +0 -0
- package/src/interfaces/desktop/assets/blobs/zafiro.png +0 -0
- package/src/interfaces/desktop/assets/notification.mp3 +0 -0
- package/src/interfaces/desktop/main.js +473 -29
- package/src/interfaces/desktop/mascot-blobs.js +41 -0
- package/src/interfaces/desktop/mascot-preload.js +32 -0
- package/src/interfaces/desktop/mascot.css +186 -0
- package/src/interfaces/desktop/mascot.html +40 -0
- package/src/interfaces/desktop/mascot.js +163 -0
- package/src/interfaces/desktop/preload.js +10 -0
- package/src/interfaces/desktop/renderer.js +308 -48
- package/src/interfaces/desktop/style.css +34 -0
- package/src/interfaces/mcp-server/index.js +87 -0
- package/src/interfaces/tui/_shims/util-locale.ts +0 -2
- package/src/interfaces/tui/app.tsx +0 -6
- package/src/interfaces/tui/attach.ts +0 -1
- package/src/interfaces/tui/context/sdk-apx.tsx +0 -4
- package/src/interfaces/tui/plugin/api.tsx +0 -3
- package/src/interfaces/tui/plugin/runtime.ts +0 -3
- package/src/interfaces/tui/thread.ts +0 -16
- package/src/interfaces/web/README.md +22 -14
- package/src/interfaces/web/dist/assets/claude-XtpLmGtF.webp +0 -0
- package/src/interfaces/web/dist/assets/codex-DExPUgvh.webp +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css +32 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.br +0 -0
- package/src/interfaces/web/dist/assets/index-BEoRgIqd.css.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js +1074 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.gz +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.br +0 -0
- package/src/interfaces/web/dist/assets/index-C6fXHc1p.js.map.gz +0 -0
- package/src/interfaces/web/dist/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/dist/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/dist/index.html +22 -6
- package/src/interfaces/web/dist/index.html.br +0 -0
- package/src/interfaces/web/dist/index.html.gz +0 -0
- package/src/interfaces/web/dist/manifest.webmanifest +25 -0
- package/src/interfaces/web/dist/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/dist/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/dist/sw.js +106 -0
- package/src/interfaces/web/dist/sw.js.br +0 -0
- package/src/interfaces/web/dist/sw.js.gz +0 -0
- package/src/interfaces/web/eslint.config.js +83 -0
- package/src/interfaces/web/index.html +20 -4
- package/src/interfaces/web/package-lock.json +1651 -1280
- package/src/interfaces/web/package.json +9 -10
- package/src/interfaces/web/pnpm-lock.yaml +867 -869
- package/src/interfaces/web/public/favicon/dark/site.webmanifest +12 -6
- package/src/interfaces/web/public/favicon/white/site.webmanifest +12 -6
- package/src/interfaces/web/public/manifest.webmanifest +25 -0
- package/src/interfaces/web/public/modules/blobs/amatista.png +0 -0
- package/src/interfaces/web/public/modules/blobs/aqua.png +0 -0
- package/src/interfaces/web/public/modules/blobs/brasa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/campana.png +0 -0
- package/src/interfaces/web/public/modules/blobs/caracol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/carbon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cobalto.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cometa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/coral.png +0 -0
- package/src/interfaces/web/public/modules/blobs/cubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/eclipse.png +0 -0
- package/src/interfaces/web/public/modules/blobs/faro.png +0 -0
- package/src/interfaces/web/public/modules/blobs/gajo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/iris.png +0 -0
- package/src/interfaces/web/public/modules/blobs/kiwi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/laguna.png +0 -0
- package/src/interfaces/web/public/modules/blobs/lila.png +0 -0
- package/src/interfaces/web/public/modules/blobs/menta.png +0 -0
- package/src/interfaces/web/public/modules/blobs/nimbo.png +0 -0
- package/src/interfaces/web/public/modules/blobs/noche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/onyx.png +0 -0
- package/src/interfaces/web/public/modules/blobs/orbita.png +0 -0
- package/src/interfaces/web/public/modules/blobs/ovni.png +0 -0
- package/src/interfaces/web/public/modules/blobs/papa.png +0 -0
- package/src/interfaces/web/public/modules/blobs/parche.png +0 -0
- package/src/interfaces/web/public/modules/blobs/peon.png +0 -0
- package/src/interfaces/web/public/modules/blobs/perla.png +0 -0
- package/src/interfaces/web/public/modules/blobs/pino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/quad.png +0 -0
- package/src/interfaces/web/public/modules/blobs/rubi.png +0 -0
- package/src/interfaces/web/public/modules/blobs/saturno.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trebol.png +0 -0
- package/src/interfaces/web/public/modules/blobs/trino.png +0 -0
- package/src/interfaces/web/public/modules/blobs/volcan.png +0 -0
- package/src/interfaces/web/public/modules/blobs/zafiro.png +0 -0
- package/src/interfaces/web/public/sw.js +106 -0
- package/src/interfaces/web/src/App.tsx +106 -10
- package/src/interfaces/web/src/assets/cli/claude.webp +0 -0
- package/src/interfaces/web/src/assets/cli/codex.webp +0 -0
- package/src/interfaces/web/src/assets/cli/cursor.svg +1 -0
- package/src/interfaces/web/src/assets/cli/opencode.png +0 -0
- package/src/interfaces/web/src/components/Combobox.tsx +201 -0
- package/src/interfaces/web/src/components/MobileHint.tsx +95 -0
- package/src/interfaces/web/src/components/MobileLinkDialog.tsx +156 -0
- package/src/interfaces/web/src/components/ModelCombobox.tsx +21 -113
- package/src/interfaces/web/src/components/{routines/ReadOnlyBlock.tsx → ReadOnlyBlock.tsx} +13 -4
- package/src/interfaces/web/src/components/Roby.tsx +5 -3
- package/src/interfaces/web/src/components/RobyBubble.tsx +23 -5
- package/src/interfaces/web/src/components/RowMenu.tsx +46 -0
- package/src/interfaces/web/src/components/TimezoneSelect.tsx +4 -1
- package/src/interfaces/web/src/components/Toast.tsx +50 -14
- package/src/interfaces/web/src/components/UiSelect.tsx +12 -5
- package/src/interfaces/web/src/components/agents/AgentAvatar.tsx +171 -0
- package/src/interfaces/web/src/components/agents/AgentFormFields.tsx +42 -11
- package/src/interfaces/web/src/components/agents/AgentModelBadge.tsx +157 -0
- package/src/interfaces/web/src/components/agents/AgentModelSelect.tsx +57 -0
- package/src/interfaces/web/src/components/agents/AgentSkillsPicker.tsx +115 -0
- package/src/interfaces/web/src/components/agents/BlobAvatar.tsx +50 -0
- package/src/interfaces/web/src/components/agents/blobPresets.ts +50 -0
- package/src/interfaces/web/src/components/agents/modelCatalog.ts +66 -0
- package/src/interfaces/web/src/components/chat/ActionGroup.tsx +162 -0
- package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +4 -3
- package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +1 -1
- package/src/interfaces/web/src/components/chat/Attachment.tsx +220 -0
- package/src/interfaces/web/src/components/chat/ChatList.tsx +226 -51
- package/src/interfaces/web/src/components/chat/ChatRowActivity.tsx +45 -0
- package/src/interfaces/web/src/components/chat/Composer.tsx +672 -23
- package/src/interfaces/web/src/components/chat/ComposerCommands.tsx +175 -0
- package/src/interfaces/web/src/components/chat/ComposerSuggest.tsx +215 -0
- package/src/interfaces/web/src/components/chat/ContextBar.tsx +133 -65
- package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +107 -47
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +460 -119
- package/src/interfaces/web/src/components/chat/MessageList.tsx +165 -18
- package/src/interfaces/web/src/components/chat/ReasoningBlock.tsx +58 -0
- package/src/interfaces/web/src/components/chat/SessionPicker.tsx +182 -0
- package/src/interfaces/web/src/components/chat/SkillTrace.tsx +183 -0
- package/src/interfaces/web/src/components/chat/ToolCall.tsx +11 -11
- package/src/interfaces/web/src/components/code/CodeContextTab.tsx +87 -53
- package/src/interfaces/web/src/components/code/CodeFileTree.tsx +11 -52
- package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +5 -4
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +31 -7
- package/src/interfaces/web/src/components/code/CodeSessionList.tsx +32 -11
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +33 -3
- package/src/interfaces/web/src/components/code/CodeTerminal.tsx +5 -4
- package/src/interfaces/web/src/components/code/NewCodeSessionDialog.tsx +164 -0
- package/src/interfaces/web/src/components/commitments/CommitmentDetail.tsx +162 -0
- package/src/interfaces/web/src/components/commitments/CommitmentFormDialog.tsx +158 -0
- package/src/interfaces/web/src/components/commitments/CommitmentList.tsx +194 -0
- package/src/interfaces/web/src/components/commitments/commitmentState.tsx +46 -0
- package/src/interfaces/web/src/components/common/BulkActionBar.tsx +60 -0
- package/src/interfaces/web/src/components/common/ConfirmDialog.tsx +4 -1
- package/src/interfaces/web/src/components/common/SelectCheckbox.tsx +40 -0
- package/src/interfaces/web/src/components/common/TabNav.tsx +1 -1
- package/src/interfaces/web/src/components/cron/CronPicker.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileBrowser.tsx +1 -1
- package/src/interfaces/web/src/components/files/FileTree.tsx +6 -4
- package/src/interfaces/web/src/components/files/FileViewer.tsx +9 -5
- package/src/interfaces/web/src/components/files/MarkdownPreview.tsx +45 -9
- package/src/interfaces/web/src/components/images/ImageDefaultsCard.tsx +93 -0
- package/src/interfaces/web/src/components/images/ImageProviderList.tsx +142 -0
- package/src/interfaces/web/src/components/images/ImageProviderModal.tsx +263 -0
- package/src/interfaces/web/src/components/images/ImageTestCard.tsx +142 -0
- package/src/interfaces/web/src/components/inbox/ChannelFilter.tsx +178 -0
- package/src/interfaces/web/src/components/inbox/InboxList.tsx +77 -81
- package/src/interfaces/web/src/components/inbox/InboxRowItem.tsx +140 -0
- package/src/interfaces/web/src/components/integrations/ComingSoonPlugin.tsx +2 -2
- package/src/interfaces/web/src/components/integrations/PluginConnect.tsx +208 -30
- package/src/interfaces/web/src/components/integrations/PluginToolsSection.tsx +1 -1
- package/src/interfaces/web/src/components/layout/ProjectAvatar.tsx +39 -24
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +253 -58
- package/src/interfaces/web/src/components/memory/MemoryBrowser.tsx +94 -47
- package/src/interfaces/web/src/components/routines/ExecutionsList.tsx +202 -90
- package/src/interfaces/web/src/components/routines/RoutineDetail.tsx +28 -6
- package/src/interfaces/web/src/components/routines/RoutineEditor.tsx +16 -5
- package/src/interfaces/web/src/components/routines/RoutineList.tsx +49 -9
- package/src/interfaces/web/src/components/routines/VarTextarea.tsx +1 -1
- package/src/interfaces/web/src/components/routines/runChat.ts +121 -0
- package/src/interfaces/web/src/components/sessions/SessionDetail.tsx +148 -0
- package/src/interfaces/web/src/components/sessions/SessionTerminal.tsx +98 -0
- package/src/interfaces/web/src/components/settings/AccessPanel.tsx +205 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +246 -101
- package/src/interfaces/web/src/components/settings/DesktopSettingsPanel.tsx +36 -2
- package/src/interfaces/web/src/components/settings/DevicesPanel.tsx +19 -6
- package/src/interfaces/web/src/components/settings/EmbedProviderList.tsx +274 -0
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +26 -6
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +118 -119
- package/src/interfaces/web/src/components/settings/NudgePanel.tsx +4 -3
- package/src/interfaces/web/src/components/settings/PairDeviceDialog.tsx +15 -4
- package/src/interfaces/web/src/components/settings/PanelPrefs.tsx +374 -0
- package/src/interfaces/web/src/components/settings/ProfilePanel.tsx +70 -2
- package/src/interfaces/web/src/components/settings/RoutingPanel.tsx +2 -1
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +102 -43
- package/src/interfaces/web/src/components/settings/SkillsManager.tsx +76 -21
- package/src/interfaces/web/src/components/settings/SkillsSettings.tsx +10 -3
- package/src/interfaces/web/src/components/settings/SuperAgentPanel.tsx +8 -0
- package/src/interfaces/web/src/components/settings/TelegramChannelsPanel.tsx +11 -2
- package/src/interfaces/web/src/components/settings/TelegramContactsPanel.tsx +19 -8
- package/src/interfaces/web/src/components/settings/TelegramRolesPanel.tsx +12 -2
- package/src/interfaces/web/src/components/settings/WebPanel.tsx +22 -31
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +15 -3
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +97 -66
- package/src/interfaces/web/src/components/settings/providers/ProviderTestDialog.tsx +150 -0
- package/src/interfaces/web/src/components/settings/providers/typeStyles.ts +67 -25
- package/src/interfaces/web/src/components/settings/providers/types.ts +3 -0
- package/src/interfaces/web/src/components/tasks/TaskBoard.tsx +201 -0
- package/src/interfaces/web/src/components/tasks/TaskColumnsDialog.tsx +243 -0
- package/src/interfaces/web/src/components/tasks/TaskComments.tsx +167 -0
- package/src/interfaces/web/src/components/tasks/TaskDetail.tsx +335 -0
- package/src/interfaces/web/src/components/tasks/TaskFormDialog.tsx +406 -0
- package/src/interfaces/web/src/components/tasks/TaskList.tsx +258 -0
- package/src/interfaces/web/src/components/tasks/TaskSubtasks.tsx +126 -0
- package/src/interfaces/web/src/components/tasks/columns.ts +51 -0
- package/src/interfaces/web/src/components/tasks/taskStatus.tsx +159 -34
- package/src/interfaces/web/src/components/tasks/taskViewPrefs.ts +73 -0
- package/src/interfaces/web/src/components/tasks/useTaskColumns.ts +31 -0
- package/src/interfaces/web/src/components/ui/chat-input.tsx +136 -12
- package/src/interfaces/web/src/components/ui/context-menu.tsx +15 -198
- package/src/interfaces/web/src/components/ui/dialog.tsx +3 -2
- package/src/interfaces/web/src/components/ui/filter-chips.tsx +4 -0
- package/src/interfaces/web/src/components/ui/popover.tsx +14 -49
- package/src/interfaces/web/src/components/ui/sheet.tsx +2 -1
- package/src/interfaces/web/src/components/ui/spinner.tsx +2 -1
- package/src/interfaces/web/src/components/ui.tsx +62 -23
- package/src/interfaces/web/src/components/voice/VoiceProviderList.tsx +2 -1
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +66 -8
- package/src/interfaces/web/src/components/voice/VoiceQvoxInstallCard.tsx +63 -0
- package/src/interfaces/web/src/components/voice/VoiceQvoxStatusCard.tsx +51 -0
- package/src/interfaces/web/src/components/voice/VoiceSttCard.tsx +4 -3
- package/src/interfaces/web/src/components/voice/VoiceTestCard.tsx +38 -4
- package/src/interfaces/web/src/constants/index.ts +1 -0
- package/src/interfaces/web/src/hooks/useChannelPrefs.ts +39 -0
- package/src/interfaces/web/src/hooks/useChat.ts +1092 -85
- package/src/interfaces/web/src/hooks/useChatActivity.ts +24 -0
- package/src/interfaces/web/src/hooks/useInbox.ts +26 -4
- package/src/interfaces/web/src/hooks/useLiveMessages.ts +16 -0
- package/src/interfaces/web/src/hooks/useOllamaModels.ts +79 -0
- package/src/interfaces/web/src/hooks/useRecorder.ts +198 -0
- package/src/interfaces/web/src/hooks/useTokenBootstrap.ts +23 -6
- package/src/interfaces/web/src/i18n/en.ts +832 -175
- package/src/interfaces/web/src/i18n/es.ts +841 -188
- package/src/interfaces/web/src/lib/api/agents.ts +23 -4
- package/src/interfaces/web/src/lib/api/code.ts +17 -0
- package/src/interfaces/web/src/lib/api/commitments.ts +7 -1
- package/src/interfaces/web/src/lib/api/conversations.ts +38 -11
- package/src/interfaces/web/src/lib/api/embeddings.ts +3 -0
- package/src/interfaces/web/src/lib/api/engines.ts +14 -0
- package/src/interfaces/web/src/lib/api/groups.ts +93 -0
- package/src/interfaces/web/src/lib/api/images.ts +193 -0
- package/src/interfaces/web/src/lib/api/inbox.ts +29 -5
- package/src/interfaces/web/src/lib/api/integrations.ts +9 -0
- package/src/interfaces/web/src/lib/api/media.ts +126 -0
- package/src/interfaces/web/src/lib/api/net.ts +44 -0
- package/src/interfaces/web/src/lib/api/profiles.ts +12 -0
- package/src/interfaces/web/src/lib/api/projects.ts +9 -1
- package/src/interfaces/web/src/lib/api/routines.ts +9 -1
- package/src/interfaces/web/src/lib/api/sessions.ts +18 -0
- package/src/interfaces/web/src/lib/api/skills.ts +8 -0
- package/src/interfaces/web/src/lib/api/super_agent.ts +3 -0
- package/src/interfaces/web/src/lib/api/tasks.ts +46 -6
- package/src/interfaces/web/src/lib/api/tools.ts +2 -0
- package/src/interfaces/web/src/lib/api/transcribe.ts +31 -0
- package/src/interfaces/web/src/lib/api/turns.ts +20 -0
- package/src/interfaces/web/src/lib/api/voice.ts +72 -2
- package/src/interfaces/web/src/lib/api.ts +3 -0
- package/src/interfaces/web/src/lib/channels.ts +214 -0
- package/src/interfaces/web/src/lib/chat-activity.ts +175 -0
- package/src/interfaces/web/src/lib/chat-prefs.ts +48 -0
- package/src/interfaces/web/src/lib/code-context.ts +0 -2
- package/src/interfaces/web/src/lib/http.ts +51 -17
- package/src/interfaces/web/src/lib/inbox-selection.ts +29 -0
- package/src/interfaces/web/src/lib/live.ts +252 -0
- package/src/interfaces/web/src/lib/net.ts +211 -0
- package/src/interfaces/web/src/lib/notify.ts +331 -0
- package/src/interfaces/web/src/lib/projectNav.ts +40 -0
- package/src/interfaces/web/src/lib/pwa.ts +115 -0
- package/src/interfaces/web/src/lib/qvox.ts +24 -0
- package/src/interfaces/web/src/lib/slug.ts +3 -0
- package/src/interfaces/web/src/lib/tone.ts +150 -0
- package/src/interfaces/web/src/main.tsx +15 -4
- package/src/interfaces/web/src/screens/ApxAdminScreen.tsx +33 -11
- package/src/interfaces/web/src/screens/InboxScreen.tsx +126 -71
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -4
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +7 -4
- package/src/interfaces/web/src/screens/base/AgentDefaultsTab.tsx +30 -9
- package/src/interfaces/web/src/screens/base/CommitmentsTab.tsx +150 -168
- package/src/interfaces/web/src/screens/base/LogsTab.tsx +8 -7
- package/src/interfaces/web/src/screens/base/SessionsTab.tsx +99 -37
- package/src/interfaces/web/src/screens/base/WorkspacesTab.tsx +1 -1
- package/src/interfaces/web/src/screens/mobile/MobileChat.tsx +85 -0
- package/src/interfaces/web/src/screens/mobile/MobileChatList.tsx +244 -0
- package/src/interfaces/web/src/screens/mobile/MobileCommitments.tsx +350 -0
- package/src/interfaces/web/src/screens/mobile/MobileScreen.tsx +138 -0
- package/src/interfaces/web/src/screens/mobile/MobileTabBar.tsx +105 -0
- package/src/interfaces/web/src/screens/mobile/MobileTasks.tsx +407 -0
- package/src/interfaces/web/src/screens/mobile/NewChatSheet.tsx +313 -0
- package/src/interfaces/web/src/screens/mobile/mobileList.tsx +194 -0
- package/src/interfaces/web/src/screens/mobile/routes.ts +239 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +135 -64
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +0 -1
- package/src/interfaces/web/src/screens/modules/ImagesScreen.tsx +172 -0
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +36 -4
- package/src/interfaces/web/src/screens/project/AgentBrainGraph.tsx +117 -30
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +537 -92
- package/src/interfaces/web/src/screens/project/AgentsTab.tsx +344 -93
- package/src/interfaces/web/src/screens/project/ArtifactsTab.tsx +1 -1
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +1160 -94
- package/src/interfaces/web/src/screens/project/IntegrationsTab.tsx +3 -2
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +62 -14
- package/src/interfaces/web/src/screens/project/Overview.tsx +36 -15
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +93 -8
- package/src/interfaces/web/src/screens/project/SkillsTab.tsx +4 -1
- package/src/interfaces/web/src/screens/project/StructureTab.tsx +5 -4
- package/src/interfaces/web/src/screens/project/TasksTab.tsx +351 -129
- package/src/interfaces/web/src/screens/project/VarsTab.tsx +17 -5
- package/src/interfaces/web/src/styles.css +106 -31
- package/src/interfaces/web/src/types/daemon.ts +246 -2
- package/src/interfaces/web/src/vite-env.d.ts +20 -0
- package/src/interfaces/tui/plugin/command-shim.ts +0 -109
- package/src/interfaces/web/components.json +0 -25
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js +0 -849
- package/src/interfaces/web/dist/assets/index-CvEoGtTf.js.map +0 -1
- package/src/interfaces/web/dist/assets/index-DzBBXFaO.css +0 -1
- package/src/interfaces/web/src/components/tasks/TaskDetailPanel.tsx +0 -142
- package/src/interfaces/web/src/components/ui/accordion.tsx +0 -72
- package/src/interfaces/web/src/components/ui/alert-dialog.tsx +0 -187
- package/src/interfaces/web/src/components/ui/alert.tsx +0 -76
- package/src/interfaces/web/src/components/ui/aspect-ratio.tsx +0 -22
- package/src/interfaces/web/src/components/ui/avatar.tsx +0 -107
- package/src/interfaces/web/src/components/ui/breadcrumb.tsx +0 -125
- package/src/interfaces/web/src/components/ui/button-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/calendar.tsx +0 -221
- package/src/interfaces/web/src/components/ui/card.tsx +0 -103
- package/src/interfaces/web/src/components/ui/carousel.tsx +0 -242
- package/src/interfaces/web/src/components/ui/chart.tsx +0 -371
- package/src/interfaces/web/src/components/ui/checkbox.tsx +0 -29
- package/src/interfaces/web/src/components/ui/collapsible.tsx +0 -19
- package/src/interfaces/web/src/components/ui/combobox.tsx +0 -295
- package/src/interfaces/web/src/components/ui/command.tsx +0 -196
- package/src/interfaces/web/src/components/ui/direction.tsx +0 -4
- package/src/interfaces/web/src/components/ui/drawer.tsx +0 -134
- package/src/interfaces/web/src/components/ui/empty.tsx +0 -104
- package/src/interfaces/web/src/components/ui/field.tsx +0 -236
- package/src/interfaces/web/src/components/ui/hover-card.tsx +0 -51
- package/src/interfaces/web/src/components/ui/input-otp.tsx +0 -85
- package/src/interfaces/web/src/components/ui/item.tsx +0 -201
- package/src/interfaces/web/src/components/ui/menubar.tsx +0 -280
- package/src/interfaces/web/src/components/ui/native-select.tsx +0 -61
- package/src/interfaces/web/src/components/ui/navigation-menu.tsx +0 -168
- package/src/interfaces/web/src/components/ui/pagination.tsx +0 -130
- package/src/interfaces/web/src/components/ui/progress.tsx +0 -83
- package/src/interfaces/web/src/components/ui/radio-group.tsx +0 -36
- package/src/interfaces/web/src/components/ui/resizable.tsx +0 -50
- package/src/interfaces/web/src/components/ui/scroll-area.tsx +0 -53
- package/src/interfaces/web/src/components/ui/sidebar.tsx +0 -726
- package/src/interfaces/web/src/components/ui/slider.tsx +0 -52
- package/src/interfaces/web/src/components/ui/sonner.tsx +0 -49
- package/src/interfaces/web/src/components/ui/table.tsx +0 -116
- package/src/interfaces/web/src/components/ui/toggle-group.tsx +0 -87
- package/src/interfaces/web/src/components/ui/toggle.tsx +0 -45
- package/src/interfaces/web/src/hooks/use-mobile.ts +0 -19
- package/src/interfaces/web/src/screens/base/GlobalTasksTab.tsx +0 -161
|
@@ -33,6 +33,10 @@ export const DEFAULT_LOCAL = {
|
|
|
33
33
|
language: "auto",
|
|
34
34
|
beam_size: 5,
|
|
35
35
|
idle_minutes: 10,
|
|
36
|
+
// The daemon re-warms the model inside this window so the first utterance of
|
|
37
|
+
// the day isn't the one that pays the ~10s load. Set false to let the server
|
|
38
|
+
// idle out and hand the RAM back instead.
|
|
39
|
+
keep_warm: true,
|
|
36
40
|
// Long audio (Telegram voice notes > 10 min) can take several minutes on
|
|
37
41
|
// CPU. 20 minutes covers ~60-minute notes on a small int8 model.
|
|
38
42
|
timeout_ms: 20 * 60_000,
|
package/src/core/voice/tts.js
CHANGED
|
@@ -13,12 +13,13 @@ import { TTS_TMP_DIR } from "#core/config/paths.js";
|
|
|
13
13
|
export { TTS_TMP_DIR };
|
|
14
14
|
import { readConfig } from "../config/index.js";
|
|
15
15
|
import {
|
|
16
|
-
|
|
16
|
+
resolveTtsCandidates,
|
|
17
17
|
listAvailableTtsEngines,
|
|
18
18
|
resolveMode,
|
|
19
19
|
resolveChainOrder,
|
|
20
20
|
} from "./engines/index.js";
|
|
21
21
|
import { emotionConfigFor, stripEmotionTags } from "./emotions.js";
|
|
22
|
+
import { logWarn } from "#core/logging.js";
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
|
|
@@ -28,8 +29,11 @@ export function ensureTtsTmpDir() {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
/**
|
|
31
|
-
* Generate speech audio for `text`.
|
|
32
|
-
*
|
|
32
|
+
* Generate speech audio for `text`. In chain mode every configured engine is
|
|
33
|
+
* tried in order until one answers, so a dead local server costs a retry and
|
|
34
|
+
* not the voice. The returned `provider` says who actually spoke: "mock" means
|
|
35
|
+
* nothing did and the audio is silence — check it before presenting the result
|
|
36
|
+
* as speech.
|
|
33
37
|
*
|
|
34
38
|
* @param {object} opts
|
|
35
39
|
* @param {string} opts.text Text to speak. Required.
|
|
@@ -44,6 +48,47 @@ export function ensureTtsTmpDir() {
|
|
|
44
48
|
* @param {object} [opts.globalConfig] Pass-in for tests; falls back to readConfig().
|
|
45
49
|
* @returns {Promise<{audio_path, duration_s, mime, provider}>}
|
|
46
50
|
*/
|
|
51
|
+
/**
|
|
52
|
+
* Duration of a PCM WAV, read from its header. Most engines don't report one —
|
|
53
|
+
* mock and piper were the only two that did, which is how the desktop ended up
|
|
54
|
+
* able to play its silent placeholder and nothing else — and a player that
|
|
55
|
+
* doesn't know how long the clip is can't draw a progress bar.
|
|
56
|
+
*
|
|
57
|
+
* The chunks are walked rather than read at fixed offsets. Only the canonical
|
|
58
|
+
* 44-byte layout puts `fmt ` at 12 and `data` at 36; a float32 wav carries a
|
|
59
|
+
* `fact` chunk between them, and reading offset 40 there lands mid-chunk and
|
|
60
|
+
* yields a confident wrong answer — a 12.4s clip reported as 3.0s.
|
|
61
|
+
*
|
|
62
|
+
* Returns null for anything that isn't a readable RIFF/WAVE (mp3, ogg).
|
|
63
|
+
*/
|
|
64
|
+
function wavDurationSeconds(filePath) {
|
|
65
|
+
try {
|
|
66
|
+
const head = Buffer.alloc(4096);
|
|
67
|
+
const fd = fs.openSync(filePath, "r");
|
|
68
|
+
const read = fs.readSync(fd, head, 0, head.length, 0);
|
|
69
|
+
fs.closeSync(fd);
|
|
70
|
+
if (read < 12) return null;
|
|
71
|
+
if (head.toString("ascii", 0, 4) !== "RIFF" || head.toString("ascii", 8, 12) !== "WAVE") return null;
|
|
72
|
+
|
|
73
|
+
let byteRate = 0;
|
|
74
|
+
let pos = 12;
|
|
75
|
+
while (pos + 8 <= read) {
|
|
76
|
+
const id = head.toString("ascii", pos, pos + 4);
|
|
77
|
+
const size = head.readUInt32LE(pos + 4);
|
|
78
|
+
const body = pos + 8;
|
|
79
|
+
if (id === "fmt " && body + 16 <= read) byteRate = head.readUInt32LE(body + 8);
|
|
80
|
+
// `data` is the last chunk read: its size is the sample bytes, and by
|
|
81
|
+
// now `fmt ` has been seen, since a wav that ordered them the other way
|
|
82
|
+
// would be unplayable everywhere else too.
|
|
83
|
+
if (id === "data") return byteRate ? size / byteRate : null;
|
|
84
|
+
pos = body + size + (size % 2); // chunks are word-aligned
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
47
92
|
export async function synthesize({
|
|
48
93
|
text,
|
|
49
94
|
voice,
|
|
@@ -58,29 +103,74 @@ export async function synthesize({
|
|
|
58
103
|
throw new Error("synthesize: text required");
|
|
59
104
|
}
|
|
60
105
|
const cfg = globalConfig || readConfig() || {};
|
|
61
|
-
const {
|
|
62
|
-
|
|
63
|
-
provider,
|
|
64
|
-
});
|
|
106
|
+
const candidates = await resolveTtsCandidates({ globalConfig: cfg, provider });
|
|
107
|
+
const outDir = ensureTtsTmpDir();
|
|
65
108
|
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
109
|
+
// Walk the chain. An engine that throws (local server down, key revoked,
|
|
110
|
+
// quota) hands the text to the next one — being available and answering are
|
|
111
|
+
// different questions, and only the request settles the second.
|
|
112
|
+
let lastError = null;
|
|
113
|
+
for (const { provider: selectedProvider, adapter, engineConfig } of candidates) {
|
|
114
|
+
// Safety net: if the engine that will speak does NOT support inline emotion
|
|
115
|
+
// tags, scrub any stray [tag] markers so they're never read aloud literally.
|
|
116
|
+
const speakText = emotionConfigFor(cfg, selectedProvider).enabled
|
|
117
|
+
? text
|
|
118
|
+
: stripEmotionTags(text);
|
|
119
|
+
try {
|
|
120
|
+
const r = await adapter.synthesize({
|
|
121
|
+
text: speakText,
|
|
122
|
+
voice,
|
|
123
|
+
language,
|
|
124
|
+
format,
|
|
125
|
+
style,
|
|
126
|
+
outDir,
|
|
127
|
+
config: engineConfig,
|
|
128
|
+
parentEnginesCfg: cfg.engines,
|
|
129
|
+
signal,
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
...r,
|
|
133
|
+
// Fill in what the engine didn't measure, so every caller sees the same
|
|
134
|
+
// shape whoever spoke.
|
|
135
|
+
duration_s: r.duration_s ?? (r.audio_path ? wavDurationSeconds(r.audio_path) : null),
|
|
136
|
+
provider: selectedProvider || r.provider,
|
|
137
|
+
};
|
|
138
|
+
} catch (e) {
|
|
139
|
+
lastError = e;
|
|
140
|
+
// An aborted turn is the caller changing its mind, not an engine fault —
|
|
141
|
+
// trying the next voice would speak a reply nobody is waiting for.
|
|
142
|
+
if (e?.name === "AbortError" || signal?.aborted) throw e;
|
|
143
|
+
logWarn("tts", `${selectedProvider} failed — ${e?.message || e}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
throw lastError || new Error("synthesize: no TTS engine available");
|
|
147
|
+
}
|
|
71
148
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
149
|
+
/**
|
|
150
|
+
* Ask whoever is about to speak to get ready, if they can.
|
|
151
|
+
*
|
|
152
|
+
* Only the engine that would actually handle the next synthesize() is warmed —
|
|
153
|
+
* warming the whole chain would spin up fallbacks that are not going to be
|
|
154
|
+
* used. Engines with nothing to warm (every cloud API) simply have no warmup()
|
|
155
|
+
* and are skipped.
|
|
156
|
+
*
|
|
157
|
+
* Fire-and-forget by contract: a warmup that fails costs a slower first reply,
|
|
158
|
+
* never a failed one, so this resolves rather than throws.
|
|
159
|
+
*/
|
|
160
|
+
export async function warmupTts({ globalConfig } = {}) {
|
|
161
|
+
const cfg = globalConfig || readConfig() || {};
|
|
162
|
+
const [first] = await resolveTtsCandidates({ globalConfig: cfg });
|
|
163
|
+
if (!first) return { ok: false, error: "no TTS engine" };
|
|
164
|
+
if (typeof first.adapter.warmup !== "function") {
|
|
165
|
+
return { ok: true, provider: first.provider, skipped: "engine has no warmup" };
|
|
166
|
+
}
|
|
167
|
+
try {
|
|
168
|
+
const r = await first.adapter.warmup(first.engineConfig, cfg.engines);
|
|
169
|
+
return { ok: true, provider: first.provider, ...r };
|
|
170
|
+
} catch (e) {
|
|
171
|
+
logWarn("tts", `warmup of ${first.provider} failed — ${e?.message || e}`);
|
|
172
|
+
return { ok: false, provider: first.provider, error: e?.message || String(e) };
|
|
173
|
+
}
|
|
84
174
|
}
|
|
85
175
|
|
|
86
176
|
/** List engines and whether they look usable right now. */
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
// In-progress chat turns, so streaming survives the tab that started it.
|
|
2
|
+
//
|
|
3
|
+
// The per-request NDJSON stream belongs to the sender: refresh the page or walk
|
|
4
|
+
// to another chat and it is gone, even though the turn keeps running on the
|
|
5
|
+
// daemon. This registry is the daemon's own record of what is being written
|
|
6
|
+
// right now — the accumulated text plus who/where — so ANY surface can be caught
|
|
7
|
+
// up (via the conversation GET) and then followed live (via the events-ws
|
|
8
|
+
// "turn" frames the chat handlers broadcast). It is pure in-memory runtime
|
|
9
|
+
// state: if the daemon restarts mid-turn the turn is gone anyway.
|
|
10
|
+
//
|
|
11
|
+
// Key is the conversation's identity as the client already addresses it:
|
|
12
|
+
// project agent → `${projectId}:conv:${conversationId}`
|
|
13
|
+
// super-agent → `${projectId}:thread:${channel}:${threadId}`
|
|
14
|
+
// so a client on that conversation can match a frame without extra plumbing.
|
|
15
|
+
|
|
16
|
+
let seq = 0;
|
|
17
|
+
const byId = new Map(); // turnId -> record
|
|
18
|
+
const byKey = new Map(); // key -> turnId (the latest turn on that conversation)
|
|
19
|
+
|
|
20
|
+
/** Public client shape. Abort hooks and internal keys never leave this module. */
|
|
21
|
+
function publicTurn(rec) {
|
|
22
|
+
if (!rec) return null;
|
|
23
|
+
return {
|
|
24
|
+
turn_id: rec.id,
|
|
25
|
+
text: rec.text,
|
|
26
|
+
project_id: rec.project_id ?? null,
|
|
27
|
+
agent_slug: rec.agent_slug,
|
|
28
|
+
conversation_id: rec.conversation_id,
|
|
29
|
+
channel: rec.channel,
|
|
30
|
+
thread_id: rec.thread_id,
|
|
31
|
+
model: rec.model,
|
|
32
|
+
started_at: rec.started_at,
|
|
33
|
+
// The text alone is not enough to re-open a multi-step turn: it loses the
|
|
34
|
+
// actual tools and makes a still-working turn look idle. Keep the compact,
|
|
35
|
+
// render-ready timeline alongside it; abort hooks and private keys remain
|
|
36
|
+
// inside this module.
|
|
37
|
+
...(rec.parts?.length
|
|
38
|
+
? {
|
|
39
|
+
parts: rec.parts.map((part) => {
|
|
40
|
+
const copy = { ...part };
|
|
41
|
+
if (copy.streaming === false) delete copy.streaming;
|
|
42
|
+
return copy;
|
|
43
|
+
}),
|
|
44
|
+
}
|
|
45
|
+
: {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Key for a project-agent conversation turn. */
|
|
50
|
+
export function convTurnKey(projectId, conversationId) {
|
|
51
|
+
return `${projectId}:conv:${conversationId}`;
|
|
52
|
+
}
|
|
53
|
+
/** Key for a super-agent channel-thread turn. */
|
|
54
|
+
export function threadTurnKey(projectId, channel, threadId) {
|
|
55
|
+
return `${projectId}:thread:${channel}:${threadId}`;
|
|
56
|
+
}
|
|
57
|
+
/** Key for a super-agent chat turn. Roby's web chat has no conversation id —
|
|
58
|
+
* its thread IS the channel (the ledger is written per channel+day), so there
|
|
59
|
+
* is one live turn per project+channel, exactly as Telegram keys one live turn
|
|
60
|
+
* per chat_id. */
|
|
61
|
+
export function superAgentTurnKey(projectId, channel) {
|
|
62
|
+
return `${projectId}:sa:${channel}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Begin tracking a turn. `meta` is echoed to clients (agent_slug, model, …),
|
|
66
|
+
* except `abort`: a function that stops the run, kept private to this module
|
|
67
|
+
* and to abortActiveTurn. */
|
|
68
|
+
export function startActiveTurn(key, meta = {}) {
|
|
69
|
+
const id = `turn_${Date.now().toString(36)}_${++seq}`;
|
|
70
|
+
const rec = { id, key, text: "", started_at: new Date().toISOString(), ...meta, parts: [] };
|
|
71
|
+
byId.set(id, rec);
|
|
72
|
+
byKey.set(key, id);
|
|
73
|
+
return rec;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function syncText(rec) {
|
|
77
|
+
rec.text = rec.parts
|
|
78
|
+
.filter((part) => part.kind === "text")
|
|
79
|
+
.map((part) => part.text || "")
|
|
80
|
+
.join("");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Grow the accumulated text as tokens arrive. */
|
|
84
|
+
export function appendActiveTurn(id, delta) {
|
|
85
|
+
const rec = byId.get(id);
|
|
86
|
+
if (!rec || !delta) return;
|
|
87
|
+
const last = rec.parts.at(-1);
|
|
88
|
+
if (last?.kind === "text" && last.streaming) last.text += delta;
|
|
89
|
+
else rec.parts.push({ kind: "text", text: delta, streaming: true });
|
|
90
|
+
syncText(rec);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Record the visible work timeline of a live turn. This is deliberately a
|
|
94
|
+
* small transport shape: text segments plus tool starts/results, never hidden
|
|
95
|
+
* reasoning or the abort hook. A refresh can therefore show the same tools the
|
|
96
|
+
* original pane was watching. */
|
|
97
|
+
export function recordActiveTurnEvent(id, event) {
|
|
98
|
+
const rec = byId.get(id);
|
|
99
|
+
if (!rec || !event) return;
|
|
100
|
+
if (event.type === "assistant_text" && event.text) {
|
|
101
|
+
const last = rec.parts.at(-1);
|
|
102
|
+
if (last?.kind === "text" && last.streaming) {
|
|
103
|
+
last.text = event.text;
|
|
104
|
+
last.streaming = false;
|
|
105
|
+
} else {
|
|
106
|
+
rec.parts.push({ kind: "text", text: event.text });
|
|
107
|
+
}
|
|
108
|
+
syncText(rec);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (event.type === "tool_start" && event.trace?.id) {
|
|
112
|
+
rec.parts.push({
|
|
113
|
+
kind: "tool",
|
|
114
|
+
id: event.trace.id,
|
|
115
|
+
tool: event.trace.tool || "tool",
|
|
116
|
+
args: event.trace.args,
|
|
117
|
+
status: "running",
|
|
118
|
+
});
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (event.type === "tool_result" && event.trace?.id) {
|
|
122
|
+
const failed = !!event.trace.result && typeof event.trace.result === "object" && !!event.trace.result.error;
|
|
123
|
+
const part = rec.parts.findLast((item) => item.kind === "tool" && item.id === event.trace.id);
|
|
124
|
+
if (part) {
|
|
125
|
+
part.result = event.trace.result;
|
|
126
|
+
part.status = failed ? "error" : "done";
|
|
127
|
+
} else {
|
|
128
|
+
rec.parts.push({
|
|
129
|
+
kind: "tool",
|
|
130
|
+
id: event.trace.id,
|
|
131
|
+
tool: event.trace.tool || "tool",
|
|
132
|
+
args: event.trace.args,
|
|
133
|
+
result: event.trace.result,
|
|
134
|
+
status: failed ? "error" : "done",
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Stop tracking. Idempotent — the finally block and an error path both call it. */
|
|
141
|
+
export function endActiveTurn(id) {
|
|
142
|
+
const rec = byId.get(id);
|
|
143
|
+
if (!rec) return;
|
|
144
|
+
byId.delete(id);
|
|
145
|
+
if (byKey.get(rec.key) === id) byKey.delete(rec.key);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Stop the turn running on that conversation. Returns false when there is
|
|
150
|
+
* nothing to stop — no live turn, or one registered without an abort hook.
|
|
151
|
+
*
|
|
152
|
+
* This is what makes "stop" and "interrupt" real. A client closing its NDJSON
|
|
153
|
+
* socket deliberately does NOT end the run (that is what lets a refresh catch
|
|
154
|
+
* up on it), so cancelling has to be said out loud: the surface asks for it,
|
|
155
|
+
* the run's AbortController is signalled here, and the loop notices at its next
|
|
156
|
+
* iteration boundary. Same shape Telegram has had all along — one controller
|
|
157
|
+
* per live conversation, aborted when a newer message says "no, do this
|
|
158
|
+
* instead" (see core/channels/telegram/dispatch.js).
|
|
159
|
+
*/
|
|
160
|
+
export function abortActiveTurn(key) {
|
|
161
|
+
const id = byKey.get(key);
|
|
162
|
+
const rec = id ? byId.get(id) : null;
|
|
163
|
+
if (!rec || typeof rec.abort !== "function") return false;
|
|
164
|
+
rec.aborted = true;
|
|
165
|
+
try {
|
|
166
|
+
rec.abort();
|
|
167
|
+
} catch {
|
|
168
|
+
/* the run is already gone; the caller only needs to know we tried */
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/** The turn currently being written on that conversation, if any — the partial
|
|
174
|
+
* a just-arrived client renders before it starts following the live frames. */
|
|
175
|
+
export function getActiveTurnByKey(key) {
|
|
176
|
+
const id = byKey.get(key);
|
|
177
|
+
const rec = id ? byId.get(id) : null;
|
|
178
|
+
return publicTurn(rec);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Every live turn, optionally scoped to one project. Used by aggregate list
|
|
182
|
+
* surfaces (Inbox / Chats) so they all render the same daemon-owned status. */
|
|
183
|
+
export function listActiveTurns({ projectId } = {}) {
|
|
184
|
+
const want = projectId === undefined || projectId === null ? null : String(projectId);
|
|
185
|
+
return [...byId.values()]
|
|
186
|
+
.filter((rec) => want === null || String(rec.project_id) === want)
|
|
187
|
+
.map(publicTurn);
|
|
188
|
+
}
|
|
@@ -15,6 +15,8 @@ import {
|
|
|
15
15
|
mergeRedactedChannels,
|
|
16
16
|
} from "#core/config/redact.js";
|
|
17
17
|
import { collectSecretValues, registerSecretValues } from "#core/config/secret-values.js";
|
|
18
|
+
import { isBlobKey, resolveSuperAgentBlob } from "#core/apc/agent-identity.js";
|
|
19
|
+
import { broadcastSuperAgentAvatar } from "../events-ws.js";
|
|
18
20
|
|
|
19
21
|
export function register(api, { config, scheduler, plugins }) {
|
|
20
22
|
api.get("/admin/config", (_req, res) => {
|
|
@@ -28,6 +30,11 @@ export function register(api, { config, scheduler, plugins }) {
|
|
|
28
30
|
|
|
29
31
|
api.patch("/admin/config", (req, res) => {
|
|
30
32
|
const { set, unset } = req.body || {};
|
|
33
|
+
const avatarTouched = (set && Object.hasOwn(set, "super_agent.icon"))
|
|
34
|
+
|| (Array.isArray(unset) && unset.includes("super_agent.icon"));
|
|
35
|
+
if (set && Object.hasOwn(set, "super_agent.icon") && !isBlobKey(set["super_agent.icon"])) {
|
|
36
|
+
return res.status(400).json({ error: "Invalid super-agent avatar" });
|
|
37
|
+
}
|
|
31
38
|
let cfg;
|
|
32
39
|
try {
|
|
33
40
|
cfg = readConfig();
|
|
@@ -64,6 +71,7 @@ export function register(api, { config, scheduler, plugins }) {
|
|
|
64
71
|
registerSecretValues(collectSecretValues(fresh));
|
|
65
72
|
if (scheduler) scheduler.globalConfig = config;
|
|
66
73
|
if (plugins) plugins.config = config;
|
|
74
|
+
if (avatarTouched) broadcastSuperAgentAvatar(fresh);
|
|
67
75
|
res.json({ ok: true, config: redact(fresh) });
|
|
68
76
|
});
|
|
69
77
|
|
|
@@ -75,6 +83,7 @@ export function register(api, { config, scheduler, plugins }) {
|
|
|
75
83
|
res.json({
|
|
76
84
|
enabled: !!sa.enabled,
|
|
77
85
|
name: resolveAgentName(fresh),
|
|
86
|
+
icon: resolveSuperAgentBlob(fresh),
|
|
78
87
|
model: sa.model || "",
|
|
79
88
|
system: sa.system || "",
|
|
80
89
|
permission_mode: sa.permission_mode || PERMISSION_MODES.PERMISO,
|
|
@@ -4,10 +4,17 @@
|
|
|
4
4
|
// POST /projects/:pid/agents — create from slug
|
|
5
5
|
// GET /projects/:pid/agents/:slug/memory
|
|
6
6
|
// PUT /projects/:pid/agents/:slug/memory
|
|
7
|
-
import fs from "node:fs";
|
|
8
|
-
import path from "node:path";
|
|
9
7
|
import { readAgents, readVaultAgents, readVaultAgent } from "#core/apc/parser.js";
|
|
10
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
readProjectMemory,
|
|
10
|
+
writeProjectMemory,
|
|
11
|
+
projectMemoryPath,
|
|
12
|
+
} from "#core/apc/project-memory.js";
|
|
13
|
+
import {
|
|
14
|
+
readProjectLocalMemory,
|
|
15
|
+
writeProjectLocalMemory,
|
|
16
|
+
projectLocalMemoryPath,
|
|
17
|
+
} from "#core/stores/project-memory.js";
|
|
11
18
|
import {
|
|
12
19
|
writeAgentFile,
|
|
13
20
|
writeVaultAgentFile,
|
|
@@ -19,15 +26,14 @@ import {
|
|
|
19
26
|
ensureAgentRuntimeDir,
|
|
20
27
|
readAgentMemory,
|
|
21
28
|
writeAgentMemory,
|
|
22
|
-
agentMemoryPath,
|
|
23
|
-
legacyAgentMemoryPath,
|
|
24
29
|
} from "#core/agent/memory.js";
|
|
25
|
-
import {
|
|
30
|
+
import { createAgent, cloneAgent, setAgentConfig, removeAgent, renameAgent } from "#core/apc/agent-write.js";
|
|
31
|
+
import { agentToResponse, asyncRoute } from "./shared.js";
|
|
26
32
|
import { normalizeVaultPatch } from "#core/apc/agents-vault.js";
|
|
27
|
-
import { PERMISSION_MODES } from "#core/constants/permissions.js";
|
|
28
33
|
import { listConversations } from "#core/stores/conversations.js";
|
|
29
34
|
import { listTasks } from "#core/stores/tasks.js";
|
|
30
35
|
import { listRoutines } from "#core/stores/routines.js";
|
|
36
|
+
import { slugifyName } from "#core/stores/organization.js";
|
|
31
37
|
import { readProjectMessages } from "#core/stores/messages.js";
|
|
32
38
|
|
|
33
39
|
// Attach a per-agent activity summary ({ threads, records, tasks, heartbeats })
|
|
@@ -60,16 +66,6 @@ function attachAgentStats(p, agents) {
|
|
|
60
66
|
}
|
|
61
67
|
}
|
|
62
68
|
|
|
63
|
-
// Autonomy mirrors the super-agent permission modes (total/automatico/permiso).
|
|
64
|
-
// An invalid value is dropped rather than persisted so a typo can't silently
|
|
65
|
-
// widen an agent's autonomy.
|
|
66
|
-
const AUTONOMY_VALUES = new Set(Object.values(PERMISSION_MODES));
|
|
67
|
-
function normalizeAutonomy(v) {
|
|
68
|
-
if (v === undefined) return undefined;
|
|
69
|
-
if (v === null || v === "") return null;
|
|
70
|
-
return AUTONOMY_VALUES.has(v) ? v : undefined;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
69
|
export function register(api, { projects, project }) {
|
|
74
70
|
// Vault = global agent templates. Two-layer: bundled defaults shipped with
|
|
75
71
|
// APX (assets/agent-vault-defaults/) + user overrides/new ones in
|
|
@@ -175,34 +171,12 @@ export function register(api, { projects, project }) {
|
|
|
175
171
|
api.post("/projects/:pid/agents", (req, res) => {
|
|
176
172
|
const p = project(req, res);
|
|
177
173
|
if (!p) return;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (!slug) return res.status(400).json({ error: "slug required" });
|
|
183
|
-
if (!/^[a-z][a-z0-9_-]*$/.test(slug))
|
|
184
|
-
return res.status(400).json({ error: "invalid slug" });
|
|
185
|
-
const existing = readAgents(p.path).find((a) => a.slug === slug);
|
|
186
|
-
if (existing)
|
|
187
|
-
return res.status(400).json({ error: `agent ${slug} already exists` });
|
|
188
|
-
const autonomyVal = normalizeAutonomy(autonomy);
|
|
174
|
+
// Field normalization, avatar pick, slug/type validation and the file write
|
|
175
|
+
// all live in core (agent-write.js), shared with the super-agent's
|
|
176
|
+
// create_agent tool so the two surfaces can never drift. The route only
|
|
177
|
+
// resolves the project, rebuilds the registry, and shapes the response.
|
|
189
178
|
try {
|
|
190
|
-
|
|
191
|
-
Role: role || null,
|
|
192
|
-
Model: model || null,
|
|
193
|
-
Language: language || null,
|
|
194
|
-
Description: description || null,
|
|
195
|
-
Skills: skills || [],
|
|
196
|
-
Tools: tools || [],
|
|
197
|
-
Master: is_master ? true : null,
|
|
198
|
-
Parent: parent || null,
|
|
199
|
-
Type: type || null,
|
|
200
|
-
Area: area || null,
|
|
201
|
-
Emoji: emoji || null,
|
|
202
|
-
Autonomy: autonomyVal || null,
|
|
203
|
-
});
|
|
204
|
-
ensureAgentDir(p.path, slug);
|
|
205
|
-
ensureAgentRuntimeDir(p, slug);
|
|
179
|
+
const slug = createAgent(p, req.body || {});
|
|
206
180
|
projects.rebuild(p.id);
|
|
207
181
|
const created = readAgents(p.path).find((a) => a.slug === slug);
|
|
208
182
|
res.status(201).json(agentToResponse(created));
|
|
@@ -211,41 +185,36 @@ export function register(api, { projects, project }) {
|
|
|
211
185
|
}
|
|
212
186
|
});
|
|
213
187
|
|
|
188
|
+
// Duplicate an agent (frontmatter + prompt + memory) into a fresh "<slug>-n"
|
|
189
|
+
// whose display Name gains a " (n)" suffix. Clone/naming live in core
|
|
190
|
+
// (agent-write.js); the route resolves the project, rebuilds, and returns the
|
|
191
|
+
// new agent so the UI can jump straight to it.
|
|
192
|
+
api.post("/projects/:pid/agents/:slug/clone", (req, res) => {
|
|
193
|
+
const p = project(req, res);
|
|
194
|
+
if (!p) return;
|
|
195
|
+
try {
|
|
196
|
+
const newSlug = cloneAgent(p, req.params.slug);
|
|
197
|
+
projects.rebuild(p.id);
|
|
198
|
+
const created = readAgents(p.path).find((a) => a.slug === newSlug);
|
|
199
|
+
res.status(201).json(agentToResponse(created));
|
|
200
|
+
} catch (e) {
|
|
201
|
+
const status = /not found/.test(e.message) ? 404 : 400;
|
|
202
|
+
res.status(status).json({ error: e.message });
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
|
|
214
206
|
// Edit an existing agent. Merges provided fields into the AGENT.md
|
|
215
207
|
// frontmatter; `system` rewrites the body (the agent's system prompt).
|
|
216
208
|
api.patch("/projects/:pid/agents/:slug", (req, res) => {
|
|
217
209
|
const p = project(req, res);
|
|
218
210
|
if (!p) return;
|
|
219
211
|
const slug = req.params.slug;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const setStr = (key, val) => {
|
|
225
|
-
if (val === undefined) return;
|
|
226
|
-
if (val === null || val === "") delete fields[key];
|
|
227
|
-
else fields[key] = val;
|
|
228
|
-
};
|
|
229
|
-
setStr("Role", b.role);
|
|
230
|
-
setStr("Model", b.model);
|
|
231
|
-
setStr("Language", b.language);
|
|
232
|
-
setStr("Description", b.description);
|
|
233
|
-
setStr("Parent", b.parent);
|
|
234
|
-
setStr("Type", b.type);
|
|
235
|
-
setStr("Area", b.area);
|
|
236
|
-
setStr("Emoji", b.emoji);
|
|
237
|
-
setStr("Autonomy", normalizeAutonomy(b.autonomy));
|
|
238
|
-
if (b.skills !== undefined) fields.Skills = Array.isArray(b.skills) ? b.skills : [];
|
|
239
|
-
if (b.tools !== undefined) fields.Tools = Array.isArray(b.tools) ? b.tools : [];
|
|
240
|
-
if (b.is_master !== undefined) {
|
|
241
|
-
if (b.is_master) fields.Master = true;
|
|
242
|
-
else { delete fields.Master; delete fields.Primary; }
|
|
243
|
-
}
|
|
244
|
-
const body = b.system !== undefined ? b.system : (existing.body || "");
|
|
212
|
+
if (!readAgents(p.path).some((a) => a.slug === slug))
|
|
213
|
+
return res.status(404).json({ error: "agent not found" });
|
|
214
|
+
// Field normalization + write live in core (agent-write.js), shared with the
|
|
215
|
+
// super-agent's configure_agent / set_agent_prompt tools.
|
|
245
216
|
try {
|
|
246
|
-
|
|
247
|
-
ensureAgentDir(p.path, slug);
|
|
248
|
-
ensureAgentRuntimeDir(p, slug);
|
|
217
|
+
setAgentConfig(p, slug, req.body || {});
|
|
249
218
|
projects.rebuild(p.id);
|
|
250
219
|
const updated = readAgents(p.path).find((a) => a.slug === slug);
|
|
251
220
|
res.json(agentToResponse(updated));
|
|
@@ -254,34 +223,59 @@ export function register(api, { projects, project }) {
|
|
|
254
223
|
}
|
|
255
224
|
});
|
|
256
225
|
|
|
226
|
+
// Rename an agent's slug — moves its .apc/agents/<slug>.md and runtime dir and
|
|
227
|
+
// repoints every live reference to it (child `Parent`, routines, group
|
|
228
|
+
// rosters, tasks, deliveries, code sessions, telegram routes, the RAG scope).
|
|
229
|
+
// Distinct from PATCH on purpose: it's an irreversible file move and it
|
|
230
|
+
// changes the resource URL, so the UI must navigate to the returned slug
|
|
231
|
+
// rather than revalidate in place. The new slug can be sent raw (`{ slug }`)
|
|
232
|
+
// or derived from a name (`{ name }`) — the caller-side slugify is mirrored
|
|
233
|
+
// here so either surface yields the same key. The whole registry goes in so
|
|
234
|
+
// the sweep can reach rooms hosted by ANOTHER project that include this agent.
|
|
235
|
+
api.post("/projects/:pid/agents/:slug/rename", asyncRoute(async (req, res) => {
|
|
236
|
+
const p = project(req, res);
|
|
237
|
+
if (!p) return;
|
|
238
|
+
const body = req.body || {};
|
|
239
|
+
const target = body.slug ? String(body.slug) : slugifyName(body.name || "");
|
|
240
|
+
if (!target || !/^[a-z][a-z0-9_-]*$/.test(target)) {
|
|
241
|
+
return res.status(400).json({ error: "valid target slug required" });
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const finalSlug = await renameAgent(p, req.params.slug, target, { projects: projects.list() });
|
|
245
|
+
projects.rebuild(p.id);
|
|
246
|
+
const updated = readAgents(p.path).find((a) => a.slug === finalSlug);
|
|
247
|
+
res.json(agentToResponse(updated));
|
|
248
|
+
} catch (e) {
|
|
249
|
+
const status = /not found/.test(e.message) ? 404 : 400;
|
|
250
|
+
res.status(status).json({ error: e.message });
|
|
251
|
+
}
|
|
252
|
+
}));
|
|
253
|
+
|
|
257
254
|
// Delete an agent: removes .apc/agents/<slug>.md and runtime data dir.
|
|
258
255
|
api.delete("/projects/:pid/agents/:slug", (req, res) => {
|
|
259
256
|
const p = project(req, res);
|
|
260
257
|
if (!p) return;
|
|
261
|
-
const slug = req.params.slug;
|
|
262
|
-
const file = apcAgentFile(p.path, slug);
|
|
263
|
-
const runtimeDir = path.dirname(agentMemoryPath(p, slug));
|
|
264
|
-
const legacyDir = path.dirname(legacyAgentMemoryPath(p.path, slug));
|
|
265
|
-
if (!fs.existsSync(file) && !fs.existsSync(runtimeDir) && !fs.existsSync(legacyDir))
|
|
266
|
-
return res.status(404).json({ error: "agent not found" });
|
|
267
258
|
try {
|
|
268
|
-
|
|
269
|
-
if (fs.existsSync(runtimeDir)) fs.rmSync(runtimeDir, { recursive: true, force: true });
|
|
270
|
-
if (fs.existsSync(legacyDir)) fs.rmSync(legacyDir, { recursive: true, force: true });
|
|
259
|
+
removeAgent(p, req.params.slug);
|
|
271
260
|
projects.rebuild(p.id);
|
|
272
261
|
res.json({ ok: true });
|
|
273
262
|
} catch (e) {
|
|
274
|
-
|
|
263
|
+
const status = /not found/.test(e.message) ? 404 : 400;
|
|
264
|
+
res.status(status).json({ error: e.message });
|
|
275
265
|
}
|
|
276
266
|
});
|
|
277
267
|
|
|
278
|
-
// ---- Project-level memory
|
|
268
|
+
// ---- Project-level memory ----
|
|
269
|
+
// Two files, one boundary: `.apc/memory.md` is committed and only a person
|
|
270
|
+
// writes it (core/apc/project-memory.js); `~/.apx/projects/<id>/memory.md` is
|
|
271
|
+
// local, never committed, and is what the `remember` tool appends to
|
|
272
|
+
// (core/stores/project-memory.js). Both are served here so the Memories screen
|
|
273
|
+
// can show them side by side — a memory nothing displays is the bug this pair
|
|
274
|
+
// of routes exists to prevent.
|
|
279
275
|
api.get("/projects/:pid/memory", (req, res) => {
|
|
280
276
|
const p = project(req, res);
|
|
281
277
|
if (!p) return;
|
|
282
|
-
|
|
283
|
-
const body = fs.existsSync(memPath) ? fs.readFileSync(memPath, "utf8") : "";
|
|
284
|
-
res.json({ body, path: memPath });
|
|
278
|
+
res.json({ body: readProjectMemory(p.path), path: projectMemoryPath(p.path) });
|
|
285
279
|
});
|
|
286
280
|
|
|
287
281
|
api.put("/projects/:pid/memory", (req, res) => {
|
|
@@ -290,11 +284,26 @@ export function register(api, { projects, project }) {
|
|
|
290
284
|
const { body } = req.body || {};
|
|
291
285
|
if (typeof body !== "string")
|
|
292
286
|
return res.status(400).json({ error: "body must be string" });
|
|
293
|
-
|
|
294
|
-
const memPath = apcMemoryFile(p.path);
|
|
295
|
-
fs.writeFileSync(memPath, body);
|
|
287
|
+
const { bytes } = writeProjectMemory(p.path, body);
|
|
296
288
|
try { projects.rebuild(p.id); } catch {}
|
|
297
|
-
res.json({ ok: true, bytes
|
|
289
|
+
res.json({ ok: true, bytes });
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// The local half — agent-written, never committed.
|
|
293
|
+
api.get("/projects/:pid/memory/local", (req, res) => {
|
|
294
|
+
const p = project(req, res);
|
|
295
|
+
if (!p) return;
|
|
296
|
+
res.json({ body: readProjectLocalMemory(p), path: projectLocalMemoryPath(p) });
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
api.put("/projects/:pid/memory/local", (req, res) => {
|
|
300
|
+
const p = project(req, res);
|
|
301
|
+
if (!p) return;
|
|
302
|
+
const { body } = req.body || {};
|
|
303
|
+
if (typeof body !== "string")
|
|
304
|
+
return res.status(400).json({ error: "body must be string" });
|
|
305
|
+
const { bytes } = writeProjectLocalMemory(p, body);
|
|
306
|
+
res.json({ ok: true, bytes });
|
|
298
307
|
});
|
|
299
308
|
|
|
300
309
|
// ---- Per-agent memory ----
|