mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
Removed extraneous semicolons
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Executor } from '../index';
|
||||
import { SerializedWorkflow } from '@/serializer/types';
|
||||
import { Tool } from '../types';
|
||||
import { tools } from '@/tools';
|
||||
import { Executor } from '../index'
|
||||
import { SerializedWorkflow } from '@/serializer/types'
|
||||
import { Tool } from '../types'
|
||||
import { tools } from '@/tools'
|
||||
|
||||
// Mock tools
|
||||
const createMockTool = (
|
||||
@@ -39,17 +39,17 @@ const createMockTool = (
|
||||
},
|
||||
transformResponse: () => mockResponse,
|
||||
transformError: () => mockError || 'Mock error'
|
||||
});
|
||||
})
|
||||
|
||||
jest.mock('@/tools', () => ({
|
||||
tools: {}
|
||||
}));
|
||||
}))
|
||||
|
||||
describe('Executor', () => {
|
||||
beforeEach(() => {
|
||||
// Reset tools mock
|
||||
(tools as any) = {};
|
||||
});
|
||||
(tools as any) = {}
|
||||
})
|
||||
|
||||
describe('Tool Execution', () => {
|
||||
it('should execute a simple workflow with one tool', async () => {
|
||||
@@ -58,7 +58,7 @@ describe('Executor', () => {
|
||||
'Test Tool',
|
||||
{ result: 'test processed' }
|
||||
);
|
||||
(tools as any)['test-tool'] = mockTool;
|
||||
(tools as any)['test-tool'] = mockTool
|
||||
|
||||
const workflow: SerializedWorkflow = {
|
||||
version: '1.0',
|
||||
@@ -75,7 +75,7 @@ describe('Executor', () => {
|
||||
}
|
||||
}],
|
||||
connections: []
|
||||
};
|
||||
}
|
||||
|
||||
// Mock fetch
|
||||
global.fetch = jest.fn().mockImplementation(() =>
|
||||
@@ -83,13 +83,13 @@ describe('Executor', () => {
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ result: 'test processed' })
|
||||
})
|
||||
);
|
||||
)
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data).toEqual({ result: 'test processed' });
|
||||
expect(result.success).toBe(true)
|
||||
expect(result.data).toEqual({ result: 'test processed' })
|
||||
expect(global.fetch).toHaveBeenCalledWith(
|
||||
'https://api.test.com/endpoint',
|
||||
expect.objectContaining({
|
||||
@@ -100,8 +100,8 @@ describe('Executor', () => {
|
||||
},
|
||||
body: JSON.stringify({ input: 'test' })
|
||||
})
|
||||
);
|
||||
});
|
||||
)
|
||||
})
|
||||
|
||||
it('should validate required parameters', async () => {
|
||||
const mockTool = createMockTool(
|
||||
@@ -109,7 +109,7 @@ describe('Executor', () => {
|
||||
'Test Tool',
|
||||
{ result: 'test processed' }
|
||||
);
|
||||
(tools as any)['test-tool'] = mockTool;
|
||||
(tools as any)['test-tool'] = mockTool
|
||||
|
||||
const workflow: SerializedWorkflow = {
|
||||
version: '1.0',
|
||||
@@ -126,14 +126,14 @@ describe('Executor', () => {
|
||||
}
|
||||
}],
|
||||
connections: []
|
||||
};
|
||||
}
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('Missing required parameter');
|
||||
});
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toContain('Missing required parameter')
|
||||
})
|
||||
|
||||
it('should handle tool execution errors', async () => {
|
||||
const mockTool = createMockTool(
|
||||
@@ -142,7 +142,7 @@ describe('Executor', () => {
|
||||
{},
|
||||
'API Error'
|
||||
);
|
||||
(tools as any)['test-tool'] = mockTool;
|
||||
(tools as any)['test-tool'] = mockTool
|
||||
|
||||
const workflow: SerializedWorkflow = {
|
||||
version: '1.0',
|
||||
@@ -159,7 +159,7 @@ describe('Executor', () => {
|
||||
}
|
||||
}],
|
||||
connections: []
|
||||
};
|
||||
}
|
||||
|
||||
// Mock fetch to fail
|
||||
global.fetch = jest.fn().mockImplementation(() =>
|
||||
@@ -167,15 +167,15 @@ describe('Executor', () => {
|
||||
ok: false,
|
||||
json: () => Promise.resolve({ error: 'API Error' })
|
||||
})
|
||||
);
|
||||
)
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('API Error');
|
||||
});
|
||||
});
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toContain('API Error')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Interface Validation', () => {
|
||||
it('should validate input types', async () => {
|
||||
@@ -184,7 +184,7 @@ describe('Executor', () => {
|
||||
'Test Tool',
|
||||
{ result: 123 }
|
||||
);
|
||||
(tools as any)['test-tool'] = mockTool;
|
||||
(tools as any)['test-tool'] = mockTool
|
||||
|
||||
const workflow: SerializedWorkflow = {
|
||||
version: '1.0',
|
||||
@@ -201,14 +201,14 @@ describe('Executor', () => {
|
||||
}
|
||||
}],
|
||||
connections: []
|
||||
};
|
||||
}
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('Invalid type for input');
|
||||
});
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toContain('Invalid type for input')
|
||||
})
|
||||
|
||||
it('should validate tool output against interface', async () => {
|
||||
const mockTool = createMockTool(
|
||||
@@ -216,7 +216,7 @@ describe('Executor', () => {
|
||||
'Test Tool',
|
||||
{ wrongField: 'wrong type' }
|
||||
);
|
||||
(tools as any)['test-tool'] = mockTool;
|
||||
(tools as any)['test-tool'] = mockTool
|
||||
|
||||
const workflow: SerializedWorkflow = {
|
||||
version: '1.0',
|
||||
@@ -233,7 +233,7 @@ describe('Executor', () => {
|
||||
}
|
||||
}],
|
||||
connections: []
|
||||
};
|
||||
}
|
||||
|
||||
// Mock fetch
|
||||
global.fetch = jest.fn().mockImplementation(() =>
|
||||
@@ -241,15 +241,15 @@ describe('Executor', () => {
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ wrongField: 'wrong type' })
|
||||
})
|
||||
);
|
||||
)
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('Tool output missing required field');
|
||||
});
|
||||
});
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toContain('Tool output missing required field')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Complex Workflows', () => {
|
||||
it('should execute blocks in correct order and pass data between them', async () => {
|
||||
@@ -257,14 +257,14 @@ describe('Executor', () => {
|
||||
'tool-1',
|
||||
'Tool 1',
|
||||
{ output: 'test data' }
|
||||
);
|
||||
)
|
||||
const mockTool2 = createMockTool(
|
||||
'tool-2',
|
||||
'Tool 2',
|
||||
{ result: 'processed data' }
|
||||
);
|
||||
(tools as any)['tool-1'] = mockTool1;
|
||||
(tools as any)['tool-2'] = mockTool2;
|
||||
(tools as any)['tool-2'] = mockTool2
|
||||
|
||||
const workflow: SerializedWorkflow = {
|
||||
version: '1.0',
|
||||
@@ -302,7 +302,7 @@ describe('Executor', () => {
|
||||
targetHandle: 'input'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
// Mock fetch for both tools
|
||||
global.fetch = jest.fn()
|
||||
@@ -317,15 +317,15 @@ describe('Executor', () => {
|
||||
ok: true,
|
||||
json: () => Promise.resolve({ result: 'processed data' })
|
||||
})
|
||||
);
|
||||
)
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data).toEqual({ result: 'processed data' });
|
||||
expect(global.fetch).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
expect(result.success).toBe(true)
|
||||
expect(result.data).toEqual({ result: 'processed data' })
|
||||
expect(global.fetch).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('should handle cycles in workflow', async () => {
|
||||
const workflow: SerializedWorkflow = {
|
||||
@@ -370,13 +370,13 @@ describe('Executor', () => {
|
||||
targetHandle: 'input'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
const executor = new Executor(workflow);
|
||||
const result = await executor.execute('workflow-1');
|
||||
const executor = new Executor(workflow)
|
||||
const result = await executor.execute('workflow-1')
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toContain('Workflow contains cycles');
|
||||
});
|
||||
});
|
||||
});
|
||||
expect(result.success).toBe(false)
|
||||
expect(result.error).toContain('Workflow contains cycles')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
+77
-77
@@ -1,13 +1,13 @@
|
||||
import { SerializedWorkflow, SerializedBlock } from '@/serializer/types';
|
||||
import { ExecutionContext, ExecutionResult, Tool } from './types';
|
||||
import { tools } from '@/tools';
|
||||
import { BlockState } from '@/stores/workflow/types';
|
||||
import { SerializedWorkflow, SerializedBlock } from '@/serializer/types'
|
||||
import { ExecutionContext, ExecutionResult, Tool } from './types'
|
||||
import { tools } from '@/tools'
|
||||
import { BlockState } from '@/stores/workflow/types'
|
||||
|
||||
export class Executor {
|
||||
private workflow: SerializedWorkflow;
|
||||
private workflow: SerializedWorkflow
|
||||
|
||||
constructor(workflow: SerializedWorkflow) {
|
||||
this.workflow = workflow;
|
||||
this.workflow = workflow
|
||||
}
|
||||
|
||||
private async executeBlock(
|
||||
@@ -15,54 +15,54 @@ export class Executor {
|
||||
inputs: Record<string, any>,
|
||||
context: ExecutionContext
|
||||
): Promise<Record<string, any>> {
|
||||
const config = block.config;
|
||||
const toolId = config.tool;
|
||||
const config = block.config
|
||||
const toolId = config.tool
|
||||
|
||||
if (!toolId) {
|
||||
throw new Error(`Block ${block.id} does not specify a tool`);
|
||||
throw new Error(`Block ${block.id} does not specify a tool`)
|
||||
}
|
||||
|
||||
const tool = tools[toolId];
|
||||
const tool = tools[toolId]
|
||||
if (!tool) {
|
||||
throw new Error(`Tool not found: ${toolId}`);
|
||||
throw new Error(`Tool not found: ${toolId}`)
|
||||
}
|
||||
|
||||
// Validate interface compatibility
|
||||
this.validateInterface(block, inputs);
|
||||
this.validateInterface(block, inputs)
|
||||
|
||||
// Merge block parameters with runtime inputs
|
||||
const params = {
|
||||
...config.params,
|
||||
...inputs
|
||||
};
|
||||
}
|
||||
|
||||
// Validate tool parameters
|
||||
this.validateToolParams(tool, params);
|
||||
this.validateToolParams(tool, params)
|
||||
|
||||
try {
|
||||
// Make the HTTP request
|
||||
const url = typeof tool.request.url === 'function'
|
||||
? tool.request.url(params)
|
||||
: tool.request.url;
|
||||
: tool.request.url
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: tool.request.method,
|
||||
headers: tool.request.headers(params),
|
||||
body: tool.request.body ? JSON.stringify(tool.request.body(params)) : undefined
|
||||
});
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json().catch(() => ({ message: response.statusText }));
|
||||
throw new Error(tool.transformError(error));
|
||||
const error = await response.json().catch(() => ({ message: response.statusText }))
|
||||
throw new Error(tool.transformError(error))
|
||||
}
|
||||
|
||||
const result = await tool.transformResponse(response);
|
||||
const result = await tool.transformResponse(response)
|
||||
|
||||
// Validate the output matches the interface
|
||||
this.validateToolOutput(block, result);
|
||||
return result;
|
||||
this.validateToolOutput(block, result)
|
||||
return result
|
||||
} catch (error) {
|
||||
throw new Error(`Tool ${toolId} execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
throw new Error(`Tool ${toolId} execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,37 +70,37 @@ export class Executor {
|
||||
// Check required parameters
|
||||
for (const [paramName, paramConfig] of Object.entries(tool.params)) {
|
||||
if (paramConfig.required && !(paramName in params)) {
|
||||
throw new Error(`Missing required parameter '${paramName}' for tool ${tool.id}`);
|
||||
throw new Error(`Missing required parameter '${paramName}' for tool ${tool.id}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private validateInterface(block: SerializedBlock, inputs: Record<string, any>): void {
|
||||
const { interface: blockInterface } = block.config;
|
||||
const { interface: blockInterface } = block.config
|
||||
|
||||
// Check if all required inputs are provided
|
||||
for (const [inputName, inputType] of Object.entries(blockInterface.inputs)) {
|
||||
if (!(inputName in inputs)) {
|
||||
throw new Error(`Missing required input '${inputName}' of type '${inputType}' for block ${block.id}`);
|
||||
throw new Error(`Missing required input '${inputName}' of type '${inputType}' for block ${block.id}`)
|
||||
}
|
||||
// Basic type validation (can be enhanced for more complex types)
|
||||
if (!this.validateType(inputs[inputName], inputType)) {
|
||||
throw new Error(`Invalid type for input '${inputName}' in block ${block.id}. Expected ${inputType}`);
|
||||
throw new Error(`Invalid type for input '${inputName}' in block ${block.id}. Expected ${inputType}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private validateToolOutput(block: SerializedBlock, output: Record<string, any>): void {
|
||||
const { interface: blockInterface } = block.config;
|
||||
const { interface: blockInterface } = block.config
|
||||
|
||||
// Check if all promised outputs are present
|
||||
for (const [outputName, outputType] of Object.entries(blockInterface.outputs)) {
|
||||
if (!(outputName in output)) {
|
||||
throw new Error(`Tool output missing required field '${outputName}' of type '${outputType}' for block ${block.id}`);
|
||||
throw new Error(`Tool output missing required field '${outputName}' of type '${outputType}' for block ${block.id}`)
|
||||
}
|
||||
// Basic type validation (can be enhanced for more complex types)
|
||||
if (!this.validateType(output[outputName], outputType)) {
|
||||
throw new Error(`Invalid type for output '${outputName}' in block ${block.id}. Expected ${outputType}`);
|
||||
throw new Error(`Invalid type for output '${outputName}' in block ${block.id}. Expected ${outputType}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,126 +108,126 @@ export class Executor {
|
||||
private validateType(value: any, expectedType: string): boolean {
|
||||
switch (expectedType.toLowerCase()) {
|
||||
case 'string':
|
||||
return typeof value === 'string';
|
||||
return typeof value === 'string'
|
||||
case 'number':
|
||||
return typeof value === 'number';
|
||||
return typeof value === 'number'
|
||||
case 'boolean':
|
||||
return typeof value === 'boolean';
|
||||
return typeof value === 'boolean'
|
||||
case 'json':
|
||||
try {
|
||||
if (typeof value === 'string') {
|
||||
JSON.parse(value);
|
||||
JSON.parse(value)
|
||||
}
|
||||
return true;
|
||||
return true
|
||||
} catch {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
default:
|
||||
// For complex types, we just do basic object/array validation
|
||||
return true;
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
private determineExecutionOrder(): string[] {
|
||||
const { blocks, connections } = this.workflow;
|
||||
const order: string[] = [];
|
||||
const visited = new Set<string>();
|
||||
const inDegree = new Map<string, number>();
|
||||
const { blocks, connections } = this.workflow
|
||||
const order: string[] = []
|
||||
const visited = new Set<string>()
|
||||
const inDegree = new Map<string, number>()
|
||||
|
||||
blocks.forEach(block => inDegree.set(block.id, 0));
|
||||
blocks.forEach(block => inDegree.set(block.id, 0))
|
||||
connections.forEach(conn => {
|
||||
const target = conn.target;
|
||||
inDegree.set(target, (inDegree.get(target) || 0) + 1);
|
||||
});
|
||||
const target = conn.target
|
||||
inDegree.set(target, (inDegree.get(target) || 0) + 1)
|
||||
})
|
||||
|
||||
const queue = blocks
|
||||
.filter(block => (inDegree.get(block.id) || 0) === 0)
|
||||
.map(block => block.id);
|
||||
.map(block => block.id)
|
||||
|
||||
while (queue.length > 0) {
|
||||
const blockId = queue.shift()!;
|
||||
if (visited.has(blockId)) continue;
|
||||
const blockId = queue.shift()!
|
||||
if (visited.has(blockId)) continue
|
||||
|
||||
visited.add(blockId);
|
||||
order.push(blockId);
|
||||
visited.add(blockId)
|
||||
order.push(blockId)
|
||||
|
||||
connections
|
||||
.filter(conn => conn.source === blockId)
|
||||
.forEach(conn => {
|
||||
const targetId = conn.target;
|
||||
inDegree.set(targetId, (inDegree.get(targetId) || 0) - 1);
|
||||
const targetId = conn.target
|
||||
inDegree.set(targetId, (inDegree.get(targetId) || 0) - 1)
|
||||
|
||||
if (inDegree.get(targetId) === 0) {
|
||||
queue.push(targetId);
|
||||
queue.push(targetId)
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
if (order.length !== blocks.length) {
|
||||
throw new Error('Workflow contains cycles');
|
||||
throw new Error('Workflow contains cycles')
|
||||
}
|
||||
|
||||
return order;
|
||||
return order
|
||||
}
|
||||
|
||||
private resolveInputs(
|
||||
block: SerializedBlock,
|
||||
context: ExecutionContext
|
||||
): Record<string, any> {
|
||||
const inputs: Record<string, any> = {};
|
||||
const inputs: Record<string, any> = {}
|
||||
|
||||
// Get all incoming connections for this block
|
||||
const incomingConnections = this.workflow.connections.filter(
|
||||
conn => conn.target === block.id
|
||||
);
|
||||
)
|
||||
|
||||
// Map outputs from previous blocks to inputs for this block
|
||||
incomingConnections.forEach(conn => {
|
||||
const sourceOutput = context.blockStates.get(conn.source);
|
||||
const sourceOutput = context.blockStates.get(conn.source)
|
||||
if (sourceOutput && conn.sourceHandle && conn.targetHandle) {
|
||||
inputs[conn.targetHandle] = sourceOutput[conn.sourceHandle];
|
||||
inputs[conn.targetHandle] = sourceOutput[conn.sourceHandle]
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
// If this is a start block with no inputs, use the block's params
|
||||
if (Object.keys(inputs).length === 0) {
|
||||
const targetBlock = this.workflow.blocks.find(b => b.id === block.id);
|
||||
const targetBlock = this.workflow.blocks.find(b => b.id === block.id)
|
||||
if (targetBlock) {
|
||||
return targetBlock.config.params;
|
||||
return targetBlock.config.params
|
||||
}
|
||||
}
|
||||
|
||||
return inputs;
|
||||
return inputs
|
||||
}
|
||||
|
||||
async execute(workflowId: string): Promise<ExecutionResult> {
|
||||
const startTime = new Date();
|
||||
const startTime = new Date()
|
||||
const context: ExecutionContext = {
|
||||
workflowId,
|
||||
blockStates: new Map(),
|
||||
metadata: {
|
||||
startTime: startTime.toISOString()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const executionOrder = this.determineExecutionOrder();
|
||||
const executionOrder = this.determineExecutionOrder()
|
||||
|
||||
for (const blockId of executionOrder) {
|
||||
const block = this.workflow.blocks.find(b => b.id === blockId);
|
||||
const block = this.workflow.blocks.find(b => b.id === blockId)
|
||||
if (!block) {
|
||||
throw new Error(`Block ${blockId} not found in workflow`);
|
||||
throw new Error(`Block ${blockId} not found in workflow`)
|
||||
}
|
||||
|
||||
const blockInputs = this.resolveInputs(block, context);
|
||||
const result = await this.executeBlock(block, blockInputs, context);
|
||||
context.blockStates.set(blockId, result);
|
||||
const blockInputs = this.resolveInputs(block, context)
|
||||
const result = await this.executeBlock(block, blockInputs, context)
|
||||
context.blockStates.set(blockId, result)
|
||||
}
|
||||
|
||||
const lastBlockId = executionOrder[executionOrder.length - 1];
|
||||
const finalOutput = context.blockStates.get(lastBlockId);
|
||||
const lastBlockId = executionOrder[executionOrder.length - 1]
|
||||
const finalOutput = context.blockStates.get(lastBlockId)
|
||||
|
||||
const endTime = new Date();
|
||||
const endTime = new Date()
|
||||
return {
|
||||
success: true,
|
||||
data: finalOutput,
|
||||
@@ -236,9 +236,9 @@ export class Executor {
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString()
|
||||
}
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
const endTime = new Date();
|
||||
const endTime = new Date()
|
||||
return {
|
||||
success: false,
|
||||
data: {},
|
||||
@@ -248,7 +248,7 @@ export class Executor {
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString()
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-29
@@ -1,44 +1,44 @@
|
||||
export interface Tool<P = any, R = any> {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
version: string;
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
version: string
|
||||
params: {
|
||||
[key: string]: {
|
||||
type: string;
|
||||
required?: boolean;
|
||||
description?: string;
|
||||
default?: any;
|
||||
};
|
||||
};
|
||||
type: string
|
||||
required?: boolean
|
||||
description?: string
|
||||
default?: any
|
||||
}
|
||||
}
|
||||
request: {
|
||||
url: string | ((params: P) => string);
|
||||
method: string;
|
||||
headers: (params: P) => Record<string, string>;
|
||||
body?: (params: P) => Record<string, any>;
|
||||
};
|
||||
transformResponse: (response: any) => R;
|
||||
transformError: (error: any) => string;
|
||||
url: string | ((params: P) => string)
|
||||
method: string
|
||||
headers: (params: P) => Record<string, string>
|
||||
body?: (params: P) => Record<string, any>
|
||||
}
|
||||
transformResponse: (response: any) => R
|
||||
transformError: (error: any) => string
|
||||
}
|
||||
|
||||
export interface ToolRegistry {
|
||||
[key: string]: Tool;
|
||||
[key: string]: Tool
|
||||
}
|
||||
|
||||
export interface ExecutionContext {
|
||||
workflowId: string;
|
||||
blockStates: Map<string, any>;
|
||||
input?: Record<string, any>;
|
||||
metadata?: Record<string, any>;
|
||||
workflowId: string
|
||||
blockStates: Map<string, any>
|
||||
input?: Record<string, any>
|
||||
metadata?: Record<string, any>
|
||||
}
|
||||
|
||||
export interface ExecutionResult {
|
||||
success: boolean;
|
||||
data: Record<string, any>;
|
||||
error?: string;
|
||||
success: boolean
|
||||
data: Record<string, any>
|
||||
error?: string
|
||||
metadata?: {
|
||||
duration: number;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
};
|
||||
duration: number
|
||||
startTime: string
|
||||
endTime: string
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user