Skip to content

Commit aa343fb

Browse files
committed
Checkpoint
1 parent cc249c2 commit aa343fb

File tree

7 files changed

+195
-82
lines changed

7 files changed

+195
-82
lines changed
Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,37 @@
1-
import { type NextRequest, NextResponse } from 'next/server'
2-
import { z } from 'zod'
3-
import { searchDocumentation } from '@/lib/copilot/service'
1+
import { NextRequest, NextResponse } from 'next/server'
42
import { createLogger } from '@/lib/logs/console-logger'
3+
import { searchDocumentation } from '@/lib/copilot/service'
54

65
const logger = createLogger('DocsSearchAPI')
76

8-
const SearchSchema = z.object({
9-
query: z.string().min(1, 'Query is required'),
10-
topK: z.number().min(1).max(20).default(5),
11-
})
12-
13-
/**
14-
* POST /api/docs/search
15-
* Search documentation for copilot tools
16-
*/
17-
export async function POST(req: NextRequest) {
18-
const requestId = crypto.randomUUID()
19-
7+
export async function POST(request: NextRequest) {
208
try {
21-
const body = await req.json()
22-
const { query, topK } = SearchSchema.parse(body)
9+
const { query, topK = 5 } = await request.json()
2310

24-
logger.info(`[${requestId}] Documentation search request: "${query}"`, { topK })
11+
if (!query) {
12+
return NextResponse.json({ error: 'Query is required' }, { status: 400 })
13+
}
14+
15+
logger.info('Executing documentation search', { query, topK })
2516

2617
const results = await searchDocumentation(query, { topK })
2718

28-
logger.info(`[${requestId}] Found ${results.length} documentation results`, { query })
19+
logger.info(`Found ${results.length} documentation results`, { query })
2920

3021
return NextResponse.json({
3122
success: true,
3223
results,
3324
query,
3425
totalResults: results.length,
35-
metadata: {
36-
requestId,
37-
query,
38-
topK,
39-
},
4026
})
4127
} catch (error) {
42-
if (error instanceof z.ZodError) {
43-
return NextResponse.json(
44-
{ error: 'Invalid request data', details: error.errors },
45-
{ status: 400 }
46-
)
47-
}
48-
49-
logger.error(`[${requestId}] Documentation search error:`, error)
28+
logger.error('Documentation search API failed', error)
5029
return NextResponse.json(
5130
{
52-
error: 'Failed to search documentation',
53-
details: error instanceof Error ? error.message : 'Unknown error',
31+
success: false,
32+
error: `Documentation search failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
5433
},
5534
{ status: 500 }
5635
)
5736
}
58-
}
37+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { NextRequest, NextResponse } from 'next/server'
2+
import { createLogger } from '@/lib/logs/console-logger'
3+
import { useWorkflowYamlStore } from '@/stores/workflows/yaml/store'
4+
5+
const logger = createLogger('GetWorkflowYamlAPI')
6+
7+
export async function POST(request: NextRequest) {
8+
try {
9+
const { includeMetadata = false } = await request.json()
10+
11+
logger.info('Executing get user workflow', { includeMetadata })
12+
13+
// Get the workflow YAML using the same store as the UI
14+
const yamlStore = useWorkflowYamlStore.getState()
15+
const yamlContent = yamlStore.getYaml()
16+
17+
if (!yamlContent) {
18+
return NextResponse.json(
19+
{ success: false, error: 'No workflow content available' },
20+
{ status: 404 }
21+
)
22+
}
23+
24+
let metadata = undefined
25+
if (includeMetadata) {
26+
// Get additional workflow metadata if requested
27+
const workflowStore = yamlStore as any // Access internal state
28+
metadata = {
29+
name: workflowStore.workflow?.name || 'Unnamed Workflow',
30+
description: workflowStore.workflow?.description || '',
31+
createdAt: workflowStore.workflow?.createdAt,
32+
updatedAt: workflowStore.workflow?.updatedAt,
33+
}
34+
}
35+
36+
logger.info('Successfully generated workflow YAML', {
37+
includeMetadata,
38+
yamlLength: yamlContent.length
39+
})
40+
41+
return NextResponse.json({
42+
success: true,
43+
yaml: yamlContent,
44+
metadata: metadata,
45+
})
46+
} catch (error) {
47+
logger.error('Get user workflow API failed', error)
48+
return NextResponse.json(
49+
{
50+
success: false,
51+
error: `Failed to get user workflow: ${error instanceof Error ? error.message : 'Unknown error'}`,
52+
},
53+
{ status: 500 }
54+
)
55+
}
56+
}

apps/sim/lib/copilot/service.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ export async function generateChatResponse(
406406
content: message,
407407
})
408408

409-
// Define the documentation search tool for the LLM
409+
// Define the tools available to the LLM
410410
const tools: ProviderToolConfig[] = [
411411
{
412412
id: 'docs_search_internal',
@@ -430,6 +430,24 @@ export async function generateChatResponse(
430430
required: ['query'],
431431
},
432432
},
433+
{
434+
id: 'get_user_workflow',
435+
name: 'Get User Workflow',
436+
description:
437+
'Get the current user workflow as YAML format. This shows all blocks, their configurations, inputs, and connections in the workflow.',
438+
params: {},
439+
parameters: {
440+
type: 'object',
441+
properties: {
442+
includeMetadata: {
443+
type: 'boolean',
444+
description: 'Whether to include additional metadata about the workflow (default: false)',
445+
default: false,
446+
},
447+
},
448+
required: [],
449+
},
450+
},
433451
]
434452

435453
const response = await executeProviderRequest(provider, {

apps/sim/lib/copilot/tools.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,77 @@ const docsSearchTool: CopilotTool = {
7272
},
7373
}
7474

75+
// Get user workflow as YAML tool for copilot
76+
const getUserWorkflowTool: CopilotTool = {
77+
id: 'get_user_workflow',
78+
name: 'Get User Workflow',
79+
description:
80+
'Get the current user workflow as YAML format. This shows all blocks, their configurations, inputs, and connections in the workflow.',
81+
parameters: {
82+
type: 'object',
83+
properties: {
84+
includeMetadata: {
85+
type: 'boolean',
86+
description: 'Whether to include additional metadata about the workflow (default: false)',
87+
default: false,
88+
},
89+
},
90+
required: [],
91+
},
92+
execute: async (args: Record<string, any>): Promise<CopilotToolResult> => {
93+
try {
94+
const { includeMetadata = false } = args
95+
96+
logger.info('Executing get user workflow', { includeMetadata })
97+
98+
// Import the workflow YAML store dynamically to avoid import issues
99+
const { useWorkflowYamlStore } = await import('@/stores/workflows/yaml/store')
100+
const { useWorkflowRegistry } = await import('@/stores/workflows/registry/store')
101+
102+
// Get the current workflow YAML
103+
const yamlContent = useWorkflowYamlStore.getState().getYaml()
104+
105+
// Get additional metadata if requested
106+
let metadata = {}
107+
if (includeMetadata) {
108+
const registry = useWorkflowRegistry.getState()
109+
const activeWorkflowId = registry.activeWorkflowId
110+
const activeWorkflow = activeWorkflowId ? registry.workflows[activeWorkflowId] : null
111+
112+
if (activeWorkflow) {
113+
metadata = {
114+
workflowId: activeWorkflowId,
115+
name: activeWorkflow.name,
116+
description: activeWorkflow.description,
117+
lastModified: activeWorkflow.lastModified,
118+
workspaceId: activeWorkflow.workspaceId,
119+
}
120+
}
121+
}
122+
123+
logger.info('Successfully retrieved user workflow YAML')
124+
125+
return {
126+
success: true,
127+
data: {
128+
yaml: yamlContent,
129+
metadata: includeMetadata ? metadata : undefined,
130+
},
131+
}
132+
} catch (error) {
133+
logger.error('Get user workflow failed', error)
134+
return {
135+
success: false,
136+
error: `Failed to get user workflow: ${error instanceof Error ? error.message : 'Unknown error'}`,
137+
}
138+
}
139+
},
140+
}
141+
75142
// Copilot tools registry
76143
const copilotTools: Record<string, CopilotTool> = {
77144
docs_search_internal: docsSearchTool,
145+
get_user_workflow: getUserWorkflowTool,
78146
}
79147

80148
// Get a copilot tool by ID

apps/sim/tools/docs/search.ts

Lines changed: 2 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,6 @@
11
import type { ToolConfig } from '../types'
22

3-
export interface DocsSearchParams {
4-
query: string
5-
topK?: number
6-
}
7-
8-
export interface DocsSearchResponse {
9-
results: Array<{
10-
id: number
11-
title: string
12-
url: string
13-
content: string
14-
similarity: number
15-
}>
16-
query: string
17-
totalResults: number
18-
}
19-
20-
export const docsSearchTool: ToolConfig<DocsSearchParams, DocsSearchResponse> = {
3+
export const docsSearchTool: ToolConfig = {
214
id: 'docs_search_internal',
225
name: 'Search Documentation',
236
description:
@@ -34,7 +17,6 @@ export const docsSearchTool: ToolConfig<DocsSearchParams, DocsSearchResponse> =
3417
type: 'number',
3518
required: false,
3619
description: 'Number of results to return (default: 5, max: 10)',
37-
default: 5,
3820
},
3921
},
4022

@@ -50,25 +32,4 @@ export const docsSearchTool: ToolConfig<DocsSearchParams, DocsSearchResponse> =
5032
}),
5133
isInternalRoute: true,
5234
},
53-
54-
transformResponse: async (response: Response): Promise<any> => {
55-
const data = await response.json()
56-
57-
if (!response.ok) {
58-
return {
59-
success: false,
60-
output: {},
61-
error: data.error || 'Failed to search documentation',
62-
}
63-
}
64-
65-
return {
66-
success: true,
67-
output: {
68-
results: data.results || [],
69-
query: data.query || '',
70-
totalResults: data.totalResults || 0,
71-
},
72-
}
73-
},
74-
}
35+
}

apps/sim/tools/utils.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@ import { useCustomToolsStore } from '@/stores/custom-tools/store'
44
import { useEnvironmentStore } from '@/stores/settings/environment/store'
55
import { docsSearchTool } from './docs/search'
66
import { tools } from './registry'
7+
import { getUserWorkflowTool } from './workflow/get-yaml'
78
import type { TableRow, ToolConfig, ToolResponse } from './types'
89

910
const logger = createLogger('ToolsUtils')
1011

12+
// Internal-only tools (not exposed to users in workflows)
13+
const internalTools: Record<string, ToolConfig> = {
14+
docs_search_internal: docsSearchTool,
15+
get_user_workflow: getUserWorkflowTool,
16+
}
17+
1118
/**
1219
* Transforms a table from the store format to a key-value object
1320
* @param table Array of table rows from the store
@@ -268,11 +275,6 @@ export function createCustomToolRequestBody(
268275
}
269276
}
270277

271-
// Internal-only tools (not exposed to users in workflows)
272-
const internalTools: Record<string, ToolConfig> = {
273-
docs_search_internal: docsSearchTool,
274-
}
275-
276278
// Get a tool by its ID
277279
export function getTool(toolId: string): ToolConfig | undefined {
278280
// Check for internal tools first
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import type { ToolConfig } from '../types'
2+
3+
export const getUserWorkflowTool: ToolConfig = {
4+
id: 'get_user_workflow',
5+
name: 'Get User Workflow',
6+
description:
7+
'Get the current user workflow as YAML format. This shows all blocks, their configurations, inputs, and connections in the workflow.',
8+
version: '1.0.0',
9+
10+
params: {
11+
includeMetadata: {
12+
type: 'boolean',
13+
required: false,
14+
description: 'Whether to include additional metadata about the workflow (default: false)',
15+
},
16+
},
17+
18+
request: {
19+
url: '/api/workflows/current/yaml',
20+
method: 'POST',
21+
headers: () => ({
22+
'Content-Type': 'application/json',
23+
}),
24+
body: (params) => ({
25+
includeMetadata: params.includeMetadata || false,
26+
}),
27+
isInternalRoute: true,
28+
},
29+
}

0 commit comments

Comments
 (0)