dsh-mobile-plugin 0.5.27 → 0.5.29
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/extensions/catalog.json +10 -1
- package/extensions/magpie/agentcompact.js +104 -0
- package/extensions/magpie/app.css +4902 -0
- package/extensions/magpie/app.js +24474 -0
- package/extensions/magpie/autobackup.js +185 -0
- package/extensions/magpie/autoresetown.js +151 -0
- package/extensions/magpie/balfound.js +38 -0
- package/extensions/magpie/boot.js +23 -0
- package/extensions/magpie/cfgblocked.js +39 -0
- package/extensions/magpie/checkinnow.js +111 -0
- package/extensions/magpie/claudemode.js +92 -0
- package/extensions/magpie/compat.js +41 -0
- package/extensions/magpie/context.css +433 -0
- package/extensions/magpie/context.js +1576 -0
- package/extensions/magpie/ctxtext.js +223 -0
- package/extensions/magpie/fonts.js +42 -0
- package/extensions/magpie/i18n.js +18942 -0
- package/extensions/magpie/icons/ai21.svg +1 -0
- package/extensions/magpie/icons/ai302-color.svg +1 -0
- package/extensions/magpie/icons/ai360-color.svg +1 -0
- package/extensions/magpie/icons/aihubmix-color.svg +1 -0
- package/extensions/magpie/icons/aionui.svg +1 -0
- package/extensions/magpie/icons/air.svg +4 -0
- package/extensions/magpie/icons/alibaba-color.svg +1 -0
- package/extensions/magpie/icons/alibabacloud-color.svg +1 -0
- package/extensions/magpie/icons/alma.png +0 -0
- package/extensions/magpie/icons/anthropic.svg +1 -0
- package/extensions/magpie/icons/antigravity-color.svg +1 -0
- package/extensions/magpie/icons/anyscale-color.svg +1 -0
- package/extensions/magpie/icons/app-alma.png +0 -0
- package/extensions/magpie/icons/app-cc-switch.png +0 -0
- package/extensions/magpie/icons/apple-touch-icon.png +0 -0
- package/extensions/magpie/icons/aside.svg +28 -0
- package/extensions/magpie/icons/astrbot.svg +1 -0
- package/extensions/magpie/icons/atomcode.png +0 -0
- package/extensions/magpie/icons/aws.svg +1 -0
- package/extensions/magpie/icons/azure-color.svg +1 -0
- package/extensions/magpie/icons/azureai-color.svg +1 -0
- package/extensions/magpie/icons/baichuan-color.svg +1 -0
- package/extensions/magpie/icons/baidu-color.svg +1 -0
- package/extensions/magpie/icons/baiducloud-color.svg +1 -0
- package/extensions/magpie/icons/bailian-color.svg +1 -0
- package/extensions/magpie/icons/baseten.svg +1 -0
- package/extensions/magpie/icons/bedrock-color.svg +1 -0
- package/extensions/magpie/icons/burncloud-color.svg +1 -0
- package/extensions/magpie/icons/bytedance-color.svg +1 -0
- package/extensions/magpie/icons/cerebras.svg +1 -0
- package/extensions/magpie/icons/chatglm-color.svg +1 -0
- package/extensions/magpie/icons/cherryin-color.svg +1 -0
- package/extensions/magpie/icons/chutes.svg +1 -0
- package/extensions/magpie/icons/cindy.png +0 -0
- package/extensions/magpie/icons/claude-color.svg +1 -0
- package/extensions/magpie/icons/claudecode-color.svg +1 -0
- package/extensions/magpie/icons/cline.svg +1 -0
- package/extensions/magpie/icons/cloudflare-color.svg +1 -0
- package/extensions/magpie/icons/codebuddy-color.svg +1 -0
- package/extensions/magpie/icons/codex-color.svg +1 -0
- package/extensions/magpie/icons/cohere-color.svg +1 -0
- package/extensions/magpie/icons/cometapi-color.svg +1 -0
- package/extensions/magpie/icons/commandcode.svg +1 -0
- package/extensions/magpie/icons/copilot-color.svg +1 -0
- package/extensions/magpie/icons/coze.svg +1 -0
- package/extensions/magpie/icons/crush.png +0 -0
- package/extensions/magpie/icons/curl.svg +1 -0
- package/extensions/magpie/icons/cursor.svg +1 -0
- package/extensions/magpie/icons/deepinfra-color.svg +1 -0
- package/extensions/magpie/icons/deepmind-color.svg +1 -0
- package/extensions/magpie/icons/deepseek-color.svg +1 -0
- package/extensions/magpie/icons/deveco-color.svg +12 -0
- package/extensions/magpie/icons/devin.svg +1 -0
- package/extensions/magpie/icons/doubao-color.svg +1 -0
- package/extensions/magpie/icons/empryo-color.svg +1 -0
- package/extensions/magpie/icons/factory.svg +1 -0
- package/extensions/magpie/icons/favicon.svg +1 -0
- package/extensions/magpie/icons/featherless-color.svg +1 -0
- package/extensions/magpie/icons/fireworks-color.svg +1 -0
- package/extensions/magpie/icons/friendli.svg +1 -0
- package/extensions/magpie/icons/fx.svg +1 -0
- package/extensions/magpie/icons/gemini-color.svg +1 -0
- package/extensions/magpie/icons/geminicli-color.svg +1 -0
- package/extensions/magpie/icons/gemma-color.svg +1 -0
- package/extensions/magpie/icons/giteeai.svg +1 -0
- package/extensions/magpie/icons/github.svg +1 -0
- package/extensions/magpie/icons/githubcopilot.svg +1 -0
- package/extensions/magpie/icons/glama.svg +1 -0
- package/extensions/magpie/icons/gmicloud.svg +1 -0
- package/extensions/magpie/icons/google-color.svg +1 -0
- package/extensions/magpie/icons/googlecloud-color.svg +1 -0
- package/extensions/magpie/icons/goose.svg +1 -0
- package/extensions/magpie/icons/grok.svg +1 -0
- package/extensions/magpie/icons/groq.svg +1 -0
- package/extensions/magpie/icons/hanako.png +0 -0
- package/extensions/magpie/icons/hermes.svg +1 -0
- package/extensions/magpie/icons/huawei-color.svg +1 -0
- package/extensions/magpie/icons/huaweicloud-color.svg +1 -0
- package/extensions/magpie/icons/huggingface-color.svg +1 -0
- package/extensions/magpie/icons/hunyuan-color.svg +1 -0
- package/extensions/magpie/icons/hyperbolic-color.svg +1 -0
- package/extensions/magpie/icons/icon-512.png +0 -0
- package/extensions/magpie/icons/iflytekcloud-color.svg +1 -0
- package/extensions/magpie/icons/inference.svg +1 -0
- package/extensions/magpie/icons/infinigence-color.svg +1 -0
- package/extensions/magpie/icons/internlm-color.svg +1 -0
- package/extensions/magpie/icons/jcode.svg +1 -0
- package/extensions/magpie/icons/jina.svg +1 -0
- package/extensions/magpie/icons/kilo.svg +1 -0
- package/extensions/magpie/icons/kilocode.svg +1 -0
- package/extensions/magpie/icons/kimi-code-desktop.png +0 -0
- package/extensions/magpie/icons/kimi.svg +1 -0
- package/extensions/magpie/icons/kiro-color.svg +1 -0
- package/extensions/magpie/icons/kling-color.svg +1 -0
- package/extensions/magpie/icons/lambda.svg +1 -0
- package/extensions/magpie/icons/leptonai-color.svg +1 -0
- package/extensions/magpie/icons/liquid.svg +1 -0
- package/extensions/magpie/icons/liveagent-color.svg +1 -0
- package/extensions/magpie/icons/llmapi.svg +1 -0
- package/extensions/magpie/icons/lmstudio.svg +1 -0
- package/extensions/magpie/icons/lody.png +0 -0
- package/extensions/magpie/icons/longcat.svg +1 -0
- package/extensions/magpie/icons/magpie.svg +1 -0
- package/extensions/magpie/icons/meta-color.svg +1 -0
- package/extensions/magpie/icons/metaai-color.svg +1 -0
- package/extensions/magpie/icons/microsoft-color.svg +1 -0
- package/extensions/magpie/icons/mimocode.svg +1 -0
- package/extensions/magpie/icons/minimax-color.svg +1 -0
- package/extensions/magpie/icons/mistermorph-color.svg +1 -0
- package/extensions/magpie/icons/mistral-color.svg +1 -0
- package/extensions/magpie/icons/mlx-serve.png +0 -0
- package/extensions/magpie/icons/modelscope-color.svg +1 -0
- package/extensions/magpie/icons/monica-color.svg +1 -0
- package/extensions/magpie/icons/moonshot.svg +1 -0
- package/extensions/magpie/icons/morph-color.svg +1 -0
- package/extensions/magpie/icons/mothx.png +0 -0
- package/extensions/magpie/icons/nebius.svg +1 -0
- package/extensions/magpie/icons/newapi-color.svg +1 -0
- package/extensions/magpie/icons/nousresearch.svg +1 -0
- package/extensions/magpie/icons/nova-color.svg +1 -0
- package/extensions/magpie/icons/novita-color.svg +1 -0
- package/extensions/magpie/icons/nvidia-color.svg +1 -0
- package/extensions/magpie/icons/ollama.svg +1 -0
- package/extensions/magpie/icons/omlx.svg +1 -0
- package/extensions/magpie/icons/omo.svg +1 -0
- package/extensions/magpie/icons/omp.svg +1 -0
- package/extensions/magpie/icons/openai.svg +1 -0
- package/extensions/magpie/icons/openchamber.svg +11 -0
- package/extensions/magpie/icons/openclaw.svg +1 -0
- package/extensions/magpie/icons/opencode.svg +1 -0
- package/extensions/magpie/icons/openmausbot.svg +1 -0
- package/extensions/magpie/icons/openrouter.svg +1 -0
- package/extensions/magpie/icons/openwebui.svg +1 -0
- package/extensions/magpie/icons/parasail.svg +1 -0
- package/extensions/magpie/icons/penguin-color.svg +1 -0
- package/extensions/magpie/icons/perplexity-color.svg +1 -0
- package/extensions/magpie/icons/phala-color.svg +1 -0
- package/extensions/magpie/icons/pi.svg +1 -0
- package/extensions/magpie/icons/pipellm-color.svg +5 -0
- package/extensions/magpie/icons/poe.svg +1 -0
- package/extensions/magpie/icons/ppio-color.svg +1 -0
- package/extensions/magpie/icons/prime-agent.svg +1 -0
- package/extensions/magpie/icons/qiniu-color.svg +1 -0
- package/extensions/magpie/icons/qoder.svg +1 -0
- package/extensions/magpie/icons/qwen-color.svg +1 -0
- package/extensions/magpie/icons/qwenpaw.svg +1 -0
- package/extensions/magpie/icons/raycast.svg +1 -0
- package/extensions/magpie/icons/reasonix-color.svg +48 -0
- package/extensions/magpie/icons/reka.svg +1 -0
- package/extensions/magpie/icons/replicate.svg +1 -0
- package/extensions/magpie/icons/roocode.svg +1 -0
- package/extensions/magpie/icons/rtk.png +0 -0
- package/extensions/magpie/icons/sambanova-color.svg +1 -0
- package/extensions/magpie/icons/sensenova-color.svg +1 -0
- package/extensions/magpie/icons/siliconcloud-color.svg +1 -0
- package/extensions/magpie/icons/snow.png +0 -0
- package/extensions/magpie/icons/snowflake-color.svg +1 -0
- package/extensions/magpie/icons/sophnet-color.svg +1 -0
- package/extensions/magpie/icons/spark-color.svg +1 -0
- package/extensions/magpie/icons/stepfun-color.svg +1 -0
- package/extensions/magpie/icons/straico-color.svg +1 -0
- package/extensions/magpie/icons/submodel-color.svg +1 -0
- package/extensions/magpie/icons/t3code.svg +4 -0
- package/extensions/magpie/icons/targon-color.svg +1 -0
- package/extensions/magpie/icons/tencent-color.svg +1 -0
- package/extensions/magpie/icons/tencentcloud-color.svg +1 -0
- package/extensions/magpie/icons/tiangong-color.svg +1 -0
- package/extensions/magpie/icons/together-color.svg +1 -0
- package/extensions/magpie/icons/trae.svg +1 -0
- package/extensions/magpie/icons/typesafe.png +0 -0
- package/extensions/magpie/icons/upstage-color.svg +1 -0
- package/extensions/magpie/icons/venice-color.svg +1 -0
- package/extensions/magpie/icons/vercel.svg +1 -0
- package/extensions/magpie/icons/vertexai-color.svg +1 -0
- package/extensions/magpie/icons/vllm-color.svg +1 -0
- package/extensions/magpie/icons/volcengine-color.svg +1 -0
- package/extensions/magpie/icons/voyage-color.svg +1 -0
- package/extensions/magpie/icons/vscode.svg +1 -0
- package/extensions/magpie/icons/wenxin-color.svg +1 -0
- package/extensions/magpie/icons/windsurf.svg +1 -0
- package/extensions/magpie/icons/workbuddy-color.svg +1 -0
- package/extensions/magpie/icons/workersai-color.svg +1 -0
- package/extensions/magpie/icons/xai.svg +1 -0
- package/extensions/magpie/icons/xiaomimimo.svg +1 -0
- package/extensions/magpie/icons/xinference-color.svg +1 -0
- package/extensions/magpie/icons/yi.svg +1 -0
- package/extensions/magpie/icons/yuanbao-color.svg +1 -0
- package/extensions/magpie/icons/yylx.svg +5 -0
- package/extensions/magpie/icons/zai.svg +1 -0
- package/extensions/magpie/icons/zcode.png +0 -0
- package/extensions/magpie/icons/zed.svg +1 -0
- package/extensions/magpie/icons/zenmux.svg +1 -0
- package/extensions/magpie/icons/zeroone.svg +1 -0
- package/extensions/magpie/icons/zhipu-color.svg +1 -0
- package/extensions/magpie/icons/zoo-code.png +0 -0
- package/extensions/magpie/index.html +572 -0
- package/extensions/magpie/kernel.js +274 -0
- package/extensions/magpie/keyspend.js +63 -0
- package/extensions/magpie/layout.js +26 -0
- package/extensions/magpie/manifest.json +37 -0
- package/extensions/magpie/navlamp.js +47 -0
- package/extensions/magpie/omarchy.css +72 -0
- package/extensions/magpie/omarchy.js +46 -0
- package/extensions/magpie/passerrors.js +21 -0
- package/extensions/magpie/pluginpages.js +405 -0
- package/extensions/magpie/plugins/gateway/client.js +1194 -0
- package/extensions/magpie/plugins/gateway/keys.js +972 -0
- package/extensions/magpie/plugins/gateway/settings.js +459 -0
- package/extensions/magpie/plugins/library/client.js +6788 -0
- package/extensions/magpie/plugins/library/i18n.js +3228 -0
- package/extensions/magpie/plugins/library/library.css +848 -0
- package/extensions/magpie/plugins/otel/i18n.js +48 -0
- package/extensions/magpie/plugins/otel/page.js +189 -0
- package/extensions/magpie/plugins/redact/client.js +46 -0
- package/extensions/magpie/plugins/redact/demo.js +461 -0
- package/extensions/magpie/plugins/redact/i18n.js +432 -0
- package/extensions/magpie/plugins/redact/page.js +985 -0
- package/extensions/magpie/plugins/redact/redact.css +385 -0
- package/extensions/magpie/plugins/redact/settings.js +248 -0
- package/extensions/magpie/plugins/redact/xq_dark.jpg +0 -0
- package/extensions/magpie/plugins/redact/xq_dark.webm +0 -0
- package/extensions/magpie/plugins/redact/xq_light.jpg +0 -0
- package/extensions/magpie/plugins/redact/xq_light.webm +0 -0
- package/extensions/magpie/plugins/routing/client.js +8593 -0
- package/extensions/magpie/plugins/routing/i18n.js +2696 -0
- package/extensions/magpie/plugins/routing/routing.css +1111 -0
- package/extensions/magpie/plugins/search/settings.js +460 -0
- package/extensions/magpie/plugins/sessions/client.js +1622 -0
- package/extensions/magpie/plugins/sessions/i18n.js +360 -0
- package/extensions/magpie/plugins/sessions/sessions.css +181 -0
- package/extensions/magpie/plugins/sessions/settings.js +100 -0
- package/extensions/magpie/plugins/usage/client.js +150 -0
- package/extensions/magpie/plugins/usage/i18n.js +984 -0
- package/extensions/magpie/plugins/usage/page.js +4307 -0
- package/extensions/magpie/plugins.css +319 -0
- package/extensions/magpie/plugins.js +1926 -0
- package/extensions/magpie/profilerename.js +27 -0
- package/extensions/magpie/purposes.js +2 -0
- package/extensions/magpie/quitask.js +79 -0
- package/extensions/magpie/quotaall.js +142 -0
- package/extensions/magpie/ratewindows.js +123 -0
- package/extensions/magpie/registry.js +87 -0
- package/extensions/magpie/resetask.js +137 -0
- package/extensions/magpie/ruleedit.js +53 -0
- package/extensions/magpie/scrollends.js +91 -0
- package/extensions/magpie/settingshints.js +75 -0
- package/extensions/magpie/signsheets.js +86 -0
- package/extensions/magpie/start.js +26 -0
- package/extensions/magpie/syncfiles.js +216 -0
- package/extensions/magpie/theme.js +29 -0
- package/extensions/magpie/traywindows.js +41 -0
- package/extensions/magpie/webfonts.js +130 -0
- package/extensions/magpie/whatsnew.js +252 -0
- package/extensions/magpie.zip +0 -0
- package/knowledge/apps/baijiahao.md +30 -0
- package/knowledge/apps/bilibili.md +1 -0
- package/knowledge/apps/dedao.md +33 -0
- package/knowledge/apps/feishu.md +35 -0
- package/knowledge/apps/gmail.md +33 -0
- package/knowledge/apps/jike.md +31 -0
- package/knowledge/apps/kuaishou.md +34 -0
- package/knowledge/apps/linkedin.md +33 -0
- package/knowledge/apps/qqmail.md +30 -0
- package/knowledge/apps/telegram.md +27 -0
- package/knowledge/apps/toutiao.md +32 -0
- package/knowledge/apps/uber-eats.md +26 -0
- package/knowledge/apps/uber.md +27 -0
- package/knowledge/apps/whatsapp.md +27 -0
- package/knowledge/apps/x.md +32 -0
- package/knowledge/apps/xiaohongshu.md +1 -0
- package/knowledge/apps/zhihu.md +1 -0
- package/knowledge/sites/bilibili.com/SITE.md +50 -0
- package/knowledge/sites/bilibili.com/references/view-fields.md +17 -0
- package/knowledge/sites/github.com/SITE.md +51 -0
- package/knowledge/sites/github.com/references/repo-fields.md +13 -0
- package/knowledge/sites/x.com/SITE.md +47 -0
- package/knowledge/sites/xiaohongshu.com/SITE.md +48 -0
- package/knowledge/sites/xiaohongshu.com/references/note-fields.md +18 -0
- package/knowledge/sites/youtube.com/SITE.md +49 -0
- package/knowledge/sites/youtube.com/references/innertube-fields.md +14 -0
- package/knowledge/sites/zhihu.com/SITE.md +47 -0
- package/knowledge/sites/zhihu.com/references/api-fields.md +21 -0
- package/lib/mobile/extension-catalog.js +41 -1
- package/lib/mobile/extension-data.js +224 -0
- package/lib/mobile/extension-dev.js +3 -1
- package/lib/mobile/file-ops.js +252 -0
- package/lib/mobile/history-derive.js +80 -4
- package/lib/mobile/host-bridge/endpoints.js +48 -6
- package/lib/mobile/host-bridge/event-synthesis.js +33 -6
- package/lib/mobile/jobs-control.js +118 -0
- package/lib/mobile/memory.js +635 -0
- package/lib/mobile/model-badges.js +77 -0
- package/lib/mobile/pet-tools.js +50 -4
- package/lib/mobile/pets.js +214 -18
- package/lib/mobile/phone/access.js +85 -0
- package/lib/mobile/phone/evidence.js +228 -0
- package/lib/mobile/phone/gate.js +290 -0
- package/lib/mobile/phone/grounding.js +314 -0
- package/lib/mobile/phone/guard.js +465 -0
- package/lib/mobile/phone/irreversible.js +88 -8
- package/lib/mobile/phone/knowledge-tools.js +665 -0
- package/lib/mobile/phone/learn.js +329 -0
- package/lib/mobile/phone/redact.js +237 -0
- package/lib/mobile/phone/risk.js +95 -0
- package/lib/mobile/phone/routes.js +28 -1
- package/lib/mobile/phone/service.js +23 -0
- package/lib/mobile/phone/site-commands.js +271 -0
- package/lib/mobile/phone/step-summary.js +201 -0
- package/lib/mobile/phone/stop-summary.js +235 -0
- package/lib/mobile/phone/tool-groups.js +125 -0
- package/lib/mobile/phone/tools.js +589 -0
- package/lib/mobile/phone/untrusted.js +65 -0
- package/lib/mobile/phone-knowledge.js +20 -4
- package/lib/mobile/schedule-edit.js +500 -0
- package/lib/mobile/schedule.js +5 -0
- package/lib/mobile/send-continuation.js +52 -0
- package/lib/mobile/session-models.js +27 -31
- package/lib/mobile/session-send.js +12 -12
- package/lib/mobile/skill-import.js +338 -0
- package/lib/mobile/skill-store.js +524 -0
- package/lib/routes/mobile-api.js +42 -0
- package/package.json +7 -6
- package/skills/skill-authoring/SKILL.md +46 -0
- package/skills/skill-authoring/references/examples.md +82 -0
- package/skills/skill-authoring/references/frontmatter-and-fields.md +46 -0
- package/skills/skill-authoring/scripts/check_skill.py +167 -0
- package/skills/skill-authoring/scripts/manifest.json +3 -0
- package/knowledge/sites/bilibili.com.md +0 -27
- package/knowledge/sites/github.com.md +0 -27
- package/knowledge/sites/x.com.md +0 -28
- package/knowledge/sites/xiaohongshu.com.md +0 -27
- package/knowledge/sites/youtube.com.md +0 -28
- package/knowledge/sites/zhihu.com.md +0 -27
|
@@ -124,12 +124,7 @@ const ENDPOINTS = {
|
|
|
124
124
|
delivery: (p && p.delivery) || 'queue',
|
|
125
125
|
},
|
|
126
126
|
})),
|
|
127
|
-
'subagents.interrupt': (ctx, payload, signal) =>
|
|
128
|
-
invoke(ctx, 'subagents', 'interruptByParent', {
|
|
129
|
-
childSessionId: payload.childSessionId,
|
|
130
|
-
parentSessionId: payload.parentSessionId,
|
|
131
|
-
mode: payload.mode || 'continuable',
|
|
132
|
-
}, signal).then((r) => (r.error ? fail(r.error) : ok(r.value))),
|
|
127
|
+
'subagents.interrupt': (ctx, payload, signal) => subagentInterrupt(ctx, payload, signal),
|
|
133
128
|
'subagents.list': (ctx, payload, signal) => subagentCatalog(ctx, payload, signal),
|
|
134
129
|
|
|
135
130
|
// goals:objective 被宿主挪进了 request 里
|
|
@@ -174,6 +169,53 @@ function goalAction(ctx, method, payload, signal) {
|
|
|
174
169
|
.then((r) => (r.error ? fail(r.error) : ok(r.value)));
|
|
175
170
|
}
|
|
176
171
|
|
|
172
|
+
/**
|
|
173
|
+
* 打断可继续子代理当前这一轮。
|
|
174
|
+
*
|
|
175
|
+
* 上游 0.2.1-rc.2 起把旧的 `interruptByParent(childSessionId, parentSessionId, mode)`
|
|
176
|
+
* 换成了 `interruptByUser(childSessionId)`:新接口只按子会话 id 打断,授权挂在子会话本身
|
|
177
|
+
* (`@Remote({ name: 'interruptByUser', resources: { session: childSessionId => childSessionId } })`),
|
|
178
|
+
* 不再需要父会话 id 和 mode。老宿主上旧的 `interruptByParent` 还在,所以这里做兜底:
|
|
179
|
+
* 先打新接口,宿主没有这个新方法就退回旧接口。
|
|
180
|
+
*
|
|
181
|
+
* 失败信息要能分清是哪一种,别把「宿主没有这个方法」和「打断本身失败」混成一句:
|
|
182
|
+
* - 新接口存在但打断失败(网关回的是别的业务错误码,例如 gateway/internal)→ 直接如实
|
|
183
|
+
* 报那一发,**不退回**;退回只会把真失败伪装成「没这个接口」。
|
|
184
|
+
* - 新接口不存在(`host-unavailable`,即老宿主)→ 退回旧接口,旧接口成功就算成功。
|
|
185
|
+
* - 两个接口都不存在 → 明确报「宿主没有打断接口」,这跟「打断失败」是两回事。
|
|
186
|
+
* - 退回旧接口后真的打断失败 → 报旧接口的错误,它才是这一次真实的结果。
|
|
187
|
+
*
|
|
188
|
+
* App 侧 payload 仍是 `{ parentSessionId, childSessionId }`(`subagents.js` 还补了 mode):
|
|
189
|
+
* 新接口要的 `childSessionId` 正好在里面,参数名不用改;父会话 id / mode 只给旧接口用。
|
|
190
|
+
*/
|
|
191
|
+
async function subagentInterrupt(ctx, payload, signal) {
|
|
192
|
+
const childSessionId = payload && payload.childSessionId;
|
|
193
|
+
const next = await invoke(ctx, 'subagents', 'interruptByUser', { childSessionId }, signal);
|
|
194
|
+
if (!next.error) return ok(next.value);
|
|
195
|
+
|
|
196
|
+
// 新接口不存在 = 老宿主,退回旧的 interruptByParent。
|
|
197
|
+
if (next.error.code === 'host-unavailable') {
|
|
198
|
+
const legacy = await invoke(ctx, 'subagents', 'interruptByParent', {
|
|
199
|
+
childSessionId,
|
|
200
|
+
parentSessionId: payload && payload.parentSessionId,
|
|
201
|
+
mode: (payload && payload.mode) || 'continuable',
|
|
202
|
+
}, signal);
|
|
203
|
+
if (!legacy.error) return ok(legacy.value);
|
|
204
|
+
// 旧接口也不存在:宿主根本没有打断能力,与「打断失败」区分开。
|
|
205
|
+
if (legacy.error.code === 'host-unavailable') {
|
|
206
|
+
return fail({
|
|
207
|
+
code: 'host-unavailable',
|
|
208
|
+
message: '当前宿主版本没有提供子代理打断接口(interruptByUser / interruptByParent 都不存在)',
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
// 旧接口存在但打断失败:如实报旧接口的错误。
|
|
212
|
+
return fail(legacy.error);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// 新接口存在但打断失败:如实报,不退回。
|
|
216
|
+
return fail(next.error);
|
|
217
|
+
}
|
|
218
|
+
|
|
177
219
|
/**
|
|
178
220
|
* 宿主只服务 native 选择器时的清单条(**不回落到网关**)。
|
|
179
221
|
*
|
|
@@ -244,9 +244,14 @@ async function* sessionJobFrames(ctx, sessionId, signal) {
|
|
|
244
244
|
* 投影整帧(排队条、计划条、目标条、模型选择等全量快照)。
|
|
245
245
|
*
|
|
246
246
|
* 宿主 session.control 是设备级投影流:首帧 baseline 一次性给出
|
|
247
|
-
* { projections: { [sessionId]: { asOfSeq, values } } },之后是
|
|
248
|
-
*
|
|
249
|
-
*
|
|
247
|
+
* { projections: { [sessionId]: { asOfSeq, values } } },之后是 live 变化帧。
|
|
248
|
+
* live 帧有两种形状:0.2.0 及更早是「一 key 一帧」的
|
|
249
|
+
* { type:'projection', sessionId, key, value, seq },0.2.2-alpha.2 起改成「一个 committed
|
|
250
|
+
* event 一帧」的 { type:'projection', sessionId, seq, changes:[{ key, val }] } —— 同一次
|
|
251
|
+
* 事件改掉的键全在这一帧里、共用一个 seq。两种都得认,否则宿主管家升上去之后投影会停在
|
|
252
|
+
* 首帧:排队条、计划条、模型选择、上下文统计一起不动。
|
|
253
|
+
*
|
|
254
|
+
* 对外仍是整帧(幂等全量),这里保持整帧语义 —— 更新帧就带上累积后的 values 重发。
|
|
250
255
|
*/
|
|
251
256
|
function projectionState() {
|
|
252
257
|
const values = new Map(); // sessionId -> { asOfSeq, values }
|
|
@@ -265,11 +270,33 @@ function projectionState() {
|
|
|
265
270
|
}
|
|
266
271
|
return touched;
|
|
267
272
|
},
|
|
273
|
+
/**
|
|
274
|
+
* 一帧 live 变化 → 累积后的整帧。
|
|
275
|
+
*
|
|
276
|
+
* 新形状一次带多个 change,按 `changes` 顺序全部应用(后来的同名键覆盖前面的);
|
|
277
|
+
* 旧形状只有单个 key/value。认不出的帧不抛错也不动 values —— 这条流后面还接着
|
|
278
|
+
* baseline 和别的会话,一帧脏数据不该把整条投影流打断。
|
|
279
|
+
*/
|
|
268
280
|
applyUpdate(update) {
|
|
269
|
-
|
|
270
|
-
|
|
281
|
+
if (!update || typeof update !== 'object') return [];
|
|
282
|
+
const sessionId = update.sessionId;
|
|
283
|
+
if (typeof sessionId !== 'string' || !sessionId) return [];
|
|
284
|
+
const changes = [];
|
|
285
|
+
if (Array.isArray(update.changes)) {
|
|
286
|
+
for (const change of update.changes) {
|
|
287
|
+
if (!change || typeof change !== 'object') continue;
|
|
288
|
+
if (typeof change.key !== 'string' || !change.key) continue;
|
|
289
|
+
changes.push([change.key, change.val]);
|
|
290
|
+
}
|
|
291
|
+
} else if (typeof update.key === 'string' && update.key) {
|
|
292
|
+
changes.push([update.key, update.value]);
|
|
293
|
+
}
|
|
294
|
+
if (changes.length === 0 && !Number.isSafeInteger(update.seq)) return [];
|
|
271
295
|
const current = values.get(sessionId) || { asOfSeq: 0, values: {} };
|
|
272
|
-
|
|
296
|
+
let nextValues = current.values;
|
|
297
|
+
for (const [key, val] of changes) nextValues = { ...nextValues, [key]: val };
|
|
298
|
+
current.values = nextValues;
|
|
299
|
+
// seq 是「造成这批变化的那个 committed event」的序号;一帧里多个 change 共用它。
|
|
273
300
|
if (Number.isSafeInteger(update.seq)) current.asOfSeq = update.seq;
|
|
274
301
|
values.set(sessionId, current);
|
|
275
302
|
return [sessionId];
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 后台任务的启停控制。
|
|
5
|
+
*
|
|
6
|
+
* 宿主把后台任务拆成两半:
|
|
7
|
+
* - 读:`session/jobs` 帧(`jobs.js` 只做形状收敛)与 `jobController` 的流式 `list` /
|
|
8
|
+
* `follow`(桌面端的任务面板用)。手机端已有的 `jobs` 帧已经能显示「进行中 N / 共 M」。
|
|
9
|
+
* - 写:宿主 `JobController` 只公开一条 `kill`(`job/kill`,人类代删,reason 记
|
|
10
|
+
* 「cancelled by the user」,owner 仍会收到完成通知)。它接 `{ sessionId, jobId }`,
|
|
11
|
+
* 回 `{ outcome: 'requested' | 'already-finished' }`,任务看不见时抛 `job/not-found`。
|
|
12
|
+
*
|
|
13
|
+
* 所以**取消能接,启动接不了**:`ctx.jobs.start()` 是给 bash / PTY 之类「生产者」用的
|
|
14
|
+
* 内部 seam,`tool-jobs` 插件靠它把命令跑起来;移动 API 一旦放开「启动」就等于放开「跑任意
|
|
15
|
+
* 命令」,直接撞上「不暴露 shell」那条能力边界。这里给启动一条显式 501(`jobs-start-
|
|
16
|
+
* unsupported`),让 App 能明确显示「这台电脑只能看和取消,不能从这里起任务」,而不是装作
|
|
17
|
+
* 成功或 404。
|
|
18
|
+
*
|
|
19
|
+
* 服务同进程直查 `ctx.get('jobController')`,不写进 inject:老宿主没有它时只该让这一条
|
|
20
|
+
* 路由回 503,不该影响整个插件装配。没有这个服务就回 503(与 schedule 那套同口径)。
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const { sendJson, readJsonBody } = require('../shared/http-util');
|
|
24
|
+
|
|
25
|
+
const JOB_ID_MAX = 200;
|
|
26
|
+
const SESSION_ID_MAX = 200;
|
|
27
|
+
|
|
28
|
+
/** 宿主没有后台任务控制服务时的统一回答。 */
|
|
29
|
+
const UNAVAILABLE = Object.freeze({
|
|
30
|
+
code: 'jobs-unavailable',
|
|
31
|
+
message: '宿主没有后台任务控制服务',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
/** 启动能力的统一回答:宿主不提供,只能取消。 */
|
|
35
|
+
const START_UNSUPPORTED = Object.freeze({
|
|
36
|
+
code: 'jobs-start-unsupported',
|
|
37
|
+
message: '宿主的移动 API 不能启动后台任务,只能查看与取消',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
/** 必填文本:非字符串或全空白 → '';超长截断。 */
|
|
41
|
+
function requiredText(value, max) {
|
|
42
|
+
if (typeof value !== 'string') return '';
|
|
43
|
+
const text = value.trim();
|
|
44
|
+
if (!text) return '';
|
|
45
|
+
return text.length > max ? text.slice(0, max) : text;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** 错误文字:宿主 reject 的原文,取不到就退回 String()。 */
|
|
49
|
+
function errorText(error) {
|
|
50
|
+
if (error === undefined || error === null) return '未知错误';
|
|
51
|
+
if (typeof error.message === 'string' && error.message) return error.message;
|
|
52
|
+
return String(error);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** 同进程直查 `jobController`;拿不到返回 null。 */
|
|
56
|
+
function jobControllerService(ctx) {
|
|
57
|
+
try {
|
|
58
|
+
if (!ctx || typeof ctx.get !== 'function') return null;
|
|
59
|
+
return ctx.get('jobController') || null;
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* POST /api/mobile/v1/jobs/cancel
|
|
67
|
+
* body { sessionId?, jobId } —— 取消一条后台任务。
|
|
68
|
+
*
|
|
69
|
+
* `sessionId` 取任务那一帧上带的会话(owner fence):宿主只让会话看得见的任务被取消。
|
|
70
|
+
* 无主任务可以不传;传了也不会错。
|
|
71
|
+
*/
|
|
72
|
+
async function handleJobsCancel(ctx, req, res) {
|
|
73
|
+
const body = (await readJsonBody(req)) || {};
|
|
74
|
+
const sessionId = requiredText(body.sessionId, SESSION_ID_MAX);
|
|
75
|
+
const jobId = requiredText(body.jobId ?? body.id, JOB_ID_MAX);
|
|
76
|
+
if (!jobId) {
|
|
77
|
+
return sendJson(res, 400, { ok: false, error: { code: 'invalid_selector', message: '需要 jobId' } });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const service = jobControllerService(ctx);
|
|
81
|
+
if (!service || typeof service.kill !== 'function') {
|
|
82
|
+
return sendJson(res, 503, { ok: false, error: { ...UNAVAILABLE } });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let result;
|
|
86
|
+
try {
|
|
87
|
+
result = await service.kill({ sessionId, jobId });
|
|
88
|
+
} catch (error) {
|
|
89
|
+
const code = error && typeof error.code === 'string' ? error.code.trim() : '';
|
|
90
|
+
if (code === 'job/not-found' || /not[\s-]?found/i.test(errorText(error))) {
|
|
91
|
+
// 任务已经不在了不算大错:手机刷新一下就没有它了。
|
|
92
|
+
return sendJson(res, 404, { ok: false, error: { code: 'job-not-found', message: '没有这个后台任务' } });
|
|
93
|
+
}
|
|
94
|
+
return sendJson(res, 502, { ok: false, error: { code: 'jobs_failed', message: errorText(error) } });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const outcome = result && typeof result === 'object' ? result.outcome : result;
|
|
98
|
+
sendJson(res, 200, {
|
|
99
|
+
ok: true,
|
|
100
|
+
id: jobId,
|
|
101
|
+
outcome: typeof outcome === 'string' && outcome ? outcome : 'requested',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* POST /api/mobile/v1/jobs/start —— 宿主不提供这个能力,显式 501。
|
|
107
|
+
*
|
|
108
|
+
* 保留这条是为了让 App 能拿到一个明确答复(据此决定按钮显不显示 / 怎么写提示),
|
|
109
|
+
* 而不是靠 404 猜。真要支持启动,得先改设计:那等于让移动端跑任意命令。
|
|
110
|
+
*/
|
|
111
|
+
async function handleJobsStart(_ctx, _req, res) {
|
|
112
|
+
sendJson(res, 501, { ok: false, error: { ...START_UNSUPPORTED } });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
module.exports = {
|
|
116
|
+
handleJobsCancel,
|
|
117
|
+
handleJobsStart,
|
|
118
|
+
};
|