mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-26 00:01:37 +00:00
fix: read ai chat db drafts
This commit is contained in:
@@ -361,6 +361,87 @@ describe('global AI tools', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('reads saved DB script drafts when no local draft exists', async () => {
|
||||
vi.mocked(ScriptService.getScriptByPathWithDraft).mockResolvedValueOnce({
|
||||
path: 'f/scripts/existing',
|
||||
hash: 'deployed-hash',
|
||||
summary: 'deployed summary',
|
||||
description: 'deployed description',
|
||||
content: 'deployed content',
|
||||
language: 'bun',
|
||||
kind: 'script',
|
||||
draft: {
|
||||
path: 'f/scripts/existing',
|
||||
summary: 'db draft summary',
|
||||
description: 'db draft description',
|
||||
content: 'db draft content',
|
||||
language: 'bun',
|
||||
kind: 'script'
|
||||
}
|
||||
} as any)
|
||||
|
||||
const raw = await callGlobalTool('read_workspace_item', {
|
||||
type: 'script',
|
||||
path: 'f/scripts/existing'
|
||||
})
|
||||
const item = JSON.parse(raw)
|
||||
|
||||
expect(item).toEqual({
|
||||
type: 'script',
|
||||
path: 'f/scripts/existing',
|
||||
summary: 'db draft summary',
|
||||
language: 'bun',
|
||||
value: 'db draft content',
|
||||
isDraft: false
|
||||
})
|
||||
expect(raw).not.toContain('deployed content')
|
||||
})
|
||||
|
||||
it('reads saved DB flow drafts when no local draft exists', async () => {
|
||||
vi.mocked(FlowService.getFlowByPathWithDraft).mockResolvedValueOnce({
|
||||
path: 'f/flows/existing',
|
||||
summary: 'deployed summary',
|
||||
value: {
|
||||
modules: [{ id: 'deployed_step', value: { type: 'identity' } }]
|
||||
},
|
||||
schema: { type: 'object', properties: { deployed: { type: 'boolean' } } },
|
||||
edited_by: 'admin',
|
||||
edited_at: '2026-05-22T09:00:00Z',
|
||||
archived: false,
|
||||
extra_perms: {},
|
||||
draft: {
|
||||
path: 'f/flows/existing',
|
||||
summary: 'db draft summary',
|
||||
value: {
|
||||
modules: [{ id: 'draft_step', value: { type: 'identity' } }]
|
||||
},
|
||||
schema: { type: 'object', properties: { draft: { type: 'string' } } },
|
||||
edited_by: 'admin',
|
||||
edited_at: '2026-05-22T10:00:00Z',
|
||||
archived: false,
|
||||
extra_perms: {}
|
||||
}
|
||||
} as any)
|
||||
|
||||
const raw = await callGlobalTool('read_workspace_item', {
|
||||
type: 'flow',
|
||||
path: 'f/flows/existing'
|
||||
})
|
||||
const item = JSON.parse(raw)
|
||||
|
||||
expect(item).toMatchObject({
|
||||
type: 'flow',
|
||||
path: 'f/flows/existing',
|
||||
summary: 'db draft summary',
|
||||
isDraft: false,
|
||||
value: {
|
||||
modules: [{ id: 'draft_step', value: { type: 'identity' } }],
|
||||
schema: { type: 'object', properties: { draft: { type: 'string' } } }
|
||||
}
|
||||
})
|
||||
expect(raw).not.toContain('deployed_step')
|
||||
})
|
||||
|
||||
it('applies path_prefix to local drafts before enforcing the result limit', async () => {
|
||||
await callGlobalTool('write_script', {
|
||||
path: 'f/other/outside',
|
||||
|
||||
@@ -591,7 +591,9 @@ function itemMatches(
|
||||
)
|
||||
}
|
||||
|
||||
function scriptToItem(script: Script, includeValue: boolean): WorkspaceItem {
|
||||
type ReadableScript = Pick<Script, 'path' | 'summary' | 'language' | 'content'>
|
||||
|
||||
function scriptToItem(script: ReadableScript, includeValue: boolean): WorkspaceItem {
|
||||
return {
|
||||
type: 'script',
|
||||
path: script.path,
|
||||
@@ -602,7 +604,10 @@ function scriptToItem(script: Script, includeValue: boolean): WorkspaceItem {
|
||||
}
|
||||
}
|
||||
|
||||
function flowToItem(flow: Flow, includeValue: boolean): WorkspaceItem {
|
||||
function flowToItem(
|
||||
flow: Pick<Flow, 'path' | 'summary' | 'value' | 'schema'>,
|
||||
includeValue: boolean
|
||||
): WorkspaceItem {
|
||||
return {
|
||||
type: 'flow',
|
||||
path: flow.path,
|
||||
@@ -614,6 +619,19 @@ function flowToItem(flow: Flow, includeValue: boolean): WorkspaceItem {
|
||||
}
|
||||
}
|
||||
|
||||
async function loadScriptWithDbDraft(path: string, workspace: string): Promise<ReadableScript> {
|
||||
const script = await ScriptService.getScriptByPathWithDraft({ workspace, path })
|
||||
return script.draft ? { ...script, ...script.draft, path: script.path } : script
|
||||
}
|
||||
|
||||
async function loadFlowWithDbDraft(
|
||||
path: string,
|
||||
workspace: string
|
||||
): Promise<Pick<Flow, 'path' | 'summary' | 'value' | 'schema'>> {
|
||||
const flow = await FlowService.getFlowByPathWithDraft({ workspace, path })
|
||||
return flow.draft ? { ...flow, ...flow.draft, path: flow.path } : flow
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a flow workspace item into the compact response we send to the model:
|
||||
* rawscript content is replaced with `inline_script.<moduleId>` placeholders.
|
||||
@@ -1098,9 +1116,9 @@ async function readWorkspaceItem(
|
||||
): Promise<WorkspaceItem> {
|
||||
switch (type) {
|
||||
case 'script':
|
||||
return scriptToItem(await ScriptService.getScriptByPath({ workspace, path }), true)
|
||||
return scriptToItem(await loadScriptWithDbDraft(path, workspace), true)
|
||||
case 'flow':
|
||||
return flowToItem(await FlowService.getFlowByPath({ workspace, path }), true)
|
||||
return flowToItem(await loadFlowWithDbDraft(path, workspace), true)
|
||||
case 'schedule':
|
||||
return scheduleToItem(await ScheduleService.getSchedule({ workspace, path }), true)
|
||||
case 'trigger':
|
||||
@@ -2327,7 +2345,7 @@ async function loadScriptForEdit(
|
||||
}
|
||||
return { content: draft.value, language: draft.language, summary: draft.summary }
|
||||
}
|
||||
const script = await ScriptService.getScriptByPath({ workspace, path })
|
||||
const script = await loadScriptWithDbDraft(path, workspace)
|
||||
return { content: script.content, language: script.language, summary: script.summary }
|
||||
}
|
||||
|
||||
@@ -2362,7 +2380,7 @@ async function loadFlowDraftValue(
|
||||
}
|
||||
return { flow: draft.value as FlowDraftValue, summary: draft.summary }
|
||||
}
|
||||
const flow = await FlowService.getFlowByPath({ workspace, path })
|
||||
const flow = await loadFlowWithDbDraft(path, workspace)
|
||||
return {
|
||||
flow: { value: flow.value, schema: flow.schema, groups: flow.value.groups ?? null },
|
||||
summary: flow.summary
|
||||
|
||||
Reference in New Issue
Block a user