Skip to content

Commit 50bae9d

Browse files
committed
feat: pass search query directly to endpoints
1 parent a48445e commit 50bae9d

File tree

1 file changed

+141
-38
lines changed

1 file changed

+141
-38
lines changed

codersdk/toolsdk/chatgpt.go

Lines changed: 141 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ func createObjectID(objectType ObjectType, id string) ObjectID {
5555
}
5656
}
5757

58-
func searchTemplates(ctx context.Context, deps Deps) ([]SearchResultItem, error) {
58+
func searchTemplates(ctx context.Context, deps Deps, query string) ([]SearchResultItem, error) {
5959
serverURL := getServerURL(deps)
60-
templates, err := deps.coderClient.Templates(ctx, codersdk.TemplateFilter{})
60+
templates, err := deps.coderClient.Templates(ctx, codersdk.TemplateFilter{
61+
SearchQuery: query,
62+
})
6163
if err != nil {
6264
return nil, err
6365
}
@@ -73,13 +75,10 @@ func searchTemplates(ctx context.Context, deps Deps) ([]SearchResultItem, error)
7375
return results, nil
7476
}
7577

76-
func searchWorkspaces(ctx context.Context, deps Deps, owner string) ([]SearchResultItem, error) {
78+
func searchWorkspaces(ctx context.Context, deps Deps, query string) ([]SearchResultItem, error) {
7779
serverURL := getServerURL(deps)
78-
if owner == "" {
79-
owner = "me"
80-
}
8180
workspaces, err := deps.coderClient.Workspaces(ctx, codersdk.WorkspaceFilter{
82-
Owner: owner,
81+
FilterQuery: query,
8382
})
8483
if err != nil {
8584
return nil, err
@@ -89,8 +88,8 @@ func searchWorkspaces(ctx context.Context, deps Deps, owner string) ([]SearchRes
8988
results[i] = SearchResultItem{
9089
ID: createObjectID(ObjectTypeWorkspace, workspace.ID.String()).String(),
9190
Title: workspace.Name,
92-
Text: fmt.Sprintf("Owner: %s\nTemplate: %s\nLatest transition: %s", owner, workspace.TemplateDisplayName, workspace.LatestBuild.Transition),
93-
URL: fmt.Sprintf("%s/%s/%s", serverURL, owner, workspace.Name),
91+
Text: fmt.Sprintf("Owner: %s\nTemplate: %s\nLatest transition: %s", workspace.OwnerName, workspace.TemplateDisplayName, workspace.LatestBuild.Transition),
92+
URL: fmt.Sprintf("%s/%s/%s", serverURL, workspace.OwnerName, workspace.Name),
9493
}
9594
}
9695
return results, nil
@@ -104,32 +103,24 @@ const (
104103
)
105104

106105
type SearchQuery struct {
107-
Type SearchQueryType
108-
WorkspaceOwner string
106+
Type SearchQueryType
107+
Query string
109108
}
110109

111110
func parseSearchQuery(query string) (SearchQuery, error) {
112-
parts := strings.Split(query, ":")
113-
switch SearchQueryType(parts[0]) {
114-
case SearchQueryTypeTemplates:
115-
// expected format: templates
116-
return SearchQuery{
117-
Type: SearchQueryTypeTemplates,
118-
}, nil
119-
case SearchQueryTypeWorkspaces:
120-
// expected format: workspaces:owner
121-
owner := "me"
122-
if len(parts) == 2 {
123-
owner = parts[1]
124-
} else if len(parts) != 1 {
125-
return SearchQuery{}, xerrors.Errorf("invalid query: %s", query)
126-
}
127-
return SearchQuery{
128-
Type: SearchQueryTypeWorkspaces,
129-
WorkspaceOwner: owner,
130-
}, nil
111+
parts := strings.Split(query, "/")
112+
queryType := SearchQueryType(parts[0])
113+
if !(queryType == SearchQueryTypeTemplates || queryType == SearchQueryTypeWorkspaces) {
114+
return SearchQuery{}, xerrors.Errorf("invalid query: %s", query)
131115
}
132-
return SearchQuery{}, xerrors.Errorf("invalid query: %s", query)
116+
queryString := ""
117+
if len(parts) > 1 {
118+
queryString = strings.Join(parts[1:], "/")
119+
}
120+
return SearchQuery{
121+
Type: queryType,
122+
Query: queryString,
123+
}, nil
133124
}
134125

135126
type SearchArgs struct {
@@ -154,32 +145,100 @@ type SearchResult struct {
154145
var ChatGPTSearch = Tool[SearchArgs, SearchResult]{
155146
Tool: aisdk.Tool{
156147
Name: ToolNameChatGPTSearch,
148+
// Note: the queries are passed directly to the list workspaces and list templates
149+
// endpoints. The list of accepted parameters below is not exhaustive - some are omitted
150+
// because they are not as useful in ChatGPT.
157151
Description: `Search for templates, workspaces, and files in workspaces.
158152
159153
To pick what you want to search for, use the following query formats:
160154
161-
- ` + "`" + `templates` + "`" + `: List all templates. This query is not parameterized.
162-
- ` + "`" + `workspaces:$owner` + "`" + `: List workspaces belonging to a user. If owner is not specified, the current user is used. The special value ` + "`" + `me` + "`" + ` can be used to search for workspaces owned by the current user.
155+
- ` + "`" + `templates/<template-query>` + "`" + `: List templates. The query accepts the following, optional parameters delineated by whitespace:
156+
- "name:<name>" - Fuzzy search by template name (substring matching). Example: "name:docker"
157+
- "organization:<organization>" - Filter by organization ID or name. Example: "organization:coder"
158+
- "deprecated:<true|false>" - Filter by deprecated status. Example: "deprecated:true"
159+
- "deleted:<true|false>" - Filter by deleted status. Example: "deleted:true"
160+
- "has-ai-task:<true|false>" - Filter by whether the template has an AI task. Example: "has-ai-task:true"
161+
- ` + "`" + `workspaces/<workspace-query>` + "`" + `: List workspaces. The query accepts the following, optional parameters delineated by whitespace:
162+
- "owner:<username>" - Filter by workspace owner (username or "me"). Example: "owner:alice" or "owner:me"
163+
- "template:<template-name>" - Filter by template name. Example: "template:web-development"
164+
- "name:<workspace-name>" - Filter by workspace name (substring matching). Example: "name:project"
165+
- "organization:<organization>" - Filter by organization ID or name. Example: "organization:engineering"
166+
- "status:<status>" - Filter by workspace/build status. Values: starting, stopping, deleting, deleted, stopped, started, running, pending, canceling, canceled, failed. Example: "status:running"
167+
- "has-agent:<agent-status>" - Filter by agent connectivity status. Values: connecting, connected, disconnected, timeout. Example: "has-agent:connected"
168+
- "dormant:<true|false>" - Filter dormant workspaces. Example: "dormant:true"
169+
- "outdated:<true|false>" - Filter workspaces using outdated template versions. Example: "outdated:true"
170+
- "last_used_after:<timestamp>" - Filter workspaces last used after a specific date. Example: "last_used_after:2023-12-01T00:00:00Z"
171+
- "last_used_before:<timestamp>" - Filter workspaces last used before a specific date. Example: "last_used_before:2023-12-31T23:59:59Z"
172+
- "has-ai-task:<true|false>" - Filter workspaces with AI tasks. Example: "has-ai-task:true"
173+
- "param:<name>" or "param:<name>=<value>" - Match workspaces by build parameters. Example: "param:environment=production" or "param:gpu"
163174
164175
# Examples
165176
166177
## Listing templates
167178
168-
List all templates.
179+
List all templates without any filters.
169180
170181
` + "```" + `json
171182
{
172183
"query": "templates"
173184
}
174185
` + "```" + `
175186
187+
List all templates with a "docker" substring in the name.
188+
189+
` + "```" + `json
190+
{
191+
"query": "templates/name:docker"
192+
}
193+
` + "```" + `
194+
195+
List templates in a specific organization.
196+
197+
` + "```" + `json
198+
{
199+
"query": "templates/organization:engineering"
200+
}
201+
` + "```" + `
202+
203+
List deprecated templates.
204+
205+
` + "```" + `json
206+
{
207+
"query": "templates/deprecated:true"
208+
}
209+
` + "```" + `
210+
211+
List templates that have AI tasks.
212+
213+
` + "```" + `json
214+
{
215+
"query": "templates/has-ai-task:true"
216+
}
217+
` + "```" + `
218+
219+
List templates with multiple filters - non-deprecated templates with "web" in the name.
220+
221+
` + "```" + `json
222+
{
223+
"query": "templates/name:web deprecated:false"
224+
}
225+
` + "```" + `
226+
227+
List deleted templates (requires appropriate permissions).
228+
229+
` + "```" + `json
230+
{
231+
"query": "templates/deleted:true"
232+
}
233+
` + "```" + `
234+
176235
## Listing workspaces
177236
178237
List all workspaces belonging to the current user.
179238
180239
` + "```" + `json
181240
{
182-
"query": "workspaces:me"
241+
"query": "workspaces/owner:me"
183242
}
184243
` + "```" + `
185244
@@ -195,7 +254,47 @@ List all workspaces belonging to a user with username "josh".
195254
196255
` + "```" + `json
197256
{
198-
"query": "workspaces:josh"
257+
"query": "workspaces/owner:josh"
258+
}
259+
` + "```" + `
260+
261+
List all running workspaces.
262+
263+
` + "```" + `json
264+
{
265+
"query": "workspaces/status:running"
266+
}
267+
` + "```" + `
268+
269+
List workspaces using a specific template.
270+
271+
` + "```" + `json
272+
{
273+
"query": "workspaces/template:web-development"
274+
}
275+
` + "```" + `
276+
277+
List dormant workspaces.
278+
279+
` + "```" + `json
280+
{
281+
"query": "workspaces/dormant:true"
282+
}
283+
` + "```" + `
284+
285+
List workspaces with connected agents.
286+
287+
` + "```" + `json
288+
{
289+
"query": "workspaces/has-agent:connected"
290+
}
291+
` + "```" + `
292+
293+
List workspaces with multiple filters - running workspaces owned by "alice".
294+
295+
` + "```" + `json
296+
{
297+
"query": "workspaces/owner:alice status:running"
199298
}
200299
` + "```" + `
201300
`,
@@ -215,13 +314,17 @@ List all workspaces belonging to a user with username "josh".
215314
}
216315
switch query.Type {
217316
case SearchQueryTypeTemplates:
218-
results, err := searchTemplates(ctx, deps)
317+
results, err := searchTemplates(ctx, deps, query.Query)
219318
if err != nil {
220319
return SearchResult{}, err
221320
}
222321
return SearchResult{Results: results}, nil
223322
case SearchQueryTypeWorkspaces:
224-
results, err := searchWorkspaces(ctx, deps, query.WorkspaceOwner)
323+
searchQuery := query.Query
324+
if searchQuery == "" {
325+
searchQuery = "owner:me"
326+
}
327+
results, err := searchWorkspaces(ctx, deps, searchQuery)
225328
if err != nil {
226329
return SearchResult{}, err
227330
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy