Compute output schema on frontend (#16530)

Fixes https://github.com/twentyhq/core-team-issues/issues/1382

Current issue : all step output schemas are computed and stored on
backend side. Which means that, when the database schema is updated -
like a field creation - steps needs to be deleted an recreated. Which is
invisible to users.

Solution : schema generation is moved on frontend side

1. Coming on the page the first time, the schema is populated for all
steps except a few ones that are handled differently (Code, Webhook,
http node, Agent)

2. A separated state allow to determine if a step needs a recomputation.

3. The user only needs a refresh to see the whole schema re-computed

Follow-up:
- check if remaining backend steps could be moved to runtime
computation. But Code will still require storage.
- Clean backend service that is not used anymore
This commit is contained in:
Thomas Trompette
2025-12-15 16:20:35 +01:00
committed by GitHub
parent 2e104c8e76
commit 95e0793f81
43 changed files with 3152 additions and 209 deletions
@@ -0,0 +1,87 @@
import { getAgentIdFromStep } from '../getAgentIdFromStep';
describe('getAgentIdFromStep', () => {
it('should return undefined when stepDefinition is undefined', () => {
const result = getAgentIdFromStep(undefined);
expect(result).toBeUndefined();
});
it('should return undefined when stepDefinition type is trigger', () => {
const result = getAgentIdFromStep({
type: 'trigger',
definition: { type: 'DATABASE_EVENT' },
});
expect(result).toBeUndefined();
});
it('should return undefined when definition is undefined', () => {
const result = getAgentIdFromStep({
type: 'action',
definition: undefined,
});
expect(result).toBeUndefined();
});
it('should return undefined when definition type is not AI_AGENT', () => {
const result = getAgentIdFromStep({
type: 'action',
definition: { type: 'CREATE_RECORD' },
});
expect(result).toBeUndefined();
});
it('should return undefined when settings is missing', () => {
const result = getAgentIdFromStep({
type: 'action',
definition: { type: 'AI_AGENT' },
});
expect(result).toBeUndefined();
});
it('should return undefined when settings.input is missing', () => {
const result = getAgentIdFromStep({
type: 'action',
definition: {
type: 'AI_AGENT',
settings: {},
},
});
expect(result).toBeUndefined();
});
it('should return undefined when settings.input.agentId is missing', () => {
const result = getAgentIdFromStep({
type: 'action',
definition: {
type: 'AI_AGENT',
settings: {
input: {},
},
},
});
expect(result).toBeUndefined();
});
it('should return agentId when all conditions are met', () => {
const result = getAgentIdFromStep({
type: 'action',
definition: {
type: 'AI_AGENT',
settings: {
input: {
agentId: 'agent-123',
},
},
},
});
expect(result).toBe('agent-123');
});
});