This commit is contained in:
Aditya Raj Prasad 2025-12-02 06:40:28 +01:00 committed by GitHub
commit 8fe790eed4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -42,7 +42,9 @@ export const createAgentStream = async ({
searchScopeRepoNames, searchScopeRepoNames,
}); });
const stream = streamText({ let stream;
try {
stream = streamText({
model, model,
providerOptions, providerOptions,
system: baseSystemPrompt, system: baseSystemPrompt,
@ -56,51 +58,35 @@ export const createAgentStream = async ({
[toolNames.listAllRepos]: listAllReposTool, [toolNames.listAllRepos]: listAllReposTool,
}, },
prepareStep: async ({ stepNumber }) => { prepareStep: async ({ stepNumber }) => {
// The first step attaches any mentioned sources to the system prompt.
if (stepNumber === 0 && inputSources.length > 0) { if (stepNumber === 0 && inputSources.length > 0) {
const fileSources = inputSources.filter((source) => source.type === 'file'); const fileSources = inputSources.filter((source) => source.type === 'file');
const resolvedFileSources = ( const resolvedFileSources = (
await Promise.all(fileSources.map(resolveFileSource))) await Promise.all(fileSources.map(resolveFileSource)))
.filter((source) => source !== undefined) .filter((source) => source !== undefined)
const fileSourcesSystemPrompt = await createFileSourcesSystemPrompt({ const fileSourcesSystemPrompt = await createFileSourcesSystemPrompt({
files: resolvedFileSources files: resolvedFileSources
}); });
return { return {
system: `${baseSystemPrompt}\n\n${fileSourcesSystemPrompt}` system: `${baseSystemPrompt}\n\n${fileSourcesSystemPrompt}`
} }
} }
if (stepNumber === env.SOURCEBOT_CHAT_MAX_STEP_COUNT - 1) { if (stepNumber === env.SOURCEBOT_CHAT_MAX_STEP_COUNT - 1) {
return { return {
system: `**CRITICAL**: You have reached the maximum number of steps!! YOU MUST PROVIDE YOUR FINAL ANSWER NOW. DO NOT KEEP RESEARCHING.\n\n${answerInstructions}`, system: `**CRITICAL**: You have reached the maximum number of steps!! YOU MUST PROVIDE YOUR FINAL ANSWER NOW. DO NOT KEEP RESEARCHING.\n\n${answerInstructions}`,
activeTools: [], activeTools: [],
} }
} }
return undefined; return undefined;
}, },
temperature: env.SOURCEBOT_CHAT_MODEL_TEMPERATURE, temperature: env.SOURCEBOT_CHAT_MODEL_TEMPERATURE,
stopWhen: [ stopWhen: [
stepCountIsGTE(env.SOURCEBOT_CHAT_MAX_STEP_COUNT), stepCountIsGTE(env.SOURCEBOT_CHAT_MAX_STEP_COUNT),
], ],
toolChoice: "auto", // Let the model decide when to use tools toolChoice: "auto",
onStepFinish: ({ toolResults }) => { onStepFinish: ({ toolResults }) => {
// This takes care of extracting any sources that the LLM has seen as part of
// the tool calls it made.
toolResults.forEach(({ toolName, output, dynamic }) => { toolResults.forEach(({ toolName, output, dynamic }) => {
// we don't care about dynamic tool results here. if (dynamic) return;
if (dynamic) { if (isServiceError(output)) return;
return;
}
if (isServiceError(output)) {
// is there something we want to do here?
return;
}
if (toolName === toolNames.readFiles) { if (toolName === toolNames.readFiles) {
output.forEach((file) => { output.forEach((file) => {
onWriteSource({ onWriteSource({
@ -112,8 +98,7 @@ export const createAgentStream = async ({
name: file.path.split('/').pop() ?? file.path, name: file.path.split('/').pop() ?? file.path,
}) })
}) })
} } else if (toolName === toolNames.searchCode) {
else if (toolName === toolNames.searchCode) {
output.files.forEach((file) => { output.files.forEach((file) => {
onWriteSource({ onWriteSource({
type: 'file', type: 'file',
@ -124,8 +109,7 @@ export const createAgentStream = async ({
name: file.fileName.split('/').pop() ?? file.fileName, name: file.fileName.split('/').pop() ?? file.fileName,
}) })
}) })
} } else if (toolName === toolNames.findSymbolDefinitions || toolName === toolNames.findSymbolReferences) {
else if (toolName === toolNames.findSymbolDefinitions || toolName === toolNames.findSymbolReferences) {
output.forEach((file) => { output.forEach((file) => {
onWriteSource({ onWriteSource({
type: 'file', type: 'file',
@ -139,7 +123,6 @@ export const createAgentStream = async ({
} }
}) })
}, },
// Only enable langfuse traces in cloud environments.
experimental_telemetry: { experimental_telemetry: {
isEnabled: clientEnv.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT !== undefined, isEnabled: clientEnv.NEXT_PUBLIC_SOURCEBOT_CLOUD_ENVIRONMENT !== undefined,
metadata: { metadata: {
@ -150,7 +133,12 @@ export const createAgentStream = async ({
logger.error(error); logger.error(error);
}, },
}); });
} catch (err) {
if (model?.providerId === 'openai-compatible') {
throw new Error('The selected AI provider does not support codebase tool calls. Please use a provider that supports function/tool calls for codebase-related questions.');
}
throw err;
}
return stream; return stream;
} }