sintbot 1.0.16 → 1.3.0
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/CHANGELOG.en.json +99 -0
- package/CHANGELOG.json +99 -0
- package/README.md +20 -158
- package/README.zh-CN.md +20 -166
- package/THIRD-PARTY-NOTICES.md +394 -0
- package/bin/sintbot-v2.js +363 -0
- package/docs/AI-ASSISTED-INSTALL.md +11 -35
- package/docs/install.md +61 -167
- package/docs/zh-CN/AI-ASSISTED-INSTALL.md +11 -35
- package/docs/zh-CN/install.md +61 -165
- package/install.sh +84 -0
- package/package.json +73 -37
- package/src/agent/claudecode.js +149 -108
- package/src/agent/codexapp.js +458 -0
- package/src/agent/codexcode.js +210 -107
- package/src/agent/errtag.js +34 -0
- package/src/agent/privatecore.js +790 -0
- package/src/agent/privatecore.wasm +0 -0
- package/src/agent/runner.js +10 -8
- package/src/agent/winexec.js +35 -5
- package/src/c2install.js +117 -0
- package/src/config.js +2 -1
- package/src/core/c2cardeffectbridge.js +51 -0
- package/src/core/c2cardterminalpath.js +216 -0
- package/src/core/c2durableingress.js +148 -0
- package/src/core/c2durablejournal.js +1560 -0
- package/src/core/c2durableruntime.js +2361 -0
- package/src/core/c2eventidentity.js +90 -0
- package/src/core/c2globalfault.js +401 -0
- package/src/core/c2localeffectexecutor.js +193 -0
- package/src/core/c2payloadhandles.js +333 -0
- package/src/core/c2persistrelation.js +179 -0
- package/src/core/c2persiststate.js +342 -0
- package/src/core/c2platformrecoverysender.js +76 -0
- package/src/core/c2recoverygate.js +385 -0
- package/src/core/c2runnerinput.js +63 -0
- package/src/core/c2servicestartgate.js +103 -0
- package/src/core/c2sessionbridge.js +72 -0
- package/src/core/c2sourcequarantine.js +30 -0
- package/src/core/c2startuprecovery.js +105 -0
- package/src/core/c2successorbridge.js +151 -0
- package/src/core/c2terminaleffectbridge.js +154 -0
- package/src/core/c2terminalprune.js +108 -0
- package/src/core/c2turnprojection.js +177 -0
- package/src/core/enginecheckpoint.js +211 -0
- package/src/core/engineeffectcursor.js +394 -0
- package/src/core/enginestepcoordinator.js +183 -0
- package/src/core/store.js +52 -8
- package/src/core/v2engine.js +1469 -0
- package/src/platform/feishu.js +324 -67
- package/src/plugins.js +1 -9
- package/assets/design-styles/acid-pop.md +0 -155
- package/assets/design-styles/archive-index.md +0 -161
- package/assets/design-styles/art-deco.md +0 -164
- package/assets/design-styles/cinematic-noir.md +0 -178
- package/assets/design-styles/editorial.md +0 -121
- package/assets/design-styles/extra/README.md +0 -23
- package/assets/design-styles/extra/constructivism.md +0 -146
- package/assets/design-styles/extra/neo-brutalism.md +0 -175
- package/assets/design-styles/extra/new-wave.md +0 -166
- package/assets/design-styles/extra/nordic-material.md +0 -162
- package/assets/design-styles/extra/paris-couture.md +0 -162
- package/assets/design-styles/extra/tropical-modern.md +0 -168
- package/assets/design-styles/extra/ulm-functional.md +0 -182
- package/assets/design-styles/extra/wa-shikimen.md +0 -160
- package/assets/design-styles/extra/y2k-chrome.md +0 -172
- package/assets/design-styles/geometric-pop.md +0 -122
- package/assets/design-styles/hand-drawn.md +0 -117
- package/assets/design-styles/islamic-geometry.md +0 -155
- package/assets/design-styles/liquid-glass.md +0 -183
- package/assets/design-styles/neo-chinese.md +0 -136
- package/assets/design-styles/precision-mono.md +0 -156
- package/assets/design-styles/quiet-luxury.md +0 -163
- package/assets/design-styles/riso-print.md +0 -116
- package/assets/design-styles/soft-friendly.md +0 -174
- package/assets/design-styles/swiss-grid.md +0 -156
- package/assets/design-styles/tech-dark.md +0 -182
- package/assets/favicon.svg +0 -6
- package/assets/logo.svg +0 -24
- package/bin/sbot.js +0 -4716
- package/docs/slack-app-manifest.yaml +0 -104
- package/sbot.config.example.json +0 -235
- package/src/agent/askonce.js +0 -76
- package/src/agent/claudemodels.js +0 -60
- package/src/agent/claudestatus.js +0 -74
- package/src/agent/claudeusage.js +0 -200
- package/src/agent/codexstatus.js +0 -181
- package/src/agent/imagen.js +0 -458
- package/src/agent/quotaerr.js +0 -44
- package/src/agent/transienterr.js +0 -32
- package/src/cdp.js +0 -254
- package/src/cli-secret.js +0 -36
- package/src/clilang.js +0 -31
- package/src/core/cron.js +0 -182
- package/src/core/cronfire.js +0 -120
- package/src/core/cronrun.js +0 -116
- package/src/core/engine.js +0 -2758
- package/src/core/interfaces.js +0 -114
- package/src/core/issues.js +0 -185
- package/src/core/ledger.js +0 -30
- package/src/core/opsalert.js +0 -214
- package/src/core/pending.js +0 -123
- package/src/core/proxy.js +0 -424
- package/src/core/quotaalert.js +0 -79
- package/src/core/quotaerr.js +0 -55
- package/src/core/scheduler.js +0 -59
- package/src/design.js +0 -5161
- package/src/gitrepo.js +0 -150
- package/src/health.js +0 -353
- package/src/installdeps.js +0 -72
- package/src/leftover.js +0 -174
- package/src/platform/boardnotice.js +0 -77
- package/src/platform/boardops.js +0 -36
- package/src/platform/boardwatch.js +0 -447
- package/src/platform/cli.js +0 -45
- package/src/platform/slack.js +0 -1289
- package/src/platform/takeovercard.js +0 -37
- package/src/platform/wecom.js +0 -938
- package/src/platform/wecomcli.js +0 -128
- package/src/platform/wecomgate.js +0 -108
- package/src/platform/wecomname.js +0 -43
- package/src/platform/wecompoll.js +0 -241
- package/src/preview.js +0 -581
- package/src/projectmemory.js +0 -175
- package/src/service.js +0 -317
- package/src/ui/auth.js +0 -31
- package/src/ui/browser.html +0 -392
- package/src/ui/browserroutes.js +0 -234
- package/src/ui/console.html +0 -5526
- package/src/ui/dashboard.js +0 -168
- package/src/ui/feishulogin.js +0 -136
- package/src/ui/server.js +0 -2314
- package/src/ui/sessions.js +0 -78
- package/src/ui/takeover.js +0 -108
- package/src/updater.js +0 -243
- package/src/upgrade.js +0 -35
- package/src/usage.js +0 -144
|
@@ -0,0 +1,790 @@
|
|
|
1
|
+
// ABI v34 adapter for the private binary decision core. Manifest assembly still stays in JS.
|
|
2
|
+
const fs = require('node:fs')
|
|
3
|
+
const path = require('node:path')
|
|
4
|
+
const { createHash } = require('node:crypto')
|
|
5
|
+
|
|
6
|
+
const EXPECTED_SHA256 = 'c9b89e6f748c94415aa853be6ccaef35030f754b8898cb81b6cc0d02cf85e222'
|
|
7
|
+
let bytes
|
|
8
|
+
try {
|
|
9
|
+
bytes = fs.readFileSync(path.join(__dirname, 'privatecore.wasm'))
|
|
10
|
+
} catch (cause) {
|
|
11
|
+
throw new Error('SintBot binary core is missing or unreadable; reinstall the matching package', { cause })
|
|
12
|
+
}
|
|
13
|
+
if (createHash('sha256').update(bytes).digest('hex') !== EXPECTED_SHA256) {
|
|
14
|
+
throw new Error('SintBot binary core does not match its loader; reinstall the matching package')
|
|
15
|
+
}
|
|
16
|
+
let core
|
|
17
|
+
let compiled
|
|
18
|
+
function boot() {
|
|
19
|
+
compiled = compiled || new WebAssembly.Module(bytes)
|
|
20
|
+
core = new WebAssembly.Instance(compiled).exports
|
|
21
|
+
}
|
|
22
|
+
let engineStepPoisoned = false
|
|
23
|
+
function resetBinaryCore() { boot(); engineStepPoisoned = false }
|
|
24
|
+
try {
|
|
25
|
+
boot()
|
|
26
|
+
} catch (cause) {
|
|
27
|
+
throw new Error('SintBot binary core cannot start on this runtime', { cause })
|
|
28
|
+
}
|
|
29
|
+
if (core.abi_version() !== 34) throw new Error('SintBot binary core ABI mismatch')
|
|
30
|
+
const encoder = new TextEncoder()
|
|
31
|
+
const decoder = new TextDecoder('utf-8', { fatal: true })
|
|
32
|
+
|
|
33
|
+
function callText(name, text, ...args) {
|
|
34
|
+
const input = encoder.encode(String(text || ''))
|
|
35
|
+
const ptr = core.alloc(input.length)
|
|
36
|
+
try {
|
|
37
|
+
new Uint8Array(core.memory.buffer).set(input, ptr)
|
|
38
|
+
return core[name](ptr, input.length, ...args)
|
|
39
|
+
} finally {
|
|
40
|
+
new Uint8Array(core.memory.buffer).fill(0, ptr, ptr + input.length)
|
|
41
|
+
core.dealloc(ptr, input.length)
|
|
42
|
+
input.fill(0)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const HUMAN = {
|
|
47
|
+
overload: '模型这会儿排不上队(服务端过载)',
|
|
48
|
+
ratelimit: '请求太密,被暂时限流了',
|
|
49
|
+
gateway: '模型服务暂时不可用',
|
|
50
|
+
network: '暂时连不上模型服务(网络故障)',
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function classifyError(text) {
|
|
54
|
+
const code = callText('classify_error', text)
|
|
55
|
+
if (code >= 1 && code <= 4) return {
|
|
56
|
+
quota: { kind: code === 4 ? 'account' : 'quota', window: code === 1 ? 'weekly' : code === 2 ? 'session' : null },
|
|
57
|
+
}
|
|
58
|
+
if (code === 9) return { sessionMissing: true }
|
|
59
|
+
const kind = { 5: 'overload', 6: 'ratelimit', 7: 'gateway', 8: 'network' }[code]
|
|
60
|
+
if (kind) return { transient: { kind, human: HUMAN[kind] } }
|
|
61
|
+
if (code !== 0) throw new Error(`SintBot binary core returned unknown result ${code}`)
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function routeBackend(runner, codexApp, codexSteer, codexProjectDocFallback) {
|
|
66
|
+
const flags = (codexApp ? 1 : 0) | (codexSteer ? 2 : 0) | (codexProjectDocFallback ? 4 : 0)
|
|
67
|
+
const code = callText('route_backend', runner, flags)
|
|
68
|
+
const route = { 0: 'claude', 1: 'codex-exec', 2: 'codex-app' }[code]
|
|
69
|
+
if (!route) throw new Error(`SintBot binary core returned unknown backend ${code}`)
|
|
70
|
+
return route
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function sandboxTier(permissionMode) {
|
|
74
|
+
const code = callText('sandbox_tier', permissionMode)
|
|
75
|
+
if (code === 0) return 'read-only'
|
|
76
|
+
if (code === 1) return 'danger-full-access'
|
|
77
|
+
throw new Error(`SintBot binary core returned unknown sandbox tier ${code}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function appErrorOverride(status, hasKind, hasQuota, sessionMissing, hasTransient) {
|
|
81
|
+
const code = core.app_error_override(Number(status), Number(!!hasKind), Number(!!hasQuota), Number(!!sessionMissing), Number(!!hasTransient))
|
|
82
|
+
if (code === 0) return null
|
|
83
|
+
if (code === 1) return 'account'
|
|
84
|
+
if (code === 2) return 'network'
|
|
85
|
+
if (code === 3) return 'gateway'
|
|
86
|
+
throw new Error(`SintBot binary core returned unknown App error decision ${code}`)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function codexBuildPrompt(prompt, appendSystemPrompt, isResume) {
|
|
90
|
+
const promptBytes = encoder.encode(prompt)
|
|
91
|
+
const appendixBytes = encoder.encode(appendSystemPrompt || '')
|
|
92
|
+
const promptPtr = core.alloc(promptBytes.length)
|
|
93
|
+
let appendixPtr = 0, outputPtr = 0, outputSize = 0
|
|
94
|
+
try {
|
|
95
|
+
appendixPtr = core.alloc(appendixBytes.length)
|
|
96
|
+
new Uint8Array(core.memory.buffer).set(promptBytes, promptPtr)
|
|
97
|
+
new Uint8Array(core.memory.buffer).set(appendixBytes, appendixPtr)
|
|
98
|
+
outputPtr = core.codex_build_prompt(promptPtr, promptBytes.length, appendixPtr, appendixBytes.length, Number(!!isResume))
|
|
99
|
+
if (!outputPtr) throw new Error('SintBot binary core could not build Codex prompt')
|
|
100
|
+
const buffer = core.memory.buffer
|
|
101
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned an invalid Codex prompt')
|
|
102
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
103
|
+
outputSize = length + 4
|
|
104
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned an invalid Codex prompt')
|
|
105
|
+
return decoder.decode(new Uint8Array(buffer, outputPtr + 4, length))
|
|
106
|
+
} finally {
|
|
107
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
108
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
109
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
110
|
+
memory.fill(0, promptPtr, promptPtr + promptBytes.length)
|
|
111
|
+
core.dealloc(promptPtr, promptBytes.length)
|
|
112
|
+
if (appendixPtr) {
|
|
113
|
+
memory.fill(0, appendixPtr, appendixPtr + appendixBytes.length)
|
|
114
|
+
core.dealloc(appendixPtr, appendixBytes.length)
|
|
115
|
+
}
|
|
116
|
+
promptBytes.fill(0)
|
|
117
|
+
appendixBytes.fill(0)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function codexBuildArgs(options) {
|
|
122
|
+
const input = encoder.encode(JSON.stringify(options))
|
|
123
|
+
const inputPtr = core.alloc(input.length)
|
|
124
|
+
let outputPtr = 0, outputSize = 0
|
|
125
|
+
try {
|
|
126
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
127
|
+
outputPtr = core.codex_build_args(inputPtr, input.length)
|
|
128
|
+
if (!outputPtr) throw new Error('SintBot binary core could not build Codex arguments')
|
|
129
|
+
const buffer = core.memory.buffer
|
|
130
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Codex arguments')
|
|
131
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
132
|
+
outputSize = length + 4
|
|
133
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Codex arguments')
|
|
134
|
+
const args = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
135
|
+
if (!Array.isArray(args) || !args.every((arg) => typeof arg === 'string')) {
|
|
136
|
+
throw new Error('SintBot binary core returned invalid Codex arguments')
|
|
137
|
+
}
|
|
138
|
+
return args
|
|
139
|
+
} finally {
|
|
140
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
141
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
142
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
143
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
144
|
+
core.dealloc(inputPtr, input.length)
|
|
145
|
+
input.fill(0)
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function appUsageFromTotal(total) {
|
|
150
|
+
const input = encoder.encode(JSON.stringify(total ?? null))
|
|
151
|
+
const inputPtr = core.alloc(input.length)
|
|
152
|
+
let outputPtr = 0, outputSize = 0
|
|
153
|
+
try {
|
|
154
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
155
|
+
outputPtr = core.app_usage_from_total(inputPtr, input.length)
|
|
156
|
+
if (!outputPtr) throw new Error('SintBot binary core could not map App usage')
|
|
157
|
+
const buffer = core.memory.buffer
|
|
158
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid App usage')
|
|
159
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
160
|
+
outputSize = length + 4
|
|
161
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid App usage')
|
|
162
|
+
const usage = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
163
|
+
if (usage !== null && (typeof usage !== 'object' || Array.isArray(usage))) {
|
|
164
|
+
throw new Error('SintBot binary core returned invalid App usage')
|
|
165
|
+
}
|
|
166
|
+
return usage
|
|
167
|
+
} finally {
|
|
168
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
169
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
170
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
171
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
172
|
+
core.dealloc(inputPtr, input.length)
|
|
173
|
+
input.fill(0)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function settleUsage(prior, sessionKey, result) {
|
|
178
|
+
// Only numeric/accounting fields cross this ABI. A run result may also hold
|
|
179
|
+
// model text or tool output, which the usage decision must never receive.
|
|
180
|
+
const usage = result && result.usage
|
|
181
|
+
const projection = {
|
|
182
|
+
usage: usage ? {
|
|
183
|
+
input_tokens: usage.input_tokens,
|
|
184
|
+
cached_input_tokens: usage.cached_input_tokens,
|
|
185
|
+
output_tokens: usage.output_tokens,
|
|
186
|
+
cache_read_input_tokens: usage.cache_read_input_tokens,
|
|
187
|
+
cache_creation_input_tokens: usage.cache_creation_input_tokens,
|
|
188
|
+
} : null,
|
|
189
|
+
usageCumulative: result && result.usageCumulative,
|
|
190
|
+
contextTokens: result && result.contextTokens,
|
|
191
|
+
contextCompacted: result && result.contextCompacted,
|
|
192
|
+
}
|
|
193
|
+
const input = encoder.encode(JSON.stringify({ prior, sessionKey, result: projection }))
|
|
194
|
+
const inputPtr = core.alloc(input.length)
|
|
195
|
+
let outputPtr = 0, outputSize = 0
|
|
196
|
+
try {
|
|
197
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
198
|
+
outputPtr = core.settle_usage(inputPtr, input.length)
|
|
199
|
+
if (!outputPtr) throw new Error('SintBot binary core could not settle usage')
|
|
200
|
+
const buffer = core.memory.buffer
|
|
201
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid usage decision')
|
|
202
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
203
|
+
outputSize = length + 4
|
|
204
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid usage decision')
|
|
205
|
+
const decision = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
206
|
+
if (!decision || typeof decision !== 'object' || typeof decision.write !== 'boolean' ||
|
|
207
|
+
(decision.tokens !== null && (typeof decision.tokens !== 'object' || Array.isArray(decision.tokens))) ||
|
|
208
|
+
(decision.write && (!decision.stats || typeof decision.stats !== 'object' || Array.isArray(decision.stats)))) {
|
|
209
|
+
throw new Error('SintBot binary core returned invalid usage decision')
|
|
210
|
+
}
|
|
211
|
+
return decision
|
|
212
|
+
} finally {
|
|
213
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
214
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
215
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
216
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
217
|
+
core.dealloc(inputPtr, input.length)
|
|
218
|
+
input.fill(0)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function appBuildRequest(options) {
|
|
223
|
+
const input = encoder.encode(JSON.stringify(options))
|
|
224
|
+
const inputPtr = core.alloc(input.length)
|
|
225
|
+
let outputPtr = 0, outputSize = 0
|
|
226
|
+
try {
|
|
227
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
228
|
+
outputPtr = core.app_build_request(inputPtr, input.length)
|
|
229
|
+
if (!outputPtr) throw new Error('SintBot binary core could not build App request')
|
|
230
|
+
const buffer = core.memory.buffer
|
|
231
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid App request')
|
|
232
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
233
|
+
outputSize = length + 4
|
|
234
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid App request')
|
|
235
|
+
const request = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
236
|
+
if (!request || !['thread/start', 'thread/resume', 'turn/start'].includes(request.method) ||
|
|
237
|
+
!request.params || typeof request.params !== 'object' || Array.isArray(request.params)) {
|
|
238
|
+
throw new Error('SintBot binary core returned invalid App request')
|
|
239
|
+
}
|
|
240
|
+
return request
|
|
241
|
+
} finally {
|
|
242
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
243
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
244
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
245
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
246
|
+
core.dealloc(inputPtr, input.length)
|
|
247
|
+
input.fill(0)
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function claudeBaseSkillAllows() {
|
|
252
|
+
const outputPtr = core.claude_base_skills()
|
|
253
|
+
if (!outputPtr) throw new Error('SintBot binary core could not provide Claude base skills')
|
|
254
|
+
let outputSize = 0
|
|
255
|
+
try {
|
|
256
|
+
const buffer = core.memory.buffer
|
|
257
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude base skills')
|
|
258
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
259
|
+
outputSize = length + 4
|
|
260
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude base skills')
|
|
261
|
+
const skills = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
262
|
+
if (!Array.isArray(skills) || !skills.every((s) => typeof s === 'string')) throw new Error('SintBot binary core returned invalid Claude base skills')
|
|
263
|
+
return skills
|
|
264
|
+
} finally {
|
|
265
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
266
|
+
if (outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
267
|
+
if (outputSize) core.dealloc(outputPtr, outputSize)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function claudeBuildArgs(options) {
|
|
272
|
+
const input = encoder.encode(JSON.stringify(options))
|
|
273
|
+
const inputPtr = core.alloc(input.length)
|
|
274
|
+
let outputPtr = 0, outputSize = 0
|
|
275
|
+
try {
|
|
276
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
277
|
+
outputPtr = core.claude_build_args(inputPtr, input.length)
|
|
278
|
+
if (!outputPtr) throw new Error('SintBot binary core could not build Claude arguments')
|
|
279
|
+
const buffer = core.memory.buffer
|
|
280
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude arguments')
|
|
281
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
282
|
+
outputSize = length + 4
|
|
283
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude arguments')
|
|
284
|
+
const args = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
285
|
+
if (!Array.isArray(args) || !args.every((a) => typeof a === 'string')) throw new Error('SintBot binary core returned invalid Claude arguments')
|
|
286
|
+
return args
|
|
287
|
+
} finally {
|
|
288
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
289
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
290
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
291
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
292
|
+
core.dealloc(inputPtr, input.length)
|
|
293
|
+
input.fill(0)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function claudeNormalizeEvent(event) {
|
|
298
|
+
const errorJson = event && event.is_error && Array.isArray(event.errors)
|
|
299
|
+
? event.errors.map((item) => JSON.stringify(item) ?? null) : null
|
|
300
|
+
const input = encoder.encode(JSON.stringify({ event, errorJson }))
|
|
301
|
+
const inputPtr = core.alloc(input.length)
|
|
302
|
+
let outputPtr = 0, outputSize = 0
|
|
303
|
+
try {
|
|
304
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
305
|
+
outputPtr = core.claude_normalize_event(inputPtr, input.length)
|
|
306
|
+
if (!outputPtr) throw new Error('SintBot binary core could not normalize Claude event')
|
|
307
|
+
const buffer = core.memory.buffer
|
|
308
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude event')
|
|
309
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
310
|
+
outputSize = length + 4
|
|
311
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid Claude event')
|
|
312
|
+
const normalized = JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
313
|
+
if (!normalized || typeof normalized !== 'object' || Array.isArray(normalized)) {
|
|
314
|
+
throw new Error('SintBot binary core returned invalid Claude event')
|
|
315
|
+
}
|
|
316
|
+
return normalized
|
|
317
|
+
} finally {
|
|
318
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
319
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
320
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
321
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
322
|
+
core.dealloc(inputPtr, input.length)
|
|
323
|
+
input.fill(0)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function coreJson(name, inputValue, context) {
|
|
328
|
+
const input = encoder.encode(JSON.stringify(inputValue))
|
|
329
|
+
const inputPtr = core.alloc(input.length)
|
|
330
|
+
let outputPtr = 0, outputSize = 0
|
|
331
|
+
try {
|
|
332
|
+
new Uint8Array(core.memory.buffer).set(input, inputPtr)
|
|
333
|
+
outputPtr = core[name](inputPtr, input.length)
|
|
334
|
+
if (!outputPtr) throw new Error(`SintBot binary core could not ${context}`)
|
|
335
|
+
const buffer = core.memory.buffer
|
|
336
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error(`SintBot binary core returned invalid ${context}`)
|
|
337
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
338
|
+
outputSize = length + 4
|
|
339
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error(`SintBot binary core returned invalid ${context}`)
|
|
340
|
+
return JSON.parse(decoder.decode(new Uint8Array(buffer, outputPtr + 4, length)))
|
|
341
|
+
} finally {
|
|
342
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
343
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
344
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
345
|
+
memory.fill(0, inputPtr, inputPtr + input.length)
|
|
346
|
+
core.dealloc(inputPtr, input.length)
|
|
347
|
+
input.fill(0)
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
function claudePluginAllowRules(mcpNames, skillNames) {
|
|
352
|
+
if (!Array.isArray(mcpNames) || !Array.isArray(skillNames) ||
|
|
353
|
+
[...mcpNames, ...skillNames].some((name) => typeof name !== 'string')) {
|
|
354
|
+
throw new TypeError('invalid Claude plugin names')
|
|
355
|
+
}
|
|
356
|
+
const value = coreJson('claude_plugin_allow_rules', { mcpNames, skillNames }, 'decide Claude plugin permissions')
|
|
357
|
+
if (!Array.isArray(value) || value.some((rule) => typeof rule !== 'string')) {
|
|
358
|
+
throw new Error('SintBot binary core returned invalid Claude plugin permissions')
|
|
359
|
+
}
|
|
360
|
+
return value
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function codexNormalizeEvent(event) {
|
|
364
|
+
const value = coreJson('codex_normalize_event', event, 'normalize Codex event')
|
|
365
|
+
if (value !== null && (typeof value !== 'object' || Array.isArray(value))) throw new Error('SintBot binary core returned invalid Codex event')
|
|
366
|
+
return value
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function codexParseError(raw) {
|
|
370
|
+
const value = coreJson('codex_parse_error', String(raw || ''), 'parse Codex error')
|
|
371
|
+
if (!value || typeof value.text !== 'string' || typeof value.param !== 'string') throw new Error('SintBot binary core returned invalid Codex error')
|
|
372
|
+
return value
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function appNormalizeItem(method, item) {
|
|
376
|
+
const value = coreJson('app_normalize_item', { method, item }, 'normalize App item')
|
|
377
|
+
if (value !== null && (typeof value !== 'object' || Array.isArray(value))) throw new Error('SintBot binary core returned invalid App item')
|
|
378
|
+
return value
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function appStreamTail(finalText, streamed) {
|
|
382
|
+
const value = coreJson('app_stream_tail', { finalText, streamed }, 'reconcile App message deltas')
|
|
383
|
+
if (value !== null && typeof value !== 'string') throw new Error('SintBot binary core returned invalid App message tail')
|
|
384
|
+
return value
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
function appNoticeAction(method, { threadMatches, turnMatches, activeTurn, completed, codexApp, hasTurnId, hasItemId }) {
|
|
388
|
+
const flags = (threadMatches ? 1 : 0) | (turnMatches ? 2 : 0) | (activeTurn ? 4 : 0) |
|
|
389
|
+
(completed ? 8 : 0) | (codexApp ? 16 : 0) | (hasTurnId ? 32 : 0) | (hasItemId ? 64 : 0)
|
|
390
|
+
const code = callText('app_notice_action', method, flags)
|
|
391
|
+
if (code >= 0 && code <= 5) return code
|
|
392
|
+
throw new Error(`SintBot binary core returned unknown App notification action ${code}`)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function appDeltaNext(previous, delta) {
|
|
396
|
+
const previousBytes = new Uint8Array(previous.length * 2)
|
|
397
|
+
const deltaBytes = new Uint8Array(delta.length * 2)
|
|
398
|
+
for (let i = 0; i < previous.length; i++) {
|
|
399
|
+
const unit = previous.charCodeAt(i)
|
|
400
|
+
previousBytes[i * 2] = unit & 255
|
|
401
|
+
previousBytes[i * 2 + 1] = unit >>> 8
|
|
402
|
+
}
|
|
403
|
+
for (let i = 0; i < delta.length; i++) {
|
|
404
|
+
const unit = delta.charCodeAt(i)
|
|
405
|
+
deltaBytes[i * 2] = unit & 255
|
|
406
|
+
deltaBytes[i * 2 + 1] = unit >>> 8
|
|
407
|
+
}
|
|
408
|
+
const previousPtr = core.alloc(previousBytes.length)
|
|
409
|
+
let deltaPtr = 0, outputPtr = 0, outputSize = 0
|
|
410
|
+
try {
|
|
411
|
+
deltaPtr = core.alloc(deltaBytes.length)
|
|
412
|
+
new Uint8Array(core.memory.buffer).set(previousBytes, previousPtr)
|
|
413
|
+
new Uint8Array(core.memory.buffer).set(deltaBytes, deltaPtr)
|
|
414
|
+
outputPtr = core.app_delta_next(previousPtr, previousBytes.length, deltaPtr, deltaBytes.length)
|
|
415
|
+
if (!outputPtr) {
|
|
416
|
+
if (!delta.length) return null
|
|
417
|
+
throw new Error('SintBot binary core could not accumulate App message delta')
|
|
418
|
+
}
|
|
419
|
+
const buffer = core.memory.buffer
|
|
420
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid App delta')
|
|
421
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
422
|
+
outputSize = length + 4
|
|
423
|
+
if (length !== previousBytes.length + deltaBytes.length || outputPtr + outputSize > buffer.byteLength) {
|
|
424
|
+
throw new Error('SintBot binary core returned invalid App delta')
|
|
425
|
+
}
|
|
426
|
+
const bytes = new Uint8Array(buffer, outputPtr + 4, length)
|
|
427
|
+
const units = new Uint16Array(length / 2)
|
|
428
|
+
for (let i = 0; i < units.length; i++) units[i] = bytes[i * 2] | (bytes[i * 2 + 1] << 8)
|
|
429
|
+
let result = ''
|
|
430
|
+
for (let i = 0; i < units.length; i += 8192) result += String.fromCharCode(...units.subarray(i, i + 8192))
|
|
431
|
+
return result
|
|
432
|
+
} finally {
|
|
433
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
434
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
435
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
436
|
+
memory.fill(0, previousPtr, previousPtr + previousBytes.length)
|
|
437
|
+
core.dealloc(previousPtr, previousBytes.length)
|
|
438
|
+
if (deltaPtr) {
|
|
439
|
+
memory.fill(0, deltaPtr, deltaPtr + deltaBytes.length)
|
|
440
|
+
core.dealloc(deltaPtr, deltaBytes.length)
|
|
441
|
+
}
|
|
442
|
+
previousBytes.fill(0)
|
|
443
|
+
deltaBytes.fill(0)
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function appLandedAction(itemType, done, hasClientId, alreadyLanded) {
|
|
448
|
+
const flags = (done ? 1 : 0) | (hasClientId ? 2 : 0) | (alreadyLanded ? 4 : 0)
|
|
449
|
+
const code = callText('app_landed_action', itemType, flags)
|
|
450
|
+
if (code === 0) return false
|
|
451
|
+
if (code === 1) return true
|
|
452
|
+
throw new Error(`SintBot binary core returned unknown App landing action ${code}`)
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
function appCompletionAction(status, matchesTurn, completed, hasEffort, retriedEffort, effortRejected) {
|
|
456
|
+
const flags = (matchesTurn ? 1 : 0) | (completed ? 2 : 0) | (hasEffort ? 4 : 0) |
|
|
457
|
+
(retriedEffort ? 8 : 0) | (effortRejected ? 16 : 0)
|
|
458
|
+
const code = callText('app_completion_action', status, flags)
|
|
459
|
+
if (code >= 0 && code <= 4) return code
|
|
460
|
+
throw new Error(`SintBot binary core returned unknown App completion action ${code}`)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// The host owns opaque turn IDs; the core selects which completion can settle
|
|
464
|
+
// the active turn or be retained until turn/start returns its ID.
|
|
465
|
+
function appCompletionNoticeAction({ threadMatches, hasTurnId, activeTurn, activeTurnMatches, pendingStart, completed }) {
|
|
466
|
+
const flags = (threadMatches ? 1 : 0) | (hasTurnId ? 2 : 0) | (activeTurn ? 4 : 0) |
|
|
467
|
+
(activeTurnMatches ? 8 : 0) | (pendingStart ? 16 : 0) | (completed ? 32 : 0)
|
|
468
|
+
const code = core.app_completion_notice_action(flags)
|
|
469
|
+
if (code >= 0 && code <= 2) return code
|
|
470
|
+
throw new Error(`SintBot binary core returned unknown App completion notice action ${code}`)
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
function manifestFeatures(features) {
|
|
474
|
+
const keys = ['boards', 'cardPinned', 'download', 'editRecall', 'history', 'imagen',
|
|
475
|
+
'noticeCard', 'plainSend', 'react', 'skills', 'takeoverCard', 'mediaByPath']
|
|
476
|
+
const projected = {}
|
|
477
|
+
for (const key of keys) if (key !== 'mediaByPath') projected[key] = features ? features[key] : undefined
|
|
478
|
+
projected.mediaMarker = features ? features.mediaMarker : undefined
|
|
479
|
+
const value = coreJson('manifest_features', { features: projected }, 'select manifest platform features')
|
|
480
|
+
if (!value || keys.some((key) => typeof value[key] !== 'boolean')) {
|
|
481
|
+
throw new Error('SintBot binary core returned invalid manifest features')
|
|
482
|
+
}
|
|
483
|
+
return value
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function systemAppendix(noReply) {
|
|
487
|
+
const bytes = encoder.encode(String(noReply))
|
|
488
|
+
const ptr = core.alloc(bytes.length)
|
|
489
|
+
let outputPtr = 0, outputSize = 0
|
|
490
|
+
try {
|
|
491
|
+
new Uint8Array(core.memory.buffer).set(bytes, ptr)
|
|
492
|
+
outputPtr = core.system_appendix(ptr, bytes.length)
|
|
493
|
+
if (!outputPtr) throw new Error('SintBot binary core could not render group appendix')
|
|
494
|
+
const buffer = core.memory.buffer
|
|
495
|
+
if (outputPtr + 4 > buffer.byteLength) throw new Error('SintBot binary core returned invalid group appendix')
|
|
496
|
+
const length = new DataView(buffer).getUint32(outputPtr, true)
|
|
497
|
+
outputSize = length + 4
|
|
498
|
+
if (outputPtr + outputSize > buffer.byteLength) throw new Error('SintBot binary core returned invalid group appendix')
|
|
499
|
+
return decoder.decode(new Uint8Array(buffer, outputPtr + 4, length))
|
|
500
|
+
} finally {
|
|
501
|
+
const memory = new Uint8Array(core.memory.buffer)
|
|
502
|
+
if (outputPtr && outputSize && outputPtr + outputSize <= memory.length) memory.fill(0, outputPtr, outputPtr + outputSize)
|
|
503
|
+
if (outputPtr && outputSize) core.dealloc(outputPtr, outputSize)
|
|
504
|
+
memory.fill(0, ptr, ptr + bytes.length)
|
|
505
|
+
core.dealloc(ptr, bytes.length)
|
|
506
|
+
bytes.fill(0)
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function codexEffortRejection(result) {
|
|
511
|
+
const value = result && { isError: result.isError, effortRejected: result.effortRejected, text: result.text }
|
|
512
|
+
const code = callText('codex_effort_rejection', JSON.stringify(value))
|
|
513
|
+
if (code === 0) return false
|
|
514
|
+
if (code === 1) return true
|
|
515
|
+
throw new Error(`SintBot binary core returned unknown Codex effort decision ${code}`)
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
function parseResetFields(text) {
|
|
519
|
+
const value = coreJson('parse_reset_fields', String(text || ''), 'parse reset time')
|
|
520
|
+
if (value !== null && (!value || typeof value !== 'object' || Array.isArray(value) ||
|
|
521
|
+
(value.month !== null && !Number.isInteger(value.month)) ||
|
|
522
|
+
(value.day !== null && !Number.isInteger(value.day)) ||
|
|
523
|
+
!Number.isInteger(value.hour) || !Number.isInteger(value.minute) ||
|
|
524
|
+
(value.zone !== null && typeof value.zone !== 'string'))) {
|
|
525
|
+
throw new Error('SintBot binary core returned invalid reset time')
|
|
526
|
+
}
|
|
527
|
+
return value
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function chooseResetEpoch(now, primary, nextYear, dated) {
|
|
531
|
+
const result = core.choose_reset_epoch(now, primary, nextYear, Number(!!dated))
|
|
532
|
+
return Number.isNaN(result) ? null : result
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function wecomGatePrompt(input) {
|
|
536
|
+
const value = coreJson('wecom_gate_prompt', input, 'render WeCom gate prompt')
|
|
537
|
+
if (!value || typeof value.system !== 'string' || typeof value.user !== 'string') {
|
|
538
|
+
throw new Error('SintBot binary core returned invalid WeCom gate prompt')
|
|
539
|
+
}
|
|
540
|
+
return value
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
function manifestHeader(input) {
|
|
544
|
+
const lines = coreJson('manifest_header', input, 'render manifest header')
|
|
545
|
+
if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) {
|
|
546
|
+
throw new Error('SintBot binary core returned invalid manifest header')
|
|
547
|
+
}
|
|
548
|
+
return lines
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function manifestContext(input) {
|
|
552
|
+
const lines = coreJson('manifest_context', input, 'render manifest context')
|
|
553
|
+
if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) {
|
|
554
|
+
throw new Error('SintBot binary core returned invalid manifest context')
|
|
555
|
+
}
|
|
556
|
+
return lines
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
function manifestSkills(input) {
|
|
560
|
+
const lines = coreJson('manifest_skills', input, 'render manifest platform skills')
|
|
561
|
+
if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest platform skills')
|
|
562
|
+
return lines
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
function manifestStyleBoard(input) {
|
|
566
|
+
const lines = coreJson('manifest_style_board', input, 'render manifest style and board rules')
|
|
567
|
+
if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest style and board rules')
|
|
568
|
+
return lines
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
function manifestImagenAsset(input) {
|
|
572
|
+
const lines = coreJson('manifest_imagen_asset', input, 'render manifest image and asset rules')
|
|
573
|
+
if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest image and asset rules')
|
|
574
|
+
return lines
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function manifestRuntime(input) {
|
|
578
|
+
const lines = coreJson('manifest_runtime', input, 'render manifest runtime rules')
|
|
579
|
+
if (!Array.isArray(lines) || !lines.every((line) => typeof line === 'string')) throw new Error('SintBot binary core returned invalid manifest runtime rules')
|
|
580
|
+
return lines
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
function imagenPrompt(input) {
|
|
584
|
+
const value = coreJson('imagen_prompt', input, 'render image prompt')
|
|
585
|
+
if (typeof value !== 'string') throw new Error('SintBot binary core returned invalid image prompt')
|
|
586
|
+
return value
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
function turnPrompt(input) {
|
|
590
|
+
const value = coreJson('turn_prompt', input, 'render turn prompt')
|
|
591
|
+
if (typeof value !== 'string') throw new Error('SintBot binary core returned invalid turn prompt')
|
|
592
|
+
return value
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
function compactEvent(subtype) {
|
|
596
|
+
const code = callText('compact_event', subtype)
|
|
597
|
+
if (code === 0) return false
|
|
598
|
+
if (code === 1) return true
|
|
599
|
+
throw new Error(`SintBot binary core returned unknown compaction decision ${code}`)
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
function engineQueueStep(state, event) {
|
|
603
|
+
const value = coreJson('engine_queue_step', { state, event }, 'advance engine queue')
|
|
604
|
+
if (!value || !value.state || !Array.isArray(value.state.queue) ||
|
|
605
|
+
!Array.isArray(value.effects) || !Number.isInteger(value.runLen) ||
|
|
606
|
+
!Number.isInteger(value.visibleQueue)) throw new Error('SintBot binary core returned invalid engine queue transition')
|
|
607
|
+
return value
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function engineSlotsStep(state, event) {
|
|
611
|
+
const value = coreJson('engine_slots_step', { state, event }, 'advance engine slots')
|
|
612
|
+
if (!value || !value.state || typeof value.state !== 'object' ||
|
|
613
|
+
!Array.isArray(value.state.waiters) || !Array.isArray(value.effects) ||
|
|
614
|
+
value.effects.some((effect) => !effect || !['grant', 'reject'].includes(effect.type) || typeof effect.id !== 'string')) {
|
|
615
|
+
throw new Error('SintBot binary core returned invalid engine slots transition')
|
|
616
|
+
}
|
|
617
|
+
return value
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function engineTurnStep(state, event) {
|
|
621
|
+
const value = coreJson('engine_turn_step', { state, event }, 'advance engine turn identity')
|
|
622
|
+
if (!value || !value.state || Array.isArray(value.state) || typeof value.state !== 'object' ||
|
|
623
|
+
!Number.isSafeInteger(value.state.epoch) || value.state.epoch < 0 ||
|
|
624
|
+
!(value.state.active === null || (Number.isSafeInteger(value.state.active) && value.state.active > 0)) ||
|
|
625
|
+
!Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
|
|
626
|
+
!['turnToken', 'effectAllowed'].includes(effect.type) ||
|
|
627
|
+
!Number.isSafeInteger(effect.type === 'turnToken' ? effect.value : effect.turnToken))) {
|
|
628
|
+
throw new Error('SintBot binary core returned invalid engine turn transition')
|
|
629
|
+
}
|
|
630
|
+
return value
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
function engineSessionStep(state, event) {
|
|
634
|
+
const value = coreJson('engine_session_step', { state, event }, 'advance engine session')
|
|
635
|
+
const next = value && value.state
|
|
636
|
+
if (!next || Array.isArray(next) || typeof next !== 'object' ||
|
|
637
|
+
!Number.isSafeInteger(next.epoch) || next.epoch < 0 ||
|
|
638
|
+
typeof next.closeSeen !== 'boolean' || typeof next.settled !== 'boolean' ||
|
|
639
|
+
!Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
|
|
640
|
+
!['writeSession', 'markTainted', 'resetSessionAndStats'].includes(effect.type))) {
|
|
641
|
+
throw new Error('SintBot binary core returned invalid engine session transition')
|
|
642
|
+
}
|
|
643
|
+
return value
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
function engineHandoffStep(state, event) {
|
|
647
|
+
const value = coreJson('engine_handoff_step', { state, event }, 'advance engine handoff')
|
|
648
|
+
const next = value && value.state
|
|
649
|
+
if (!next || Array.isArray(next) || typeof next !== 'object' ||
|
|
650
|
+
!['idle', 'running', 'releasing', 'handoff', 'sealed'].includes(next.phase) ||
|
|
651
|
+
!(next.turnToken === null || (Number.isSafeInteger(next.turnToken) && next.turnToken > 0)) ||
|
|
652
|
+
![0, 1].includes(next.attempt) || !Array.isArray(next.acceptedReceiptIds) ||
|
|
653
|
+
!(next.nextJobId === null || typeof next.nextJobId === 'string') ||
|
|
654
|
+
!Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
|
|
655
|
+
!['attemptQueueRelease', 'retryQueueRelease', 'sealGroup', 'notifyAccepted',
|
|
656
|
+
'holdHandoff', 'scheduleDispatch', 'clearHandoff', 'dispatch'].includes(effect.type))) {
|
|
657
|
+
throw new Error('SintBot binary core returned invalid engine handoff transition')
|
|
658
|
+
}
|
|
659
|
+
return value
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
function engineIntakeStep(state, event) {
|
|
663
|
+
const value = coreJson('engine_intake_step', { state, event }, 'advance engine intake')
|
|
664
|
+
const next = value && value.state
|
|
665
|
+
if (!next || Array.isArray(next) || typeof next !== 'object' ||
|
|
666
|
+
!Number.isSafeInteger(next.watermark) || next.watermark < 0 ||
|
|
667
|
+
!Array.isArray(next.seen) || typeof next.unboundNotified !== 'boolean' ||
|
|
668
|
+
!(next.pending === null || (next.pending && typeof next.pending === 'object' &&
|
|
669
|
+
typeof next.pending.key === 'string' && Number.isSafeInteger(next.pending.at) &&
|
|
670
|
+
Number.isSafeInteger(next.pending.watermark))) ||
|
|
671
|
+
!Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
|
|
672
|
+
!['notifyOrphan', 'sendUnboundGuide', 'clearQueue', 'handleCommand',
|
|
673
|
+
'persistReceipt', 'dispatch'].includes(effect.type))) {
|
|
674
|
+
throw new Error('SintBot binary core returned invalid engine intake transition')
|
|
675
|
+
}
|
|
676
|
+
return value
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
function engineLifecycleStep(state, event) {
|
|
680
|
+
const value = coreJson('engine_lifecycle_step', { state, event }, 'advance engine lifecycle')
|
|
681
|
+
if (!value || !value.state || Array.isArray(value.state) || typeof value.state !== 'object' ||
|
|
682
|
+
!Array.isArray(value.effects) || value.effects.some((effect) => !effect || typeof effect.type !== 'string')) {
|
|
683
|
+
throw new Error('SintBot binary core returned invalid engine lifecycle transition')
|
|
684
|
+
}
|
|
685
|
+
return value
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
function engineTerminalStep(state, event) {
|
|
689
|
+
const value = coreJson('engine_terminal_step', { state, event }, 'advance engine terminal state')
|
|
690
|
+
const next = value && value.state
|
|
691
|
+
const outcome = next && next.outcome
|
|
692
|
+
const fields = ['silent', 'nothingProduced', 'sideEffects', 'sessionMissing',
|
|
693
|
+
'lostRetry', 'network', 'quotaError', 'resumed']
|
|
694
|
+
if (!next || next.finalized !== true || !outcome ||
|
|
695
|
+
!['stopped', 'error', 'no-reply', 'empty', 'ok'].includes(outcome.status) ||
|
|
696
|
+
fields.some((field) => typeof outcome[field] !== 'boolean') ||
|
|
697
|
+
!Array.isArray(value.effects) || value.effects.some((effect) => !effect ||
|
|
698
|
+
!['markTainted', 'clearTainted', 'clearExhausted', 'verifyTurn'].includes(effect.type) ||
|
|
699
|
+
(effect.type === 'verifyTurn' && typeof effect.success !== 'boolean'))) {
|
|
700
|
+
throw new Error('SintBot binary core returned invalid engine terminal transition')
|
|
701
|
+
}
|
|
702
|
+
return value
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
function engineSteerStep(state, event) {
|
|
706
|
+
const value = coreJson('engine_steer_step', { state, event }, 'advance Codex follow-up')
|
|
707
|
+
if (!value || !value.state || Array.isArray(value.state) || typeof value.state !== 'object' ||
|
|
708
|
+
!Array.isArray(value.state.entries) || !Array.isArray(value.effects) ||
|
|
709
|
+
value.effects.some((effect) => !effect || typeof effect.type !== 'string')) {
|
|
710
|
+
throw new Error('SintBot binary core returned invalid Codex follow-up transition')
|
|
711
|
+
}
|
|
712
|
+
return value
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function engineRecoveryStep(event) {
|
|
716
|
+
const value = coreJson('engine_recovery_step', event, 'advance engine recovery')
|
|
717
|
+
if (!value || !Array.isArray(value.effects)) throw new Error('SintBot binary core returned invalid engine recovery transition')
|
|
718
|
+
return value
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
function engineFailoverStep(event) {
|
|
722
|
+
const value = coreJson('engine_failover_step', event, 'advance engine failover')
|
|
723
|
+
if (!value || !Array.isArray(value.effects)) throw new Error('SintBot binary core returned invalid engine failover transition')
|
|
724
|
+
return value
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// This stateful C2 entry is deliberately outside guarded(): a failed step may
|
|
728
|
+
// have mutated WASM memory before throwing, so later events must wait for an
|
|
729
|
+
// explicit instance rebuild from the host's last committed state.
|
|
730
|
+
function engineStep(state, event, admission = null) {
|
|
731
|
+
if (engineStepPoisoned) throw new Error('SintBot binary core C2 state needs recovery')
|
|
732
|
+
if (!state || ![1, 2].includes(state.version) || !Number.isSafeInteger(state.seq) || state.seq < 0 ||
|
|
733
|
+
!state.lanes || typeof state.lanes !== 'object' || Array.isArray(state.lanes) ||
|
|
734
|
+
!event || typeof event.id !== 'string' || !event.id ||
|
|
735
|
+
typeof event.domain !== 'string' || !event.domain ||
|
|
736
|
+
typeof event.scope !== 'string' || !event.scope ||
|
|
737
|
+
!Number.isSafeInteger(event.expectedCursor) || event.expectedCursor !== state.seq ||
|
|
738
|
+
!event.payload || typeof event.payload !== 'object' || Array.isArray(event.payload) ||
|
|
739
|
+
(state.version === 1 && admission !== null) ||
|
|
740
|
+
(state.version === 2 && (!admission || admission.version !== 1 ||
|
|
741
|
+
admission.cursor !== state.seq || admission.eventId !== event.id ||
|
|
742
|
+
admission.unseen !== true || Object.keys(admission).length !== 4))) {
|
|
743
|
+
throw new TypeError('invalid C2 step input')
|
|
744
|
+
}
|
|
745
|
+
try {
|
|
746
|
+
const input = state.version === 2 ? { state, event, admission } : { state, event }
|
|
747
|
+
const value = coreJson('engine_step', input, 'advance C2 engine')
|
|
748
|
+
if (!value || !value.state || value.state.version !== state.version ||
|
|
749
|
+
!Number.isSafeInteger(value.state.seq) || value.state.seq !== state.seq + 1 ||
|
|
750
|
+
!value.state.lanes || typeof value.state.lanes !== 'object' || Array.isArray(value.state.lanes) ||
|
|
751
|
+
value.cursor !== value.state.seq || value.eventId !== event.id ||
|
|
752
|
+
!Array.isArray(value.effects) || value.effects.some((effect, index) =>
|
|
753
|
+
!effect || typeof effect !== 'object' || typeof effect.type !== 'string' ||
|
|
754
|
+
effect.effectId !== `sbot-c2-effect-v1:${Buffer.byteLength(event.id)}:${event.id}:${index}`) ||
|
|
755
|
+
!value.decision || typeof value.decision !== 'object' || Array.isArray(value.decision)) {
|
|
756
|
+
throw new Error('SintBot binary core returned invalid C2 engine transition')
|
|
757
|
+
}
|
|
758
|
+
return value
|
|
759
|
+
} catch (error) {
|
|
760
|
+
engineStepPoisoned = true
|
|
761
|
+
throw error
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function manifestPolicy(permissionMode, isCodex, allowedTools, disallowedTools) {
|
|
766
|
+
const value = coreJson('manifest_policy', { permissionMode, isCodex, allowedTools, disallowedTools }, 'decide manifest permissions')
|
|
767
|
+
if (!value || !Number.isInteger(value.tier) || value.tier < 0 || value.tier > 3 ||
|
|
768
|
+
typeof value.full !== 'boolean' || typeof value.pushDenied !== 'boolean') {
|
|
769
|
+
throw new Error('SintBot binary core returned invalid manifest policy')
|
|
770
|
+
}
|
|
771
|
+
return value
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// A trap or exhausted stack can leave the instance's own stack pointer wrong, and
|
|
775
|
+
// C1 calls hold no state, so the next call simply gets a fresh instance.
|
|
776
|
+
function guarded(fn) {
|
|
777
|
+
return (...args) => {
|
|
778
|
+
try {
|
|
779
|
+
return fn(...args)
|
|
780
|
+
} catch (error) {
|
|
781
|
+
if (error instanceof WebAssembly.RuntimeError || error instanceof RangeError) boot()
|
|
782
|
+
throw error
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
const entries = { classifyError, routeBackend, sandboxTier, appErrorOverride, appNormalizeItem, appStreamTail, appNoticeAction, appDeltaNext, appLandedAction, appCompletionAction, appCompletionNoticeAction, manifestFeatures, manifestHeader, manifestContext, manifestSkills, manifestStyleBoard, manifestImagenAsset, manifestRuntime, manifestPolicy, systemAppendix, codexEffortRejection, wecomGatePrompt, imagenPrompt, turnPrompt, compactEvent, engineQueueStep, engineSlotsStep, engineTurnStep, engineSessionStep, engineHandoffStep, engineIntakeStep, engineLifecycleStep, engineTerminalStep, engineSteerStep, engineRecoveryStep, engineFailoverStep, parseResetFields, chooseResetEpoch, codexBuildPrompt, codexBuildArgs, appUsageFromTotal, settleUsage, appBuildRequest, claudeBaseSkillAllows, claudeBuildArgs, claudePluginAllowRules, claudeNormalizeEvent, codexNormalizeEvent, codexParseError }
|
|
788
|
+
for (const name of Object.keys(entries)) entries[name] = guarded(entries[name])
|
|
789
|
+
|
|
790
|
+
module.exports = { ...entries, engineStep, resetBinaryCore, HUMAN_BY_KIND: HUMAN }
|