Skip to content

Commit ec66a7a

Browse files
committed
better fallback
1 parent fb1f1ec commit ec66a7a

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

frontend/src/lib/components/copilot/chat/flow/core.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
getLangContext,
1313
SUPPORTED_CHAT_SCRIPT_LANGUAGES
1414
} from '../script/core'
15-
import { createSearchHubScriptsTool, createToolDef, type Tool, executeTestRun, buildSchemaForTool } from '../shared'
15+
import { createSearchHubScriptsTool, createToolDef, type Tool, executeTestRun, buildSchemaForTool, buildTestRunArgs } from '../shared'
1616
import type { ExtendedOpenFlow } from '$lib/components/flows/types'
1717

1818
export type AIModuleAction = 'added' | 'modified' | 'removed'
@@ -562,7 +562,7 @@ export const flowTools: Tool<FlowAIChatHelpers>[] = [
562562
},
563563
{
564564
def: testRunFlowToolDef,
565-
fn: async ({ args, workspace, helpers, toolCallbacks, toolId }) => {
565+
fn: async function({ args, workspace, helpers, toolCallbacks, toolId }) {
566566
const { flow } = helpers.getFlowAndSelectedId()
567567

568568
if (!flow || !flow.value) {
@@ -575,11 +575,12 @@ export const flowTools: Tool<FlowAIChatHelpers>[] = [
575575
)
576576
}
577577

578+
const parsedArgs = await buildTestRunArgs(args, this.def)
578579
return executeTestRun({
579580
jobStarter: () => JobService.runFlowPreview({
580581
workspace: workspace,
581582
requestBody: {
582-
args: args,
583+
args: parsedArgs,
583584
value: flow.value,
584585
}
585586
}),

frontend/src/lib/components/copilot/chat/script/core.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { scriptLangToEditorLang } from '$lib/scripts'
1313
import { getDbSchemas } from '$lib/components/apps/components/display/dbtable/utils'
1414
import type { CodePieceElement, ContextElement } from '../context'
1515
import { PYTHON_PREPROCESSOR_MODULE_CODE, TS_PREPROCESSOR_MODULE_CODE } from '$lib/script_helpers'
16-
import { createSearchHubScriptsTool, type Tool, executeTestRun, buildSchemaForTool } from '../shared'
16+
import { createSearchHubScriptsTool, type Tool, executeTestRun, buildSchemaForTool, buildTestRunArgs } from '../shared'
1717
import { setupTypeAcquisition, type DepsToGet } from '$lib/ata'
1818
import { getModelContextWindow } from '../../lib'
1919
import { inferArgs } from '$lib/infer'
@@ -855,7 +855,7 @@ const TEST_RUN_SCRIPT_TOOL: ChatCompletionTool = {
855855

856856
export const testRunScriptTool: Tool<ScriptChatHelpers> = {
857857
def: TEST_RUN_SCRIPT_TOOL,
858-
fn: async ({ args, workspace, helpers, toolCallbacks, toolId }) => {
858+
fn: async function({ args, workspace, helpers, toolCallbacks, toolId }) {
859859
const scriptOptions = helpers.getScriptOptions()
860860

861861
if (!scriptOptions) {
@@ -880,13 +880,15 @@ export const testRunScriptTool: Tool<ScriptChatHelpers> = {
880880
toolCallbacks.setToolStatus(toolId, { content: 'Code changes applied, starting test...' })
881881
}
882882

883+
const parsedArgs = await buildTestRunArgs(args, this.def)
884+
883885
return executeTestRun({
884886
jobStarter: () => JobService.runScriptPreview({
885887
workspace: workspace,
886888
requestBody: {
887889
path: scriptOptions.path,
888890
content: codeToTest,
889-
args,
891+
args: parsedArgs,
890892
language: scriptOptions.lang as ScriptLang,
891893
}
892894
}),

frontend/src/lib/components/copilot/chat/shared.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ export function createToolDef(
190190
name,
191191
target: 'openAi'
192192
})
193+
if (name === 'test_run_step') {
194+
console.log('schema', schema)
195+
}
193196
let parameters = schema.definitions![name] as FunctionParameters
194197
parameters = {
195198
...parameters,
@@ -253,19 +256,29 @@ export const createSearchHubScriptsTool = (withContent: boolean = false) => ({
253256
}
254257
})
255258

256-
export async function buildSchemaForTool(toolDef: ChatCompletionTool, schemaBuilder: () => Promise<FunctionParameters>): Promise<void> {
259+
export async function buildSchemaForTool(toolDef: ChatCompletionTool, schemaBuilder: () => Promise<FunctionParameters>): Promise<boolean> {
257260
try {
258261
const schema = await schemaBuilder()
262+
263+
// if schema properties contains values different from '^[a-zA-Z0-9_.-]{1,64}$'
264+
const invalidProperties = Object.keys(schema.properties ?? {}).filter((key) => !/^[a-zA-Z0-9_.-]{1,64}$/.test(key))
265+
if (invalidProperties.length > 0) {
266+
console.warn(`Invalid flow inputs schema: ${invalidProperties.join(', ')}`)
267+
throw new Error(`Invalid flow inputs schema: ${invalidProperties.join(', ')}`)
268+
}
269+
259270
toolDef.function.parameters = { ...schema, additionalProperties: false }
260271
// OPEN AI models don't support strict mode well with schema with complex properties, so we disable it
261272
const model = get(copilotSessionModel)?.provider
262273
if (model === 'openai' || model === 'azure_openai') {
263274
toolDef.function.strict = false
264275
}
276+
return true
265277
} catch (error) {
266278
console.error('Error building schema for tool', error)
267279
// fallback to schema with any properties
268-
toolDef.function.parameters = { type: 'object', properties: {}, additionalProperties: true, strict: false }
280+
toolDef.function.parameters = { type: 'object', properties: { args: { type: 'string', description: 'JSON string containing the arguments for the tool' } }, additionalProperties: false, strict: false, required: ['args'] }
281+
return false
269282
}
270283
}
271284

@@ -378,6 +391,20 @@ function getErrorMessage(result: unknown): string {
378391
return 'Unknown error'
379392
}
380393

394+
// Build test run args based on the tool definition, if it contains a fallback schema
395+
export async function buildTestRunArgs(args: any, toolDef: ChatCompletionTool): Promise<any> {
396+
let parsedArgs = args
397+
// if the schema is the fallback schema, parse the args as a JSON string
398+
if ((toolDef.function.parameters as any).properties?.args?.description === 'JSON string containing the arguments for the tool') {
399+
try {
400+
parsedArgs = JSON.parse(args.args)
401+
} catch (error) {
402+
console.error('Error parsing arguments for tool', error)
403+
}
404+
}
405+
return parsedArgs
406+
}
407+
381408
// Main execution function for test runs
382409
export async function executeTestRun(config: TestRunConfig): Promise<string> {
383410
try {

0 commit comments

Comments
 (0)