mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
Add support for claude 1M context. close #291
This commit is contained in:
+1
-1
@@ -48,7 +48,7 @@ See `src/router.tsx` for route definitions.
|
||||
- Message thread with infinite scroll.
|
||||
- Composer for sending messages.
|
||||
- Permission mode toggle (default/acceptEdits/bypassPermissions/plan).
|
||||
- Model selection (default/sonnet/opus).
|
||||
- Model selection (default/sonnet/sonnet[1m]/opus/opus[1m]).
|
||||
- Session abort and mode switch controls.
|
||||
- Context size display.
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { getContextBudgetTokens } from './modelConfig'
|
||||
|
||||
describe('getContextBudgetTokens', () => {
|
||||
it('uses the existing 200k budget for default Claude modes', () => {
|
||||
expect(getContextBudgetTokens(undefined)).toBe(190_000)
|
||||
expect(getContextBudgetTokens('default')).toBe(190_000)
|
||||
expect(getContextBudgetTokens('sonnet')).toBe(190_000)
|
||||
expect(getContextBudgetTokens('opus')).toBe(190_000)
|
||||
})
|
||||
|
||||
it('uses the 1m budget for Claude 1m modes', () => {
|
||||
expect(getContextBudgetTokens('sonnet[1m]')).toBe(990_000)
|
||||
expect(getContextBudgetTokens('opus[1m]')).toBe(990_000)
|
||||
})
|
||||
})
|
||||
@@ -13,10 +13,12 @@ import type { ModelMode } from '@/types/api'
|
||||
const CONTEXT_HEADROOM_TOKENS = 10_000
|
||||
|
||||
const MODEL_CONTEXT_WINDOWS: Record<ModelMode, number> = {
|
||||
// Claude Code modes used in this app; currently treated as ~200k context.
|
||||
// Claude Code modes used in this app. 1M variants get the larger budget.
|
||||
default: 200_000,
|
||||
sonnet: 200_000,
|
||||
opus: 200_000
|
||||
'sonnet[1m]': 1_000_000,
|
||||
opus: 200_000,
|
||||
'opus[1m]': 1_000_000
|
||||
}
|
||||
|
||||
export function getContextBudgetTokens(modelMode: ModelMode | undefined): number | null {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { getModelModeLabel, MODEL_MODES } from '@hapi/protocol'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { MODEL_OPTIONS } from './types'
|
||||
|
||||
describe('Claude model options', () => {
|
||||
it('includes 1m model options in the expected order', () => {
|
||||
expect(MODEL_OPTIONS.claude).toEqual([
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
{ value: 'opus', label: 'Opus' },
|
||||
{ value: 'opus[1m]', label: 'Opus 1M' },
|
||||
{ value: 'sonnet', label: 'Sonnet' },
|
||||
{ value: 'sonnet[1m]', label: 'Sonnet 1M' },
|
||||
])
|
||||
})
|
||||
|
||||
it('exposes friendly labels for session model modes', () => {
|
||||
expect(MODEL_MODES).toEqual(['default', 'sonnet', 'sonnet[1m]', 'opus', 'opus[1m]'])
|
||||
expect(getModelModeLabel('sonnet[1m]')).toBe('Sonnet 1M')
|
||||
expect(getModelModeLabel('opus[1m]')).toBe('Opus 1M')
|
||||
})
|
||||
})
|
||||
@@ -5,7 +5,9 @@ export const MODEL_OPTIONS: Record<AgentType, { value: string; label: string }[]
|
||||
claude: [
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
{ value: 'opus', label: 'Opus' },
|
||||
{ value: 'opus[1m]', label: 'Opus 1M' },
|
||||
{ value: 'sonnet', label: 'Sonnet' },
|
||||
{ value: 'sonnet[1m]', label: 'Sonnet 1M' },
|
||||
],
|
||||
codex: [
|
||||
{ value: 'auto', label: 'Auto' },
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getModelModeLabel } from '@hapi/protocol'
|
||||
import { useId, useMemo, useRef, useState } from 'react'
|
||||
import type { Session } from '@/types/api'
|
||||
import type { ApiClient } from '@/api/client'
|
||||
@@ -70,6 +71,7 @@ export function SessionHeader(props: {
|
||||
const { session, api, onSessionDeleted } = props
|
||||
const title = useMemo(() => getSessionTitle(session), [session])
|
||||
const worktreeBranch = session.metadata?.worktree?.branch
|
||||
const modelModeLabel = getModelModeLabel(session.modelMode ?? 'default')
|
||||
|
||||
const [menuOpen, setMenuOpen] = useState(false)
|
||||
const [menuAnchorPoint, setMenuAnchorPoint] = useState<{ x: number; y: number }>({ x: 0, y: 0 })
|
||||
@@ -139,7 +141,7 @@ export function SessionHeader(props: {
|
||||
{session.metadata?.flavor?.trim() || 'unknown'}
|
||||
</span>
|
||||
<span>
|
||||
{t('session.item.modelMode')}: {session.modelMode || 'default'}
|
||||
{t('session.item.modelMode')}: {modelModeLabel}
|
||||
</span>
|
||||
{worktreeBranch ? (
|
||||
<span>{t('session.item.worktree')}: {worktreeBranch}</span>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getModelModeLabel } from '@hapi/protocol'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import type { SessionSummary } from '@/types/api'
|
||||
import type { ApiClient } from '@/api/client'
|
||||
@@ -198,6 +199,7 @@ function SessionItem(props: {
|
||||
})
|
||||
|
||||
const sessionName = getSessionTitle(s)
|
||||
const modelModeLabel = getModelModeLabel(s.modelMode ?? 'default')
|
||||
const statusDotClass = s.active
|
||||
? (s.thinking ? 'bg-[#007AFF]' : 'bg-[var(--app-badge-success-text)]')
|
||||
: 'bg-[var(--app-hint)]'
|
||||
@@ -259,7 +261,7 @@ function SessionItem(props: {
|
||||
</span>
|
||||
{getAgentLabel(s)}
|
||||
</span>
|
||||
<span>{t('session.item.modelMode')}: {s.modelMode || 'default'}</span>
|
||||
<span>{t('session.item.modelMode')}: {modelModeLabel}</span>
|
||||
{s.metadata?.worktree?.branch ? (
|
||||
<span>{t('session.item.worktree')}: {s.metadata.worktree.branch}</span>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user