@turmind/halo 1.6.3 → 1.6.5
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/README.md +66 -67
- package/admin-out/404.html +1 -1
- package/admin-out/_next/static/chunks/87-6a2716c98a819c4e.js +1 -0
- package/admin-out/_next/static/chunks/989-066a874961bd519f.js +1 -0
- package/admin-out/_next/static/chunks/app/page-812bcbb46db628b6.js +1 -0
- package/admin-out/_next/static/css/e890aa0d13e94290.css +1 -0
- package/admin-out/index.html +1 -1
- package/admin-out/index.txt +5 -5
- package/bin/halo.js +4 -0
- package/bundled-docs/design/architecture.md +1 -1
- package/bundled-docs/design/canvas-extensions.md +40 -9
- package/bundled-docs/design/cron.md +12 -4
- package/bundled-docs/design/halo-city.md +14 -149
- package/bundled-docs/design/observability.md +7 -5
- package/bundled-docs/design/storage.md +14 -7
- package/bundled-docs/design/stt-local.md +106 -0
- package/bundled-docs/design/web.md +1 -1
- package/bundled-docs/design/wechat.md +1 -1
- package/bundled-docs/dev/add-model-provider.md +2 -1
- package/bundled-docs/dev/api.md +13 -9
- package/bundled-docs/dev/deploy.md +114 -26
- package/bundled-docs/dev/desktop-packaging.md +50 -10
- package/bundled-docs/dev/env.md +4 -4
- package/bundled-docs/dev/logging.md +13 -2
- package/bundled-docs/dev/tools.md +2 -2
- package/bundled-docs/guide/agents.md +2 -2
- package/bundled-docs/guide/cli.md +20 -8
- package/bundled-docs/guide/getting-started.md +13 -5
- package/bundled-docs/guide/workspace.md +2 -0
- package/bundled-docs/requirements/agent.md +1 -1
- package/bundled-docs/requirements/chat.md +8 -0
- package/bundled-docs/requirements/explorer.md +14 -2
- package/bundled-docs/requirements/settings.md +2 -2
- package/bundled-docs/requirements/workspace.md +4 -0
- package/dist/index.js +3645 -1725
- package/package.json +4 -2
- package/templates/models/gemini.yaml +93 -0
- package/templates/skills/cron/SKILL.md +2 -1
- package/templates/skills/cron/manage-cron.py +2 -1
- package/admin-out/_next/static/chunks/147-d4200c70445aabb6.js +0 -1
- package/admin-out/_next/static/chunks/989-ddba0eb72566da23.js +0 -1
- package/admin-out/_next/static/chunks/app/page-7ffcbddb49dc56c4.js +0 -1
- package/admin-out/_next/static/css/3b4dcd0ac6b8eae8.css +0 -1
- /package/admin-out/_next/static/{k5zuJrivSdbaPifBatwdr → 8v1hCXbUqJhyMuK7LVeet}/_buildManifest.js +0 -0
- /package/admin-out/_next/static/{k5zuJrivSdbaPifBatwdr → 8v1hCXbUqJhyMuK7LVeet}/_ssgManifest.js +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@turmind/halo",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.5",
|
|
4
4
|
"description": "Halo — multi-agent collaborative workspace. CLI + TUI + HTTP/WS server in one package.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -55,9 +55,11 @@
|
|
|
55
55
|
"qrcode": "^1.5.4",
|
|
56
56
|
"react": "^19.2.5",
|
|
57
57
|
"react-dom": "^19.2.5",
|
|
58
|
+
"sherpa-onnx-node": "1.13.8",
|
|
58
59
|
"simple-git": "^3.27.0",
|
|
59
60
|
"ws": "^8.21.3",
|
|
60
|
-
"yaml": "^2.8.3"
|
|
61
|
+
"yaml": "^2.8.3",
|
|
62
|
+
"yazl": "3.3.1"
|
|
61
63
|
},
|
|
62
64
|
"engines": {
|
|
63
65
|
"node": ">=22"
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
id: gemini
|
|
2
|
+
runtime: gemini
|
|
3
|
+
revision: 2026101201
|
|
4
|
+
displayName: Google Gemini
|
|
5
|
+
displayName_zh: Google Gemini
|
|
6
|
+
description: Google Gemini 3.x via the Gemini API's OpenAI-compatible chat completions surface
|
|
7
|
+
description_zh: Google Gemini 3.x,通过 Gemini API 的 OpenAI 兼容 chat completions 接口调用
|
|
8
|
+
defaultEndpoint: https://generativelanguage.googleapis.com/v1beta/openai
|
|
9
|
+
defaultModelId: gemini-3.8-flash
|
|
10
|
+
|
|
11
|
+
secrets:
|
|
12
|
+
- key: api_key
|
|
13
|
+
description: Gemini API Key. Get from https://aistudio.google.com/apikey
|
|
14
|
+
description_zh: Gemini API Key。从 https://aistudio.google.com/apikey 获取
|
|
15
|
+
default: <<GEMINI_API_KEY>>
|
|
16
|
+
secret: true
|
|
17
|
+
|
|
18
|
+
# Capabilities verified via live probes (2026-10-12) on the OpenAI-compatible
|
|
19
|
+
# endpoint (Bearer auth; the runtime appends /chat/completions). Limits are
|
|
20
|
+
# GET /v1beta/models inputTokenLimit / outputTokenLimit (1048576 / 65536).
|
|
21
|
+
#
|
|
22
|
+
# Why a `gemini` runtime and not plain openai-chat: Gemini 3 puts
|
|
23
|
+
# `extra_content.google.thought_signature` on the first tool call of a reply
|
|
24
|
+
# and 400s a follow-up that replays the call without it; it also ends
|
|
25
|
+
# tool-call replies with finish_reason "stop", which OpenAIAgent reads as
|
|
26
|
+
# end-of-turn (the tool never ran). gemini-agent.ts handles both.
|
|
27
|
+
#
|
|
28
|
+
# Thinking can't be switched off on Gemini 3 (doc + reasoning_effort "none"
|
|
29
|
+
# 400s on 3.5-flash-lite, still thinks on 3.8-flash). Levels per model, from
|
|
30
|
+
# the thinking doc's table and the API's own 400s: xhigh / max are invalid
|
|
31
|
+
# everywhere, `minimal` 400s on 3.8-flash. The runtime sends the level as
|
|
32
|
+
# extra_body.google.thinking_config.thinking_level + include_thoughts (the
|
|
33
|
+
# summary streams inline as <thought>…</thought>, split out into thinking);
|
|
34
|
+
# Off sends nothing — model default level, no summary.
|
|
35
|
+
#
|
|
36
|
+
# Caching is implicit: the same ~9.8K-token prefix sent twice came back with
|
|
37
|
+
# prompt_tokens_details.cached_tokens 6121 on run 2 (3.5-flash-lite). The 5m
|
|
38
|
+
# preset is a form hint only — nothing is sent.
|
|
39
|
+
#
|
|
40
|
+
# Not shipped: gemini-3.1-pro-preview — this key is free-tier and every call
|
|
41
|
+
# 429s with quota limit 0, so the tool round-trip couldn't be probed. Aliases
|
|
42
|
+
# (*-latest), image / tts / live / gemma / deep-research models are left out.
|
|
43
|
+
models:
|
|
44
|
+
# Tool round-trip OK (signature replayed → 200; without it → 400).
|
|
45
|
+
# reasoning_effort low / medium / high 200, minimal 400.
|
|
46
|
+
- id: gemini-3.8-flash
|
|
47
|
+
displayName: Gemini 3.8 Flash
|
|
48
|
+
maxOutputTokens: 65536
|
|
49
|
+
contextWindow: 272000
|
|
50
|
+
maxContextWindow: 1048576
|
|
51
|
+
compressAt: 0.9
|
|
52
|
+
capabilities:
|
|
53
|
+
# Not probed on this id — its free-tier quota (20 requests/day) ran out
|
|
54
|
+
# first. The same image_url path read a 64×64 blue PNG on
|
|
55
|
+
# 3.5-flash-lite, 3.6-flash and gemini-flash-latest; flip after a probe.
|
|
56
|
+
image: false
|
|
57
|
+
video: false
|
|
58
|
+
audio: false
|
|
59
|
+
# promptCaching: not declared — caching wasn't probed on this id.
|
|
60
|
+
thinking:
|
|
61
|
+
# Always on server-side; the doc's default level is medium.
|
|
62
|
+
defaultEnabled: true
|
|
63
|
+
default: medium
|
|
64
|
+
effortPresets:
|
|
65
|
+
- { value: low, label: Low }
|
|
66
|
+
- { value: medium, label: Medium }
|
|
67
|
+
- { value: high, label: High }
|
|
68
|
+
|
|
69
|
+
# Tool round-trip OK; 64×64 blue PNG → "Blue"; implicit caching (above).
|
|
70
|
+
# reasoning_effort minimal / low / medium / high 200, none 400.
|
|
71
|
+
- id: gemini-3.5-flash-lite
|
|
72
|
+
displayName: Gemini 3.5 Flash-Lite
|
|
73
|
+
maxOutputTokens: 65536
|
|
74
|
+
contextWindow: 272000
|
|
75
|
+
maxContextWindow: 1048576
|
|
76
|
+
compressAt: 0.9
|
|
77
|
+
capabilities:
|
|
78
|
+
image: true
|
|
79
|
+
video: false
|
|
80
|
+
audio: false
|
|
81
|
+
promptCaching:
|
|
82
|
+
default: 5m
|
|
83
|
+
ttlPresets:
|
|
84
|
+
- { value: 5m, label: 5min }
|
|
85
|
+
thinking:
|
|
86
|
+
# Always on server-side; the doc's default level is minimal.
|
|
87
|
+
defaultEnabled: true
|
|
88
|
+
default: minimal
|
|
89
|
+
effortPresets:
|
|
90
|
+
- { value: minimal, label: Minimal }
|
|
91
|
+
- { value: low, label: Low }
|
|
92
|
+
- { value: medium, label: Medium }
|
|
93
|
+
- { value: high, label: High }
|
|
@@ -128,7 +128,8 @@ tasks that don't need memory ("每天抓一次行情发给我", a fixed report).
|
|
|
128
128
|
Excludes `--session`. On `update`: `--stateless on` / `--stateless off`
|
|
129
129
|
(clear `--session ""` first if one is set). Only the newest 10 runs are kept;
|
|
130
130
|
an older run's session is deleted with it (unless someone continued chatting
|
|
131
|
-
in it).
|
|
131
|
+
in it). After `delete`, the server clears the job's run history and these
|
|
132
|
+
sessions within about 10 seconds (a continued session stays). `get` / `list` show
|
|
132
133
|
`effective_session_id: null` for a stateless job.
|
|
133
134
|
|
|
134
135
|
**Folder (`--dir`, optional)** — the run focuses on a workspace sub-folder:
|
|
@@ -551,11 +551,12 @@ def _toggle_enabled(job_id: str, on: bool):
|
|
|
551
551
|
|
|
552
552
|
|
|
553
553
|
def cmd_delete(args):
|
|
554
|
+
# Job row only: the server's reconcile pass deletes the job's cron_runs
|
|
555
|
+
# rows, and with them each stateless run's session (runner.ts deleteOrphanRuns).
|
|
554
556
|
conn = open_db()
|
|
555
557
|
cur = conn.execute('DELETE FROM cron_jobs WHERE id = ?', (args.id,))
|
|
556
558
|
if cur.rowcount == 0:
|
|
557
559
|
die(f'job {args.id} not found', 2)
|
|
558
|
-
conn.execute('DELETE FROM cron_runs WHERE job_id = ?', (args.id,))
|
|
559
560
|
conn.commit()
|
|
560
561
|
print(json.dumps({'id': args.id, 'deleted': True}, ensure_ascii=False))
|
|
561
562
|
|