Compare commits

..

5 Commits

Author SHA1 Message Date
john 010e277180 fix(wechat): reserve space for uploaded follow QR in draft body
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 09:43:16 +08:00
john eaba8542a8 feat(wechat): refine daily news draft layout and follow QR block
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 09:40:51 +08:00
john 84b38f397e fix(wechat): add fallback trim profiles for 20k content limit 2026-09-10 09:28:04 +08:00
john 257edb4917 feat(dev-tools): add shadow portal and dsh gateway local E2E scripts
Add events-only Context Runtime shadow portal verification to save LLM
tokens, wire Tool Gateway → dsh headless smoke, and document both flows.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 09:24:57 +08:00
john 6d76618c0b feat(wechat): add news morning draft inline HTML converter
Push daily-news pages to WeChat drafts as inline-styled HTML instead of
full-page long images, with automatic trimming to stay within the 20k limit.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-10 09:23:24 +08:00
12 changed files with 1491 additions and 1770 deletions
-10
View File
@@ -21,16 +21,6 @@ export const CONTEXT_RUNTIME_SHADOW_ENV = Object.freeze({
MEMIND_ZVEC_WORKSPACE_MODE: 'shadow',
});
/** Local active bundle (MCP/ budget / recall / zvec / headroom). Injection stays shadow separately. */
export const CONTEXT_RUNTIME_ACTIVE_ENV = Object.freeze({
MEMIND_HEADROOM_MODE: 'active',
MEMIND_CONTEXT_BUDGET_MODE: 'active',
MEMIND_RECALL_FUSION_MODE: 'active',
MEMIND_MCP_COMPACT_MODE: 'active',
MEMIND_ZVEC_WORKSPACE_MODE: 'active',
HEADROOM_OUTPUT_SHAPER: '0',
});
export function describeContextRuntimeProfile(env = process.env) {
return {
headroom: resolveHeadroomMode(env),
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
{
"schemaVersion": "goose-v149-message-sanitize-v2",
"capturedAt": "2026-09-10T04:19:57.799Z",
"capturedAt": "2026-09-09T13:35:24.843Z",
"v149": {
"root": "/Users/john/Project/tkmind_go-v149",
"version": "1.49.0",
@@ -1,6 +1,6 @@
{
"schemaVersion": "goose-v149-thinking-preservation-v1",
"capturedAt": "2026-09-10T04:31:51.798Z",
"capturedAt": "2026-09-09T13:47:20.080Z",
"worktree": "/Users/john/Project/tkmind_go-v149",
"tests": [
"test_deepseek_thinking_preserved_in_tool_call_message",
+1 -1
View File
@@ -984,7 +984,7 @@ fusion-plan §6.6 本机开发工具:`codebase-memory-mcp` 本地安装验证
审计日期:2026-09-10
分支 HEAD:(见 merge commit
`origin/main` 对应提交:`f3348f45`
`origin/main` 对应提交:(见 merge commit
### 原始用途
+1 -39
View File
@@ -26,23 +26,6 @@ HEADROOM_OUTPUT_SHAPER=0
Bundle 常量见 `context-runtime-profile.mjs``CONTEXT_RUNTIME_SHADOW_ENV`
## 本地 active 配置
五件套可全部 `active``CONTEXT_RUNTIME_ACTIVE_ENV`)。**memory injection 仍保持 shadow**`MEMORY_AGENT_INJECTION_MODE=shadow`,禁止 active injection)。
```bash
node scripts/check-context-runtime-active-local.mjs
# → CONTEXT_RUNTIME_ACTIVE_OK
```
| 开关 | active 行为 |
|------|-------------|
| MCP compact | 压缩大 tool 结果 + `ctx_fetch` |
| context budget | 编排注入按预算 dedupe/drop |
| recall fusion | 融合 recall 结果生效 |
| zvec workspace | code 任务附加 workspace 检索 |
| headroom | LLM 经 proxy(不可达 fail-open |
## 离线事件形状预览
不启动 Portal 也可查看 gateway 将 emit 的 shadow 事件:
@@ -73,16 +56,12 @@ node scripts/check-zvec-workspace-local.mjs
# MCP compactor shadow/active 逻辑
node scripts/check-mcp-compactor-local.mjs
node scripts/check-mcp-compact-active-local.mjs
# codebase-memory-mcp CLI + Memind 索引(见 docs/codebase-memory-mcp-local.md
node scripts/check-codebase-memory-mcp-local.mjs
# dsh CLI + dry-run launch plan(见 docs/dsh-executor-local.md,默认零 LLM
node scripts/check-dsh-executor-local.mjs
# Context Runtime active 五件套(零 LLM
node scripts/check-context-runtime-active-local.mjs
```
## Shadow Portal E2E1 轮,省 token 默认只验事件)
@@ -95,24 +74,7 @@ node scripts/run-context-runtime-shadow-portal-e2e.mjs
# 通过 → CONTEXT_RUNTIME_SHADOW_PORTAL_OK
```
`recall_fusion_resolved` 需要 **agent memory resolve 开启**admin-db `runtimeControl.agentResolveEnabled=true` + `agentInjectionMode=shadow`**不要**开 `active` injection)。缺失脚本 WARN 但不阻断。
本地曾用(仅 dev,不入库):
```bash
# admin-db 写入 shadow resolve(示例 one-shot
node -e "
import { createDbPool } from './db.mjs';
import { createMemoryV2AdminConfigService } from './memory-v2-admin-config.mjs';
const pool = createDbPool();
const svc = createMemoryV2AdminConfigService(pool);
await svc.updateAdminConfig({
runtimeControl: { agentResolveEnabled: true, agentInjectionMode: 'shadow' },
chatIntentRouter: { memoryResolveEnabled: true },
}, { updatedBy: 'local:context-runtime-shadow' });
await pool.end();
"
```
`recall_fusion_resolved` agent memory 关闭时可能缺失脚本 WARN 但不阻断。
## 用户自测清单(有 LLM 配额时)
+2 -2
View File
@@ -49,8 +49,8 @@ GOOSE_V149_ALLOW_REAL_LLM=1 node scripts/run-goosed-v149-phase3.mjs
1. [ ] `upgrade/v1.49-tkmind` worktree 变更已 review`tkmind_go-v149` 独立仓库/worktree
2. [ ] Memind 侧脚本/文档/canary 开关 PR 就绪
3. [x] `node scripts/run-goosed-v149-phase3.mjs` 连续通过(2026-09-10canary=all 下两次 `GOOSE_V149_PHASE3_OK`,日志 `/tmp/v149-phase3-run2.log``/tmp/v149-phase3-run3.log`
4. [x] Memory manifest 无 drift`compare-goose-v149-memory-manifest.mjs` · 2026-09-10 `GOOSE_V149_MEMORY_DRIFT_OK`
3. [ ] `node scripts/run-goosed-v149-phase3.mjs` 连续通过(2026-09-09:失败项 `phase2`/`page-e2e`/`multiturn-provider` 超时;非 goose 不可用
4. [ ] Memory manifest 无 drift`compare-goose-v149-memory-manifest.mjs`
5. [x] 主 Portal 重启后 canary 联调:`check-goosed-v149-portal-smoke.mjs`targets 含 `:18049`);canary 块强制 `H5_PUBLIC_BASE_URL=http://127.0.0.1:8081` 避免 5173 未起时链接失效
6. [ ] **用户明确批准** 后才:`git push`、合并 `main`、任何 103 构建
+3 -4
View File
@@ -3,12 +3,11 @@
# Default includes code-mode (required for TKMind). Use GOOSE_V149_BUILD_MODE=minimal to skip v8.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
GOOSED_ROOT="${GOOSED_V149_ROOT:-/Users/john/Project/tkmind_go-v149}"
LOG="${GOOSE_V149_BUILD_LOG:-/tmp/goosed-v149-build.log}"
MODE="${GOOSE_V149_BUILD_MODE:-codemode}"
bash "${SCRIPT_DIR}/ensure-goose-v149-vendor.sh"
bash "$(dirname "$0")/ensure-goose-v149-vendor.sh"
cd "${GOOSED_ROOT}"
: > "${LOG}"
@@ -17,11 +16,11 @@ echo "[goose-v149-build] mode=${MODE} start $(date -u +%Y-%m-%dT%H:%M:%SZ)" | te
case "${MODE}" in
full)
bash "${SCRIPT_DIR}/ensure-goose-v149-v8.sh" 2>&1 | tee -a "${LOG}"
bash "$(dirname "$0")/ensure-goose-v149-v8.sh" 2>&1 | tee -a "${LOG}"
rustup run 1.96.1 cargo build --release --package goose-cli --bin goose 2>&1 | tee -a "${LOG}"
;;
codemode)
bash "${SCRIPT_DIR}/ensure-goose-v149-v8.sh" 2>&1 | tee -a "${LOG}"
bash "$(dirname "$0")/ensure-goose-v149-v8.sh" 2>&1 | tee -a "${LOG}"
# code-mode without local-inference (smaller/faster than full default).
rustup run 1.96.1 cargo build --release --package goose-cli --bin goose \
--no-default-features \
@@ -1,84 +0,0 @@
#!/usr/bin/env node
/**
* Verify Context Runtime active profile on this machine (no LLM).
*/
import { spawnSync } from 'node:child_process';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import {
CONTEXT_RUNTIME_ACTIVE_ENV,
describeContextRuntimeProfile,
} from '../context-runtime-profile.mjs';
import {
ensureHeadroomProxyRunning,
probeHeadroomProxyReachable,
resolveHeadroomMode,
} from '../memind-headroom-policy.mjs';
const root = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
for (const [key, value] of Object.entries(CONTEXT_RUNTIME_ACTIVE_ENV)) {
process.env[key] = process.env[key] ?? value;
}
const profile = describeContextRuntimeProfile(process.env);
console.log('CONTEXT_RUNTIME_ACTIVE_PROBE:');
console.log(` profile=${JSON.stringify(profile)}`);
const issues = [];
for (const [key, expected] of Object.entries(CONTEXT_RUNTIME_ACTIVE_ENV)) {
if (key === 'HEADROOM_OUTPUT_SHAPER') continue;
const actual = profile[
key === 'MEMIND_HEADROOM_MODE' ? 'headroom'
: key === 'MEMIND_CONTEXT_BUDGET_MODE' ? 'contextBudget'
: key === 'MEMIND_RECALL_FUSION_MODE' ? 'recallFusion'
: key === 'MEMIND_MCP_COMPACT_MODE' ? 'mcpCompact'
: 'zvecWorkspace'
];
if (actual !== expected) {
issues.push(`${key}=${actual} (expected ${expected})`);
}
}
function runScript(name) {
const result = spawnSync(process.execPath, [path.join(root, 'scripts', name)], {
cwd: root,
env: process.env,
encoding: 'utf8',
});
return {
ok: result.status === 0,
stdout: (result.stdout ?? '').trim(),
stderr: (result.stderr ?? '').trim(),
};
}
for (const script of [
'check-mcp-compact-active-local.mjs',
'check-mcp-compactor-local.mjs',
'check-zvec-workspace-local.mjs',
]) {
const result = runScript(script);
console.log(` ${script}=${result.ok ? 'OK' : 'FAIL'}`);
if (!result.ok) {
issues.push(`${script} failed`);
if (result.stderr) console.error(result.stderr.slice(0, 400));
}
}
if (resolveHeadroomMode(process.env) === 'active') {
const boot = await ensureHeadroomProxyRunning({ env: process.env });
const reachable = boot.reachable || await probeHeadroomProxyReachable({ env: process.env });
console.log(` headroom_proxy=${reachable ? 'reachable' : 'unreachable'} started=${boot.started}`);
if (!reachable) {
issues.push('headroom active but proxy unreachable');
}
}
if (issues.length) {
console.error(`CONTEXT_RUNTIME_ACTIVE_FAIL: ${issues.join('; ')}`);
process.exit(1);
}
console.log('CONTEXT_RUNTIME_ACTIVE_OK');
@@ -1,21 +0,0 @@
#!/usr/bin/env node
/**
* Verify MCP compactor active promotion on this machine.
* Requires MEMIND_MCP_COMPACT_MODE=active in the environment (e.g. .env.local).
*/
import {
isMcpCompactActive,
resolveMcpCompactMode,
} from '../mcp-result-compactor.mjs';
const mode = resolveMcpCompactMode(process.env);
console.log('MCP_COMPACT_ACTIVE_PROBE:');
console.log(` mode=${mode}`);
console.log(` active=${isMcpCompactActive(process.env)}`);
if (mode !== 'active' || !isMcpCompactActive(process.env)) {
console.error('MCP_COMPACT_ACTIVE_FAIL: set MEMIND_MCP_COMPACT_MODE=active and restart Portal/MCP');
process.exit(1);
}
console.log('MCP_COMPACT_ACTIVE_OK');
@@ -149,16 +149,11 @@ async function runPortalTurn(pool) {
user_message: {
id: randomUUID(),
role: 'user',
content: [{
type: 'text',
text: process.env.MEMIND_SHADOW_E2E_MESSAGE
?? '你还记得我的偏好吗,一句话回答即可',
}],
content: [{ type: 'text', text: '帮我搜索一下今天上海的天气,简要回答即可' }],
metadata: {
userVisible: true,
agentVisible: true,
displayText: process.env.MEMIND_SHADOW_E2E_DISPLAY
?? 'context runtime shadow memory ping',
displayText: 'context runtime shadow agent ping',
},
},
}),