fix: normalize command paths to base names in shellparse (#25599)

Normalize program names in shellparse.Parse to their basename.

Does not rely on filepath.Base because the server may run on either
Linux or Windows where the behavior would differ.

Closes CODAGT-470
This commit is contained in:
Mathias Fredriksson
2026-05-22 13:36:53 +03:00
committed by GitHub
parent 5d40bac79f
commit 0ba702c43f
8 changed files with 187 additions and 159 deletions
+1 -1
View File
@@ -16825,7 +16825,7 @@ const docTemplate = `{
"type": "string" "type": "string"
}, },
"parsed_commands": { "parsed_commands": {
"description": "ParsedCommands holds parsed programs from an execute tool call's\nshell command, one entry per simple command in source order. Each\nentry is [program] or [program, arg] where arg is the first non-flag\npositional argument. Only populated when ToolName is \"execute\" and\nthe command parses successfully; nil otherwise.", "description": "ParsedCommands holds parsed programs from an execute tool call's\nshell command, one entry per simple command in source order. Each\nentry is [program] or [program, arg] where arg is the first non-flag\npositional argument. Program names are normalized to their base\nname (e.g. /usr/bin/go becomes go). Only populated when ToolName\nis \"execute\" and the command parses successfully; nil otherwise.",
"type": "array", "type": "array",
"items": { "items": {
"type": "array", "type": "array",
+1 -1
View File
@@ -15169,7 +15169,7 @@
"type": "string" "type": "string"
}, },
"parsed_commands": { "parsed_commands": {
"description": "ParsedCommands holds parsed programs from an execute tool call's\nshell command, one entry per simple command in source order. Each\nentry is [program] or [program, arg] where arg is the first non-flag\npositional argument. Only populated when ToolName is \"execute\" and\nthe command parses successfully; nil otherwise.", "description": "ParsedCommands holds parsed programs from an execute tool call's\nshell command, one entry per simple command in source order. Each\nentry is [program] or [program, arg] where arg is the first non-flag\npositional argument. Program names are normalized to their base\nname (e.g. /usr/bin/go becomes go). Only populated when ToolName\nis \"execute\" and the command parses successfully; nil otherwise.",
"type": "array", "type": "array",
"items": { "items": {
"type": "array", "type": "array",
+13 -2
View File
@@ -9,7 +9,8 @@ import (
// Parse returns one slice per simple command in src, in source order. // Parse returns one slice per simple command in src, in source order.
// Each is [program] or [program, arg], where arg is the first non-flag // Each is [program] or [program, arg], where arg is the first non-flag
// positional argument. // positional argument. Program names are normalized to their base name
// (e.g. /usr/bin/go becomes go).
// //
// Some malformed inputs (e.g. trailing unterminated tokens after valid // Some malformed inputs (e.g. trailing unterminated tokens after valid
// semicolon-separated commands) yield partial results alongside a // semicolon-separated commands) yield partial results alongside a
@@ -35,7 +36,7 @@ func Parse(src string) ([][]string, error) {
if prog == "" { if prog == "" {
return true return true
} }
step := []string{prog} step := []string{cmdBase(prog)}
if arg := firstNonFlagLiteral(call.Args[1:]); arg != "" { if arg := firstNonFlagLiteral(call.Args[1:]); arg != "" {
step = append(step, arg) step = append(step, arg)
} }
@@ -77,6 +78,16 @@ func wordLiteral(w *syntax.Word) string {
return sb.String() return sb.String()
} }
// cmdBase returns the base name of a command path, handling both
// forward and back slashes since commands may originate from Windows
// workspaces while this code runs on a Linux server.
func cmdBase(prog string) string {
if i := strings.LastIndexAny(prog, `/\`); i >= 0 {
return prog[i+1:]
}
return prog
}
// firstNonFlagLiteral returns the literal value of the first word in // firstNonFlagLiteral returns the literal value of the first word in
// ws that does not start with "-", or "" if none qualifies. // ws that does not start with "-", or "" if none qualifies.
// //
+16 -1
View File
@@ -93,7 +93,22 @@ done`,
{ {
name: "quoted-program-name", name: "quoted-program-name",
in: `"/usr/bin/git" pull`, in: `"/usr/bin/git" pull`,
want: [][]string{{"/usr/bin/git", "pull"}}, want: [][]string{{"git", "pull"}},
},
{
name: "absolute-path-binary",
in: `/opt/mise/data/installs/go/1.26.2/bin/go test ./...`,
want: [][]string{{"go", "test"}},
},
{
name: "relative-path-binary",
in: `./build.sh --verbose`,
want: [][]string{{"build.sh"}},
},
{
name: "windows-path-binary",
in: `'C:\Program Files\Go\bin\go.exe' test ./...`,
want: [][]string{{"go.exe", "test"}},
}, },
{ {
name: "double-quoted-with-variable-expansion-skipped", name: "double-quoted-with-variable-expansion-skipped",
+3 -2
View File
@@ -259,8 +259,9 @@ type ChatMessagePart struct {
// ParsedCommands holds parsed programs from an execute tool call's // ParsedCommands holds parsed programs from an execute tool call's
// shell command, one entry per simple command in source order. Each // shell command, one entry per simple command in source order. Each
// entry is [program] or [program, arg] where arg is the first non-flag // entry is [program] or [program, arg] where arg is the first non-flag
// positional argument. Only populated when ToolName is "execute" and // positional argument. Program names are normalized to their base
// the command parses successfully; nil otherwise. // name (e.g. /usr/bin/go becomes go). Only populated when ToolName
// is "execute" and the command parses successfully; nil otherwise.
ParsedCommands [][]string `json:"parsed_commands,omitempty" variants:"tool-call?"` ParsedCommands [][]string `json:"parsed_commands,omitempty" variants:"tool-call?"`
Result json.RawMessage `json:"result,omitempty" variants:"tool-result?"` Result json.RawMessage `json:"result,omitempty" variants:"tool-result?"`
ResultDelta string `json:"result_delta,omitempty" variants:"tool-result?"` ResultDelta string `json:"result_delta,omitempty" variants:"tool-result?"`
+109 -109
View File
@@ -180,115 +180,115 @@ Experimental: this endpoint is subject to change.
Status Code **200** Status Code **200**
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
|-----------------------------------|------------------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |-----------------------------------|------------------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `[array item]` | array | false | | | | `[array item]` | array | false | | |
| `» agent_id` | string(uuid) | false | | | | `» agent_id` | string(uuid) | false | | |
| `» archived` | boolean | false | | | | `» archived` | boolean | false | | |
| `» build_id` | string(uuid) | false | | | | `» build_id` | string(uuid) | false | | |
| `» children` | [codersdk.Chat](schemas.md#codersdkchat) | false | | Children holds child (subagent) chats nested under this root chat. Always initialized to an empty slice so the JSON field is present as []. Child chats cannot create their own subagents, so nesting depth is capped at 1 and this slice is always empty for child chats. | | `» children` | [codersdk.Chat](schemas.md#codersdkchat) | false | | Children holds child (subagent) chats nested under this root chat. Always initialized to an empty slice so the JSON field is present as []. Child chats cannot create their own subagents, so nesting depth is capped at 1 and this slice is always empty for child chats. |
| `» client_type` | [codersdk.ChatClientType](schemas.md#codersdkchatclienttype) | false | | | | `» client_type` | [codersdk.ChatClientType](schemas.md#codersdkchatclienttype) | false | | |
| `» created_at` | string(date-time) | false | | | | `» created_at` | string(date-time) | false | | |
| `» diff_status` | [codersdk.ChatDiffStatus](schemas.md#codersdkchatdiffstatus) | false | | | | `» diff_status` | [codersdk.ChatDiffStatus](schemas.md#codersdkchatdiffstatus) | false | | |
| `»» additions` | integer | false | | | | `»» additions` | integer | false | | |
| `»» approved` | boolean | false | | | | `»» approved` | boolean | false | | |
| `»» author_avatar_url` | string | false | | | | `»» author_avatar_url` | string | false | | |
| `»» author_login` | string | false | | | | `»» author_login` | string | false | | |
| `»» base_branch` | string | false | | | | `»» base_branch` | string | false | | |
| `»» changed_files` | integer | false | | | | `»» changed_files` | integer | false | | |
| `»» changes_requested` | boolean | false | | | | `»» changes_requested` | boolean | false | | |
| `»» chat_id` | string(uuid) | false | | | | `»» chat_id` | string(uuid) | false | | |
| `»» commits` | integer | false | | | | `»» commits` | integer | false | | |
| `»» deletions` | integer | false | | | | `»» deletions` | integer | false | | |
| `»» head_branch` | string | false | | | | `»» head_branch` | string | false | | |
| `»» pr_number` | integer | false | | | | `»» pr_number` | integer | false | | |
| `»» pull_request_draft` | boolean | false | | | | `»» pull_request_draft` | boolean | false | | |
| `»» pull_request_state` | string | false | | | | `»» pull_request_state` | string | false | | |
| `»» pull_request_title` | string | false | | | | `»» pull_request_title` | string | false | | |
| `»» refreshed_at` | string(date-time) | false | | | | `»» refreshed_at` | string(date-time) | false | | |
| `»» reviewer_count` | integer | false | | | | `»» reviewer_count` | integer | false | | |
| `»» stale_at` | string(date-time) | false | | | | `»» stale_at` | string(date-time) | false | | |
| `»» url` | string | false | | | | `»» url` | string | false | | |
| `» files` | array | false | | | | `» files` | array | false | | |
| `»» created_at` | string(date-time) | false | | | | `»» created_at` | string(date-time) | false | | |
| `»» id` | string(uuid) | false | | | | `»» id` | string(uuid) | false | | |
| `»» mime_type` | string | false | | | | `»» mime_type` | string | false | | |
| `»» name` | string | false | | | | `»» name` | string | false | | |
| `»» organization_id` | string(uuid) | false | | | | `»» organization_id` | string(uuid) | false | | |
| `»» owner_id` | string(uuid) | false | | | | `»» owner_id` | string(uuid) | false | | |
| `» has_unread` | boolean | false | | Has unread is true when assistant messages exist beyond the owner's read cursor, which updates on stream connect and disconnect. | | `» has_unread` | boolean | false | | Has unread is true when assistant messages exist beyond the owner's read cursor, which updates on stream connect and disconnect. |
| `» id` | string(uuid) | false | | | | `» id` | string(uuid) | false | | |
| `» labels` | object | false | | | | `» labels` | object | false | | |
| `»» [any property]` | string | false | | | | `»» [any property]` | string | false | | |
| `» last_error` | [codersdk.ChatError](schemas.md#codersdkchaterror) | false | | | | `» last_error` | [codersdk.ChatError](schemas.md#codersdkchaterror) | false | | |
| `»» detail` | string | false | | Detail is optional provider-specific context shown alongside the normalized error message when available. | | `»» detail` | string | false | | Detail is optional provider-specific context shown alongside the normalized error message when available. |
| `»» kind` | [codersdk.ChatErrorKind](schemas.md#codersdkchaterrorkind) | false | | Kind classifies the error for consistent client rendering. | | `»» kind` | [codersdk.ChatErrorKind](schemas.md#codersdkchaterrorkind) | false | | Kind classifies the error for consistent client rendering. |
| `»» message` | string | false | | Message is the normalized, user-facing error message. | | `»» message` | string | false | | Message is the normalized, user-facing error message. |
| `»» provider` | string | false | | Provider identifies the upstream model provider when known. | | `»» provider` | string | false | | Provider identifies the upstream model provider when known. |
| `»» retryable` | boolean | false | | Retryable reports whether the underlying error is transient. | | `»» retryable` | boolean | false | | Retryable reports whether the underlying error is transient. |
| `»» status_code` | integer | false | | Status code is the best-effort upstream HTTP status code. | | `»» status_code` | integer | false | | Status code is the best-effort upstream HTTP status code. |
| `» last_injected_context` | array | false | | Last injected context holds the most recently persisted injected context parts (AGENTS.md files and skills). It is updated only when context changes, on first workspace attach or agent change. | | `» last_injected_context` | array | false | | Last injected context holds the most recently persisted injected context parts (AGENTS.md files and skills). It is updated only when context changes, on first workspace attach or agent change. |
| `»» args` | array | false | | | | `»» args` | array | false | | |
| `»» args_delta` | string | false | | | | `»» args_delta` | string | false | | |
| `»» completed_at` | string(date-time) | false | | Completed at is the time a reasoning part finished streaming, so reasoning duration can be computed as completed_at minus created_at. For interrupted reasoning, this is the interruption time. Absent when reasoning timestamp data was not recorded (e.g. messages persisted before this feature was added). | | `»» completed_at` | string(date-time) | false | | Completed at is the time a reasoning part finished streaming, so reasoning duration can be computed as completed_at minus created_at. For interrupted reasoning, this is the interruption time. Absent when reasoning timestamp data was not recorded (e.g. messages persisted before this feature was added). |
| `»» content` | string | false | | The code content from the diff that was commented on. | | `»» content` | string | false | | The code content from the diff that was commented on. |
| `»» context_file_agent_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | Context file agent ID is the workspace agent that provided this context file. Used to detect when the agent changes (e.g. workspace rebuilt) so instruction files can be re-persisted with fresh content. | | `»» context_file_agent_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | Context file agent ID is the workspace agent that provided this context file. Used to detect when the agent changes (e.g. workspace rebuilt) so instruction files can be re-persisted with fresh content. |
| `»»» uuid` | string | false | | | | `»»» uuid` | string | false | | |
| `»»» valid` | boolean | false | | Valid is true if UUID is not NULL | | `»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»» context_file_content` | string | false | | Context file content holds the file content sent to the LLM. Internal only: stripped before API responses to keep payloads small. The backend reads it when building the prompt via partsToMessageParts. | | `»» context_file_content` | string | false | | Context file content holds the file content sent to the LLM. Internal only: stripped before API responses to keep payloads small. The backend reads it when building the prompt via partsToMessageParts. |
| `»» context_file_directory` | string | false | | Context file directory is the working directory of the workspace agent. Internal only: same purpose as ContextFileOS. | | `»» context_file_directory` | string | false | | Context file directory is the working directory of the workspace agent. Internal only: same purpose as ContextFileOS. |
| `»» context_file_os` | string | false | | Context file os is the operating system of the workspace agent. Internal only: used during prompt expansion so the LLM knows the OS even on turns where InsertSystem is not called. | | `»» context_file_os` | string | false | | Context file os is the operating system of the workspace agent. Internal only: used during prompt expansion so the LLM knows the OS even on turns where InsertSystem is not called. |
| `»» context_file_path` | string | false | | Context file path is the absolute path of a file loaded into the LLM context (e.g. an AGENTS.md instruction file). | | `»» context_file_path` | string | false | | Context file path is the absolute path of a file loaded into the LLM context (e.g. an AGENTS.md instruction file). |
| `»» context_file_skill_meta_file` | string | false | | Context file skill meta file is the basename of the skill meta file (e.g. "SKILL.md") at the time of persistence. Internal only: restored on subsequent turns so the read_skill tool uses the correct filename even when the agent configured a non-default value. | | `»» context_file_skill_meta_file` | string | false | | Context file skill meta file is the basename of the skill meta file (e.g. "SKILL.md") at the time of persistence. Internal only: restored on subsequent turns so the read_skill tool uses the correct filename even when the agent configured a non-default value. |
| `»» context_file_truncated` | boolean | false | | Context file truncated indicates the file exceeded the 64KiB instruction file limit and was truncated. | | `»» context_file_truncated` | boolean | false | | Context file truncated indicates the file exceeded the 64KiB instruction file limit and was truncated. |
| `»» created_at` | string(date-time) | false | | Created at is the timestamp this part carries. The semantics depend on the part type: for tool-call and tool-result parts it is the time the call was emitted or the result was produced (tool duration is the result's created_at minus the call's created_at); for reasoning parts it is the time reasoning started streaming. | | `»» created_at` | string(date-time) | false | | Created at is the timestamp this part carries. The semantics depend on the part type: for tool-call and tool-result parts it is the time the call was emitted or the result was produced (tool duration is the result's created_at minus the call's created_at); for reasoning parts it is the time reasoning started streaming. |
| `»» data` | array | false | | | | `»» data` | array | false | | |
| `»» end_line` | integer | false | | | | `»» end_line` | integer | false | | |
| `»» file_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | | | `»» file_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | |
| `»»» uuid` | string | false | | | | `»»» uuid` | string | false | | |
| `»»» valid` | boolean | false | | Valid is true if UUID is not NULL | | `»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»» file_name` | string | false | | | | `»» file_name` | string | false | | |
| `»» is_error` | boolean | false | | | | `»» is_error` | boolean | false | | |
| `»» is_media` | boolean | false | | | | `»» is_media` | boolean | false | | |
| `»» mcp_server_config_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | | | `»» mcp_server_config_id` | [uuid.NullUUID](schemas.md#uuidnulluuid) | false | | |
| `»»» uuid` | string | false | | | | `»»» uuid` | string | false | | |
| `»»» valid` | boolean | false | | Valid is true if UUID is not NULL | | `»»» valid` | boolean | false | | Valid is true if UUID is not NULL |
| `»» media_type` | string | false | | | | `»» media_type` | string | false | | |
| `»» name` | string | false | | | | `»» name` | string | false | | |
| `»» parsed_commands` | array | false | | Parsed commands holds parsed programs from an execute tool call's shell command, one entry per simple command in source order. Each entry is [program] or [program, arg] where arg is the first non-flag positional argument. Only populated when ToolName is "execute" and the command parses successfully; nil otherwise. | | `»» parsed_commands` | array | false | | Parsed commands holds parsed programs from an execute tool call's shell command, one entry per simple command in source order. Each entry is [program] or [program, arg] where arg is the first non-flag positional argument. Program names are normalized to their base name (e.g. /usr/bin/go becomes go). Only populated when ToolName is "execute" and the command parses successfully; nil otherwise. |
| `»» provider_executed` | boolean | false | | Provider executed indicates the tool call was executed by the provider (e.g. Anthropic computer use). | | `»» provider_executed` | boolean | false | | Provider executed indicates the tool call was executed by the provider (e.g. Anthropic computer use). |
| `»» provider_metadata` | array | false | | Provider metadata holds provider-specific response metadata (e.g. Anthropic cache control hints) as raw JSON. Internal only: stripped by db2sdk before API responses. | | `»» provider_metadata` | array | false | | Provider metadata holds provider-specific response metadata (e.g. Anthropic cache control hints) as raw JSON. Internal only: stripped by db2sdk before API responses. |
| `»» result` | array | false | | | | `»» result` | array | false | | |
| `»» result_delta` | string | false | | | | `»» result_delta` | string | false | | |
| `»» result_reset` | boolean | false | | | | `»» result_reset` | boolean | false | | |
| `»» signature` | string | false | | | | `»» signature` | string | false | | |
| `»» skill_description` | string | false | | Skill description is the short description from the skill's SKILL.md frontmatter. | | `»» skill_description` | string | false | | Skill description is the short description from the skill's SKILL.md frontmatter. |
| `»» skill_dir` | string | false | | Skill dir is the absolute path to the skill directory inside the workspace filesystem. Internal only: used by read_skill/read_skill_file tools to locate skill files. | | `»» skill_dir` | string | false | | Skill dir is the absolute path to the skill directory inside the workspace filesystem. Internal only: used by read_skill/read_skill_file tools to locate skill files. |
| `»» skill_name` | string | false | | Skill name is the kebab-case name of a discovered skill from the workspace's .agents/skills/ directory. | | `»» skill_name` | string | false | | Skill name is the kebab-case name of a discovered skill from the workspace's .agents/skills/ directory. |
| `»» source_id` | string | false | | | | `»» source_id` | string | false | | |
| `»» start_line` | integer | false | | | | `»» start_line` | integer | false | | |
| `»» text` | string | false | | | | `»» text` | string | false | | |
| `»» title` | string | false | | | | `»» title` | string | false | | |
| `»» tool_call_id` | string | false | | | | `»» tool_call_id` | string | false | | |
| `»» tool_name` | string | false | | | | `»» tool_name` | string | false | | |
| `»» type` | [codersdk.ChatMessagePartType](schemas.md#codersdkchatmessageparttype) | false | | | | `»» type` | [codersdk.ChatMessagePartType](schemas.md#codersdkchatmessageparttype) | false | | |
| `»» url` | string | false | | | | `»» url` | string | false | | |
| `» last_model_config_id` | string(uuid) | false | | | | `» last_model_config_id` | string(uuid) | false | | |
| `» last_turn_summary` | string | false | | | | `» last_turn_summary` | string | false | | |
| `» mcp_server_ids` | array | false | | | | `» mcp_server_ids` | array | false | | |
| `» organization_id` | string(uuid) | false | | | | `» organization_id` | string(uuid) | false | | |
| `» owner_id` | string(uuid) | false | | | | `» owner_id` | string(uuid) | false | | |
| `» owner_name` | string | false | | | | `» owner_name` | string | false | | |
| `» owner_username` | string | false | | | | `» owner_username` | string | false | | |
| `» parent_chat_id` | string(uuid) | false | | | | `» parent_chat_id` | string(uuid) | false | | |
| `» pin_order` | integer | false | | | | `» pin_order` | integer | false | | |
| `» plan_mode` | [codersdk.ChatPlanMode](schemas.md#codersdkchatplanmode) | false | | | | `» plan_mode` | [codersdk.ChatPlanMode](schemas.md#codersdkchatplanmode) | false | | |
| `» root_chat_id` | string(uuid) | false | | | | `» root_chat_id` | string(uuid) | false | | |
| `» status` | [codersdk.ChatStatus](schemas.md#codersdkchatstatus) | false | | | | `» status` | [codersdk.ChatStatus](schemas.md#codersdkchatstatus) | false | | |
| `» title` | string | false | | | | `» title` | string | false | | |
| `» updated_at` | string(date-time) | false | | | | `» updated_at` | string(date-time) | false | | |
| `» warnings` | array | false | | | | `» warnings` | array | false | | |
| `» workspace_id` | string(uuid) | false | | | | `» workspace_id` | string(uuid) | false | | |
#### Enumerated Values #### Enumerated Values
+41 -41
View File
@@ -3026,47 +3026,47 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
### Properties ### Properties
| Name | Type | Required | Restrictions | Description | | Name | Type | Required | Restrictions | Description |
|--------------------------------|--------------------------------------------------------------|----------|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |--------------------------------|--------------------------------------------------------------|----------|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `args` | array of integer | false | | | | `args` | array of integer | false | | |
| `args_delta` | string | false | | | | `args_delta` | string | false | | |
| `completed_at` | string | false | | Completed at is the time a reasoning part finished streaming, so reasoning duration can be computed as completed_at minus created_at. For interrupted reasoning, this is the interruption time. Absent when reasoning timestamp data was not recorded (e.g. messages persisted before this feature was added). | | `completed_at` | string | false | | Completed at is the time a reasoning part finished streaming, so reasoning duration can be computed as completed_at minus created_at. For interrupted reasoning, this is the interruption time. Absent when reasoning timestamp data was not recorded (e.g. messages persisted before this feature was added). |
| `content` | string | false | | The code content from the diff that was commented on. | | `content` | string | false | | The code content from the diff that was commented on. |
| `context_file_agent_id` | [uuid.NullUUID](#uuidnulluuid) | false | | Context file agent ID is the workspace agent that provided this context file. Used to detect when the agent changes (e.g. workspace rebuilt) so instruction files can be re-persisted with fresh content. | | `context_file_agent_id` | [uuid.NullUUID](#uuidnulluuid) | false | | Context file agent ID is the workspace agent that provided this context file. Used to detect when the agent changes (e.g. workspace rebuilt) so instruction files can be re-persisted with fresh content. |
| `context_file_content` | string | false | | Context file content holds the file content sent to the LLM. Internal only: stripped before API responses to keep payloads small. The backend reads it when building the prompt via partsToMessageParts. | | `context_file_content` | string | false | | Context file content holds the file content sent to the LLM. Internal only: stripped before API responses to keep payloads small. The backend reads it when building the prompt via partsToMessageParts. |
| `context_file_directory` | string | false | | Context file directory is the working directory of the workspace agent. Internal only: same purpose as ContextFileOS. | | `context_file_directory` | string | false | | Context file directory is the working directory of the workspace agent. Internal only: same purpose as ContextFileOS. |
| `context_file_os` | string | false | | Context file os is the operating system of the workspace agent. Internal only: used during prompt expansion so the LLM knows the OS even on turns where InsertSystem is not called. | | `context_file_os` | string | false | | Context file os is the operating system of the workspace agent. Internal only: used during prompt expansion so the LLM knows the OS even on turns where InsertSystem is not called. |
| `context_file_path` | string | false | | Context file path is the absolute path of a file loaded into the LLM context (e.g. an AGENTS.md instruction file). | | `context_file_path` | string | false | | Context file path is the absolute path of a file loaded into the LLM context (e.g. an AGENTS.md instruction file). |
| `context_file_skill_meta_file` | string | false | | Context file skill meta file is the basename of the skill meta file (e.g. "SKILL.md") at the time of persistence. Internal only: restored on subsequent turns so the read_skill tool uses the correct filename even when the agent configured a non-default value. | | `context_file_skill_meta_file` | string | false | | Context file skill meta file is the basename of the skill meta file (e.g. "SKILL.md") at the time of persistence. Internal only: restored on subsequent turns so the read_skill tool uses the correct filename even when the agent configured a non-default value. |
| `context_file_truncated` | boolean | false | | Context file truncated indicates the file exceeded the 64KiB instruction file limit and was truncated. | | `context_file_truncated` | boolean | false | | Context file truncated indicates the file exceeded the 64KiB instruction file limit and was truncated. |
| `created_at` | string | false | | Created at is the timestamp this part carries. The semantics depend on the part type: for tool-call and tool-result parts it is the time the call was emitted or the result was produced (tool duration is the result's created_at minus the call's created_at); for reasoning parts it is the time reasoning started streaming. | | `created_at` | string | false | | Created at is the timestamp this part carries. The semantics depend on the part type: for tool-call and tool-result parts it is the time the call was emitted or the result was produced (tool duration is the result's created_at minus the call's created_at); for reasoning parts it is the time reasoning started streaming. |
| `data` | array of integer | false | | | | `data` | array of integer | false | | |
| `end_line` | integer | false | | | | `end_line` | integer | false | | |
| `file_id` | [uuid.NullUUID](#uuidnulluuid) | false | | | | `file_id` | [uuid.NullUUID](#uuidnulluuid) | false | | |
| `file_name` | string | false | | | | `file_name` | string | false | | |
| `is_error` | boolean | false | | | | `is_error` | boolean | false | | |
| `is_media` | boolean | false | | | | `is_media` | boolean | false | | |
| `mcp_server_config_id` | [uuid.NullUUID](#uuidnulluuid) | false | | | | `mcp_server_config_id` | [uuid.NullUUID](#uuidnulluuid) | false | | |
| `media_type` | string | false | | | | `media_type` | string | false | | |
| `name` | string | false | | | | `name` | string | false | | |
| `parsed_commands` | array of array | false | | Parsed commands holds parsed programs from an execute tool call's shell command, one entry per simple command in source order. Each entry is [program] or [program, arg] where arg is the first non-flag positional argument. Only populated when ToolName is "execute" and the command parses successfully; nil otherwise. | | `parsed_commands` | array of array | false | | Parsed commands holds parsed programs from an execute tool call's shell command, one entry per simple command in source order. Each entry is [program] or [program, arg] where arg is the first non-flag positional argument. Program names are normalized to their base name (e.g. /usr/bin/go becomes go). Only populated when ToolName is "execute" and the command parses successfully; nil otherwise. |
| `provider_executed` | boolean | false | | Provider executed indicates the tool call was executed by the provider (e.g. Anthropic computer use). | | `provider_executed` | boolean | false | | Provider executed indicates the tool call was executed by the provider (e.g. Anthropic computer use). |
| `provider_metadata` | array of integer | false | | Provider metadata holds provider-specific response metadata (e.g. Anthropic cache control hints) as raw JSON. Internal only: stripped by db2sdk before API responses. | | `provider_metadata` | array of integer | false | | Provider metadata holds provider-specific response metadata (e.g. Anthropic cache control hints) as raw JSON. Internal only: stripped by db2sdk before API responses. |
| `result` | array of integer | false | | | | `result` | array of integer | false | | |
| `result_delta` | string | false | | | | `result_delta` | string | false | | |
| `result_reset` | boolean | false | | | | `result_reset` | boolean | false | | |
| `signature` | string | false | | | | `signature` | string | false | | |
| `skill_description` | string | false | | Skill description is the short description from the skill's SKILL.md frontmatter. | | `skill_description` | string | false | | Skill description is the short description from the skill's SKILL.md frontmatter. |
| `skill_dir` | string | false | | Skill dir is the absolute path to the skill directory inside the workspace filesystem. Internal only: used by read_skill/read_skill_file tools to locate skill files. | | `skill_dir` | string | false | | Skill dir is the absolute path to the skill directory inside the workspace filesystem. Internal only: used by read_skill/read_skill_file tools to locate skill files. |
| `skill_name` | string | false | | Skill name is the kebab-case name of a discovered skill from the workspace's .agents/skills/ directory. | | `skill_name` | string | false | | Skill name is the kebab-case name of a discovered skill from the workspace's .agents/skills/ directory. |
| `source_id` | string | false | | | | `source_id` | string | false | | |
| `start_line` | integer | false | | | | `start_line` | integer | false | | |
| `text` | string | false | | | | `text` | string | false | | |
| `title` | string | false | | | | `title` | string | false | | |
| `tool_call_id` | string | false | | | | `tool_call_id` | string | false | | |
| `tool_name` | string | false | | | | `tool_name` | string | false | | |
| `type` | [codersdk.ChatMessagePartType](#codersdkchatmessageparttype) | false | | | | `type` | [codersdk.ChatMessagePartType](#codersdkchatmessageparttype) | false | | |
| `url` | string | false | | | | `url` | string | false | | |
## codersdk.ChatMessagePartType ## codersdk.ChatMessagePartType
+3 -2
View File
@@ -2875,8 +2875,9 @@ export interface ChatToolCallPart {
* ParsedCommands holds parsed programs from an execute tool call's * ParsedCommands holds parsed programs from an execute tool call's
* shell command, one entry per simple command in source order. Each * shell command, one entry per simple command in source order. Each
* entry is [program] or [program, arg] where arg is the first non-flag * entry is [program] or [program, arg] where arg is the first non-flag
* positional argument. Only populated when ToolName is "execute" and * positional argument. Program names are normalized to their base
* the command parses successfully; nil otherwise. * name (e.g. /usr/bin/go becomes go). Only populated when ToolName
* is "execute" and the command parses successfully; nil otherwise.
*/ */
readonly parsed_commands?: readonly string[][]; readonly parsed_commands?: readonly string[][];
/** /**