toolsdk
packageThis package is not in the latest version of its module.
Details
Validgo.mod file
The Go module system was introduced in Go 1.11 and is the official dependency management solution for Go.
Redistributable license
Redistributable licenses place minimal restrictions on how software can be used, modified, and redistributed.
Tagged version
Modules with tagged versions give importers more predictable builds.
Stable version
When a project reaches major version v1 it is considered stable.
- Learn more about best practices
Repository
Links
Documentation¶
Index¶
- Constants
- Variables
- func NormalizeWorkspaceInput(input string) string
- func WithTaskReporter(fn func(ReportTaskArgs) error) func(*Deps)
- type CreateTemplateArgs
- type CreateTemplateVersionArgs
- type CreateWorkspaceArgs
- type CreateWorkspaceBuildArgs
- type DeleteTemplateArgs
- type Deps
- type FetchArgs
- type FetchResult
- type GenericHandlerFunc
- type GenericTool
- type GetTemplateVersionLogsArgs
- type GetWorkspaceAgentLogsArgs
- type GetWorkspaceArgs
- type GetWorkspaceBuildLogsArgs
- type HandlerFunc
- type ListTemplateVersionParametersArgs
- type ListWorkspacesArgs
- type MinimalTemplate
- type MinimalWorkspace
- type NoArgs
- type ObjectID
- type ObjectType
- type ReportTaskArgs
- type SearchArgs
- type SearchQuery
- type SearchQueryType
- type SearchResult
- type SearchResultItem
- type Tool
- type UpdateTemplateActiveVersionArgs
- type UploadTarFileArgs
- type WorkspaceBashArgs
- type WorkspaceBashResult
Constants¶
const (ToolNameReportTask = "coder_report_task"ToolNameGetWorkspace = "coder_get_workspace"ToolNameCreateWorkspace = "coder_create_workspace"ToolNameListWorkspaces = "coder_list_workspaces"ToolNameListTemplates = "coder_list_templates"ToolNameListTemplateVersionParams = "coder_template_version_parameters"ToolNameGetAuthenticatedUser = "coder_get_authenticated_user"ToolNameCreateWorkspaceBuild = "coder_create_workspace_build"ToolNameCreateTemplateVersion = "coder_create_template_version"ToolNameGetWorkspaceAgentLogs = "coder_get_workspace_agent_logs"ToolNameGetWorkspaceBuildLogs = "coder_get_workspace_build_logs"ToolNameGetTemplateVersionLogs = "coder_get_template_version_logs"ToolNameUpdateTemplateActiveVersion = "coder_update_template_active_version"ToolNameUploadTarFile = "coder_upload_tar_file"ToolNameCreateTemplate = "coder_create_template"ToolNameDeleteTemplate = "coder_delete_template"ToolNameWorkspaceBash = "coder_workspace_bash"ToolNameChatGPTSearch = "search"ToolNameChatGPTFetch = "fetch")
Tool name constants to avoid hardcoded strings
Variables¶
var All = []GenericTool{CreateTemplate.Generic(),CreateTemplateVersion.Generic(),CreateWorkspace.Generic(),CreateWorkspaceBuild.Generic(),DeleteTemplate.Generic(),ListTemplates.Generic(),ListTemplateVersionParameters.Generic(),ListWorkspaces.Generic(),GetAuthenticatedUser.Generic(),GetTemplateVersionLogs.Generic(),GetWorkspace.Generic(),GetWorkspaceAgentLogs.Generic(),GetWorkspaceBuildLogs.Generic(),ReportTask.Generic(),UploadTarFile.Generic(),UpdateTemplateActiveVersion.Generic(),WorkspaceBash.Generic(),ChatGPTSearch.Generic(),ChatGPTFetch.Generic(),}
All is a list of all tools that can be used in the Coder CLI.When you add a new tool, be sure to include it here!
var ChatGPTFetch =Tool[FetchArgs,FetchResult]{Tool: aisdk.Tool{Name:ToolNameChatGPTFetch,Description: `Fetch a template or workspace.ID is a unique identifier for the template or workspace. It is a combination of the type and the ID.# ExamplesFetch a template with ID "56f13b5e-be0f-4a17-bdb2-aaacc3353ea7".` + "```" + `json{"id": "template:56f13b5e-be0f-4a17-bdb2-aaacc3353ea7"}` + "```" + `Fetch a workspace with ID "fcb6fc42-ba88-4175-9508-88e6a554a61a".` + "```" + `json{"id": "workspace:fcb6fc42-ba88-4175-9508-88e6a554a61a"}` + "```" + ``,Schema: aisdk.Schema{Properties: map[string]any{"id": map[string]any{"type": "string",},},Required: []string{"id"},},},Handler: func(ctxcontext.Context, depsDeps, argsFetchArgs) (FetchResult,error) {objectID, err := parseObjectID(args.ID)if err !=nil {returnFetchResult{}, err}switch objectID.Type {caseObjectTypeTemplate:return fetchTemplate(ctx, deps, objectID.ID)caseObjectTypeWorkspace:return fetchWorkspace(ctx, deps, objectID.ID)}returnFetchResult{},xerrors.Errorf("reached unreachable code with object ID: %s", args.ID)},}
Implements the "fetch" tool as described inhttps://platform.openai.com/docs/mcp#fetch-tool.From my experiments with ChatGPT, it seems that it does not see the description that isprovided in the tool definition. ChatGPT sees "fetch" as a very simple tool that can takean ID returned by the "search" tool and return the full details of the object.
var ChatGPTSearch =Tool[SearchArgs,SearchResult]{Tool: aisdk.Tool{Name:ToolNameChatGPTSearch,Description: `Search for templates, workspaces, and files in workspaces.To pick what you want to search for, use the following query formats:- ` + "`" + `templates/<template-query>` + "`" + `: List templates. The query accepts the following, optional parameters delineated by whitespace:- "name:<name>" - Fuzzy search by template name (substring matching). Example: "name:docker"- "organization:<organization>" - Filter by organization ID or name. Example: "organization:coder"- "deprecated:<true|false>" - Filter by deprecated status. Example: "deprecated:true"- "deleted:<true|false>" - Filter by deleted status. Example: "deleted:true"- "has-ai-task:<true|false>" - Filter by whether the template has an AI task. Example: "has-ai-task:true"- ` + "`" + `workspaces/<workspace-query>` + "`" + `: List workspaces. The query accepts the following, optional parameters delineated by whitespace:- "owner:<username>" - Filter by workspace owner (username or "me"). Example: "owner:alice" or "owner:me"- "template:<template-name>" - Filter by template name. Example: "template:web-development"- "name:<workspace-name>" - Filter by workspace name (substring matching). Example: "name:project"- "organization:<organization>" - Filter by organization ID or name. Example: "organization:engineering"- "status:<status>" - Filter by workspace/build status. Values: starting, stopping, deleting, deleted, stopped, started, running, pending, canceling, canceled, failed. Example: "status:running"- "has-agent:<agent-status>" - Filter by agent connectivity status. Values: connecting, connected, disconnected, timeout. Example: "has-agent:connected"- "dormant:<true|false>" - Filter dormant workspaces. Example: "dormant:true"- "outdated:<true|false>" - Filter workspaces using outdated template versions. Example: "outdated:true"- "last_used_after:<timestamp>" - Filter workspaces last used after a specific date. Example: "last_used_after:2023-12-01T00:00:00Z"- "last_used_before:<timestamp>" - Filter workspaces last used before a specific date. Example: "last_used_before:2023-12-31T23:59:59Z"- "has-ai-task:<true|false>" - Filter workspaces with AI tasks. Example: "has-ai-task:true"- "param:<name>" or "param:<name>=<value>" - Match workspaces by build parameters. Example: "param:environment=production" or "param:gpu"# Examples## Listing templatesList all templates without any filters.` + "```" + `json{"query": "templates"}` + "```" + `List all templates with a "docker" substring in the name.` + "```" + `json{"query": "templates/name:docker"}` + "```" + `List templates in a specific organization.` + "```" + `json{"query": "templates/organization:engineering"}` + "```" + `List deprecated templates.` + "```" + `json{"query": "templates/deprecated:true"}` + "```" + `List templates that have AI tasks.` + "```" + `json{"query": "templates/has-ai-task:true"}` + "```" + `List templates with multiple filters - non-deprecated templates with "web" in the name.` + "```" + `json{"query": "templates/name:web deprecated:false"}` + "```" + `List deleted templates (requires appropriate permissions).` + "```" + `json{"query": "templates/deleted:true"}` + "```" + `## Listing workspacesList all workspaces belonging to the current user.` + "```" + `json{"query": "workspaces/owner:me"}` + "```" + `or ` + "```" + `json{"query": "workspaces"}` + "```" + `List all workspaces belonging to a user with username "josh".` + "```" + `json{"query": "workspaces/owner:josh"}` + "```" + `List all running workspaces.` + "```" + `json{"query": "workspaces/status:running"}` + "```" + `List workspaces using a specific template.` + "```" + `json{"query": "workspaces/template:web-development"}` + "```" + `List dormant workspaces.` + "```" + `json{"query": "workspaces/dormant:true"}` + "```" + `List workspaces with connected agents.` + "```" + `json{"query": "workspaces/has-agent:connected"}` + "```" + `List workspaces with multiple filters - running workspaces owned by "alice".` + "```" + `json{"query": "workspaces/owner:alice status:running"}` + "```" + ``,Schema: aisdk.Schema{Properties: map[string]any{"query": map[string]any{"type": "string",},},Required: []string{"query"},},},Handler: func(ctxcontext.Context, depsDeps, argsSearchArgs) (SearchResult,error) {query, err := parseSearchQuery(args.Query)if err !=nil {returnSearchResult{}, err}switch query.Type {caseSearchQueryTypeTemplates:results, err := searchTemplates(ctx, deps, query.Query)if err !=nil {returnSearchResult{}, err}returnSearchResult{Results: results},nilcaseSearchQueryTypeWorkspaces:searchQuery := query.Queryif searchQuery == "" {searchQuery = "owner:me"}results, err := searchWorkspaces(ctx, deps, searchQuery)if err !=nil {returnSearchResult{}, err}returnSearchResult{Results: results},nil}returnSearchResult{},xerrors.Errorf("reached unreachable code with query: %s", args.Query)},}
Implements the "search" tool as described inhttps://platform.openai.com/docs/mcp#search-tool.From my experiments with ChatGPT, it has access to the description that is provided in thetool definition. This is in contrast to the "fetch" tool, where ChatGPT does not have accessto the description.
var CreateTemplate =Tool[CreateTemplateArgs,codersdk.Template]{Tool: aisdk.Tool{Name:ToolNameCreateTemplate,Description: "Create a new template in Coder. First, you must create a template version.",Schema: aisdk.Schema{Properties: map[string]any{"name": map[string]any{"type": "string",},"display_name": map[string]any{"type": "string",},"description": map[string]any{"type": "string",},"icon": map[string]any{"type": "string","description": "A URL to an icon to use.",},"version_id": map[string]any{"type": "string","description": "The ID of the version to use.",},},Required: []string{"name", "display_name", "description", "version_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsCreateTemplateArgs) (codersdk.Template,error) {me, err := deps.coderClient.User(ctx, "me")if err !=nil {returncodersdk.Template{}, err}versionID, err :=uuid.Parse(args.VersionID)if err !=nil {returncodersdk.Template{},xerrors.Errorf("version_id must be a valid UUID: %w", err)}template, err := deps.coderClient.CreateTemplate(ctx, me.OrganizationIDs[0],codersdk.CreateTemplateRequest{Name: args.Name,DisplayName: args.DisplayName,Description: args.Description,VersionID: versionID,})if err !=nil {returncodersdk.Template{}, err}return template,nil},}
var CreateTemplateVersion =Tool[CreateTemplateVersionArgs,codersdk.TemplateVersion]{Tool: aisdk.Tool{Name:ToolNameCreateTemplateVersion,Description: `Create a new template version. This is a precursor to creating a template, or you can update an existing template.Templates are Terraform defining a development environment. The provisioned infrastructure must runan Agent that connects to the Coder Control Plane to provide a rich experience.Here are some strict rules for creating a template version:- YOU MUST NOT use "variable" or "output" blocks in the Terraform code.- YOU MUST ALWAYS check template version logs after creation to ensure the template was imported successfully.When a template version is created, a Terraform Plan occurs that ensures the infrastructure_could_ be provisioned, but actual provisioning occurs when a workspace is created.<terraform-spec>The Coder Terraform Provider can be imported like:` + "```" + `hclterraform { required_providers { coder = { source = "coder/coder" } }}` + "```" + `A destroy does not occur when a user stops a workspace, but rather the transition changes:` + "```" + `hcldata "coder_workspace" "me" {}` + "```" + `This data source provides the following fields:- id: The UUID of the workspace.- name: The name of the workspace.- transition: Either "start" or "stop".- start_count: A computed count based on the transition field. If "start", this will be 1.Access workspace owner information with:` + "```" + `hcldata "coder_workspace_owner" "me" {}` + "```" + `This data source provides the following fields:- id: The UUID of the workspace owner.- name: The name of the workspace owner.- full_name: The full name of the workspace owner.- email: The email of the workspace owner.- session_token: A token that can be used to authenticate the workspace owner. It is regenerated every time the workspace is started.- oidc_access_token: A valid OpenID Connect access token of the workspace owner. This is only available if the workspace owner authenticated with OpenID Connect. If a valid token cannot be obtained, this value will be an empty string.Parameters are defined in the template version. They are rendered in the UI on the workspace creation page:` + "```" + `hclresource "coder_parameter" "region" { name = "region" type = "string" default = "us-east-1"}` + "```" + `This resource accepts the following properties:- name: The name of the parameter.- default: The default value of the parameter.- type: The type of the parameter. Must be one of: "string", "number", "bool", or "list(string)".- display_name: The displayed name of the parameter as it will appear in the UI.- description: The description of the parameter as it will appear in the UI.- ephemeral: The value of an ephemeral parameter will not be preserved between consecutive workspace builds.- form_type: The type of this parameter. Must be one of: [radio, slider, input, dropdown, checkbox, switch, multi-select, tag-select, textarea, error].- icon: A URL to an icon to display in the UI.- mutable: Whether this value can be changed after workspace creation. This can be destructive for values like region, so use with caution!- option: Each option block defines a value for a user to select from. (see below for nested schema) Required: - name: The name of the option. - value: The value of the option. Optional: - description: The description of the option as it will appear in the UI. - icon: A URL to an icon to display in the UI.A Workspace Agent runs on provisioned infrastructure to provide access to the workspace:` + "```" + `hclresource "coder_agent" "dev" { arch = "amd64" os = "linux"}` + "```" + `This resource accepts the following properties:- arch: The architecture of the agent. Must be one of: "amd64", "arm64", or "armv7".- os: The operating system of the agent. Must be one of: "linux", "windows", or "darwin".- auth: The authentication method for the agent. Must be one of: "token", "google-instance-identity", "aws-instance-identity", or "azure-instance-identity". It is insecure to pass the agent token via exposed variables to Virtual Machines. Instance Identity enables provisioned VMs to authenticate by instance ID on start.- dir: The starting directory when a user creates a shell session. Defaults to "$HOME".- env: A map of environment variables to set for the agent.- startup_script: A script to run after the agent starts. This script MUST exit eventually to signal that startup has completed. Use "&" or "screen" to run processes in the background.This resource provides the following fields:- id: The UUID of the agent.- init_script: The script to run on provisioned infrastructure to fetch and start the agent.- token: Set the environment variable CODER_AGENT_TOKEN to this value to authenticate the agent.The agent MUST be installed and started using the init_script. A utility like curl or wget to fetch the agent binary must exist in the provisioned infrastructure.Expose terminal or HTTP applications running in a workspace with:` + "```" + `hclresource "coder_app" "dev" { agent_id = coder_agent.dev.id slug = "my-app-name" display_name = "My App" icon = "https://my-app.com/icon.svg" url = "http://127.0.0.1:3000"}` + "```" + `This resource accepts the following properties:- agent_id: The ID of the agent to attach the app to.- slug: The slug of the app.- display_name: The displayed name of the app as it will appear in the UI.- icon: A URL to an icon to display in the UI.- url: An external url if external=true or a URL to be proxied to from inside the workspace. This should be of the form http://localhost:PORT[/SUBPATH]. Either command or url may be specified, but not both.- command: A command to run in a terminal opening this app. In the web, this will open in a new tab. In the CLI, this will SSH and execute the command. Either command or url may be specified, but not both.- external: Whether this app is an external app. If true, the url will be opened in a new tab.</terraform-spec>The Coder Server may not be authenticated with the infrastructure provider a user requests. In this scenario,the user will need to provide credentials to the Coder Server before the workspace can be provisioned.Here are examples of provisioning the Coder Agent on specific infrastructure providers:<aws-ec2-instance>// The agent is configured with "aws-instance-identity" auth.terraform { required_providers { cloudinit = { source = "hashicorp/cloudinit" } aws = { source = "hashicorp/aws" } }}data "cloudinit_config" "user_data" { gzip = false base64_encode = false boundary = "//" part { filename = "cloud-config.yaml" content_type = "text/cloud-config"// Here is the content of the cloud-config.yaml.tftpl file:// #cloud-config// cloud_final_modules:// - [scripts-user, always]// hostname: ${hostname}// users:// - name: ${linux_user}// sudo: ALL=(ALL) NOPASSWD:ALL// shell: /bin/bash content = templatefile("${path.module}/cloud-init/cloud-config.yaml.tftpl", { hostname = local.hostname linux_user = local.linux_user }) } part { filename = "userdata.sh" content_type = "text/x-shellscript"// Here is the content of the userdata.sh.tftpl file:// #!/bin/bash// sudo -u '${linux_user}' sh -c '${init_script}' content = templatefile("${path.module}/cloud-init/userdata.sh.tftpl", { linux_user = local.linux_user init_script = try(coder_agent.dev[0].init_script, "") }) }}resource "aws_instance" "dev" { ami = data.aws_ami.ubuntu.id availability_zone = "${data.coder_parameter.region.value}a" instance_type = data.coder_parameter.instance_type.value user_data = data.cloudinit_config.user_data.rendered tags = { Name = "coder-${data.coder_workspace_owner.me.name}-${data.coder_workspace.me.name}" } lifecycle { ignore_changes = [ami] }}</aws-ec2-instance><gcp-vm-instance>// The agent is configured with "google-instance-identity" auth.terraform { required_providers { google = { source = "hashicorp/google" } }}resource "google_compute_instance" "dev" { zone = module.gcp_region.value count = data.coder_workspace.me.start_count name = "coder-${lower(data.coder_workspace_owner.me.name)}-${lower(data.coder_workspace.me.name)}-root" machine_type = "e2-medium" network_interface { network = "default" access_config { // Ephemeral public IP } } boot_disk { auto_delete = false source = google_compute_disk.root.name } // In order to use google-instance-identity, a service account *must* be provided. service_account { email = data.google_compute_default_service_account.default.email scopes = ["cloud-platform"] } # ONLY FOR WINDOWS: # metadata = { # windows-startup-script-ps1 = coder_agent.main.init_script # } # The startup script runs as root with no $HOME environment set up, so instead of directly # running the agent init script, create a user (with a homedir, default shell and sudo # permissions) and execute the init script as that user. # # The agent MUST be started in here. metadata_startup_script = <<EOMETA#!/usr/bin/env shset -eux# If user does not exist, create it and set up passwordless sudoif ! id -u "${local.linux_user}" >/dev/null 2>&1; then useradd -m -s /bin/bash "${local.linux_user}" echo "${local.linux_user} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/coder-userfiexec sudo -u "${local.linux_user}" sh -c '${coder_agent.main.init_script}'EOMETA}</gcp-vm-instance><azure-vm-instance>// The agent is configured with "azure-instance-identity" auth.terraform { required_providers { azurerm = { source = "hashicorp/azurerm" } cloudinit = { source = "hashicorp/cloudinit" } }}data "cloudinit_config" "user_data" { gzip = false base64_encode = true boundary = "//" part { filename = "cloud-config.yaml" content_type = "text/cloud-config"// Here is the content of the cloud-config.yaml.tftpl file:// #cloud-config// cloud_final_modules:// - [scripts-user, always]// bootcmd:// # work around https://github.com/hashicorp/terraform-provider-azurerm/issues/6117// - until [ -e /dev/disk/azure/scsi1/lun10 ]; do sleep 1; done// device_aliases:// homedir: /dev/disk/azure/scsi1/lun10// disk_setup:// homedir:// table_type: gpt// layout: true// fs_setup:// - label: coder_home// filesystem: ext4// device: homedir.1// mounts:// - ["LABEL=coder_home", "/home/${username}"]// hostname: ${hostname}// users:// - name: ${username}// sudo: ["ALL=(ALL) NOPASSWD:ALL"]// groups: sudo// shell: /bin/bash// packages:// - git// write_files:// - path: /opt/coder/init// permissions: "0755"// encoding: b64// content: ${init_script}// - path: /etc/systemd/system/coder-agent.service// permissions: "0644"// content: |// [Unit]// Description=Coder Agent// After=network-online.target// Wants=network-online.target// [Service]// User=${username}// ExecStart=/opt/coder/init// Restart=always// RestartSec=10// TimeoutStopSec=90// KillMode=process// OOMScoreAdjust=-900// SyslogIdentifier=coder-agent// [Install]// WantedBy=multi-user.target// runcmd:// - chown ${username}:${username} /home/${username}// - systemctl enable coder-agent// - systemctl start coder-agent content = templatefile("${path.module}/cloud-init/cloud-config.yaml.tftpl", { username = "coder" # Ensure this user/group does not exist in your VM image init_script = base64encode(coder_agent.main.init_script) hostname = lower(data.coder_workspace.me.name) }) }}resource "azurerm_linux_virtual_machine" "main" { count = data.coder_workspace.me.start_count name = "vm" resource_group_name = azurerm_resource_group.main.name location = azurerm_resource_group.main.location size = data.coder_parameter.instance_type.value // cloud-init overwrites this, so the value here doesn't matter admin_username = "adminuser" admin_ssh_key { public_key = tls_private_key.dummy.public_key_openssh username = "adminuser" } network_interface_ids = [ azurerm_network_interface.main.id, ] computer_name = lower(data.coder_workspace.me.name) os_disk { caching = "ReadWrite" storage_account_type = "Standard_LRS" } source_image_reference { publisher = "Canonical" offer = "0001-com-ubuntu-server-focal" sku = "20_04-lts-gen2" version = "latest" } user_data = data.cloudinit_config.user_data.rendered}</azure-vm-instance><docker-container>terraform { required_providers { coder = { source = "kreuzwerker/docker" } }}// The agent is configured with "token" auth.resource "docker_container" "workspace" { count = data.coder_workspace.me.start_count image = "codercom/enterprise-base:ubuntu" # Uses lower() to avoid Docker restriction on container names. name = "coder-${data.coder_workspace_owner.me.name}-${lower(data.coder_workspace.me.name)}" # Hostname makes the shell more user friendly: coder@my-workspace:~$ hostname = data.coder_workspace.me.name # Use the docker gateway if the access URL is 127.0.0.1. entrypoint = ["sh", "-c", replace(coder_agent.main.init_script, "/localhost|127\\.0\\.0\\.1/", "host.docker.internal")] env = ["CODER_AGENT_TOKEN=${coder_agent.main.token}"] host { host = "host.docker.internal" ip = "host-gateway" } volumes { container_path = "/home/coder" volume_name = docker_volume.home_volume.name read_only = false }}</docker-container><kubernetes-pod>// The agent is configured with "token" auth.resource "kubernetes_deployment" "main" { count = data.coder_workspace.me.start_count depends_on = [ kubernetes_persistent_volume_claim.home ] wait_for_rollout = false metadata { name = "coder-${data.coder_workspace.me.id}" } spec { replicas = 1 strategy { type = "Recreate" } template { spec { security_context { run_as_user = 1000 fs_group = 1000 run_as_non_root = true } container { name = "dev" image = "codercom/enterprise-base:ubuntu" image_pull_policy = "Always" command = ["sh", "-c", coder_agent.main.init_script] security_context { run_as_user = "1000" } env { name = "CODER_AGENT_TOKEN" value = coder_agent.main.token } } } } }}</kubernetes-pod>The file_id provided is a reference to a tar file you have uploaded containing the Terraform.`,Schema: aisdk.Schema{Properties: map[string]any{"template_id": map[string]any{"type": "string",},"file_id": map[string]any{"type": "string",},},Required: []string{"file_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsCreateTemplateVersionArgs) (codersdk.TemplateVersion,error) {me, err := deps.coderClient.User(ctx, "me")if err !=nil {returncodersdk.TemplateVersion{}, err}fileID, err :=uuid.Parse(args.FileID)if err !=nil {returncodersdk.TemplateVersion{},xerrors.Errorf("file_id must be a valid UUID: %w", err)}var templateIDuuid.UUIDif args.TemplateID != "" {tid, err :=uuid.Parse(args.TemplateID)if err !=nil {returncodersdk.TemplateVersion{},xerrors.Errorf("template_id must be a valid UUID: %w", err)}templateID = tid}templateVersion, err := deps.coderClient.CreateTemplateVersion(ctx, me.OrganizationIDs[0],codersdk.CreateTemplateVersionRequest{Message: "Created by AI",StorageMethod:codersdk.ProvisionerStorageMethodFile,FileID: fileID,Provisioner:codersdk.ProvisionerTypeTerraform,TemplateID: templateID,})if err !=nil {returncodersdk.TemplateVersion{}, err}return templateVersion,nil},}
var CreateWorkspace =Tool[CreateWorkspaceArgs,codersdk.Workspace]{Tool: aisdk.Tool{Name:ToolNameCreateWorkspace,Description: `Create a new workspace in Coder.If a user is asking to "test a template", they are typically referringto creating a workspace from a template to ensure the infrastructureis provisioned correctly and the agent can connect to the control plane.`,Schema: aisdk.Schema{Properties: map[string]any{"user": map[string]any{"type": "string","description": "Username or ID of the user to create the workspace for. Use the `me` keyword to create a workspace for the authenticated user.",},"template_version_id": map[string]any{"type": "string","description": "ID of the template version to create the workspace from.",},"name": map[string]any{"type": "string","description": "Name of the workspace to create.",},"rich_parameters": map[string]any{"type": "object","description": "Key/value pairs of rich parameters to pass to the template version to create the workspace.",},},Required: []string{"user", "template_version_id", "name", "rich_parameters"},},},Handler: func(ctxcontext.Context, depsDeps, argsCreateWorkspaceArgs) (codersdk.Workspace,error) {tvID, err :=uuid.Parse(args.TemplateVersionID)if err !=nil {returncodersdk.Workspace{},xerrors.New("template_version_id must be a valid UUID")}if args.User == "" {args.User =codersdk.Me}var buildParams []codersdk.WorkspaceBuildParameterfor k, v := range args.RichParameters {buildParams =append(buildParams,codersdk.WorkspaceBuildParameter{Name: k,Value: v,})}workspace, err := deps.coderClient.CreateUserWorkspace(ctx, args.User,codersdk.CreateWorkspaceRequest{TemplateVersionID: tvID,Name: args.Name,RichParameterValues: buildParams,})if err !=nil {returncodersdk.Workspace{}, err}return workspace,nil},}
var CreateWorkspaceBuild =Tool[CreateWorkspaceBuildArgs,codersdk.WorkspaceBuild]{Tool: aisdk.Tool{Name:ToolNameCreateWorkspaceBuild,Description: "Create a new workspace build for an existing workspace. Use this to start, stop, or delete.",Schema: aisdk.Schema{Properties: map[string]any{"workspace_id": map[string]any{"type": "string",},"transition": map[string]any{"type": "string","description": "The transition to perform. Must be one of: start, stop, delete","enum": []string{"start", "stop", "delete"},},"template_version_id": map[string]any{"type": "string","description": "(Optional) The template version ID to use for the workspace build. If not provided, the previously built version will be used.",},},Required: []string{"workspace_id", "transition"},},},Handler: func(ctxcontext.Context, depsDeps, argsCreateWorkspaceBuildArgs) (codersdk.WorkspaceBuild,error) {workspaceID, err :=uuid.Parse(args.WorkspaceID)if err !=nil {returncodersdk.WorkspaceBuild{},xerrors.Errorf("workspace_id must be a valid UUID: %w", err)}var templateVersionIDuuid.UUIDif args.TemplateVersionID != "" {tvID, err :=uuid.Parse(args.TemplateVersionID)if err !=nil {returncodersdk.WorkspaceBuild{},xerrors.Errorf("template_version_id must be a valid UUID: %w", err)}templateVersionID = tvID}cbr :=codersdk.CreateWorkspaceBuildRequest{Transition:codersdk.WorkspaceTransition(args.Transition),}if templateVersionID !=uuid.Nil {cbr.TemplateVersionID = templateVersionID}return deps.coderClient.CreateWorkspaceBuild(ctx, workspaceID, cbr)},}
var DeleteTemplate =Tool[DeleteTemplateArgs,codersdk.Response]{Tool: aisdk.Tool{Name:ToolNameDeleteTemplate,Description: "Delete a template. This is irreversible.",Schema: aisdk.Schema{Properties: map[string]any{"template_id": map[string]any{"type": "string",},},Required: []string{"template_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsDeleteTemplateArgs) (codersdk.Response,error) {templateID, err :=uuid.Parse(args.TemplateID)if err !=nil {returncodersdk.Response{},xerrors.Errorf("template_id must be a valid UUID: %w", err)}err = deps.coderClient.DeleteTemplate(ctx, templateID)if err !=nil {returncodersdk.Response{}, err}returncodersdk.Response{Message: "Template deleted successfully.",},nil},}
var GetAuthenticatedUser =Tool[NoArgs,codersdk.User]{Tool: aisdk.Tool{Name:ToolNameGetAuthenticatedUser,Description: "Get the currently authenticated user, similar to the `whoami` command.",Schema: aisdk.Schema{Properties: map[string]any{},Required: []string{},},},Handler: func(ctxcontext.Context, depsDeps, _NoArgs) (codersdk.User,error) {return deps.coderClient.User(ctx, "me")},}
var GetTemplateVersionLogs =Tool[GetTemplateVersionLogsArgs, []string]{Tool: aisdk.Tool{Name:ToolNameGetTemplateVersionLogs,Description: "Get the logs of a template version. This is useful to check whether a template version successfully imports or not.",Schema: aisdk.Schema{Properties: map[string]any{"template_version_id": map[string]any{"type": "string",},},Required: []string{"template_version_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsGetTemplateVersionLogsArgs) ([]string,error) {templateVersionID, err :=uuid.Parse(args.TemplateVersionID)if err !=nil {returnnil,xerrors.Errorf("template_version_id must be a valid UUID: %w", err)}logs, closer, err := deps.coderClient.TemplateVersionLogsAfter(ctx, templateVersionID, 0)if err !=nil {returnnil, err}defer closer.Close()var acc []stringfor log := range logs {acc =append(acc, log.Output)}return acc,nil},}
var GetWorkspace =Tool[GetWorkspaceArgs,codersdk.Workspace]{Tool: aisdk.Tool{Name:ToolNameGetWorkspace,Description: `Get a workspace by ID.This returns more data than list_workspaces to reduce token usage.`,Schema: aisdk.Schema{Properties: map[string]any{"workspace_id": map[string]any{"type": "string",},},Required: []string{"workspace_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsGetWorkspaceArgs) (codersdk.Workspace,error) {wsID, err :=uuid.Parse(args.WorkspaceID)if err !=nil {returncodersdk.Workspace{},xerrors.New("workspace_id must be a valid UUID")}return deps.coderClient.Workspace(ctx, wsID)},}
var GetWorkspaceAgentLogs =Tool[GetWorkspaceAgentLogsArgs, []string]{Tool: aisdk.Tool{Name:ToolNameGetWorkspaceAgentLogs,Description: `Get the logs of a workspace agent.More logs may appear after this call. It does not wait for the agent to finish.`,Schema: aisdk.Schema{Properties: map[string]any{"workspace_agent_id": map[string]any{"type": "string",},},Required: []string{"workspace_agent_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsGetWorkspaceAgentLogsArgs) ([]string,error) {workspaceAgentID, err :=uuid.Parse(args.WorkspaceAgentID)if err !=nil {returnnil,xerrors.Errorf("workspace_agent_id must be a valid UUID: %w", err)}logs, closer, err := deps.coderClient.WorkspaceAgentLogsAfter(ctx, workspaceAgentID, 0,false)if err !=nil {returnnil, err}defer closer.Close()var acc []stringfor logChunk := range logs {for _, log := range logChunk {acc =append(acc, log.Output)}}return acc,nil},}
var GetWorkspaceBuildLogs =Tool[GetWorkspaceBuildLogsArgs, []string]{Tool: aisdk.Tool{Name:ToolNameGetWorkspaceBuildLogs,Description: `Get the logs of a workspace build.Useful for checking whether a workspace builds successfully or not.`,Schema: aisdk.Schema{Properties: map[string]any{"workspace_build_id": map[string]any{"type": "string",},},Required: []string{"workspace_build_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsGetWorkspaceBuildLogsArgs) ([]string,error) {workspaceBuildID, err :=uuid.Parse(args.WorkspaceBuildID)if err !=nil {returnnil,xerrors.Errorf("workspace_build_id must be a valid UUID: %w", err)}logs, closer, err := deps.coderClient.WorkspaceBuildLogsAfter(ctx, workspaceBuildID, 0)if err !=nil {returnnil, err}defer closer.Close()var acc []stringfor log := range logs {acc =append(acc, log.Output)}return acc,nil},}
var ListTemplateVersionParameters =Tool[ListTemplateVersionParametersArgs, []codersdk.TemplateVersionParameter]{Tool: aisdk.Tool{Name:ToolNameListTemplateVersionParams,Description: "Get the parameters for a template version. You can refer to these as workspace parameters to the user, as they are typically important for creating a workspace.",Schema: aisdk.Schema{Properties: map[string]any{"template_version_id": map[string]any{"type": "string",},},Required: []string{"template_version_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsListTemplateVersionParametersArgs) ([]codersdk.TemplateVersionParameter,error) {templateVersionID, err :=uuid.Parse(args.TemplateVersionID)if err !=nil {returnnil,xerrors.Errorf("template_version_id must be a valid UUID: %w", err)}parameters, err := deps.coderClient.TemplateVersionRichParameters(ctx, templateVersionID)if err !=nil {returnnil, err}return parameters,nil},}
var ListTemplates =Tool[NoArgs, []MinimalTemplate]{Tool: aisdk.Tool{Name:ToolNameListTemplates,Description: "Lists templates for the authenticated user.",Schema: aisdk.Schema{Properties: map[string]any{},Required: []string{},},},Handler: func(ctxcontext.Context, depsDeps, _NoArgs) ([]MinimalTemplate,error) {templates, err := deps.coderClient.Templates(ctx,codersdk.TemplateFilter{})if err !=nil {returnnil, err}minimalTemplates :=make([]MinimalTemplate,len(templates))for i, template := range templates {minimalTemplates[i] =MinimalTemplate{DisplayName: template.DisplayName,ID: template.ID.String(),Name: template.Name,Description: template.Description,ActiveVersionID: template.ActiveVersionID,ActiveUserCount: template.ActiveUserCount,}}return minimalTemplates,nil},}
var ListWorkspaces =Tool[ListWorkspacesArgs, []MinimalWorkspace]{Tool: aisdk.Tool{Name:ToolNameListWorkspaces,Description: "Lists workspaces for the authenticated user.",Schema: aisdk.Schema{Properties: map[string]any{"owner": map[string]any{"type": "string","description": "The owner of the workspaces to list. Use \"me\" to list workspaces for the authenticated user. If you do not specify an owner, \"me\" will be assumed by default.",},},Required: []string{},},},Handler: func(ctxcontext.Context, depsDeps, argsListWorkspacesArgs) ([]MinimalWorkspace,error) {owner := args.Ownerif owner == "" {owner =codersdk.Me}workspaces, err := deps.coderClient.Workspaces(ctx,codersdk.WorkspaceFilter{Owner: owner,})if err !=nil {returnnil, err}minimalWorkspaces :=make([]MinimalWorkspace,len(workspaces.Workspaces))for i, workspace := range workspaces.Workspaces {minimalWorkspaces[i] =MinimalWorkspace{ID: workspace.ID.String(),Name: workspace.Name,TemplateID: workspace.TemplateID.String(),TemplateName: workspace.TemplateName,TemplateDisplayName: workspace.TemplateDisplayName,TemplateIcon: workspace.TemplateIcon,TemplateActiveVersionID: workspace.TemplateActiveVersionID,Outdated: workspace.Outdated,}}return minimalWorkspaces,nil},}
var ReportTask =Tool[ReportTaskArgs,codersdk.Response]{Tool: aisdk.Tool{Name:ToolNameReportTask,Description: `Report progress on your work.The user observes your work through a Task UI. To keep them updatedon your progress, or if you need help - use this tool.Good Tasks- "Cloning the repository <repository-url>"- "Working on <feature-name>"- "Figuring our why <issue> is happening"Bad Tasks- "I'm working on it"- "I'm trying to fix it"- "I'm trying to implement <feature-name>"Use the "state" field to indicate your progress. Periodically reportprogress with state "working" to keep the user updated. It is not possible to send too many updates!ONLY report an "idle" or "failure" state if you have FULLY completed the task.`,Schema: aisdk.Schema{Properties: map[string]any{"summary": map[string]any{"type": "string","description": "A concise summary of your current progress on the task. This must be less than 160 characters in length and must not include newlines or other control characters.",},"link": map[string]any{"type": "string","description": "A link to a relevant resource, such as a PR or issue.",},"state": map[string]any{"type": "string","description": "The state of your task. This can be one of the following: working, idle, or failure. Select the state that best represents your current progress.","enum": []string{string(codersdk.WorkspaceAppStatusStateWorking),string(codersdk.WorkspaceAppStatusStateIdle),string(codersdk.WorkspaceAppStatusStateFailure),},},},Required: []string{"summary", "link", "state"},},},UserClientOptional:true,Handler: func(_context.Context, depsDeps, argsReportTaskArgs) (codersdk.Response,error) {iflen(args.Summary) > 160 {returncodersdk.Response{},xerrors.New("summary must be less than 160 characters")}if deps.report ==nil {returncodersdk.Response{},xerrors.New("task reporting not available. Please ensure a task reporter is configured.")}err := deps.report(args)if err !=nil {returncodersdk.Response{}, err}returncodersdk.Response{Message: "Thanks for reporting!",},nil},}
var UpdateTemplateActiveVersion =Tool[UpdateTemplateActiveVersionArgs,string]{Tool: aisdk.Tool{Name:ToolNameUpdateTemplateActiveVersion,Description: "Update the active version of a template. This is helpful when iterating on templates.",Schema: aisdk.Schema{Properties: map[string]any{"template_id": map[string]any{"type": "string",},"template_version_id": map[string]any{"type": "string",},},Required: []string{"template_id", "template_version_id"},},},Handler: func(ctxcontext.Context, depsDeps, argsUpdateTemplateActiveVersionArgs) (string,error) {templateID, err :=uuid.Parse(args.TemplateID)if err !=nil {return "",xerrors.Errorf("template_id must be a valid UUID: %w", err)}templateVersionID, err :=uuid.Parse(args.TemplateVersionID)if err !=nil {return "",xerrors.Errorf("template_version_id must be a valid UUID: %w", err)}err = deps.coderClient.UpdateActiveTemplateVersion(ctx, templateID,codersdk.UpdateActiveTemplateVersion{ID: templateVersionID,})if err !=nil {return "", err}return "Successfully updated active version!",nil},}
var UploadTarFile =Tool[UploadTarFileArgs,codersdk.UploadResponse]{Tool: aisdk.Tool{Name:ToolNameUploadTarFile,Description: `Create and upload a tar file by key/value mapping of file names to file contents. Use this to create template versions. Reference the tool description of "create_template_version" to understand template requirements.`,Schema: aisdk.Schema{Properties: map[string]any{"files": map[string]any{"type": "object","description": "A map of file names to file contents.",},},Required: []string{"files"},},},Handler: func(ctxcontext.Context, depsDeps, argsUploadTarFileArgs) (codersdk.UploadResponse,error) {pipeReader, pipeWriter :=io.Pipe()done :=make(chan struct{})go func() {defer func() {_ = pipeWriter.Close()close(done)}()tarWriter :=tar.NewWriter(pipeWriter)for name, content := range args.Files {header := &tar.Header{Name: name,Size:int64(len(content)),Mode: 0o644,}if err := tarWriter.WriteHeader(header); err !=nil {_ = pipeWriter.CloseWithError(err)return}if _, err := tarWriter.Write([]byte(content)); err !=nil {_ = pipeWriter.CloseWithError(err)return}}if err := tarWriter.Close(); err !=nil {_ = pipeWriter.CloseWithError(err)}}()resp, err := deps.coderClient.Upload(ctx,codersdk.ContentTypeTar, pipeReader)if err !=nil {_ = pipeReader.CloseWithError(err)<-donereturncodersdk.UploadResponse{}, err}<-donereturn resp,nil},}
var WorkspaceBash =Tool[WorkspaceBashArgs,WorkspaceBashResult]{Tool: aisdk.Tool{Name:ToolNameWorkspaceBash,Description: `Execute a bash command in a Coder workspace.This tool provides the same functionality as the 'coder ssh <workspace> <command>' CLI command.It automatically starts the workspace if it's stopped and waits for the agent to be ready.The output is trimmed of leading and trailing whitespace.The workspace parameter supports various formats:- workspace (uses current user)- owner/workspace- owner--workspace- workspace.agent (specific agent)- owner/workspace.agentThe timeout_ms parameter specifies the command timeout in milliseconds (defaults to 60000ms, maximum of 300000ms).If the command times out, all output captured up to that point is returned with a cancellation message.For background commands (background: true), output is captured until the timeout is reached, then the commandcontinues running in the background. The captured output is returned as the result.Examples:- workspace: "my-workspace", command: "ls -la"- workspace: "john/dev-env", command: "git status", timeout_ms: 30000- workspace: "my-workspace", command: "npm run dev", background: true, timeout_ms: 10000- workspace: "my-workspace.main", command: "docker ps"`,Schema: aisdk.Schema{Properties: map[string]any{"workspace": map[string]any{"type": "string","description": "The workspace name in format [owner/]workspace[.agent]. If owner is not specified, the authenticated user is used.",},"command": map[string]any{"type": "string","description": "The bash command to execute in the workspace.",},"timeout_ms": map[string]any{"type": "integer","description": "Command timeout in milliseconds. Defaults to 60000ms (60 seconds) if not specified.","default": 60000,"minimum": 1,},"background": map[string]any{"type": "boolean","description": "Whether to run the command in the background. Output is captured until timeout, then the command continues running in the background.",},},Required: []string{"workspace", "command"},},},Handler: func(ctxcontext.Context, depsDeps, argsWorkspaceBashArgs) (resWorkspaceBashResult, errerror) {if args.Workspace == "" {returnWorkspaceBashResult{},xerrors.New("workspace name cannot be empty")}if args.Command == "" {returnWorkspaceBashResult{},xerrors.New("command cannot be empty")}ctx, cancel :=context.WithTimeoutCause(ctx, 5*time.Minute,xerrors.New("MCP handler timeout after 5 min"))defer cancel()workspaceName :=NormalizeWorkspaceInput(args.Workspace)_, workspaceAgent, err := findWorkspaceAndAgent(ctx, deps.coderClient, workspaceName)if err !=nil {returnWorkspaceBashResult{},xerrors.Errorf("failed to find workspace: %w", err)}if err :=cliui.Agent(ctx,io.Discard, workspaceAgent.ID,cliui.AgentOptions{FetchInterval: 0,Fetch: deps.coderClient.WorkspaceAgent,FetchLogs: deps.coderClient.WorkspaceAgentLogsAfter,Wait:true,}); err !=nil {returnWorkspaceBashResult{},xerrors.Errorf("agent not ready: %w", err)}wsClient :=workspacesdk.New(deps.coderClient)conn, err := wsClient.DialAgent(ctx, workspaceAgent.ID, &workspacesdk.DialAgentOptions{BlockEndpoints:false,})if err !=nil {returnWorkspaceBashResult{},xerrors.Errorf("failed to dial agent: %w", err)}defer conn.Close()if !conn.AwaitReachable(ctx) {returnWorkspaceBashResult{},xerrors.New("agent connection not reachable")}sshClient, err := conn.SSHClient(ctx)if err !=nil {returnWorkspaceBashResult{},xerrors.Errorf("failed to create SSH client: %w", err)}defer sshClient.Close()session, err := sshClient.NewSession()if err !=nil {returnWorkspaceBashResult{},xerrors.Errorf("failed to create SSH session: %w", err)}defer session.Close()timeoutMs := args.TimeoutMsdefaultTimeoutMs := 60000if timeoutMs <= 0 {timeoutMs = defaultTimeoutMs}command := args.Commandif args.Background {command =fmt.Sprintf("nohup %s </dev/null 2>&1", args.Command)}commandCtx, commandCancel :=context.WithTimeout(ctx,time.Duration(timeoutMs)*time.Millisecond)defer commandCancel()output, err := executeCommandWithTimeout(commandCtx, session, command)outputStr :=strings.TrimSpace(string(output))if err !=nil {iferrors.Is(context.Cause(commandCtx),context.DeadlineExceeded) {if args.Background {outputStr += "\nCommand continues running in background"} else {outputStr += "\nCommand canceled due to timeout"}returnWorkspaceBashResult{Output: outputStr,ExitCode: 124,},nil}exitCode := 1var exitErr *gossh.ExitErroriferrors.As(err, &exitErr) {exitCode = exitErr.ExitStatus()}returnWorkspaceBashResult{Output: outputStr,ExitCode: exitCode,},nil}returnWorkspaceBashResult{Output: outputStr,ExitCode: 0,},nil},}
Functions¶
funcNormalizeWorkspaceInput¶added inv2.25.0
NormalizeWorkspaceInput converts workspace name input to standard format.Handles the following input formats:
- workspace → workspace
- workspace.agent → workspace.agent
- owner/workspace → owner/workspace
- owner--workspace → owner/workspace
- owner/workspace.agent → owner/workspace.agent
- owner--workspace.agent → owner/workspace.agent
- agent.workspace.owner → owner/workspace.agent (Coder Connect format)
funcWithTaskReporter¶added inv2.24.0
func WithTaskReporter(fn func(ReportTaskArgs)error) func(*Deps)
Types¶
typeDeleteTemplateArgs¶
type DeleteTemplateArgs struct {TemplateIDstring `json:"template_id"`}
typeDeps¶
type Deps struct {// contains filtered or unexported fields}
Deps provides access to tool dependencies.
typeFetchResult¶added inv2.26.0
typeGenericHandlerFunc¶
type GenericHandlerFunc func(context.Context,Deps,json.RawMessage) (json.RawMessage,error)
GenericHandlerFunc is a function that handles a tool call.
funcWithCleanContext¶
func WithCleanContext(hGenericHandlerFunc)GenericHandlerFunc
WithCleanContext wraps a HandlerFunc to provide it with a new context.This ensures that no data is passed using context.Value.If a deadline is set on the parent context, it will be passed to the childcontext.
funcWithRecover¶
func WithRecover(hGenericHandlerFunc)GenericHandlerFunc
WithRecover wraps a HandlerFunc to recover from panics and return an error.
typeGenericTool¶
type GenericTool struct {aisdk.ToolHandlerGenericHandlerFunc// UserClientOptional indicates whether this tool can function without a valid// user authentication token. If true, the tool will be available even when// running in an unauthenticated mode with just an agent token.UserClientOptionalbool}
GenericTool is a type-erased wrapper for GenericTool.This allows referencing the tool without knowing the concrete argument orreturn type. The Handler function allows calling the tool with known types.
typeGetTemplateVersionLogsArgs¶
type GetTemplateVersionLogsArgs struct {TemplateVersionIDstring `json:"template_version_id"`}
typeGetWorkspaceAgentLogsArgs¶
type GetWorkspaceAgentLogsArgs struct {WorkspaceAgentIDstring `json:"workspace_agent_id"`}
typeGetWorkspaceArgs¶
type GetWorkspaceArgs struct {WorkspaceIDstring `json:"workspace_id"`}
typeGetWorkspaceBuildLogsArgs¶
type GetWorkspaceBuildLogsArgs struct {WorkspaceBuildIDstring `json:"workspace_build_id"`}
typeHandlerFunc¶
HandlerFunc is a typed function that handles a tool call.
typeListTemplateVersionParametersArgs¶
type ListTemplateVersionParametersArgs struct {TemplateVersionIDstring `json:"template_version_id"`}
typeListWorkspacesArgs¶
type ListWorkspacesArgs struct {Ownerstring `json:"owner"`}
typeMinimalTemplate¶
typeMinimalWorkspace¶
type MinimalWorkspace struct {IDstring `json:"id"`Namestring `json:"name"`TemplateIDstring `json:"template_id"`TemplateNamestring `json:"template_name"`TemplateDisplayNamestring `json:"template_display_name"`TemplateIconstring `json:"template_icon"`TemplateActiveVersionIDuuid.UUID `json:"template_active_version_id"`Outdatedbool `json:"outdated"`}
typeObjectID¶added inv2.26.0
type ObjectID struct {TypeObjectTypeIDstring}
typeObjectType¶added inv2.26.0
type ObjectTypestring
const (ObjectTypeTemplateObjectType = "template"ObjectTypeWorkspaceObjectType = "workspace")
typeReportTaskArgs¶
typeSearchArgs¶added inv2.26.0
type SearchArgs struct {Querystring `json:"query"`}
typeSearchQuery¶added inv2.26.0
type SearchQuery struct {TypeSearchQueryTypeQuerystring}
typeSearchQueryType¶added inv2.26.0
type SearchQueryTypestring
const (SearchQueryTypeTemplatesSearchQueryType = "templates"SearchQueryTypeWorkspacesSearchQueryType = "workspaces")
typeSearchResult¶added inv2.26.0
type SearchResult struct {Results []SearchResultItem `json:"results"`}
typeSearchResultItem¶added inv2.26.0
typeTool¶
type Tool[Arg, Retany] struct {aisdk.ToolHandlerHandlerFunc[Arg, Ret]// UserClientOptional indicates whether this tool can function without a valid// user authentication token. If true, the tool will be available even when// running in an unauthenticated mode with just an agent token.UserClientOptionalbool}
Tool consists of an aisdk.Tool and a corresponding typed handler function.
func (Tool[Arg, Ret])Generic¶
func (tTool[Arg, Ret]) Generic()GenericTool
Generic returns a type-erased version of a TypedTool where the arguments andreturn values are converted to/from json.RawMessage.This allows the tool to be referenced without knowing the concrete argumentsor return values. The original TypedHandlerFunc is wrapped to handle typeconversion.