Skip to content

Commit d2ac9eb

Browse files
Merge origin/main into brandon/cli-env-filter
Resolved merge conflict in common/src/types/contracts/billing.ts by accepting upstream changes. The upstream version uses ErrorOr<CreditFallbackResult> which is cleaner than the previous custom success/error object. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
2 parents cc015c9 + 480af9e commit d2ac9eb

File tree

13 files changed

+224
-222
lines changed

13 files changed

+224
-222
lines changed

backend/src/__tests__/web-search-tool.test.ts

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from '@codebuff/common/testing/impl/agent-runtime'
1313
import { getToolCallString } from '@codebuff/common/tools/utils'
1414
import { getInitialSessionState } from '@codebuff/common/types/session-state'
15+
import { success } from '@codebuff/common/util/error'
1516
import {
1617
afterEach,
1718
beforeAll,
@@ -25,15 +26,15 @@ import {
2526

2627
import { mockFileContext } from './test-utils'
2728
import researcherAgent from '../../../.agents/researcher/researcher'
28-
import * as linkupApi from '../llm-apis/linkup-api'
29+
import * as linkupApi from '@codebuff/agent-runtime/llm-apis/linkup-api'
2930
import { runAgentStep } from '../run-agent-step'
3031

3132
import type {
3233
AgentRuntimeDeps,
3334
AgentRuntimeScopedDeps,
3435
} from '@codebuff/common/types/contracts/agent-runtime'
3536

36-
let agentRuntimeImpl: AgentRuntimeDeps = { ...TEST_AGENT_RUNTIME_IMPL }
37+
let agentRuntimeImpl: AgentRuntimeDeps
3738
function mockAgentStream(content: string | string[]) {
3839
agentRuntimeImpl.promptAiSdkStream = async function* ({}) {
3940
if (typeof content === 'string') {
@@ -54,6 +55,14 @@ describe('web_search tool with researcher agent', () => {
5455
})
5556

5657
beforeEach(() => {
58+
agentRuntimeImpl = {
59+
...TEST_AGENT_RUNTIME_IMPL,
60+
consumeCreditsWithFallback: async () => {
61+
return success({
62+
chargedToOrganization: false,
63+
})
64+
},
65+
}
5766
agentRuntimeScopedImpl = { ...TEST_AGENT_RUNTIME_SCOPED_IMPL }
5867

5968
// Mock analytics and tracing
@@ -139,11 +148,12 @@ describe('web_search tool with researcher agent', () => {
139148
})
140149

141150
// Just verify that searchWeb was called
142-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
143-
query: 'test query',
144-
depth: 'standard',
145-
logger: expect.anything(),
146-
})
151+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
152+
expect.objectContaining({
153+
query: 'test query',
154+
depth: 'standard',
155+
}),
156+
)
147157
})
148158

149159
test('should successfully perform web search with basic query', async () => {
@@ -190,11 +200,12 @@ describe('web_search tool with researcher agent', () => {
190200
spawnParams: undefined,
191201
})
192202

193-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
194-
query: 'Next.js 15 new features',
195-
depth: 'standard',
196-
logger: expect.anything(),
197-
})
203+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
204+
expect.objectContaining({
205+
query: 'Next.js 15 new features',
206+
depth: 'standard',
207+
}),
208+
)
198209

199210
// Check that the search results were added to the message history
200211
const toolResultMessages = newAgentState.messageHistory.filter(
@@ -251,11 +262,12 @@ describe('web_search tool with researcher agent', () => {
251262
spawnParams: undefined,
252263
})
253264

254-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
255-
query: 'React Server Components tutorial',
256-
depth: 'deep',
257-
logger: expect.anything(),
258-
})
265+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
266+
expect.objectContaining({
267+
query: 'React Server Components tutorial',
268+
depth: 'deep',
269+
}),
270+
)
259271
})
260272

261273
test('should handle case when no search results are found', async () => {
@@ -298,11 +310,12 @@ describe('web_search tool with researcher agent', () => {
298310
})
299311

300312
// Verify that searchWeb was called
301-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
302-
query: 'very obscure search query that returns nothing',
303-
depth: 'standard',
304-
logger: expect.anything(),
305-
})
313+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
314+
expect.objectContaining({
315+
query: 'very obscure search query that returns nothing',
316+
depth: 'standard',
317+
}),
318+
)
306319

307320
// Check that the "no results found" message was added
308321
const toolResultMessages = newAgentState.messageHistory.filter(
@@ -358,11 +371,12 @@ describe('web_search tool with researcher agent', () => {
358371
})
359372

360373
// Verify that searchWeb was called
361-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
362-
query: 'test query',
363-
depth: 'standard',
364-
logger: expect.anything(),
365-
})
374+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
375+
expect.objectContaining({
376+
query: 'test query',
377+
depth: 'standard',
378+
}),
379+
)
366380

