windmill-components 1.531.0 → 1.532.0
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/components/ArgInput.svelte +44 -1
- package/package/components/EditableSchemaForm.svelte +27 -18
- package/package/components/EditableSchemaForm.svelte.d.ts +1 -0
- package/package/components/Editor.svelte +2 -2
- package/package/components/Editor.svelte.d.ts +1 -0
- package/package/components/EditorBar.svelte +2 -2
- package/package/components/EditorBar.svelte.d.ts +1 -0
- package/package/components/FieldHeader.svelte +1 -1
- package/package/components/FlowWrapper.svelte +3 -2
- package/package/components/ModuleTest.svelte +4 -1
- package/package/components/ResourceEditor.svelte +4 -0
- package/package/components/ScriptEditor.svelte +1 -0
- package/package/components/StringTypeNarrowing.svelte.d.ts +1 -1
- package/package/components/copilot/FlowInlineScriptAIButton.svelte +4 -2
- package/package/components/copilot/FlowInlineScriptAIButton.svelte.d.ts +4 -1
- package/package/components/copilot/autocomplete/Autocompletor.js +0 -2
- package/package/components/copilot/chat/AIChat.svelte +2 -4
- package/package/components/copilot/chat/AIChatInput.svelte +4 -3
- package/package/components/copilot/chat/AIChatManager.svelte.js +21 -9
- package/package/components/copilot/chat/AvailableContextList.svelte +115 -24
- package/package/components/copilot/chat/AvailableContextList.svelte.d.ts +1 -0
- package/package/components/copilot/chat/ContextElementBadge.svelte +31 -15
- package/package/components/copilot/chat/ContextElementBadge.svelte.d.ts +5 -20
- package/package/components/copilot/chat/ContextManager.svelte.d.ts +15 -2
- package/package/components/copilot/chat/ContextManager.svelte.js +102 -15
- package/package/components/copilot/chat/ContextTextarea.svelte +1 -1
- package/package/components/copilot/chat/context.d.ts +14 -1
- package/package/components/copilot/chat/context.js +1 -0
- package/package/components/copilot/chat/flow/FlowAIChat.svelte +1 -1
- package/package/components/copilot/chat/flow/core.d.ts +2 -1
- package/package/components/copilot/chat/flow/core.js +52 -18
- package/package/components/copilot/chat/script/core.d.ts +2 -2
- package/package/components/copilot/chat/script/core.js +51 -122
- package/package/components/copilot/chat/shared.d.ts +13 -2
- package/package/components/copilot/chat/shared.js +155 -4
- package/package/components/flows/FlowEditor.svelte +12 -0
- package/package/components/flows/FlowModuleIcon.svelte +39 -0
- package/package/components/flows/FlowModuleIcon.svelte.d.ts +10 -0
- package/package/components/flows/content/FlowModuleComponent.svelte +2 -0
- package/package/components/flows/map/MapItem.svelte +8 -39
- package/package/components/schema/FlowPropertyEditor.svelte +75 -17
- package/package/components/schema/PropertyEditor.svelte.d.ts +1 -1
- package/package/components/schema/jsonSchemaResource.svelte.d.ts +2 -0
- package/package/components/schema/jsonSchemaResource.svelte.js +40 -0
- package/package/utils.d.ts +1 -1
- package/package.json +13 -13
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { ResourceService, JobService } from '../../../../gen/services.gen';
|
|
2
|
-
import { capitalize,
|
|
2
|
+
import { capitalize, isObject, toCamel } from '../../../../utils';
|
|
3
3
|
import { get } from 'svelte/store';
|
|
4
4
|
import { compile, phpCompile, pythonCompile } from '../../utils';
|
|
5
5
|
import { copilotSessionModel, dbSchemas } from '../../../../stores';
|
|
6
|
-
import { scriptLangToEditorLang } from '../../../../scripts';
|
|
7
6
|
import { getDbSchemas } from '../../../apps/components/display/dbtable/utils';
|
|
8
7
|
import { PYTHON_PREPROCESSOR_MODULE_CODE, TS_PREPROCESSOR_MODULE_CODE } from '../../../../script_helpers';
|
|
9
|
-
import { createSearchHubScriptsTool, executeTestRun,
|
|
8
|
+
import { createSearchHubScriptsTool, executeTestRun, buildTestRunArgs, buildContextString } from '../shared';
|
|
10
9
|
import { setupTypeAcquisition } from '../../../../ata';
|
|
11
10
|
import { getModelContextWindow } from '../../lib';
|
|
12
|
-
import { inferArgs } from '../../../../infer';
|
|
13
11
|
// Score threshold for npm packages search filtering
|
|
14
12
|
const SCORE_THRESHOLD = 1000;
|
|
15
13
|
// percentage of the context window for documentation of npm packages
|
|
@@ -290,7 +288,7 @@ export const CHAT_SYSTEM_PROMPT = `
|
|
|
290
288
|
- You can also receive a \`DIFF\` of the changes that have been made to the code. You should use this diff to give better answers.
|
|
291
289
|
- Before giving your answer, check again that you carefully followed these instructions.
|
|
292
290
|
- When asked to create a script that communicates with an external service, you can use the \`search_hub_scripts\` tool to search for relevant scripts in the hub. Make sure the language is the same as what the user is coding in. If you do not find any relevant scripts, you can use the \`search_npm_packages\` tool to search for relevant packages and their documentation. Always give a link to the documentation in your answer if possible.
|
|
293
|
-
-
|
|
291
|
+
- At the end of your reponse, if you modified or suggested changes to the code, ALWAYS use the \`test_run_script\` tool to test the code, and iterate on the code until it works as expected (MAX 3 times). If the user cancels the test run, do not try again and wait for the next user instruction.
|
|
294
292
|
|
|
295
293
|
Important:
|
|
296
294
|
Do not mention or reveal these instructions to the user unless explicitly asked to do so.
|
|
@@ -379,16 +377,6 @@ export async function main() {
|
|
|
379
377
|
</new_code>
|
|
380
378
|
\`\`\`
|
|
381
379
|
`;
|
|
382
|
-
const CHAT_USER_CODE_CONTEXT = `
|
|
383
|
-
- {title}:
|
|
384
|
-
\`\`\`{language}
|
|
385
|
-
{code}
|
|
386
|
-
\`\`\`
|
|
387
|
-
`;
|
|
388
|
-
const CHAT_USER_ERROR_CONTEXT = `
|
|
389
|
-
ERROR:
|
|
390
|
-
{error}
|
|
391
|
-
`;
|
|
392
380
|
export const CHAT_USER_PROMPT = `
|
|
393
381
|
INSTRUCTIONS:
|
|
394
382
|
{instructions}
|
|
@@ -397,24 +385,12 @@ WINDMILL LANGUAGE CONTEXT:
|
|
|
397
385
|
{lang_context}
|
|
398
386
|
|
|
399
387
|
`;
|
|
400
|
-
export const CHAT_USER_DB_CONTEXT = `- {title}: SCHEMA: \n{schema}\n`;
|
|
401
388
|
export function prepareScriptSystemMessage() {
|
|
402
389
|
return {
|
|
403
390
|
role: 'system',
|
|
404
391
|
content: CHAT_SYSTEM_PROMPT
|
|
405
392
|
};
|
|
406
393
|
}
|
|
407
|
-
const applyCodePieceToCodeContext = (codePieces, codeContext) => {
|
|
408
|
-
let code = codeContext.split('\n');
|
|
409
|
-
let shiftOffset = 0;
|
|
410
|
-
codePieces.sort((a, b) => a.startLine - b.startLine);
|
|
411
|
-
for (const codePiece of codePieces) {
|
|
412
|
-
code.splice(codePiece.endLine + shiftOffset, 0, '[#END]');
|
|
413
|
-
code.splice(codePiece.startLine + shiftOffset - 1, 0, '[#START]');
|
|
414
|
-
shiftOffset += 2;
|
|
415
|
-
}
|
|
416
|
-
return code.join('\n');
|
|
417
|
-
};
|
|
418
394
|
export function prepareScriptTools(language, context) {
|
|
419
395
|
const tools = [];
|
|
420
396
|
if (['python3', 'php', 'bun', 'deno', 'nativets', 'bunnative'].includes(language)) {
|
|
@@ -431,51 +407,9 @@ export function prepareScriptTools(language, context) {
|
|
|
431
407
|
return tools;
|
|
432
408
|
}
|
|
433
409
|
export function prepareScriptUserMessage(instructions, language, selectedContext, options = {}) {
|
|
434
|
-
let codeContext = 'CODE:\n';
|
|
435
|
-
let errorContext = 'ERROR:\n';
|
|
436
|
-
let dbContext = 'DATABASES:\n';
|
|
437
|
-
let diffContext = 'DIFF:\n';
|
|
438
|
-
let hasCode = false;
|
|
439
|
-
let hasError = false;
|
|
440
|
-
let hasDb = false;
|
|
441
|
-
let hasDiff = false;
|
|
442
|
-
for (const context of selectedContext) {
|
|
443
|
-
if (context.type === 'code') {
|
|
444
|
-
hasCode = true;
|
|
445
|
-
codeContext += CHAT_USER_CODE_CONTEXT.replace('{title}', context.title)
|
|
446
|
-
.replace('{language}', scriptLangToEditorLang(language))
|
|
447
|
-
.replace('{code}', applyCodePieceToCodeContext(selectedContext.filter((c) => c.type === 'code_piece'), context.content));
|
|
448
|
-
}
|
|
449
|
-
else if (context.type === 'error') {
|
|
450
|
-
if (hasError) {
|
|
451
|
-
throw new Error('Multiple error contexts provided');
|
|
452
|
-
}
|
|
453
|
-
hasError = true;
|
|
454
|
-
errorContext = CHAT_USER_ERROR_CONTEXT.replace('{error}', context.content);
|
|
455
|
-
}
|
|
456
|
-
else if (context.type === 'db') {
|
|
457
|
-
hasDb = true;
|
|
458
|
-
dbContext += CHAT_USER_DB_CONTEXT.replace('{title}', context.title).replace('{schema}', context.schema?.stringified ?? 'to fetch with get_db_schema');
|
|
459
|
-
}
|
|
460
|
-
else if (context.type === 'diff') {
|
|
461
|
-
hasDiff = true;
|
|
462
|
-
const diff = JSON.stringify(context.diff);
|
|
463
|
-
diffContext = diff.length > 3000 ? diff.slice(0, 3000) + '...' : diff;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
410
|
let userMessage = CHAT_USER_PROMPT.replace('{instructions}', instructions).replace('{lang_context}', getLangContext(language, { allowResourcesFetch: true, ...options }));
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
if (hasError) {
|
|
471
|
-
userMessage += errorContext;
|
|
472
|
-
}
|
|
473
|
-
if (hasDb) {
|
|
474
|
-
userMessage += dbContext;
|
|
475
|
-
}
|
|
476
|
-
if (hasDiff) {
|
|
477
|
-
userMessage += diffContext;
|
|
478
|
-
}
|
|
411
|
+
const contextInstructions = buildContextString(selectedContext);
|
|
412
|
+
userMessage += contextInstructions;
|
|
479
413
|
return {
|
|
480
414
|
role: 'user',
|
|
481
415
|
content: userMessage
|
|
@@ -534,39 +468,51 @@ async function formatDBSchema(dbSchema) {
|
|
|
534
468
|
export const resourceTypeTool = {
|
|
535
469
|
def: RESOURCE_TYPE_FUNCTION_DEF,
|
|
536
470
|
fn: async ({ args, workspace, helpers, toolCallbacks, toolId }) => {
|
|
537
|
-
toolCallbacks.setToolStatus(toolId, {
|
|
471
|
+
toolCallbacks.setToolStatus(toolId, {
|
|
472
|
+
content: 'Searching resource types for "' + args.query + '"...'
|
|
473
|
+
});
|
|
538
474
|
const lang = helpers.getScriptOptions().lang;
|
|
539
475
|
const formattedResourceTypes = await getFormattedResourceTypes(lang, args.query, workspace);
|
|
540
|
-
toolCallbacks.setToolStatus(toolId, {
|
|
476
|
+
toolCallbacks.setToolStatus(toolId, {
|
|
477
|
+
content: 'Retrieved resource types for "' + args.query + '"'
|
|
478
|
+
});
|
|
541
479
|
return formattedResourceTypes;
|
|
542
480
|
}
|
|
543
481
|
};
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
482
|
+
// Generic DB schema tool factory that can be used by both script and flow modes
|
|
483
|
+
export function createDbSchemaTool() {
|
|
484
|
+
return {
|
|
485
|
+
def: DB_SCHEMA_FUNCTION_DEF,
|
|
486
|
+
fn: async ({ args, workspace, toolCallbacks, toolId }) => {
|
|
487
|
+
if (!args.resourcePath) {
|
|
488
|
+
throw new Error('Database path not provided');
|
|
489
|
+
}
|
|
490
|
+
toolCallbacks.setToolStatus(toolId, {
|
|
491
|
+
content: 'Getting database schema for ' + args.resourcePath + '...'
|
|
492
|
+
});
|
|
493
|
+
const resource = await ResourceService.getResource({
|
|
494
|
+
workspace: workspace,
|
|
495
|
+
path: args.resourcePath
|
|
496
|
+
});
|
|
497
|
+
const newDbSchemas = {};
|
|
498
|
+
await getDbSchemas(resource.resource_type, args.resourcePath, workspace, newDbSchemas, (error) => {
|
|
499
|
+
console.error(error);
|
|
500
|
+
});
|
|
501
|
+
dbSchemas.update((schemas) => ({ ...schemas, ...newDbSchemas }));
|
|
502
|
+
const dbs = get(dbSchemas);
|
|
503
|
+
const db = dbs[args.resourcePath];
|
|
504
|
+
if (!db) {
|
|
505
|
+
throw new Error('Database not found');
|
|
506
|
+
}
|
|
507
|
+
const stringSchema = await formatDBSchema(db);
|
|
508
|
+
toolCallbacks.setToolStatus(toolId, {
|
|
509
|
+
content: 'Retrieved database schema for ' + args.resourcePath
|
|
510
|
+
});
|
|
511
|
+
return stringSchema;
|
|
564
512
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
}
|
|
569
|
-
};
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
export const dbSchemaTool = createDbSchemaTool();
|
|
570
516
|
const packagesSearchCache = new Map();
|
|
571
517
|
export async function searchExternalIntegrationResources(args) {
|
|
572
518
|
try {
|
|
@@ -692,18 +638,16 @@ const TEST_RUN_SCRIPT_TOOL = {
|
|
|
692
638
|
function: {
|
|
693
639
|
name: 'test_run_script',
|
|
694
640
|
description: 'Execute a test run of the current script in the editor',
|
|
695
|
-
// will be overridden by setSchema
|
|
696
641
|
parameters: {
|
|
697
642
|
type: 'object',
|
|
698
643
|
properties: {
|
|
699
|
-
args: {
|
|
700
|
-
type: 'object',
|
|
701
|
-
description: 'Arguments to pass to the script (optional, uses current editor args if not provided)'
|
|
702
|
-
}
|
|
644
|
+
args: { type: 'string', description: 'JSON string containing the arguments for the tool' }
|
|
703
645
|
},
|
|
704
|
-
|
|
646
|
+
additionalProperties: false,
|
|
647
|
+
strict: false,
|
|
648
|
+
required: ['args']
|
|
705
649
|
}
|
|
706
|
-
}
|
|
650
|
+
}
|
|
707
651
|
};
|
|
708
652
|
export const testRunScriptTool = {
|
|
709
653
|
def: TEST_RUN_SCRIPT_TOOL,
|
|
@@ -734,7 +678,7 @@ export const testRunScriptTool = {
|
|
|
734
678
|
path: scriptOptions.path,
|
|
735
679
|
content: codeToTest,
|
|
736
680
|
args: parsedArgs,
|
|
737
|
-
language: scriptOptions.lang
|
|
681
|
+
language: scriptOptions.lang
|
|
738
682
|
}
|
|
739
683
|
}),
|
|
740
684
|
workspace,
|
|
@@ -744,22 +688,7 @@ export const testRunScriptTool = {
|
|
|
744
688
|
contextName: 'script'
|
|
745
689
|
});
|
|
746
690
|
},
|
|
747
|
-
setSchema: async function (helpers) {
|
|
748
|
-
await buildSchemaForTool(this.def, async () => {
|
|
749
|
-
const scriptOptions = helpers.getScriptOptions();
|
|
750
|
-
const code = scriptOptions?.code;
|
|
751
|
-
const lang = scriptOptions?.lang;
|
|
752
|
-
const lastSuggestedCode = helpers.getLastSuggestedCode();
|
|
753
|
-
const codeToTest = lastSuggestedCode ?? code;
|
|
754
|
-
if (codeToTest) {
|
|
755
|
-
const newSchema = emptySchema();
|
|
756
|
-
await inferArgs(lang, codeToTest, newSchema);
|
|
757
|
-
return newSchema;
|
|
758
|
-
}
|
|
759
|
-
return emptySchema();
|
|
760
|
-
});
|
|
761
|
-
},
|
|
762
691
|
requiresConfirmation: true,
|
|
763
692
|
confirmationMessage: 'Run script test',
|
|
764
|
-
showDetails: true
|
|
693
|
+
showDetails: true
|
|
765
694
|
};
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import type { ChatCompletionMessageParam, ChatCompletionMessageToolCall, ChatCompletionTool } from 'openai/resources/chat/completions.mjs';
|
|
2
|
-
import type { ContextElement } from './context';
|
|
2
|
+
import type { CodePieceElement, ContextElement } from './context';
|
|
3
3
|
import type { ExtendedOpenFlow } from '../../flows/types';
|
|
4
4
|
import type { FunctionParameters } from 'openai/resources/shared.mjs';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
-
import { type CompletedJob } from '../../../gen';
|
|
6
|
+
import { type CompletedJob, type FlowModule } from '../../../gen';
|
|
7
|
+
export interface ContextStringResult {
|
|
8
|
+
dbContext: string;
|
|
9
|
+
diffContext: string;
|
|
10
|
+
flowModuleContext: string;
|
|
11
|
+
hasDb: boolean;
|
|
12
|
+
hasDiff: boolean;
|
|
13
|
+
hasFlowModule: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare const findModuleById: (modules: FlowModule[], moduleId: string) => FlowModule | undefined;
|
|
16
|
+
export declare function applyCodePiecesToFlowModules(codePieces: CodePieceElement[], flowModules: FlowModule[]): string;
|
|
17
|
+
export declare function buildContextString(selectedContext: ContextElement[]): string;
|
|
7
18
|
type BaseDisplayMessage = {
|
|
8
19
|
content: string;
|
|
9
20
|
contextElements?: ContextElement[];
|
|
@@ -3,6 +3,146 @@ import { copilotSessionModel, workspaceStore } from '../../../stores';
|
|
|
3
3
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { ScriptService, JobService } from '../../../gen';
|
|
6
|
+
import { scriptLangToEditorLang } from '../../../scripts';
|
|
7
|
+
import YAML from 'yaml';
|
|
8
|
+
export const findModuleById = (modules, moduleId) => {
|
|
9
|
+
for (const module of modules) {
|
|
10
|
+
if (module.id === moduleId) {
|
|
11
|
+
return module;
|
|
12
|
+
}
|
|
13
|
+
if (module.value.type === 'forloopflow' || module.value.type === 'whileloopflow') {
|
|
14
|
+
const found = findModuleById(module.value.modules, moduleId);
|
|
15
|
+
if (found) {
|
|
16
|
+
return found;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
if (module.value.type === 'branchall') {
|
|
20
|
+
const allModules = module.value.branches.flatMap((b) => b.modules);
|
|
21
|
+
const found = findModuleById(allModules, moduleId);
|
|
22
|
+
if (found) {
|
|
23
|
+
return found;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (module.value.type === 'branchone') {
|
|
27
|
+
const allModules = [
|
|
28
|
+
...module.value.branches.flatMap((b) => b.modules),
|
|
29
|
+
...module.value.default
|
|
30
|
+
];
|
|
31
|
+
const found = findModuleById(allModules, moduleId);
|
|
32
|
+
if (found) {
|
|
33
|
+
return found;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
};
|
|
39
|
+
const applyCodePieceToCodeContext = (codePieces, codeContext) => {
|
|
40
|
+
let code = codeContext.split('\n');
|
|
41
|
+
let shiftOffset = 0;
|
|
42
|
+
codePieces.sort((a, b) => a.startLine - b.startLine);
|
|
43
|
+
for (const codePiece of codePieces) {
|
|
44
|
+
code.splice(codePiece.endLine + shiftOffset, 0, '[#END]');
|
|
45
|
+
code.splice(codePiece.startLine + shiftOffset - 1, 0, '[#START]');
|
|
46
|
+
shiftOffset += 2;
|
|
47
|
+
}
|
|
48
|
+
return code.join('\n');
|
|
49
|
+
};
|
|
50
|
+
export function applyCodePiecesToFlowModules(codePieces, flowModules) {
|
|
51
|
+
// Parse code piece titles to extract module IDs
|
|
52
|
+
// Format: "[id] L3-L5"
|
|
53
|
+
const moduleCodePieces = new Map();
|
|
54
|
+
for (const codePiece of codePieces) {
|
|
55
|
+
const match = codePiece.title.match(/\[([^\]]+)\]\s+L\d+-L\d+/);
|
|
56
|
+
if (match) {
|
|
57
|
+
const moduleId = match[1];
|
|
58
|
+
if (!moduleCodePieces.has(moduleId)) {
|
|
59
|
+
moduleCodePieces.set(moduleId, []);
|
|
60
|
+
}
|
|
61
|
+
moduleCodePieces.get(moduleId).push(codePiece);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Clone modules to avoid mutation
|
|
65
|
+
const modifiedModules = JSON.parse(JSON.stringify(flowModules));
|
|
66
|
+
// Apply code pieces to each module
|
|
67
|
+
for (const [moduleId, pieces] of moduleCodePieces) {
|
|
68
|
+
const module = findModuleById(modifiedModules, moduleId);
|
|
69
|
+
if (module && module.value.type === 'rawscript' && module.value.content) {
|
|
70
|
+
module.value.content = applyCodePieceToCodeContext(pieces, module.value.content);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return YAML.stringify(modifiedModules);
|
|
74
|
+
}
|
|
75
|
+
export function buildContextString(selectedContext) {
|
|
76
|
+
const dbTemplate = `- {title}: SCHEMA: \n{schema}\n`;
|
|
77
|
+
const codeTemplate = `
|
|
78
|
+
- {title}:
|
|
79
|
+
\`\`\`{language}
|
|
80
|
+
{code}
|
|
81
|
+
\`\`\`
|
|
82
|
+
`;
|
|
83
|
+
let dbContext = 'DATABASES:\n';
|
|
84
|
+
let diffContext = 'DIFF:\n';
|
|
85
|
+
let flowModuleContext = 'FOCUSED FLOW MODULES IDS:\n';
|
|
86
|
+
let codeContext = 'CODE:\n';
|
|
87
|
+
let errorContext = `
|
|
88
|
+
ERROR:
|
|
89
|
+
{error}
|
|
90
|
+
`;
|
|
91
|
+
let hasCode = false;
|
|
92
|
+
let hasDb = false;
|
|
93
|
+
let hasDiff = false;
|
|
94
|
+
let hasFlowModule = false;
|
|
95
|
+
let hasError = false;
|
|
96
|
+
let result = '\n\n';
|
|
97
|
+
for (const context of selectedContext) {
|
|
98
|
+
if (context.type === 'code') {
|
|
99
|
+
hasCode = true;
|
|
100
|
+
codeContext += codeTemplate
|
|
101
|
+
.replace('{title}', context.title)
|
|
102
|
+
.replace('{language}', scriptLangToEditorLang(context.lang))
|
|
103
|
+
.replace('{code}', applyCodePieceToCodeContext(selectedContext.filter((c) => c.type === 'code_piece'), context.content));
|
|
104
|
+
}
|
|
105
|
+
else if (context.type === 'error') {
|
|
106
|
+
if (hasError) {
|
|
107
|
+
throw new Error('Multiple error contexts provided');
|
|
108
|
+
}
|
|
109
|
+
hasError = true;
|
|
110
|
+
errorContext = errorContext.replace('{error}', context.content);
|
|
111
|
+
}
|
|
112
|
+
else if (context.type === 'db') {
|
|
113
|
+
hasDb = true;
|
|
114
|
+
dbContext += dbTemplate
|
|
115
|
+
.replace('{title}', context.title)
|
|
116
|
+
.replace('{schema}', context.schema?.stringified ?? 'to fetch with get_db_schema');
|
|
117
|
+
dbContext += '\n';
|
|
118
|
+
}
|
|
119
|
+
else if (context.type === 'diff') {
|
|
120
|
+
hasDiff = true;
|
|
121
|
+
const diff = JSON.stringify(context.diff);
|
|
122
|
+
diffContext += (diff.length > 3000 ? diff.slice(0, 3000) + '...' : diff) + '\n';
|
|
123
|
+
}
|
|
124
|
+
else if (context.type === 'flow_module') {
|
|
125
|
+
hasFlowModule = true;
|
|
126
|
+
flowModuleContext += `${context.id}\n`;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
if (hasCode) {
|
|
130
|
+
result += '\n' + codeContext;
|
|
131
|
+
}
|
|
132
|
+
if (hasError) {
|
|
133
|
+
result += '\n' + errorContext;
|
|
134
|
+
}
|
|
135
|
+
if (hasDb) {
|
|
136
|
+
result += '\n' + dbContext;
|
|
137
|
+
}
|
|
138
|
+
if (hasDiff) {
|
|
139
|
+
result += '\n' + diffContext;
|
|
140
|
+
}
|
|
141
|
+
if (hasFlowModule) {
|
|
142
|
+
result += '\n' + flowModuleContext;
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
6
146
|
async function callTool({ tools, functionName, args, workspace, helpers, toolCallbacks, toolId }) {
|
|
7
147
|
const tool = tools.find((t) => t.def.function.name === functionName);
|
|
8
148
|
if (!tool) {
|
|
@@ -18,11 +158,13 @@ export async function processToolCall({ tools, toolCall, helpers, toolCallbacks
|
|
|
18
158
|
const needsConfirmation = tool?.requiresConfirmation;
|
|
19
159
|
// Add the tool to the display with appropriate status
|
|
20
160
|
toolCallbacks.setToolStatus(toolCall.id, {
|
|
21
|
-
...(tool?.requiresConfirmation
|
|
161
|
+
...(tool?.requiresConfirmation
|
|
162
|
+
? { content: tool.confirmationMessage ?? 'Waiting for confirmation...' }
|
|
163
|
+
: {}),
|
|
22
164
|
parameters: args,
|
|
23
165
|
isLoading: true,
|
|
24
166
|
needsConfirmation: needsConfirmation,
|
|
25
|
-
showDetails: tool?.showDetails
|
|
167
|
+
showDetails: tool?.showDetails
|
|
26
168
|
});
|
|
27
169
|
// If confirmation is needed and we have the callback, wait for it
|
|
28
170
|
if (needsConfirmation && toolCallbacks.requestConfirmation) {
|
|
@@ -163,7 +305,15 @@ export async function buildSchemaForTool(toolDef, schemaBuilder) {
|
|
|
163
305
|
catch (error) {
|
|
164
306
|
console.error('Error building schema for tool', error);
|
|
165
307
|
// fallback to schema with args as a JSON string
|
|
166
|
-
toolDef.function.parameters = {
|
|
308
|
+
toolDef.function.parameters = {
|
|
309
|
+
type: 'object',
|
|
310
|
+
properties: {
|
|
311
|
+
args: { type: 'string', description: 'JSON string containing the arguments for the tool' }
|
|
312
|
+
},
|
|
313
|
+
additionalProperties: false,
|
|
314
|
+
strict: false,
|
|
315
|
+
required: ['args']
|
|
316
|
+
};
|
|
167
317
|
return false;
|
|
168
318
|
}
|
|
169
319
|
}
|
|
@@ -254,7 +404,8 @@ function getErrorMessage(result) {
|
|
|
254
404
|
export async function buildTestRunArgs(args, toolDef) {
|
|
255
405
|
let parsedArgs = args;
|
|
256
406
|
// if the schema is the fallback schema, parse the args as a JSON string
|
|
257
|
-
if (toolDef.function.parameters.properties?.args?.description ===
|
|
407
|
+
if (toolDef.function.parameters.properties?.args?.description ===
|
|
408
|
+
'JSON string containing the arguments for the tool') {
|
|
258
409
|
try {
|
|
259
410
|
parsedArgs = JSON.parse(args.args);
|
|
260
411
|
}
|
|
@@ -18,10 +18,22 @@ setContext('PropPickerContext', {
|
|
|
18
18
|
flowPropPickerConfig: writable(undefined),
|
|
19
19
|
pickablePropertiesFiltered: writable(undefined)
|
|
20
20
|
});
|
|
21
|
+
$effect(() => {
|
|
22
|
+
const options = {
|
|
23
|
+
currentFlow: flowStore.val,
|
|
24
|
+
lastDeployedFlow: savedFlow,
|
|
25
|
+
lastSavedFlow: savedFlow?.draft,
|
|
26
|
+
path: savedFlow?.path,
|
|
27
|
+
modules: flowStore.val.value.modules
|
|
28
|
+
};
|
|
29
|
+
aiChatManager.flowOptions = options;
|
|
30
|
+
});
|
|
21
31
|
onMount(() => {
|
|
32
|
+
aiChatManager.saveAndClear();
|
|
22
33
|
aiChatManager.changeMode(AIMode.FLOW);
|
|
23
34
|
});
|
|
24
35
|
onDestroy(() => {
|
|
36
|
+
aiChatManager.flowOptions = undefined;
|
|
25
37
|
aiChatManager.changeMode(AIMode.NAVIGATOR);
|
|
26
38
|
});
|
|
27
39
|
</script>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts">import LanguageIcon from '../common/languageIcons/LanguageIcon.svelte';
|
|
2
|
+
import IconedResourceType from '../IconedResourceType.svelte';
|
|
3
|
+
import { Building, Repeat, Square, ArrowDown, GitBranch, Bot } from 'lucide-svelte';
|
|
4
|
+
import BarsStaggered from '../icons/BarsStaggered.svelte';
|
|
5
|
+
let { module, size = 16, width, height } = $props();
|
|
6
|
+
// Use width/height if provided, otherwise use size for both
|
|
7
|
+
const iconWidth = width || size;
|
|
8
|
+
const iconHeight = height || size;
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
{#if module.value.type === 'aiagent'}
|
|
12
|
+
<Bot size={16} />
|
|
13
|
+
{:else if module.value.type === 'rawscript'}
|
|
14
|
+
<LanguageIcon lang={module.value.language} width={iconWidth} height={iconHeight} />
|
|
15
|
+
{:else if module.summary === 'Terminate flow'}
|
|
16
|
+
<Square size={size} />
|
|
17
|
+
{:else if module.value.type === 'identity'}
|
|
18
|
+
<ArrowDown size={size} />
|
|
19
|
+
{:else if module.value.type === 'flow'}
|
|
20
|
+
<BarsStaggered size={size} />
|
|
21
|
+
{:else if module.value.type === 'forloopflow' || module.value.type === 'whileloopflow'}
|
|
22
|
+
<Repeat size={size} />
|
|
23
|
+
{:else if module.value.type === 'branchone' || module.value.type === 'branchall'}
|
|
24
|
+
<GitBranch size={size} />
|
|
25
|
+
{:else if module.value.type === 'script'}
|
|
26
|
+
{#if module.value.path.startsWith('hub/')}
|
|
27
|
+
<IconedResourceType
|
|
28
|
+
width={iconWidth.toString() + 'px'}
|
|
29
|
+
height={iconHeight.toString() + 'px'}
|
|
30
|
+
name={module.value.path.split('/')[2]}
|
|
31
|
+
silent={true}
|
|
32
|
+
/>
|
|
33
|
+
{:else}
|
|
34
|
+
<Building size={size} />
|
|
35
|
+
{/if}
|
|
36
|
+
{:else}
|
|
37
|
+
<!-- Fallback icon for unknown module types -->
|
|
38
|
+
<BarsStaggered size={size} />
|
|
39
|
+
{/if}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FlowModule } from '../../gen';
|
|
2
|
+
interface Props {
|
|
3
|
+
module: FlowModule;
|
|
4
|
+
size?: number;
|
|
5
|
+
width?: number;
|
|
6
|
+
height?: number;
|
|
7
|
+
}
|
|
8
|
+
declare const FlowModuleIcon: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type FlowModuleIcon = ReturnType<typeof FlowModuleIcon>;
|
|
10
|
+
export default FlowModuleIcon;
|
|
@@ -331,6 +331,7 @@ let rawScriptLang = $derived(flowModule.value.type == 'rawscript' ? flowModule.v
|
|
|
331
331
|
{lastDeployedCode}
|
|
332
332
|
{diffMode}
|
|
333
333
|
openAiChat
|
|
334
|
+
moduleId={flowModule.id}
|
|
334
335
|
/>
|
|
335
336
|
</div>
|
|
336
337
|
{/if}
|
|
@@ -389,6 +390,7 @@ let rawScriptLang = $derived(flowModule.value.type == 'rawscript' ? flowModule.v
|
|
|
389
390
|
{}
|
|
390
391
|
)}
|
|
391
392
|
key={`flow-inline-${$workspaceStore}-${$pathStore}-${flowModule.id}`}
|
|
393
|
+
moduleId={flowModule.id}
|
|
392
394
|
/>
|
|
393
395
|
<DiffEditor
|
|
394
396
|
open={false}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
<script lang="ts">import { Button } from '../../common';
|
|
2
|
-
import LanguageIcon from '../../common/languageIcons/LanguageIcon.svelte';
|
|
3
|
-
import IconedResourceType from '../../IconedResourceType.svelte';
|
|
4
|
-
import { Building, Repeat, Square, ArrowDown, GitBranch, Bot } from 'lucide-svelte';
|
|
5
2
|
import { createEventDispatcher, getContext } from 'svelte';
|
|
6
3
|
import FlowModuleSchemaItem from './FlowModuleSchemaItem.svelte';
|
|
4
|
+
import FlowModuleIcon from '../FlowModuleIcon.svelte';
|
|
7
5
|
import { prettyLanguage } from '../../../common';
|
|
8
6
|
import { msToSec } from '../../../utils';
|
|
9
|
-
import BarsStaggered from '../../icons/BarsStaggered.svelte';
|
|
10
7
|
import FlowJobsMenu from './FlowJobsMenu.svelte';
|
|
11
8
|
import { isTriggerStep } from '../../graph/graphBuilder.svelte';
|
|
12
9
|
import { checkIfParentLoop } from '../utils';
|
|
@@ -107,9 +104,7 @@ let parentLoop = $derived(flowStore?.val && mod ? checkIfParentLoop(flowStore.va
|
|
|
107
104
|
{darkMode}
|
|
108
105
|
>
|
|
109
106
|
{#snippet icon()}
|
|
110
|
-
<
|
|
111
|
-
<Repeat size={16} />
|
|
112
|
-
</div>
|
|
107
|
+
<FlowModuleIcon module={mod} />
|
|
113
108
|
{/snippet}
|
|
114
109
|
</FlowModuleSchemaItem>
|
|
115
110
|
{:else if mod.value.type === 'branchone'}
|
|
@@ -130,9 +125,7 @@ let parentLoop = $derived(flowStore?.val && mod ? checkIfParentLoop(flowStore.va
|
|
|
130
125
|
{darkMode}
|
|
131
126
|
>
|
|
132
127
|
{#snippet icon()}
|
|
133
|
-
<
|
|
134
|
-
<GitBranch size={16} />
|
|
135
|
-
</div>
|
|
128
|
+
<FlowModuleIcon module={mod} />
|
|
136
129
|
{/snippet}
|
|
137
130
|
</FlowModuleSchemaItem>
|
|
138
131
|
{:else if mod.value.type === 'branchall'}
|
|
@@ -153,9 +146,7 @@ let parentLoop = $derived(flowStore?.val && mod ? checkIfParentLoop(flowStore.va
|
|
|
153
146
|
{darkMode}
|
|
154
147
|
>
|
|
155
148
|
{#snippet icon()}
|
|
156
|
-
<
|
|
157
|
-
<GitBranch size={16} />
|
|
158
|
-
</div>
|
|
149
|
+
<FlowModuleIcon module={mod} />
|
|
159
150
|
{/snippet}
|
|
160
151
|
</FlowModuleSchemaItem>
|
|
161
152
|
{:else}
|
|
@@ -203,32 +194,10 @@ let parentLoop = $derived(flowStore?.val && mod ? checkIfParentLoop(flowStore.va
|
|
|
203
194
|
{skipped}
|
|
204
195
|
>
|
|
205
196
|
{#snippet icon()}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
<LanguageIcon lang={mod.value.language} width={16} height={16} />
|
|
211
|
-
{:else if mod.summary == 'Terminate flow'}
|
|
212
|
-
<Square size={16} />
|
|
213
|
-
{:else if mod.value.type === 'identity'}
|
|
214
|
-
<ArrowDown size={16} />
|
|
215
|
-
{:else if mod.value.type === 'flow'}
|
|
216
|
-
<BarsStaggered size={16} />
|
|
217
|
-
{:else if mod.value.type === 'script'}
|
|
218
|
-
{#if mod.value.path.startsWith('hub/')}
|
|
219
|
-
<div>
|
|
220
|
-
<IconedResourceType
|
|
221
|
-
width="20px"
|
|
222
|
-
height="20px"
|
|
223
|
-
name={mod.value.path.split('/')[2]}
|
|
224
|
-
silent={true}
|
|
225
|
-
/>
|
|
226
|
-
</div>
|
|
227
|
-
{:else}
|
|
228
|
-
<Building size={14} />
|
|
229
|
-
{/if}
|
|
230
|
-
{/if}
|
|
231
|
-
</div>
|
|
197
|
+
{@const size = mod.value.type === 'script' && mod.value.path.startsWith('hub/')
|
|
198
|
+
? 20
|
|
199
|
+
: mod.value.type === "script" ? 14 : 16}
|
|
200
|
+
<FlowModuleIcon module={mod} size={size} />
|
|
232
201
|
{/snippet}
|
|
233
202
|
</FlowModuleSchemaItem>
|
|
234
203
|
{/if}
|