shennian 0.2.89 → 0.2.90

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.
Files changed (118) hide show
  1. package/dist/assets/wechat-channel/macos/manifest.json +13 -4
  2. package/dist/assets/wechat-channel/macos/shennian-wechat-channel-helper +0 -0
  3. package/dist/bin/shennian.js +1 -1
  4. package/dist/publish-build-manifest.json +548 -0
  5. package/dist/scripts/wechat-rpa-confirmation.mjs +5 -97
  6. package/dist/src/agent-env.js +4 -105
  7. package/dist/src/agents/adapter.js +1 -19
  8. package/dist/src/agents/claude.js +8 -305
  9. package/dist/src/agents/codex-control.js +2 -188
  10. package/dist/src/agents/codex-utils.js +7 -200
  11. package/dist/src/agents/codex.js +15 -916
  12. package/dist/src/agents/command-spec.js +2 -413
  13. package/dist/src/agents/config-status.js +1 -226
  14. package/dist/src/agents/cursor.js +1 -249
  15. package/dist/src/agents/custom.js +4 -271
  16. package/dist/src/agents/detect.js +1 -56
  17. package/dist/src/agents/external-channel-instructions.js +10 -94
  18. package/dist/src/agents/gemini.js +1 -173
  19. package/dist/src/agents/manager.js +13 -157
  20. package/dist/src/agents/model-registry/cache.js +1 -37
  21. package/dist/src/agents/model-registry/discovery.js +2 -187
  22. package/dist/src/agents/model-registry/parsers.js +4 -447
  23. package/dist/src/agents/model-registry/runner.js +1 -30
  24. package/dist/src/agents/model-registry/service.js +1 -78
  25. package/dist/src/agents/model-registry/types.js +1 -8
  26. package/dist/src/agents/model-registry.js +1 -18
  27. package/dist/src/agents/openclaw.js +2 -275
  28. package/dist/src/agents/opencode.js +1 -231
  29. package/dist/src/agents/pi-context.js +12 -217
  30. package/dist/src/agents/pi.js +14 -723
  31. package/dist/src/agents/platform-instructions.js +9 -54
  32. package/dist/src/channels/base.js +1 -3
  33. package/dist/src/channels/registry.js +1 -30
  34. package/dist/src/channels/reply-split.js +10 -89
  35. package/dist/src/channels/runtime.js +5 -564
  36. package/dist/src/channels/secret-registry.js +1 -46
  37. package/dist/src/channels/websocket.js +8 -378
  38. package/dist/src/channels/wechat-channel/anchor.js +1 -65
  39. package/dist/src/channels/wechat-channel/client.js +1 -96
  40. package/dist/src/channels/wechat-channel/cooldown.js +1 -38
  41. package/dist/src/channels/wechat-channel/fingerprint.js +1 -71
  42. package/dist/src/channels/wechat-channel/helper-assets.d.ts +10 -1
  43. package/dist/src/channels/wechat-channel/helper-assets.js +1 -68
  44. package/dist/src/channels/wechat-channel/helper-client.js +3 -149
  45. package/dist/src/channels/wechat-channel/helper-protocol.d.ts +1 -1
  46. package/dist/src/channels/wechat-channel/helper-protocol.js +1 -115
  47. package/dist/src/channels/wechat-channel/index.d.ts +1 -0
  48. package/dist/src/channels/wechat-channel/index.js +1 -19
  49. package/dist/src/channels/wechat-channel/ledger.js +1 -54
  50. package/dist/src/channels/wechat-channel/media-resolver.js +1 -181
  51. package/dist/src/channels/wechat-channel/message-key.js +1 -105
  52. package/dist/src/channels/wechat-channel/observer.js +1 -118
  53. package/dist/src/channels/wechat-channel/outbound-ledger.d.ts +3 -0
  54. package/dist/src/channels/wechat-channel/outbound-ledger.js +2 -112
  55. package/dist/src/channels/wechat-channel/outbound-sender.d.ts +26 -0
  56. package/dist/src/channels/wechat-channel/outbound-sender.js +1 -0
  57. package/dist/src/channels/wechat-channel/preflight.js +1 -48
  58. package/dist/src/channels/wechat-channel/runner.js +1 -84
  59. package/dist/src/channels/wechat-channel/runtime.js +1 -66
  60. package/dist/src/channels/wechat-channel/scheduler.d.ts +5 -0
  61. package/dist/src/channels/wechat-channel/scheduler.js +1 -152
  62. package/dist/src/channels/wechat-rpa/macos-flow.js +1 -96
  63. package/dist/src/channels/wechat-rpa/macos.js +6 -48
  64. package/dist/src/channels/wechat-rpa/normalizer.js +7 -127
  65. package/dist/src/channels/wechat-rpa.js +6 -1028
  66. package/dist/src/channels/wecom.js +4 -357
  67. package/dist/src/commands/agent.js +6 -131
  68. package/dist/src/commands/daemon-windows.js +8 -48
  69. package/dist/src/commands/daemon.js +19 -1013
  70. package/dist/src/commands/external-attachments.js +1 -51
  71. package/dist/src/commands/external.js +1 -137
  72. package/dist/src/commands/manager.js +2 -391
  73. package/dist/src/commands/pair-qr.js +1 -6
  74. package/dist/src/commands/pair.js +9 -287
  75. package/dist/src/commands/tools.js +1 -34
  76. package/dist/src/commands/upgrade.js +1 -198
  77. package/dist/src/config/index.js +1 -35
  78. package/dist/src/daemon-log.js +6 -58
  79. package/dist/src/env-path.js +1 -64
  80. package/dist/src/fs/boundary.js +1 -126
  81. package/dist/src/fs/handler.js +1 -130
  82. package/dist/src/fs/security.js +1 -32
  83. package/dist/src/fs/text-decoder.js +1 -110
  84. package/dist/src/index.js +2 -404
  85. package/dist/src/log-reporter.js +1 -16
  86. package/dist/src/manager/prompt.js +29 -34
  87. package/dist/src/manager/registry.js +2 -269
  88. package/dist/src/manager/runtime.js +19 -1007
  89. package/dist/src/native-fusion/config.js +1 -5
  90. package/dist/src/native-fusion/opencode-parser.js +3 -123
  91. package/dist/src/native-fusion/parser-common.js +8 -264
  92. package/dist/src/native-fusion/parsers.js +8 -729
  93. package/dist/src/native-fusion/service.js +2 -225
  94. package/dist/src/native-fusion/state.js +1 -22
  95. package/dist/src/native-fusion/types.js +1 -1
  96. package/dist/src/region.js +1 -88
  97. package/dist/src/relay/client.js +1 -343
  98. package/dist/src/session/archive-zip.js +1 -220
  99. package/dist/src/session/handlers/agent-config.js +1 -150
  100. package/dist/src/session/handlers/agents.js +1 -55
  101. package/dist/src/session/handlers/chat.js +2 -751
  102. package/dist/src/session/handlers/control.js +1 -55
  103. package/dist/src/session/handlers/fs.js +1 -783
  104. package/dist/src/session/handlers/session-refresh.js +1 -47
  105. package/dist/src/session/handlers/skills.js +1 -121
  106. package/dist/src/session/handlers/title.js +1 -60
  107. package/dist/src/session/handlers/tool-detail.js +1 -218
  108. package/dist/src/session/manager.js +1 -319
  109. package/dist/src/session/projection.js +1 -54
  110. package/dist/src/session/queue.js +4 -317
  111. package/dist/src/session/remote-attachments.js +1 -72
  112. package/dist/src/session/store.js +3 -109
  113. package/dist/src/session/types.js +1 -4
  114. package/dist/src/skills/registry.js +15 -148
  115. package/dist/src/skills/setup.js +1 -101
  116. package/dist/src/tools/markdown-to-pdf.js +10 -346
  117. package/dist/src/upgrade/engine.js +3 -347
  118. package/package.json +3 -2
