bingocode 1.1.200-beta.9 → 1.1.201
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/package.json +1 -1
- package/src/cli/ProviderPanel.tsx +813 -813
- package/src/commands/brain/brain.ts +1 -1
- package/src/constants/prompts.ts +30 -18
- package/src/hooks/useMergedTools.ts +3 -1
- package/src/main.tsx +4693 -4691
- package/src/manager/CliMenuManager.tsx +1589 -1583
- package/src/screens/REPL.tsx +5010 -5008
- package/src/screens/ResumeConversation.tsx +7 -1
- package/src/server/api/providers.ts +24 -0
- package/src/server/config/providers.yaml +21 -0
- package/src/server/proxy/handler.ts +16 -3
- package/src/server/services/providerService.ts +181 -43
- package/src/tools/AgentTool/UI.tsx +73 -8
- package/src/tools/AgentTool/agentToolUtils.ts +2 -2
- package/src/tools.ts +397 -390
- package/src/utils/attachments.ts +2 -2
- package/src/utils/context.ts +1 -1
- package/src/utils/sessionStorage.ts +39 -8
- package/src/utils/tokens.ts +23 -0
package/src/utils/attachments.ts
CHANGED
|
@@ -64,6 +64,7 @@ import {
|
|
|
64
64
|
} from 'src/types/textInputTypes.js'
|
|
65
65
|
import { randomUUID, type UUID } from 'crypto'
|
|
66
66
|
import { getInitialSettings, getSettings_DEPRECATED } from './settings/settings.js'
|
|
67
|
+
import { getCurrentSessionBrainMode } from './sessionStorage.js'
|
|
67
68
|
import { getSnippetForTwoFileDiff } from 'src/tools/FileEditTool/utils.js'
|
|
68
69
|
import type {
|
|
69
70
|
ContentBlockParam,
|
|
@@ -1594,7 +1595,6 @@ function getCriticalSystemReminderAttachment(
|
|
|
1594
1595
|
}
|
|
1595
1596
|
|
|
1596
1597
|
function getBrainModeReminderAttachment(): Attachment[] {
|
|
1597
|
-
const { getCurrentSessionBrainMode } = require('./sessionStorage.js')
|
|
1598
1598
|
if (!getInitialSettings().brainMode && !getCurrentSessionBrainMode()) {
|
|
1599
1599
|
return []
|
|
1600
1600
|
}
|
|
@@ -1602,7 +1602,7 @@ function getBrainModeReminderAttachment(): Attachment[] {
|
|
|
1602
1602
|
{
|
|
1603
1603
|
type: 'system_reminder' as const,
|
|
1604
1604
|
content:
|
|
1605
|
-
'/brain active —
|
|
1605
|
+
'/brain active — You are the high-dimensional thinker. Delegate everything through Agent.',
|
|
1606
1606
|
},
|
|
1607
1607
|
]
|
|
1608
1608
|
}
|
package/src/utils/context.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { getCanonicalName } from './model/model.js'
|
|
|
6
6
|
import { getModelCapability } from './model/modelCapabilities.js'
|
|
7
7
|
|
|
8
8
|
// Model context window size (200k tokens for all models right now)
|
|
9
|
-
export const MODEL_CONTEXT_WINDOW_DEFAULT =
|
|
9
|
+
export const MODEL_CONTEXT_WINDOW_DEFAULT = 1_000_000
|
|
10
10
|
|
|
11
11
|
// Maximum output tokens for compact operations
|
|
12
12
|
export const COMPACT_MAX_OUTPUT_TOKENS = 20_000
|
|
@@ -2303,6 +2303,7 @@ export async function loadTranscriptFromFile(
|
|
|
2303
2303
|
filePath: string,
|
|
2304
2304
|
): Promise<LogOption> {
|
|
2305
2305
|
if (filePath.endsWith('.jsonl')) {
|
|
2306
|
+
const data = await loadTranscriptFile(filePath)
|
|
2306
2307
|
const {
|
|
2307
2308
|
messages,
|
|
2308
2309
|
summaries,
|
|
@@ -2315,7 +2316,7 @@ export async function loadTranscriptFromFile(
|
|
|
2315
2316
|
leafUuids,
|
|
2316
2317
|
contentReplacements,
|
|
2317
2318
|
worktreeStates,
|
|
2318
|
-
} =
|
|
2319
|
+
} = data
|
|
2319
2320
|
|
|
2320
2321
|
if (messages.size === 0) {
|
|
2321
2322
|
throw new Error('No messages found in JSONL file')
|
|
@@ -2360,6 +2361,7 @@ export async function loadTranscriptFromFile(
|
|
|
2360
2361
|
worktreeSession: worktreeStates.has(sessionId)
|
|
2361
2362
|
? worktreeStates.get(sessionId)
|
|
2362
2363
|
: undefined,
|
|
2364
|
+
brainMode: resolveBrainMode(data, sessionId),
|
|
2363
2365
|
}
|
|
2364
2366
|
}
|
|
2365
2367
|
|
|
@@ -2988,6 +2990,7 @@ export async function loadFullLog(log: LogOption): Promise<LogOption> {
|
|
|
2988
2990
|
}
|
|
2989
2991
|
|
|
2990
2992
|
try {
|
|
2993
|
+
const data = await loadTranscriptFile(sessionFile)
|
|
2991
2994
|
const {
|
|
2992
2995
|
messages,
|
|
2993
2996
|
summaries,
|
|
@@ -3008,7 +3011,7 @@ export async function loadFullLog(log: LogOption): Promise<LogOption> {
|
|
|
3008
3011
|
contextCollapseCommits,
|
|
3009
3012
|
contextCollapseSnapshot,
|
|
3010
3013
|
leafUuids,
|
|
3011
|
-
} =
|
|
3014
|
+
} = data
|
|
3012
3015
|
|
|
3013
3016
|
if (messages.size === 0) {
|
|
3014
3017
|
return log
|
|
@@ -3044,7 +3047,7 @@ export async function loadFullLog(log: LogOption): Promise<LogOption> {
|
|
|
3044
3047
|
agentColor: sessionId ? agentColors.get(sessionId) : log.agentColor,
|
|
3045
3048
|
agentSetting: sessionId ? agentSettings.get(sessionId) : log.agentSetting,
|
|
3046
3049
|
mode: sessionId ? (modes.get(sessionId) as LogOption['mode']) : log.mode,
|
|
3047
|
-
brainMode: sessionId ?
|
|
3050
|
+
brainMode: sessionId ? resolveBrainMode(data, sessionId) : log.brainMode,
|
|
3048
3051
|
worktreeSession:
|
|
3049
3052
|
sessionId && worktreeStates.has(sessionId)
|
|
3050
3053
|
? worktreeStates.get(sessionId)
|
|
@@ -3633,7 +3636,7 @@ export async function loadTranscriptFile(
|
|
|
3633
3636
|
agentColors.set(entry.sessionId, entry.agentColor)
|
|
3634
3637
|
} else if (entry.type === 'agent-setting' && entry.sessionId) {
|
|
3635
3638
|
agentSettings.set(entry.sessionId, entry.agentSetting)
|
|
3636
|
-
} else if (entry.type === 'mode' && entry.sessionId) {
|
|
3639
|
+
} else if (entry.type === 'mode' && entry.sessionId) {
|
|
3637
3640
|
modes.set(entry.sessionId, entry.mode)
|
|
3638
3641
|
} else if (entry.type === 'brain-mode' && entry.sessionId) {
|
|
3639
3642
|
brainModes.set(entry.sessionId, entry.brainMode)
|
|
@@ -3851,6 +3854,17 @@ export async function loadTranscriptFile(
|
|
|
3851
3854
|
}
|
|
3852
3855
|
}
|
|
3853
3856
|
|
|
3857
|
+
/**
|
|
3858
|
+
* Resolves the brainMode flag for a given session from a loaded transcript.
|
|
3859
|
+
* Encapsulates the Map.get() pattern so callers do not need to remember it.
|
|
3860
|
+
*/
|
|
3861
|
+
export function resolveBrainMode(
|
|
3862
|
+
transcript: Awaited<ReturnType<typeof loadTranscriptFile>>,
|
|
3863
|
+
sessionId: string,
|
|
3864
|
+
): boolean | undefined {
|
|
3865
|
+
return transcript.brainModes.get(sessionId as UUID)
|
|
3866
|
+
}
|
|
3867
|
+
|
|
3854
3868
|
/**
|
|
3855
3869
|
* Loads all messages, summaries, file history snapshots, and attribution snapshots from a specific session file.
|
|
3856
3870
|
*/
|
|
@@ -3860,6 +3874,11 @@ async function loadSessionFile(sessionId: UUID): Promise<{
|
|
|
3860
3874
|
customTitles: Map<UUID, string>
|
|
3861
3875
|
tags: Map<UUID, string>
|
|
3862
3876
|
agentSettings: Map<UUID, string>
|
|
3877
|
+
agentColors: Map<UUID, string>
|
|
3878
|
+
modes: Map<UUID, string>
|
|
3879
|
+
prNumbers: Map<UUID, number>
|
|
3880
|
+
prUrls: Map<UUID, string>
|
|
3881
|
+
prRepositories: Map<UUID, string>
|
|
3863
3882
|
worktreeStates: Map<UUID, PersistedWorktreeSession | null>
|
|
3864
3883
|
fileHistorySnapshots: Map<UUID, FileHistorySnapshotMessage>
|
|
3865
3884
|
attributionSnapshots: Map<UUID, AttributionSnapshotMessage>
|
|
@@ -3910,12 +3929,18 @@ export async function getLastSessionLog(
|
|
|
3910
3929
|
sessionId: UUID,
|
|
3911
3930
|
): Promise<LogOption | null> {
|
|
3912
3931
|
// Single read: load all session data at once instead of reading the file twice
|
|
3932
|
+
const data = await loadSessionFile(sessionId)
|
|
3913
3933
|
const {
|
|
3914
3934
|
messages,
|
|
3915
3935
|
summaries,
|
|
3916
3936
|
customTitles,
|
|
3917
3937
|
tags,
|
|
3918
3938
|
agentSettings,
|
|
3939
|
+
modes,
|
|
3940
|
+
agentColors,
|
|
3941
|
+
prNumbers,
|
|
3942
|
+
prUrls,
|
|
3943
|
+
prRepositories,
|
|
3919
3944
|
worktreeStates,
|
|
3920
3945
|
brainModes,
|
|
3921
3946
|
fileHistorySnapshots,
|
|
@@ -3923,7 +3948,7 @@ export async function getLastSessionLog(
|
|
|
3923
3948
|
contentReplacements,
|
|
3924
3949
|
contextCollapseCommits,
|
|
3925
3950
|
contextCollapseSnapshot,
|
|
3926
|
-
} =
|
|
3951
|
+
} = data
|
|
3927
3952
|
if (messages.size === 0) return null
|
|
3928
3953
|
// Prime getSessionMessages cache so recordTranscript (called after REPL
|
|
3929
3954
|
// mount on --resume) skips a second full file load. -170~227ms on large sessions.
|
|
@@ -3962,7 +3987,12 @@ export async function getLastSessionLog(
|
|
|
3962
3987
|
contentReplacements.get(sessionId) ?? [],
|
|
3963
3988
|
),
|
|
3964
3989
|
worktreeSession: worktreeStates.get(sessionId),
|
|
3965
|
-
brainMode:
|
|
3990
|
+
brainMode: resolveBrainMode(data, sessionId),
|
|
3991
|
+
mode: modes.get(sessionId) as 'coordinator' | 'normal' | undefined,
|
|
3992
|
+
agentColor: agentColors.get(sessionId),
|
|
3993
|
+
prNumber: prNumbers.get(sessionId),
|
|
3994
|
+
prUrl: prUrls.get(sessionId),
|
|
3995
|
+
prRepository: prRepositories.get(sessionId),
|
|
3966
3996
|
contextCollapseCommits: contextCollapseCommits.filter(
|
|
3967
3997
|
e => e.sessionId === sessionId,
|
|
3968
3998
|
),
|
|
@@ -4641,6 +4671,7 @@ export async function loadAllLogsFromSessionFile(
|
|
|
4641
4671
|
sessionFile: string,
|
|
4642
4672
|
projectPathOverride?: string,
|
|
4643
4673
|
): Promise<LogOption[]> {
|
|
4674
|
+
const data = await loadTranscriptFile(sessionFile, { keepAllLeaves: true })
|
|
4644
4675
|
const {
|
|
4645
4676
|
messages,
|
|
4646
4677
|
summaries,
|
|
@@ -4658,7 +4689,7 @@ export async function loadAllLogsFromSessionFile(
|
|
|
4658
4689
|
attributionSnapshots,
|
|
4659
4690
|
contentReplacements,
|
|
4660
4691
|
leafUuids,
|
|
4661
|
-
} =
|
|
4692
|
+
} = data
|
|
4662
4693
|
|
|
4663
4694
|
if (messages.size === 0) return []
|
|
4664
4695
|
|
|
@@ -4716,7 +4747,7 @@ export async function loadAllLogsFromSessionFile(
|
|
|
4716
4747
|
agentColor: agentColors.get(sessionId),
|
|
4717
4748
|
agentSetting: agentSettings.get(sessionId),
|
|
4718
4749
|
mode: modes.get(sessionId) as LogOption['mode'],
|
|
4719
|
-
brainMode:
|
|
4750
|
+
brainMode: resolveBrainMode(data, sessionId),
|
|
4720
4751
|
prNumber: prNumbers.get(sessionId),
|
|
4721
4752
|
prUrl: prUrls.get(sessionId),
|
|
4722
4753
|
prRepository: prRepositories.get(sessionId),
|
package/src/utils/tokens.ts
CHANGED
|
@@ -52,6 +52,29 @@ export function getTokenCountFromUsage(usage: Usage): number {
|
|
|
52
52
|
)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Calculate total tokens across all agent messages, matching the ProgressTracker
|
|
57
|
+
* accumulation logic in LocalAgentTask. In Claude's API:
|
|
58
|
+
* - input_tokens (and cache tokens) are cumulative per turn — each call already
|
|
59
|
+
* includes all previous context, so we keep only the LATEST value.
|
|
60
|
+
* - output_tokens are per-turn independent, so we SUM them across all turns.
|
|
61
|
+
*/
|
|
62
|
+
export function getTokenCountFromMessages(messages: Message[]): number {
|
|
63
|
+
let latestInputTokens = 0
|
|
64
|
+
let cumulativeOutputTokens = 0
|
|
65
|
+
for (const message of messages) {
|
|
66
|
+
const usage = getTokenUsage(message)
|
|
67
|
+
if (usage) {
|
|
68
|
+
latestInputTokens =
|
|
69
|
+
usage.input_tokens +
|
|
70
|
+
(usage.cache_creation_input_tokens ?? 0) +
|
|
71
|
+
(usage.cache_read_input_tokens ?? 0)
|
|
72
|
+
cumulativeOutputTokens += usage.output_tokens
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return latestInputTokens + cumulativeOutputTokens
|
|
76
|
+
}
|
|
77
|
+
|
|
55
78
|
export function tokenCountFromLastAPIResponse(messages: Message[]): number {
|
|
56
79
|
let i = messages.length - 1
|
|
57
80
|
while (i >= 0) {
|