367381
// Check that the error message was added
368382
const toolResultMessages = newAgentState.messageHistory.filter(
@@ -417,11 +431,12 @@ describe('web_search tool with researcher agent', () => {
417431
})
418432

419433
// Verify that searchWeb was called
420-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
421-
query: 'test query',
422-
depth: 'standard',
423-
logger: expect.anything(),
424-
})
434+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
435+
expect.objectContaining({
436+
query: 'test query',
437+
depth: 'standard',
438+
}),
439+
)
425440
})
426441

427442
test('should handle non-Error exceptions', async () => {
@@ -466,11 +481,12 @@ describe('web_search tool with researcher agent', () => {
466481
})
467482

468483
// Verify that searchWeb was called
469-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
470-
query: 'test query',
471-
depth: 'standard',
472-
logger: expect.anything(),
473-
})
484+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
485+
expect.objectContaining({
486+
query: 'test query',
487+
depth: 'standard',
488+
}),
489+
)
474490

475491
// Check that the error message was added
476492
const toolResultMessages = newAgentState.messageHistory.filter(
@@ -527,11 +543,12 @@ describe('web_search tool with researcher agent', () => {
527543
})
528544

529545
// Verify that searchWeb was called
530-
expect(linkupApi.searchWeb).toHaveBeenCalledWith({
531-
query: 'test formatting',
532-
depth: 'standard',
533-
logger: expect.anything(),
534-
})
546+
expect(linkupApi.searchWeb).toHaveBeenCalledWith(
547+
expect.objectContaining({
548+
query: 'test formatting',
549+
depth: 'standard',
550+
}),
551+
)
535552

536553
// Check that the search results were formatted correctly
537554
const toolResultMessages = newAgentState.messageHistory.filter(

backend/src/impl/agent-runtime.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { consumeCreditsWithFallback } from '@codebuff/billing'
12
import { trackEvent } from '@codebuff/common/analytics'
23
import { consumeCreditsWithFallback } from '@codebuff/billing'
34

@@ -22,6 +23,9 @@ export const BACKEND_AGENT_RUNTIME_IMPL: AgentRuntimeDeps = Object.freeze({
2223
finishAgentRun,
2324
addAgentStep,
2425

26+
// Billing
27+
consumeCreditsWithFallback,
28+
2529
// LLM
2630
promptAiSdkStream,
2731
promptAiSdk,

backend/src/tools/handlers/list.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ import { handleRunFileChangeHooks } from '@codebuff/agent-runtime/tools/handlers
1414
import { handleRunTerminalCommand } from '@codebuff/agent-runtime/tools/handlers/tool/run-terminal-command'
1515
import { handleSetMessages } from '@codebuff/agent-runtime/tools/handlers/tool/set-messages'
1616
import { handleSetOutput } from '@codebuff/agent-runtime/tools/handlers/tool/set-output'
17+
import { handleStrReplace } from '@codebuff/agent-runtime/tools/handlers/tool/str-replace'
1718
import { handleThinkDeeply } from '@codebuff/agent-runtime/tools/handlers/tool/think-deeply'
1819
import { handleUpdateSubgoal } from '@codebuff/agent-runtime/tools/handlers/tool/update-subgoal'
20+
import { handleWebSearch } from '@codebuff/agent-runtime/tools/handlers/tool/web-search'
1921
import { handleWriteFile } from '@codebuff/agent-runtime/tools/handlers/tool/write-file'
2022

2123
import { handleSpawnAgentInline } from './tool/spawn-agent-inline'
2224
import { handleSpawnAgents } from './tool/spawn-agents'
23-
import { handleStrReplace } from './tool/str-replace'
24-
import { handleWebSearch } from './tool/web-search'
2525

2626
import type { CodebuffToolHandlerFunction } from '@codebuff/agent-runtime/tools/handlers/handler-function-type'
2727
import type { ToolName } from '@codebuff/common/tools/constants'

common/src/testing/impl/agent-runtime.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ export const TEST_AGENT_RUNTIME_IMPL = Object.freeze<AgentRuntimeDeps>({
3131
finishAgentRun: async () => {},
3232
addAgentStep: async () => 'test-agent-step-id',
3333

34+
// Billing
35+
consumeCreditsWithFallback: async () => {
36+
throw new Error(
37+
'consumeCreditsWithFallback not implemented in test runtime',
38+
)
39+
},
40+
3441
// LLM
3542
promptAiSdkStream: async function* () {
3643
throw new Error('promptAiSdkStream not implemented in test runtime')

common/src/types/contracts/agent-runtime.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export type AgentRuntimeDeps = {
3333
finishAgentRun: FinishAgentRunFn
3434
addAgentStep: AddAgentStepFn
3535

36+
// Billing
37+
consumeCreditsWithFallback: ConsumeCreditsWithFallbackFn
38+
3639
// LLM
3740
promptAiSdkStream: PromptAiSdkStreamFn
3841
promptAiSdk: PromptAiSdkFn

common/src/types/contracts/billing.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Logger } from './logger'
2+
import type { ErrorOr } from '../../util/error'
23

34
export type GetUserUsageDataFn = (params: {
45
userId: string
@@ -12,12 +13,12 @@ export type ConsumeCreditsWithFallbackFn = (params: {
1213
userId: string
1314
creditsToCharge: number
1415
repoUrl?: string | null
15-
context: string
16+
context: string // Description of what the credits are for (e.g., 'web search', 'documentation lookup')
1617
logger: Logger
17-
}) => Promise<{
18-
success: boolean
18+
}) => Promise<ErrorOr<CreditFallbackResult>>
19+
20+
export type CreditFallbackResult = {
1921
organizationId?: string
2022
organizationName?: string
2123
chargedToOrganization: boolean
22-
error?: string
23-
}>
24+
}

evals/impl/agent-runtime.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { success } from '@codebuff/common/util/error'
2+
13
import type { AgentTemplate } from '@codebuff/common/types/agent-template'
24
import type { AgentRuntimeDeps } from '@codebuff/common/types/contracts/agent-runtime'
35

@@ -13,6 +15,13 @@ export const EVALS_AGENT_RUNTIME_IMPL = Object.freeze<AgentRuntimeDeps>({
1315
finishAgentRun: async () => {},
1416
addAgentStep: async () => 'test-agent-step-id',
1517

18+
// Backend
19+
consumeCreditsWithFallback: async () => {
20+
return success({
21+
chargedToOrganization: false,
22+
})
23+
},
24+
1625
// LLM
1726
promptAiSdkStream: async function* () {
1827
throw new Error('promptAiSdkStream not implemented in eval runtime')

packages/agent-runtime/src/find-files/request-files-prompt.ts

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { dirname, isAbsolute, normalize } from 'path'
22

3-
import { insertTrace } from '@codebuff/bigquery'
43
import {
54
finetunedVertexModels,
65
models,
@@ -17,10 +16,6 @@ import {
1716
} from '../util/messages'
1817

1918
import type { TextBlock } from '../llm-api/claude'
20-
import type {
21-
GetExpandedFileContextForTrainingTrace,
22-
GetRelevantFilesTrace,
23-
} from '@codebuff/bigquery'
2419
import type { PromptAiSdkFn } from '@codebuff/common/types/contracts/llm'
2520
import type { Logger } from '@codebuff/common/types/contracts/logger'
2621
import type { ParamsExcluding } from '@codebuff/common/types/function-params'
@@ -236,29 +231,6 @@ async function getRelevantFiles(
236231

237232
const files = validateFilePaths(response.split('\n'))
238233

239-
const trace: GetRelevantFilesTrace = {
240-
id: crypto.randomUUID(),
241-
agent_step_id: agentStepId,
242-
user_id: userId ?? '',
243-
created_at: new Date(),
244-
type: 'get-relevant-files',
245-
payload: {
246-
messages: messagesWithPrompt,
247-
system,
248-
output: response,
249-
request_type: requestType,
250-
user_input_id: userInputId,
251-
client_session_id: clientSessionId,
252-
fingerprint_id: fingerprintId,
253-
model: finetunedModel,
254-
repo_name: repoId, // Use repoId parameter for trace
255-
},
256-
}
257-
258-
insertTrace({ trace, logger }).catch((error: Error) => {
259-
logger.error({ error }, 'Failed to insert trace')
260-
})
261-
262234
return { files, duration, requestType, response }
263235
}
264236

@@ -317,29 +289,6 @@ async function getRelevantFilesForTraining(
317289

318290
const files = validateFilePaths(response.split('\n'))
319291

320-
const trace: GetExpandedFileContextForTrainingTrace = {
321-
id: crypto.randomUUID(),
322-
agent_step_id: agentStepId,
323-
user_id: userId ?? '',
324-
created_at: new Date(),
325-
type: 'get-expanded-file-context-for-training',
326-
payload: {
327-
messages: messagesWithPrompt,
328-
system,
329-
output: response,
330-
request_type: requestType,
331-
user_input_id: userInputId,
332-
client_session_id: clientSessionId,
333-
fingerprint_id: fingerprintId,
334-
model: models.ft_filepicker_005, // Use specific model for trace
335-
repo_name: repoId, // Use repoId parameter for trace
336-
},
337-
}
338-
339-
insertTrace({ trace, logger }).catch((error: Error) => {
340-
logger.error({ error }, 'Failed to insert trace')
341-
})
342-
343292
return { files, duration, requestType, response }
344293
}
345294

0 commit comments

Comments
 (0)