@@ -1,217 +1,12 @@
1
- // @arch docs/architecture/cli/agent-adapters.md#pi-agent-上下文管理
2
- // @test src/__tests__/pi-context.test.ts
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { resolveShennianPath } from '../config/index.js';
6
- export const PI_DEFAULT_MODEL_ID = 'qwen3.6-plus';
7
- export function buildShellCommandSpec(command, platform = process.platform) {
8
- if (platform === 'win32') {
9
- return {
10
- file: 'powershell.exe',
11
- args: ['-NoLogo', '-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-Command', command],
12
- shell: 'powershell',
13
- };
14
- }
15
- return {
16
- file: 'bash',
17
- args: ['-c', command],
18
- shell: 'bash',
19
- };
20
- }
21
- export function createPiModel(modelId = PI_DEFAULT_MODEL_ID, overrides = {}) {
22
- return {
23
- id: modelId,
24
- name: modelId,
25
- api: 'openai-completions',
26
- provider: overrides.provider ?? 'shennian-proxy',
27
- baseUrl: overrides.baseUrl ?? '',
28
- reasoning: false,
29
- input: ['text', 'image'],
30
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
31
- contextWindow: 128000,
32
- maxTokens: 8192,
33
- ...(overrides.compat ? { compat: overrides.compat } : {}),
34
- };
35
- }
36
- export const SYSTEM_PROMPT = `你是神念内置编程助手,运行在用户本地机器上。
37
- 你可以读写文件、执行 shell 命令、帮助用户完成编程和系统管理任务。
38
- 工作目录已设置,操作文件时使用相对路径或绝对路径均可。
39
- 当前 shell 会随操作系统选择:Windows 使用 PowerShell,macOS/Linux 使用 bash。Windows 下需要真实 curl 时使用 curl.exe,避免 PowerShell 的 curl 别名。
40
- 保持回复简洁、准确,中文回复。`;
41
- const AGENTS_MD_MAX_CHARS = 24_000;
42
- export function findAgentsMd(startDir) {
43
- let current = path.resolve(startDir || process.cwd());
44
- try {
45
- const stat = fs.existsSync(current) ? fs.statSync(current) : null;
46
- if (stat && !stat.isDirectory())
47
- current = path.dirname(current);
48
- }
49
- catch {
50
- // Fall back to the resolved path.
51
- }
52
- while (true) {
53
- const candidate = path.join(current, 'AGENTS.md');
54
- if (fs.existsSync(candidate))
55
- return candidate;
56
- const parent = path.dirname(current);
57
- if (parent === current)
58
- return null;
59
- current = parent;
60
- }
61
- }
62
- export function loadAgentsMdInstructions(workDir) {
63
- const filePath = findAgentsMd(workDir);
64
- if (!filePath)
65
- return null;
66
- try {
67
- const content = fs.readFileSync(filePath, 'utf-8').trim();
68
- if (!content)
69
- return null;
70
- const truncated = content.length > AGENTS_MD_MAX_CHARS
71
- ? `${content.slice(0, AGENTS_MD_MAX_CHARS)}\n\n...(AGENTS.md 已截断)`
72
- : content;
73
- return `# AGENTS.md instructions for ${path.dirname(filePath)}\n\n${truncated}`;
74
- }
75
- catch {
76
- return null;
77
- }
78
- }
79
- // ── Context compression ──────────────────────────────────────────────────────
80
- export const CONTEXT_TOKEN_THRESHOLD = 90_000;
81
- export const KEEP_RECENT_MESSAGES = 6;
82
- const SESSIONS_DIR = resolveShennianPath('sessions');
83
- export const SUMMARY_FILENAME = 'summary.json';
84
- export const SNAPSHOT_FILENAME = 'snapshot.json';
85
- export const MESSAGES_FILENAME = 'messages.jsonl';
86
- export const LEGACY_SUMMARY_FILENAME = 'pi-context.json';
87
- export function estimateTokens(messages) {
88
- let chars = 0;
89
- for (const msg of messages)
90
- chars += JSON.stringify(msg).length;
91
- return Math.ceil(chars / 3);
92
- }
93
- export function messagesToText(messages) {
94
- const lines = [];
95
- for (const msg of messages) {
96
- const m = msg;
97
- const role = String(m.role ?? 'unknown');
98
- if (!Array.isArray(m.content))
99
- continue;
100
- for (const c of m.content) {
101
- if (c.type === 'text' && typeof c.text === 'string') {
102
- lines.push(`[${role}] ${c.text.slice(0, 500)}`);
103
- }
104
- else if (c.type === 'toolCall') {
105
- const name = typeof c.name === 'string' ? c.name : typeof c.toolName === 'string' ? c.toolName : 'tool';
106
- const args = c.arguments ?? c.args ?? {};
107
- lines.push(`[${role}] tool:${name}(${JSON.stringify(args).slice(0, 200)})`);
108
- }
109
- }
110
- }
111
- return lines.join('\n');
112
- }
113
- export function cloneMessages(messages) {
114
- return JSON.parse(JSON.stringify(messages));
115
- }
116
- export function getSessionDir(sessionId) {
117
- return path.join(SESSIONS_DIR, sessionId);
118
- }
119
- function getMessageContentText(content) {
120
- if (!content || typeof content !== 'object')
121
- return null;
122
- const chunk = content;
123
- if (chunk.type === 'text' && typeof chunk.text === 'string')
124
- return chunk.text;
125
- if (chunk.type === 'thinking' && typeof chunk.thinking === 'string')
126
- return `[thinking] ${chunk.thinking}`;
127
- if (chunk.type === 'toolCall') {
128
- const name = typeof chunk.name === 'string'
129
- ? chunk.name
130
- : typeof chunk.toolName === 'string'
131
- ? chunk.toolName
132
- : 'tool';
133
- const args = chunk.arguments ?? chunk.args ?? {};
134
- return `[toolCall] ${name}(${JSON.stringify(args).slice(0, 300)})`;
135
- }
136
- if (chunk.type === 'image' && typeof chunk.mimeType === 'string') {
137
- return `[image] ${chunk.mimeType}`;
138
- }
139
- return null;
140
- }
141
- export function buildRollingSummary(cachedSummary, messages) {
142
- const recentLines = [];
143
- for (const msg of messages) {
144
- const role = String(msg.role ?? 'unknown');
145
- const content = Array.isArray(msg.content)
146
- ? msg.content
147
- : [];
148
- for (const chunk of content) {
149
- const text = getMessageContentText(chunk);
150
- if (text)
151
- recentLines.push(`[${role}] ${text}`);
152
- }
153
- }
154
- const recent = recentLines.slice(-8).join('\n').trim();
155
- const summary = recent || cachedSummary?.trim() || null;
156
- if (!summary)
157
- return null;
158
- return summary.length > 2000 ? summary.slice(summary.length - 2000) : summary;
159
- }
160
- export function longestCommonPrefixLength(left, right) {
161
- const max = Math.min(left.length, right.length);
162
- for (let i = 0; i < max; i++) {
163
- if (JSON.stringify(left[i]) !== JSON.stringify(right[i]))
164
- return i;
165
- }
166
- return max;
167
- }
168
- export async function requestProxySummary(proxyUrl, authToken, prompt) {
169
- const response = await fetch(`${proxyUrl}/api/stream`, {
170
- method: 'POST',
171
- headers: {
172
- 'Content-Type': 'application/json',
173
- Authorization: `Bearer ${authToken}`,
174
- },
175
- body: JSON.stringify({
176
- model: createPiModel('qwen-plus'),
177
- context: {
178
- messages: [
179
- {
180
- role: 'user',
181
- content: [{ type: 'text', text: prompt }],
182
- },
183
- ],
184
- },
185
- options: {
186
- temperature: 0.3,
187
- maxTokens: 500,
188
- },
189
- }),
190
- });
191
- if (!response.ok || !response.body)
192
- return null;
193
- const reader = response.body.getReader();
194
- const decoder = new TextDecoder();
195
- const parts = [];
196
- let buffer = '';
197
- while (true) {
198
- const { done, value } = await reader.read();
199
- if (done)
200
- break;
201
- buffer += decoder.decode(value, { stream: true });
202
- const lines = buffer.split('\n');
203
- buffer = lines.pop() ?? '';
204
- for (const line of lines) {
205
- if (!line.startsWith('data: '))
206
- continue;
207
- const raw = line.slice(6).trim();
208
- if (!raw)
209
- continue;
210
- const event = JSON.parse(raw);
211
- if (event.type === 'text_delta' && typeof event.delta === 'string') {
212
- parts.push(event.delta);
213
- }
214
- }
215
- }
216
- return parts.join('').trim() || null;
217
- }
1
+ import u from"node:fs";import l from"node:path";import{resolveShennianPath as x}from"../config/index.js";const S="qwen3.6-plus";function w(e,t=process.platform){return t==="win32"?{file:"powershell.exe",args:["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-Command",e],shell:"powershell"}:{file:"bash",args:["-c",e],shell:"bash"}}function d(e=S,t={}){return{id:e,name:e,api:"openai-completions",provider:t.provider??"shennian-proxy",baseUrl:t.baseUrl??"",reasoning:!1,input:["text","image"],cost:{input:0,output:0,cacheRead:0,cacheWrite:0},contextWindow:128e3,maxTokens:8192,...t.compat?{compat:t.compat}:{}}}const O=`\u4F60\u662F\u795E\u5FF5\u5185\u7F6E\u7F16\u7A0B\u52A9\u624B\uFF0C\u8FD0\u884C\u5728\u7528\u6237\u672C\u5730\u673A\u5668\u4E0A\u3002
2
+ \u4F60\u53EF\u4EE5\u8BFB\u5199\u6587\u4EF6\u3001\u6267\u884C shell \u547D\u4EE4\u3001\u5E2E\u52A9\u7528\u6237\u5B8C\u6210\u7F16\u7A0B\u548C\u7CFB\u7EDF\u7BA1\u7406\u4EFB\u52A1\u3002
3
+ \u5DE5\u4F5C\u76EE\u5F55\u5DF2\u8BBE\u7F6E\uFF0C\u64CD\u4F5C\u6587\u4EF6\u65F6\u4F7F\u7528\u76F8\u5BF9\u8DEF\u5F84\u6216\u7EDD\u5BF9\u8DEF\u5F84\u5747\u53EF\u3002
4
+ \u5F53\u524D shell \u4F1A\u968F\u64CD\u4F5C\u7CFB\u7EDF\u9009\u62E9\uFF1AWindows \u4F7F\u7528 PowerShell\uFF0CmacOS/Linux \u4F7F\u7528 bash\u3002Windows \u4E0B\u9700\u8981\u771F\u5B9E curl \u65F6\u4F7F\u7528 curl.exe\uFF0C\u907F\u514D PowerShell \u7684 curl \u522B\u540D\u3002
5
+ \u4FDD\u6301\u56DE\u590D\u7B80\u6D01\u3001\u51C6\u786E\uFF0C\u4E2D\u6587\u56DE\u590D\u3002`,h=24e3;function E(e){let t=l.resolve(e||process.cwd());try{const n=u.existsSync(t)?u.statSync(t):null;n&&!n.isDirectory()&&(t=l.dirname(t))}catch{}for(;;){const n=l.join(t,"AGENTS.md");if(u.existsSync(n))return n;const o=l.dirname(t);if(o===t)return null;t=o}}function $(e){const t=E(e);if(!t)return null;try{const n=u.readFileSync(t,"utf-8").trim();if(!n)return null;const o=n.length>h?`${n.slice(0,h)}
6
+
7
+ ...\uFF08AGENTS.md \u5DF2\u622A\u65AD\uFF09`:n;return`# AGENTS.md instructions for ${l.dirname(t)}
8
+
9
+ ${o}`}catch{return null}}const P=9e4,b=6,N=x("sessions"),k="summary.json",C="snapshot.json",L="messages.jsonl",j="pi-context.json";function R(e){let t=0;for(const n of e)t+=JSON.stringify(n).length;return Math.ceil(t/3)}function D(e){const t=[];for(const n of e){const o=n,s=String(o.role??"unknown");if(Array.isArray(o.content)){for(const r of o.content)if(r.type==="text"&&typeof r.text=="string")t.push(`[${s}] ${r.text.slice(0,500)}`);else if(r.type==="toolCall"){const c=typeof r.name=="string"?r.name:typeof r.toolName=="string"?r.toolName:"tool",i=r.arguments??r.args??{};t.push(`[${s}] tool:${c}(${JSON.stringify(i).slice(0,200)})`)}}}return t.join(`
10
+ `)}function I(e){return JSON.parse(JSON.stringify(e))}function J(e){return l.join(N,e)}function A(e){if(!e||typeof e!="object")return null;const t=e;if(t.type==="text"&&typeof t.text=="string")return t.text;if(t.type==="thinking"&&typeof t.thinking=="string")return`[thinking] ${t.thinking}`;if(t.type==="toolCall"){const n=typeof t.name=="string"?t.name:typeof t.toolName=="string"?t.toolName:"tool",o=t.arguments??t.args??{};return`[toolCall] ${n}(${JSON.stringify(o).slice(0,300)})`}return t.type==="image"&&typeof t.mimeType=="string"?`[image] ${t.mimeType}`:null}function G(e,t){const n=[];for(const r of t){const c=String(r.role??"unknown"),i=Array.isArray(r.content)?r.content:[];for(const p of i){const a=A(p);a&&n.push(`[${c}] ${a}`)}}const s=n.slice(-8).join(`
11
+ `).trim()||e?.trim()||null;return s?s.length>2e3?s.slice(s.length-2e3):s:null}function F(e,t){const n=Math.min(e.length,t.length);for(let o=0;o<n;o++)if(JSON.stringify(e[o])!==JSON.stringify(t[o]))return o;return n}async function U(e,t,n){const o=await fetch(`${e}/api/stream`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:d("qwen-plus"),context:{messages:[{role:"user",content:[{type:"text",text:n}]}]},options:{temperature:.3,maxTokens:500}})});if(!o.ok||!o.body)return null;const s=o.body.getReader(),r=new TextDecoder,c=[];let i="";for(;;){const{done:p,value:a}=await s.read();if(p)break;i+=r.decode(a,{stream:!0});const m=i.split(`
12
+ `);i=m.pop()??"";for(const g of m){if(!g.startsWith("data: "))continue;const y=g.slice(6).trim();if(!y)continue;const f=JSON.parse(y);f.type==="text_delta"&&typeof f.delta=="string"&&c.push(f.delta)}}return c.join("").trim()||null}export{P as CONTEXT_TOKEN_THRESHOLD,b as KEEP_RECENT_MESSAGES,j as LEGACY_SUMMARY_FILENAME,L as MESSAGES_FILENAME,S as PI_DEFAULT_MODEL_ID,C as SNAPSHOT_FILENAME,k as SUMMARY_FILENAME,O as SYSTEM_PROMPT,G as buildRollingSummary,w as buildShellCommandSpec,I as cloneMessages,d as createPiModel,R as estimateTokens,E as findAgentsMd,J as getSessionDir,$ as loadAgentsMdInstructions,F as longestCommonPrefixLength,D as messagesToText,U as requestProxySummary};