mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
feat(opencode): add plan mode, reasoning effort, and status telemetry (#688)
* feat(opencode): support plan mode * feat(opencode): support reasoning effort * feat(opencode): surface context usage in web Bridge OpenCode ACP usage updates into the existing token-count pipeline so the web status bar can show live context and cache information without a separate UI path. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(opencode): restrict plan mode to remote, rollback reasoning effort on failure - Block local OpenCode plan startup (tools not enforced in local path) - Allow remote OpenCode plan only (ACP permission handler denies tools) - Guard web /permission-mode endpoint for local OpenCode plan sessions - Rollback session reasoning effort when OpenCode rejects set_config_option - Wire rollback callback through opencodeLoop to runOpencode closure - Add tests: local plan rejected, remote plan allowed, web guard, effort rollback * fix(web): auto-retry OpenCode models query to populate model selector without refresh - Retry early failures (RPC may still be registering on new sessions) - Poll briefly until availableModels is non-empty - Stop polling once model options are discovered - Add tests for retry/poll/stop policy * fix(opencode): cap model discovery polling --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -641,6 +641,42 @@ describe('normalizeDecryptedMessage', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('normalizes token_count payloads with explicit contextTokens', () => {
|
||||
const message = makeMessage({
|
||||
role: 'agent',
|
||||
content: {
|
||||
type: 'codex',
|
||||
data: {
|
||||
type: 'token_count',
|
||||
info: {
|
||||
total: {
|
||||
inputTokens: 8_119,
|
||||
outputTokens: 2,
|
||||
cachedInputTokens: 5_760,
|
||||
thoughtTokens: 11,
|
||||
totalTokens: 13_892
|
||||
},
|
||||
contextTokens: 13_879,
|
||||
modelContextWindow: 65_536
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const normalized = normalizeDecryptedMessage(message)
|
||||
|
||||
expect(normalized).toMatchObject({
|
||||
role: 'event',
|
||||
usage: {
|
||||
input_tokens: 8119,
|
||||
output_tokens: 2,
|
||||
cache_read_input_tokens: 5760,
|
||||
context_tokens: 13879,
|
||||
context_window: 65536
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('normalizes Codex context_compacted as a compact event', () => {
|
||||
const message = makeMessage({
|
||||
role: 'agent',
|
||||
|
||||
@@ -88,7 +88,12 @@ function normalizeCodexTokenUsage(value: unknown, data?: Record<string, unknown>
|
||||
?? usageSource.cacheReadInputTokens
|
||||
?? usageSource.cache_read_input_tokens
|
||||
) ?? undefined,
|
||||
context_tokens: inputTokens,
|
||||
context_tokens: asNumber(
|
||||
info.contextTokens
|
||||
?? info.context_tokens
|
||||
?? usageSource.contextTokens
|
||||
?? usageSource.context_tokens
|
||||
) ?? inputTokens,
|
||||
context_window: asNumber(info.modelContextWindow ?? info.model_context_window) ?? undefined,
|
||||
thread_id: asString(
|
||||
data?.thread_id
|
||||
|
||||
Reference in New Issue
Block a user