@agentprojectcontext/apx 1.80.2 → 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 +134 -0
- 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
package/src/core/agent/retry.js
CHANGED
|
@@ -33,6 +33,19 @@ const RETRYABLE_PHRASES = [
|
|
|
33
33
|
/timeout/i,
|
|
34
34
|
];
|
|
35
35
|
|
|
36
|
+
// A 404 that means "this model is retired / unknown", as opposed to a 404 that
|
|
37
|
+
// means "wrong base_url". Kept narrow on purpose: a typo'd model id also lands
|
|
38
|
+
// here, and rotating past it is still the better outcome than a dead turn.
|
|
39
|
+
const MODEL_RETIRED_PHRASES = [
|
|
40
|
+
/no longer available/i,
|
|
41
|
+
/not found for API version/i,
|
|
42
|
+
/does not exist/i,
|
|
43
|
+
/unknown model/i,
|
|
44
|
+
/model.{0,20}(not found|is not supported)/i,
|
|
45
|
+
/has been (deprecated|retired|removed)/i,
|
|
46
|
+
/model is unavailable/i,
|
|
47
|
+
];
|
|
48
|
+
|
|
36
49
|
const FATAL_STATUS = new Set([400, 401, 403, 404, 422]);
|
|
37
50
|
|
|
38
51
|
const FATAL_PHRASES = [
|
|
@@ -45,6 +58,8 @@ const FATAL_PHRASES = [
|
|
|
45
58
|
];
|
|
46
59
|
|
|
47
60
|
export function isRetryableEngineError(err) {
|
|
61
|
+
if (err?.name === "AbortError" || err?.code === "ABORT_ERR") return false;
|
|
62
|
+
|
|
48
63
|
const msg = String(err?.message || err || "");
|
|
49
64
|
if (!msg) return false;
|
|
50
65
|
|
|
@@ -69,9 +84,36 @@ export function isRetryableEngineError(err) {
|
|
|
69
84
|
/looks like (object|array)|can'?t find closing|unexpected end of json|invalid (json|grammar)/i.test(msg)) {
|
|
70
85
|
return true;
|
|
71
86
|
}
|
|
87
|
+
// A gateway 400 with no message at all — Zen answers upstream failures
|
|
88
|
+
// with a bare `{"object":"error","model":"..."}` envelope. There is
|
|
89
|
+
// nothing in it to fix, and it is as likely to be the vendor behind the
|
|
90
|
+
// gateway as it is to be our payload, so the chain gets to try the next
|
|
91
|
+
// model rather than ending the run on an error the user cannot act on.
|
|
92
|
+
if (/^[a-z0-9_-]+ 400:\s*\{"object":\s*"error"/i.test(msg)) return true;
|
|
93
|
+
// A gateway that answers 400 (not 404) for a model it no longer serves:
|
|
94
|
+
// zen 400: Error from provider (Console): Upstream request failed:
|
|
95
|
+
// Model is unavailable
|
|
96
|
+
// Same situation as a retired model, different status code — the model
|
|
97
|
+
// is not coming back this turn, so walk the chain.
|
|
98
|
+
if (MODEL_RETIRED_PHRASES.some((re) => re.test(msg))) return true;
|
|
99
|
+
// A history-fidelity requirement we may not be able to satisfy: the turn
|
|
100
|
+
// being replayed came from a different engine (post-rotation) and never
|
|
101
|
+
// carried the field. Serialising it correctly is zen.js's job; when the
|
|
102
|
+
// data isn't there, a model that doesn't demand it is the only way out.
|
|
103
|
+
if (/reasoning_content|thought.?signature/i.test(msg)) return true;
|
|
72
104
|
// explicit schema / param errors are our bug, not transient
|
|
73
105
|
return false;
|
|
74
106
|
}
|
|
107
|
+
// 404 usually means "you pointed at the wrong endpoint" — fatal, fix it.
|
|
108
|
+
// But it is ALSO how a provider retires a model:
|
|
109
|
+
// gemini 404: This model models/gemini-2.5-flash-lite is no longer
|
|
110
|
+
// available. Please update your code to use models/gemini-3.5-flash-lite
|
|
111
|
+
// openai 404: The model `x` does not exist or you do not have access
|
|
112
|
+
// That is exactly what the fallback chain is for. The model is gone for
|
|
113
|
+
// good, the user cannot act on it mid-turn, and the next model in the
|
|
114
|
+
// chain will answer — so rotate instead of ending the run on a wall of
|
|
115
|
+
// provider text. A 404 that is NOT about the model stays fatal.
|
|
116
|
+
if (status === 404 && MODEL_RETIRED_PHRASES.some((re) => re.test(msg))) return true;
|
|
75
117
|
return false;
|
|
76
118
|
}
|
|
77
119
|
if (status && RETRYABLE_STATUS.has(status)) return true;
|
|
@@ -3,12 +3,14 @@ import {
|
|
|
3
3
|
extractPseudoToolCalls,
|
|
4
4
|
extractBareFunctionCalls,
|
|
5
5
|
cleanTextOfPseudoToolCalls,
|
|
6
|
+
looksLikeFabricatedToolLog,
|
|
6
7
|
} from "./tools/tool-call-parser.js";
|
|
7
|
-
import { resolveActiveModel, fallbackModels } from "./model-router.js";
|
|
8
|
+
import { resolveActiveModel, fallbackModels, isFallbackEnabled } from "./model-router.js";
|
|
8
9
|
import { MAX_TOOL_ITERS, ACK_ONLY_TOOLS, MAX_CONSECUTIVE_ACKS, TURN_ENDING_TOOLS } from "./constants.js";
|
|
9
10
|
import { TOOLS } from "./tools/names.js";
|
|
10
11
|
import { pseudoToolSystem, shouldRetryWithPseudoTools } from "./tools/pseudo-tools.js";
|
|
11
12
|
import { filterToolSchemas } from "./tools-overlap.js";
|
|
13
|
+
import { buildRuntimeBlock } from "./prompt-builder.js";
|
|
12
14
|
import { isRetryableEngineError, shortRetryReason } from "./retry.js";
|
|
13
15
|
import {
|
|
14
16
|
securityRiskConfig,
|
|
@@ -25,17 +27,57 @@ import {
|
|
|
25
27
|
} from "./stuck-detector.js";
|
|
26
28
|
import { createGreetingGuard } from "./loop/greeting-guard.js";
|
|
27
29
|
import { createSideEffectLedger } from "./loop/side-effects.js";
|
|
30
|
+
import {
|
|
31
|
+
describeTurnImages,
|
|
32
|
+
providerWiresVision,
|
|
33
|
+
withImageDescription,
|
|
34
|
+
} from "./vision-bridge.js";
|
|
35
|
+
import { messagesForModel } from "./model-capabilities.js";
|
|
28
36
|
|
|
29
37
|
async function emitProgress(onEvent, event) {
|
|
30
38
|
if (typeof onEvent !== "function") return;
|
|
31
39
|
await onEvent(event);
|
|
32
40
|
}
|
|
33
41
|
|
|
42
|
+
// How much of one tool result the trace carries. The trace is what gets
|
|
43
|
+
// PERSISTED (message store, web viewer) and what the next turns replay as
|
|
44
|
+
// history, so this cap is the memory a past tool call leaves behind.
|
|
45
|
+
const TRACE_RESULT_CAP = 1200;
|
|
46
|
+
// Longest single string field kept inside a structured result.
|
|
47
|
+
const TRACE_FIELD_CAP = 900;
|
|
48
|
+
|
|
49
|
+
// Shrink a tool result for the trace WITHOUT destroying its shape. The old
|
|
50
|
+
// version stringified anything over 400 chars and sliced the JSON text, which
|
|
51
|
+
// left a half-open brace: unparseable, so every downstream reader (history
|
|
52
|
+
// replay, viewer) had to show escaped JSON instead of the actual output. Now
|
|
53
|
+
// the envelope survives and only the long string fields inside are clipped —
|
|
54
|
+
// `{ exit_code, stdout }` stays an object whose stdout is trimmed.
|
|
34
55
|
function summarizeForTrace(r) {
|
|
35
56
|
if (r === null || r === undefined) return r;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
57
|
+
if (typeof r === "string") {
|
|
58
|
+
return r.length <= TRACE_RESULT_CAP ? r : r.slice(0, TRACE_RESULT_CAP) + "…(truncated)";
|
|
59
|
+
}
|
|
60
|
+
if (typeof r !== "object") return r;
|
|
61
|
+
try {
|
|
62
|
+
if (JSON.stringify(r).length <= TRACE_RESULT_CAP) return r;
|
|
63
|
+
} catch {
|
|
64
|
+
return String(r).slice(0, TRACE_RESULT_CAP);
|
|
65
|
+
}
|
|
66
|
+
const clip = (v, depth) => {
|
|
67
|
+
if (typeof v === "string") {
|
|
68
|
+
return v.length <= TRACE_FIELD_CAP ? v : v.slice(0, TRACE_FIELD_CAP) + "…(truncated)";
|
|
69
|
+
}
|
|
70
|
+
if (Array.isArray(v)) {
|
|
71
|
+
const head = v.slice(0, 20).map((x) => clip(x, depth + 1));
|
|
72
|
+
return v.length > 20 ? [...head, `…(${v.length - 20} more)`] : head;
|
|
73
|
+
}
|
|
74
|
+
if (v && typeof v === "object") {
|
|
75
|
+
if (depth >= 3) return "…(nested)";
|
|
76
|
+
return Object.fromEntries(Object.entries(v).map(([k, x]) => [k, clip(x, depth + 1)]));
|
|
77
|
+
}
|
|
78
|
+
return v;
|
|
79
|
+
};
|
|
80
|
+
return clip(r, 0);
|
|
39
81
|
}
|
|
40
82
|
|
|
41
83
|
function fallbackFinalText(trace, error) {
|
|
@@ -50,6 +92,15 @@ function fallbackFinalText(trace, error) {
|
|
|
50
92
|
return lines.join("\n");
|
|
51
93
|
}
|
|
52
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Did the engine stop because it ran out of output budget? Every adapter passes
|
|
97
|
+
* the provider's own word through: OpenAI-shaped gateways say "length", Gemini
|
|
98
|
+
* says "MAX_TOKENS".
|
|
99
|
+
*/
|
|
100
|
+
function wasTruncated(result) {
|
|
101
|
+
return /^(length|max_tokens)$/i.test(String(result?.finish_reason || ""));
|
|
102
|
+
}
|
|
103
|
+
|
|
53
104
|
function previewTraceResult(result) {
|
|
54
105
|
if (result === null || result === undefined) return "ok";
|
|
55
106
|
if (typeof result === "string") return result.slice(0, 180);
|
|
@@ -115,6 +166,59 @@ const WRAPUP_SIGNAL =
|
|
|
115
166
|
"Talk like a person giving a quick status update. Do NOT emit a tool call, " +
|
|
116
167
|
"JSON, or system jargon like \"iteration\" or \"limit\".]";
|
|
117
168
|
|
|
169
|
+
// How many times one turn may be nudged past an output-limit truncation before
|
|
170
|
+
// we let it end. A model that answers with a wall of prose every time is not
|
|
171
|
+
// going to start acting on the third try, and the wrap-up still fires.
|
|
172
|
+
const MAX_LENGTH_CONTINUES = 2;
|
|
173
|
+
|
|
174
|
+
// A model that hits its output cap mid-sentence has not finished; it has been
|
|
175
|
+
// cut off. Every adapter reports that as a finish reason, and the loop used to
|
|
176
|
+
// ignore it: no tool calls in a truncated message means "the model stopped
|
|
177
|
+
// calling tools", which reads as a completed turn. So a routine that wrote six
|
|
178
|
+
// ideas out as YAML instead of filing them, ran out of budget halfway through
|
|
179
|
+
// the sixth, and never called the tool, reported `status: ok` with a reply that
|
|
180
|
+
// began mid-word.
|
|
181
|
+
//
|
|
182
|
+
// This note goes in as a conversation turn so weak models actually answer it,
|
|
183
|
+
// and it asks for the ACTION rather than a shorter essay — writing the work out
|
|
184
|
+
// is what filled the budget in the first place.
|
|
185
|
+
const TRUNCATED_SIGNAL =
|
|
186
|
+
"[Internal turn note — this is NOT from the user. Your last message hit the " +
|
|
187
|
+
"output limit and was cut off mid-way, so nothing in it counted as work.\n" +
|
|
188
|
+
"Do NOT rewrite or continue that text. If the task needs tools — creating a " +
|
|
189
|
+
"task, writing a file, sending a message — CALL THEM NOW, one step at a time, " +
|
|
190
|
+
"and keep any prose to a single short line. Composing the result as text is " +
|
|
191
|
+
"not the same as doing it.]";
|
|
192
|
+
|
|
193
|
+
// A turn that WROTE tool results instead of producing them.
|
|
194
|
+
//
|
|
195
|
+
// The shipped example (2026-08-29, Telegram): a fallback model answered with
|
|
196
|
+
// five `[result: shell]` lines — invented commands, invented output — and then
|
|
197
|
+
// "Listo, te mandé el WhatsApp". No tool ran. The user was told a message had
|
|
198
|
+
// been sent to a real phone number that was never sent.
|
|
199
|
+
//
|
|
200
|
+
// Nothing in those lines can be recovered: there is no structured call in them,
|
|
201
|
+
// and reconstructing a shell command from hallucinated prose to run it for real
|
|
202
|
+
// would be a far worse failure than the one it fixes. So the model is told the
|
|
203
|
+
// results are not real and asked to do the work — the same in-band correction
|
|
204
|
+
// the truncation case uses, and for the same reason (weak models answer a
|
|
205
|
+
// conversation turn far more reliably than a system suffix).
|
|
206
|
+
const FABRICATED_RESULTS_SIGNAL =
|
|
207
|
+
"[Internal turn note — this is NOT from the user. Your last message was " +
|
|
208
|
+
"written as if tools had run, but you called none, so none of those results " +
|
|
209
|
+
"exist and nothing you described actually happened.\n" +
|
|
210
|
+
"Lines like `[tool result: …]` in this conversation are a LOG of past calls. " +
|
|
211
|
+
"They are not a format for you to write in — writing one does not run " +
|
|
212
|
+
"anything.\n" +
|
|
213
|
+
"Do the work now: emit real tool calls, one step at a time. If you cannot " +
|
|
214
|
+
"(no such tool, missing permission, unclear arguments), say that plainly to " +
|
|
215
|
+
"the user instead — but never report an action you did not take.]";
|
|
216
|
+
|
|
217
|
+
// How many times one turn may be corrected for this before we let it end. A
|
|
218
|
+
// model that fabricates twice in a row is not going to start acting on the
|
|
219
|
+
// third try, and the wrap-up still fires.
|
|
220
|
+
const MAX_FABRICATION_RETRIES = 2;
|
|
221
|
+
|
|
118
222
|
/**
|
|
119
223
|
* Shared tool-calling agent loop used by super-agent and future surfaces.
|
|
120
224
|
*/
|
|
@@ -136,6 +240,7 @@ export async function runAgent({
|
|
|
136
240
|
onEvent = null,
|
|
137
241
|
signal,
|
|
138
242
|
onToken = null,
|
|
243
|
+
onReasoningToken = null,
|
|
139
244
|
agentName = "apx",
|
|
140
245
|
suppressTools = null, // optional list of tool names to remove from the registry
|
|
141
246
|
// Per-reply output cap. Defaults to 512 (tuned for chit-chat + small tool
|
|
@@ -165,7 +270,7 @@ export async function runAgent({
|
|
|
165
270
|
const triedHealth = new Map(
|
|
166
271
|
(routing.tried || []).map((t) => [t.modelId, t.healthy !== false])
|
|
167
272
|
);
|
|
168
|
-
const retryChain = fallbackModels(globalConfig).filter((m) => {
|
|
273
|
+
const retryChain = (isFallbackEnabled(globalConfig) ? fallbackModels(globalConfig) : []).filter((m) => {
|
|
169
274
|
if (m === activeModel) return false;
|
|
170
275
|
if (triedHealth.get(m) === false) return false;
|
|
171
276
|
return true;
|
|
@@ -183,7 +288,8 @@ export async function runAgent({
|
|
|
183
288
|
}
|
|
184
289
|
|
|
185
290
|
// Suppression: callers (notably the routine runner) can disable tools whose
|
|
186
|
-
// output would duplicate
|
|
291
|
+
// output would duplicate a sink the run already has — a post_command, or the
|
|
292
|
+
// routine's own `deliver_to`. We filter the schemas the engine
|
|
187
293
|
// sees AND keep a deny-set so a model that hallucinates a suppressed tool
|
|
188
294
|
// call gets a clear error rather than firing.
|
|
189
295
|
let effectiveSchemas = Array.isArray(suppressTools) && suppressTools.length > 0
|
|
@@ -194,7 +300,10 @@ export async function runAgent({
|
|
|
194
300
|
await emitProgress(onEvent, {
|
|
195
301
|
type: "tools_suppressed",
|
|
196
302
|
tools: [...suppressed],
|
|
197
|
-
|
|
303
|
+
// Why, generically: a post_command pipes this output somewhere, or the
|
|
304
|
+
// routine's `deliver_to` does. Either way the sink already owns the
|
|
305
|
+
// message and the loop must not send a second one.
|
|
306
|
+
reason: "output_sink_overlap",
|
|
198
307
|
});
|
|
199
308
|
}
|
|
200
309
|
// Completion contract: only meaningful when there are real tools to choose
|
|
@@ -228,6 +337,9 @@ export async function runAgent({
|
|
|
228
337
|
// (In `total` the guard returns early anyway, so this is a no-op there.)
|
|
229
338
|
if (toolHandlerCtx) toolHandlerCtx.securityRiskActive = true;
|
|
230
339
|
}
|
|
340
|
+
// Telegram (and any other abortable surface) kills in-flight shell tools
|
|
341
|
+
// when a newer turn supersedes this one. Handlers read it at call time.
|
|
342
|
+
if (toolHandlerCtx && signal) toolHandlerCtx.abortSignal = signal;
|
|
231
343
|
|
|
232
344
|
const rawHandlers = makeToolHandlers(toolHandlerCtx);
|
|
233
345
|
const handlers = suppressed.size > 0
|
|
@@ -235,7 +347,7 @@ export async function runAgent({
|
|
|
235
347
|
get(target, name) {
|
|
236
348
|
if (typeof name === "string" && suppressed.has(name)) {
|
|
237
349
|
return async () => ({
|
|
238
|
-
error: `tool "${name}" is suppressed for this invocation (
|
|
350
|
+
error: `tool "${name}" is suppressed for this invocation (this run already delivers to that channel)`,
|
|
239
351
|
});
|
|
240
352
|
}
|
|
241
353
|
return target[name];
|
|
@@ -248,6 +360,40 @@ export async function runAgent({
|
|
|
248
360
|
// that queue into effectiveSchemas at the top of each iteration, so tools
|
|
249
361
|
// activated on step N are callable from step N+1. No session → no-op.
|
|
250
362
|
const toolSession = toolHandlerCtx?.toolSession || null;
|
|
363
|
+
|
|
364
|
+
const schemaOnTheWire = (n) =>
|
|
365
|
+
effectiveSchemas.some((sc) => (sc?.function?.name || sc?.name) === n);
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* A tool the model called WITHOUT ever receiving its schema.
|
|
369
|
+
*
|
|
370
|
+
* buildLazyToolsBlock puts the NAMES of not-loaded tools in the system prompt
|
|
371
|
+
* (that is what makes them discoverable), and not every provider refuses a
|
|
372
|
+
* call to a tool that was never in the request. So the model can name a real
|
|
373
|
+
* tool and invent its arguments, and the handler will happily run them:
|
|
374
|
+
* `complete_task` was called as `{project, id}` — `id` is what list_tasks
|
|
375
|
+
* hands back, the schema says `task`, and `action` was missing entirely — and
|
|
376
|
+
* "task required" told the model nothing it could act on. It burned three
|
|
377
|
+
* iterations and left the task open.
|
|
378
|
+
*
|
|
379
|
+
* Activating and returning the schema costs one step and makes the retry
|
|
380
|
+
* informed. It also closes a gap: the role gate (`allowedTools`) only ever
|
|
381
|
+
* filtered the schemas the model was SENT, so a guessed name walked straight
|
|
382
|
+
* past it into the handler map, which holds every tool regardless.
|
|
383
|
+
*/
|
|
384
|
+
const revealUnloadedTool = (session, name) => {
|
|
385
|
+
const r = session.activate({ names: [name] });
|
|
386
|
+
if (r.denied?.length) return { error: `tool "${name}" is not available to you` };
|
|
387
|
+
if (r.unknown?.length) return { error: `unknown tool: ${name}` };
|
|
388
|
+
const schema = session.pending.find((sc) => (sc?.function?.name || sc?.name) === name);
|
|
389
|
+
return {
|
|
390
|
+
error: `tool "${name}" was not loaded, so you called it without its schema — nothing ran.`,
|
|
391
|
+
activated: name,
|
|
392
|
+
schema: schema?.function || schema || null,
|
|
393
|
+
note: "Ya está cargada. Llamala de nuevo usando exactamente los parámetros de arriba.",
|
|
394
|
+
};
|
|
395
|
+
};
|
|
396
|
+
|
|
251
397
|
const drainPendingTools = () => {
|
|
252
398
|
if (!toolSession || toolSession.pending.length === 0) return;
|
|
253
399
|
const seen = new Set(
|
|
@@ -266,22 +412,49 @@ export async function runAgent({
|
|
|
266
412
|
}
|
|
267
413
|
};
|
|
268
414
|
|
|
269
|
-
// Attachments ride on THIS turn's user message.
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
//
|
|
415
|
+
// Attachments ride on THIS turn's user message. Multimodal engines (Gemini,
|
|
416
|
+
// Claude, GPT via OpenAI-shaped wire) get the pixels. Text-only engines
|
|
417
|
+
// (zen:big-pickle and most free Zen models) get a short description from the
|
|
418
|
+
// vision bridge instead — otherwise the agent only sees "[image attached —
|
|
419
|
+
// saved to …]" and roleplays that the photo never arrived.
|
|
273
420
|
const turnImages = attachments.filter((a) => a?.data && /^image\//.test(a.mime || ""));
|
|
421
|
+
let turnPrompt = prompt;
|
|
422
|
+
let imagesForModel = turnImages;
|
|
423
|
+
if (turnImages.length && !providerWiresVision(activeModel, globalConfig)) {
|
|
424
|
+
const description = await describeTurnImages(turnImages, globalConfig, { signal });
|
|
425
|
+
if (description) {
|
|
426
|
+
turnPrompt = withImageDescription(prompt, description);
|
|
427
|
+
await emitProgress(onEvent, {
|
|
428
|
+
type: "vision_bridged",
|
|
429
|
+
model: activeModel,
|
|
430
|
+
images: turnImages.length,
|
|
431
|
+
});
|
|
432
|
+
// The description replaces the bytes for this text-only model.
|
|
433
|
+
imagesForModel = [];
|
|
434
|
+
}
|
|
435
|
+
// If the bridge is unavailable, keep the internal image field until the
|
|
436
|
+
// per-model call adapter replaces it with a safe attachment marker. Raw
|
|
437
|
+
// bytes still never reach a text-only provider.
|
|
438
|
+
}
|
|
274
439
|
const conversation = [
|
|
275
440
|
...previousMessages,
|
|
276
441
|
{
|
|
277
442
|
role: "user",
|
|
278
|
-
content:
|
|
279
|
-
...(
|
|
443
|
+
content: turnPrompt,
|
|
444
|
+
...(imagesForModel.length > 0 ? { images: imagesForModel } : {}),
|
|
280
445
|
},
|
|
281
446
|
];
|
|
282
447
|
const trace = [];
|
|
283
448
|
const totalUsage = { input_tokens: 0, output_tokens: 0 };
|
|
284
449
|
let lastText = "";
|
|
450
|
+
// How much of `maxIters` this run actually spent. Returned so a CALLER that
|
|
451
|
+
// runs the loop more than once for one turn (the judge loop) can subtract it
|
|
452
|
+
// from a shared budget instead of handing every round the full number again.
|
|
453
|
+
// Counted in iterations, not tool calls: one iteration can carry several
|
|
454
|
+
// parallel calls or none, and iterations are what maxIters is denominated in.
|
|
455
|
+
// The empty-retry below deliberately rewinds `iter`, so it doesn't count here
|
|
456
|
+
// either — same rule in both places.
|
|
457
|
+
let itersUsed = 0;
|
|
285
458
|
|
|
286
459
|
// Collapse repeated greetings within a single turn. A turn can produce several
|
|
287
460
|
// text segments (pre-tool narration + final answer) and weaker models greet in
|
|
@@ -297,6 +470,8 @@ export async function runAgent({
|
|
|
297
470
|
// the turn empty, and the retry does NOT consume an iteration of the tool
|
|
298
471
|
// budget. Bounded so a model that only ever returns empty can't spin forever.
|
|
299
472
|
let emptyRetries = 0;
|
|
473
|
+
let lengthContinues = 0;
|
|
474
|
+
let fabricationRetries = 0;
|
|
300
475
|
const MAX_EMPTY_RETRIES = 2;
|
|
301
476
|
// Side-effect dedupe. Weaker models (Gemini especially) sometimes
|
|
302
477
|
// re-emit the SAME tool call across iterations — e.g. send_telegram
|
|
@@ -316,6 +491,13 @@ export async function runAgent({
|
|
|
316
491
|
const stuckDetector = createStuckDetector(stuckCfg);
|
|
317
492
|
let stuckNudged = false;
|
|
318
493
|
let forceWrapUp = false;
|
|
494
|
+
// Set when the turn closed on the reserved wrap-up step (budget exhausted, or
|
|
495
|
+
// stuck-aborted). The wrap-up ASKS the user whether to keep going, so such a
|
|
496
|
+
// turn is waiting on a person — exactly like ask_questions — not unfinished.
|
|
497
|
+
// Callers that would otherwise "continue" it (the judge loop) must not, or the
|
|
498
|
+
// user gets the same recap and the same question again every round without
|
|
499
|
+
// ever being given the chance to answer it.
|
|
500
|
+
let endedAwaitingUser = false;
|
|
319
501
|
const safeSig = (v) => {
|
|
320
502
|
try {
|
|
321
503
|
return JSON.stringify(v) ?? "";
|
|
@@ -331,8 +513,13 @@ export async function runAgent({
|
|
|
331
513
|
const tryCallEngine = async (params, { allowRetry = true } = {}) => {
|
|
332
514
|
while (true) {
|
|
333
515
|
try {
|
|
334
|
-
return await callEngine({
|
|
516
|
+
return await callEngine({
|
|
517
|
+
...params,
|
|
518
|
+
messages: messagesForModel(params.messages, activeModel, globalConfig),
|
|
519
|
+
modelId: activeModel,
|
|
520
|
+
});
|
|
335
521
|
} catch (e) {
|
|
522
|
+
if (signal?.aborted || e?.name === "AbortError") throw e;
|
|
336
523
|
if (!allowRetry || retryChain.length === 0 || !isRetryableEngineError(e)) throw e;
|
|
337
524
|
const nextModel = retryChain.shift();
|
|
338
525
|
await emitProgress(onEvent, {
|
|
@@ -350,6 +537,12 @@ export async function runAgent({
|
|
|
350
537
|
};
|
|
351
538
|
|
|
352
539
|
for (let iter = 0; iter < maxIters; iter++) {
|
|
540
|
+
if (signal?.aborted) {
|
|
541
|
+
const err = new Error("aborted");
|
|
542
|
+
err.name = "AbortError";
|
|
543
|
+
throw err;
|
|
544
|
+
}
|
|
545
|
+
itersUsed = iter + 1;
|
|
353
546
|
// Merge any tools activated via discover_tools on the previous iteration.
|
|
354
547
|
drainPendingTools();
|
|
355
548
|
// Final iteration of a non-contract turn: the model is out of action steps.
|
|
@@ -375,9 +568,14 @@ export async function runAgent({
|
|
|
375
568
|
effectiveSchemas.length > 0 &&
|
|
376
569
|
(useContract ||
|
|
377
570
|
(ackOnlyStreak > 0 && ackOnlyStreak <= MAX_CONSECUTIVE_ACKS));
|
|
571
|
+
// Built per iteration, not per turn: the fallback router can rotate
|
|
572
|
+
// providers mid-turn, and a line that named the model we STARTED on would
|
|
573
|
+
// be exactly the kind of stale fact this block exists to kill.
|
|
574
|
+
const runtime = buildRuntimeBlock(activeModel);
|
|
575
|
+
const systemForCall = runtime ? `${system}\n\n${runtime}` : system;
|
|
378
576
|
const baseSystem = usePseudoTools
|
|
379
|
-
? pseudoToolSystem(
|
|
380
|
-
:
|
|
577
|
+
? pseudoToolSystem(systemForCall, effectiveSchemas)
|
|
578
|
+
: systemForCall;
|
|
381
579
|
let result;
|
|
382
580
|
try {
|
|
383
581
|
result = await tryCallEngine({
|
|
@@ -400,6 +598,7 @@ export async function runAgent({
|
|
|
400
598
|
maxTokens,
|
|
401
599
|
signal,
|
|
402
600
|
onToken: ((!forceTool || isFinalWrapUp) && onToken) ? onToken : null,
|
|
601
|
+
onReasoningToken: ((!forceTool || isFinalWrapUp) && onReasoningToken) ? onReasoningToken : null,
|
|
403
602
|
});
|
|
404
603
|
} catch (e) {
|
|
405
604
|
if (usePseudoTools && /^ollama:/i.test(String(activeModel || "")) && /ollama\s+500/i.test(String(e?.message || "")) && trace.length > 0) {
|
|
@@ -419,11 +618,24 @@ export async function runAgent({
|
|
|
419
618
|
maxTokens,
|
|
420
619
|
signal,
|
|
421
620
|
onToken: (iter > 0 && onToken) ? onToken : null,
|
|
621
|
+
onReasoningToken: (iter > 0 && onReasoningToken) ? onReasoningToken : null,
|
|
422
622
|
});
|
|
423
623
|
}
|
|
424
624
|
|
|
425
625
|
totalUsage.input_tokens += result.usage?.input_tokens || 0;
|
|
426
626
|
totalUsage.output_tokens += result.usage?.output_tokens || 0;
|
|
627
|
+
|
|
628
|
+
// The model thinking out loud. Adapters keep it out of `text` so no
|
|
629
|
+
// surface can leak it by forgetting to strip; it rides its own event for
|
|
630
|
+
// the ones that want to show it on purpose, and is ignored by the rest.
|
|
631
|
+
if (result.reasoning) {
|
|
632
|
+
await emitProgress(onEvent, {
|
|
633
|
+
type: "assistant_reasoning",
|
|
634
|
+
reasoning: result.reasoning,
|
|
635
|
+
iteration: iter + 1,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
|
|
427
639
|
lastText = result.text || "";
|
|
428
640
|
|
|
429
641
|
let toolCalls = result.tool_calls || (result.message && result.message.tool_calls) || null;
|
|
@@ -455,18 +667,62 @@ export async function runAgent({
|
|
|
455
667
|
}
|
|
456
668
|
|
|
457
669
|
if (!toolCalls || toolCalls.length === 0) {
|
|
458
|
-
|
|
670
|
+
// Checked BEFORE the cleaner, which is what strips the evidence.
|
|
671
|
+
const rawText = lastText;
|
|
672
|
+
const fabricated =
|
|
673
|
+
effectiveSchemas.length > 0 && looksLikeFabricatedToolLog(rawText);
|
|
674
|
+
// No `|| rawText` fallback. When the cleaner empties a turn, the turn was
|
|
675
|
+
// markup end to end — a fabricated tool log, or the `[omitted: …]`
|
|
676
|
+
// annotation the model copied out of its own history — and putting the
|
|
677
|
+
// markup back is how a reply that was ONLY that annotation went out to
|
|
678
|
+
// Telegram verbatim on 2026-09-02, twice. There is no answer in there to
|
|
679
|
+
// rescue: an empty turn is retried below and then falls to the surface's
|
|
680
|
+
// never-silent floor, which is a wrap-up written for the user.
|
|
681
|
+
lastText = cleanTextOfPseudoToolCalls(rawText, callableNames);
|
|
459
682
|
// Dud turn (no tools, no text): re-prompt instead of ending empty, and
|
|
460
683
|
// don't let it cost an iteration of the tool budget. `iter -= 1` cancels
|
|
461
684
|
// the loop's `iter++`; the emptyRetries cap stops an all-empty model from
|
|
462
685
|
// looping forever (after which we break and the surface's last-resort
|
|
463
686
|
// floor sends a non-silent reply).
|
|
464
|
-
if (!String(lastText).trim() && emptyRetries < MAX_EMPTY_RETRIES) {
|
|
687
|
+
if (!String(lastText).trim() && !fabricated && emptyRetries < MAX_EMPTY_RETRIES) {
|
|
465
688
|
emptyRetries += 1;
|
|
466
689
|
await emitProgress(onEvent, { type: "empty_retry", iteration: iter + 1, attempt: emptyRetries });
|
|
467
690
|
iter -= 1;
|
|
468
691
|
continue;
|
|
469
692
|
}
|
|
693
|
+
// It narrated the tools instead of calling them. Do NOT let this text
|
|
694
|
+
// stand as the answer — it reports work that never happened. The
|
|
695
|
+
// fabricated turn goes into the history so the model can see what it is
|
|
696
|
+
// being corrected about, followed by the correction.
|
|
697
|
+
if (fabricated && fabricationRetries < MAX_FABRICATION_RETRIES) {
|
|
698
|
+
fabricationRetries += 1;
|
|
699
|
+
await emitProgress(onEvent, {
|
|
700
|
+
type: "fabricated_results",
|
|
701
|
+
model: activeModel,
|
|
702
|
+
iteration: iter + 1,
|
|
703
|
+
attempt: fabricationRetries,
|
|
704
|
+
});
|
|
705
|
+
conversation.push({ role: "assistant", content: rawText });
|
|
706
|
+
conversation.push({ role: "user", content: FABRICATED_RESULTS_SIGNAL });
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
// Cut off at the output cap, not finished. Keep the truncated text in the
|
|
710
|
+
// history (so the model can see what it was doing) and ask for the action.
|
|
711
|
+
if (wasTruncated(result) && lengthContinues < MAX_LENGTH_CONTINUES) {
|
|
712
|
+
lengthContinues += 1;
|
|
713
|
+
await emitProgress(onEvent, {
|
|
714
|
+
type: "truncated_continue",
|
|
715
|
+
iteration: iter + 1,
|
|
716
|
+
attempt: lengthContinues,
|
|
717
|
+
});
|
|
718
|
+
conversation.push({ role: "assistant", content: lastText });
|
|
719
|
+
conversation.push({ role: "user", content: TRUNCATED_SIGNAL });
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
// The text we just took as the answer IS the wrap-up: it ends by asking
|
|
723
|
+
// the user whether to continue. Tell the caller so nobody answers on
|
|
724
|
+
// their behalf.
|
|
725
|
+
if (isFinalWrapUp) endedAwaitingUser = true;
|
|
470
726
|
break;
|
|
471
727
|
}
|
|
472
728
|
|
|
@@ -485,6 +741,11 @@ export async function runAgent({
|
|
|
485
741
|
// next request, avoiding the 400 "missing thought_signature" error.
|
|
486
742
|
// Other engines return undefined here, so this field is a no-op for them.
|
|
487
743
|
...(result._geminiRawParts ? { _geminiRawParts: result._geminiRawParts } : {}),
|
|
744
|
+
// Same idea for the OpenAI-shaped reasoners: DeepSeek's thinking mode
|
|
745
|
+
// rejects a replayed assistant turn that lost its `reasoning_content`.
|
|
746
|
+
// Stored under an underscore so only the adapters that ask for it put it
|
|
747
|
+
// back on the wire (see zen.js modelReplaysReasoning).
|
|
748
|
+
...(result.reasoning ? { _reasoning: result.reasoning } : {}),
|
|
488
749
|
});
|
|
489
750
|
|
|
490
751
|
let finishSummary = null;
|
|
@@ -521,14 +782,21 @@ export async function runAgent({
|
|
|
521
782
|
},
|
|
522
783
|
iteration: iter + 1,
|
|
523
784
|
});
|
|
524
|
-
// Dedupe identical side-effecting calls within this turn
|
|
785
|
+
// Dedupe identical side-effecting calls within this turn — and, for the
|
|
786
|
+
// ones a PERSON reads, calls that only differ in how they were worded.
|
|
787
|
+
// A model relaying something re-words it every time it repeats itself,
|
|
788
|
+
// so exact args alone let three "same" messages through (see
|
|
789
|
+
// loop/side-effects.js).
|
|
525
790
|
const sig = sideEffects.signature(name, args);
|
|
526
|
-
|
|
791
|
+
const restated = sideEffects.seen(sig) ? null : sideEffects.nearDuplicate(name, args);
|
|
792
|
+
if (sideEffects.seen(sig) || restated) {
|
|
527
793
|
toolResult = {
|
|
528
794
|
ok: true,
|
|
529
795
|
deduped: true,
|
|
530
|
-
note:
|
|
531
|
-
|
|
796
|
+
note: restated
|
|
797
|
+
? `Ya dije esto mismo con "${name}" en este turno; no lo repito.`
|
|
798
|
+
: `Ya ejecuté "${name}" con estos mismos argumentos en este turno; no lo repito.`,
|
|
799
|
+
previous: restated || sideEffects.previous(sig),
|
|
532
800
|
};
|
|
533
801
|
await emitProgress(onEvent, {
|
|
534
802
|
type: "tool_deduped",
|
|
@@ -568,14 +836,35 @@ export async function runAgent({
|
|
|
568
836
|
} else {
|
|
569
837
|
try {
|
|
570
838
|
const handler = handlers[name];
|
|
571
|
-
|
|
839
|
+
if (!handler) toolResult = { error: `unknown tool: ${name}` };
|
|
840
|
+
// Suppression comes first: a suppressed tool was REMOVED from the
|
|
841
|
+
// schema set on purpose, and telling the model it merely wasn't
|
|
842
|
+
// loaded would invite it to activate the tool and send twice.
|
|
843
|
+
else if (toolSession && !suppressed.has(name) && !schemaOnTheWire(name)) {
|
|
844
|
+
toolResult = revealUnloadedTool(toolSession, name);
|
|
845
|
+
}
|
|
846
|
+
else toolResult = await handler(args);
|
|
572
847
|
} catch (e) {
|
|
573
848
|
toolResult = { error: e.message };
|
|
574
849
|
} finally {
|
|
575
850
|
if (toolHandlerCtx) toolHandlerCtx.securityGateCleared = false;
|
|
576
851
|
}
|
|
577
852
|
}
|
|
578
|
-
sideEffects.record(sig, summarizeForTrace(toolResult));
|
|
853
|
+
sideEffects.record(sig, summarizeForTrace(toolResult), { name, args });
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// A tool may return images for the MODEL to see (view_media loads a skill
|
|
857
|
+
// photo so the model can reason about a position). Lift them off the
|
|
858
|
+
// result and onto the tool message as `images`, so the engine sends them
|
|
859
|
+
// as multimodal parts — and keep the base64 OUT of the trace and the JSON
|
|
860
|
+
// content the model re-reads as text (a dumped data URI there is both a
|
|
861
|
+
// token bomb and a worked example of pasting base64 into prose).
|
|
862
|
+
let toolImages = null;
|
|
863
|
+
if (toolResult && typeof toolResult === "object" && Array.isArray(toolResult.images)) {
|
|
864
|
+
const usable = toolResult.images.filter((im) => im && im.data && im.mime);
|
|
865
|
+
if (usable.length) toolImages = usable;
|
|
866
|
+
const { images, ...rest } = toolResult;
|
|
867
|
+
toolResult = { ...rest, ...(toolImages ? { images_attached: toolImages.length } : {}) };
|
|
579
868
|
}
|
|
580
869
|
|
|
581
870
|
const traceItem = {
|
|
@@ -605,6 +894,9 @@ export async function runAgent({
|
|
|
605
894
|
tool_call_id: tc.id || `synth_${iter}_${trace.length}`,
|
|
606
895
|
tool_name: name,
|
|
607
896
|
content: JSON.stringify(toolResult),
|
|
897
|
+
// Multimodal tool results (view_media): carried beside the JSON so a
|
|
898
|
+
// vision engine renders them as inlineData parts. Text engines drop it.
|
|
899
|
+
...(toolImages ? { images: toolImages } : {}),
|
|
608
900
|
});
|
|
609
901
|
|
|
610
902
|
// Capture turn-ending intents (e.g. ask_questions). The loop cannot
|
|
@@ -681,5 +973,10 @@ export async function runAgent({
|
|
|
681
973
|
trace,
|
|
682
974
|
model: activeModel,
|
|
683
975
|
routing,
|
|
976
|
+
// Iterations of `maxIters` consumed. See itersUsed above.
|
|
977
|
+
iterations: itersUsed,
|
|
978
|
+
// True when the turn closed on the reserved wrap-up — it asked the user a
|
|
979
|
+
// question and the next move is theirs. See endedAwaitingUser above.
|
|
980
|
+
endedAwaitingUser,
|
|
684
981
|
};
|
|
685
982
|
}
|