archastro.platform.v1.resources.threads
1# Copyright (c) 2026 ArchAstro Inc. Licensed under the MIT License. 2# This file is auto-generated by @archastro/sdk-generator. Do not edit. 3# Content hash: fe8db978c7bd 4 5from __future__ import annotations 6 7from datetime import datetime 8from typing import Any, Literal, Required, TypedDict 9 10from pydantic import BaseModel, Field 11 12from ...runtime.http_client import HttpClient, SyncHttpClient 13from ...types.chat import ChatMember 14from ...types.common import AgentComputer, AgentComputerListResponse 15from ...types.threads import Thread, ThreadReadStatus, ThreadSettings 16 17 18class ComputerCreateInputAclAddItem(TypedDict, total=False): 19 actions: Required[list[str]] 20 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 21 principal: str | None 22 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' 23 principal_type: Required[str] 24 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 25 26 27class ComputerCreateInputAclGrantsItem(TypedDict, total=False): 28 actions: Required[list[str]] 29 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 30 principal: str | None 31 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' 32 principal_type: Required[str] 33 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 34 35 36class ComputerCreateInputAclRemoveItem(TypedDict, total=False): 37 principal: str | None 38 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' 39 principal_type: Required[str] 40 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.' 41 42 43class ComputerCreateInputAcl(TypedDict, total=False): 44 add: list[ComputerCreateInputAclAddItem] | None 45 "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." 46 grants: list[ComputerCreateInputAclGrantsItem] | None 47 "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." 48 remove: list[ComputerCreateInputAclRemoveItem] | None 49 "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`." 50 51 52class ComputerCreateInput(TypedDict, total=False): 53 "Provision a computer for a thread" 54 55 acl: ComputerCreateInputAcl | None 56 "Initial access control list." 57 config: dict[str, Any] | None 58 "Provider configuration; top-level provider takes precedence." 59 key: str | None 60 "Stable key unique within this thread." 61 metadata: dict[str, Any] | None 62 "Arbitrary computer metadata." 63 name: Required[str] 64 "Human-readable computer name." 65 provider: str | None 66 "Compute backend: sprites (default), vercel or e2b." 67 region: str | None 68 "Provider region; defaults to iad." 69 70 71class ThreadMemberCreateInput(TypedDict, total=False): 72 "Add a member to a thread" 73 74 agent: str | None 75 'Agent ID of the principal to add. Required when `type` is `"agent"`.' 76 membership_type: str | None 77 'Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.' 78 type: Required[str] 79 'Kind of principal being added. Must be `"user"` or `"agent"`.' 80 user: str | None 81 'User ID of the principal to add. Required when `type` is `"user"`.' 82 83 84class SettingReplaceInput(TypedDict): 85 "Update thread settings" 86 87 settings: dict[str, Any] 88 "Map of settings fields to update. Include only the keys you want to change." 89 90 91class TagCreateInput(TypedDict): 92 "Add tags to a thread" 93 94 tags: list[str] 95 "Tags to add to the thread." 96 97 98class TagReplaceInput(TypedDict): 99 "Replace a thread's tags" 100 101 tags: list[str] 102 "The complete set of tags for the thread. An empty array clears all tags." 103 104 105class ThreadReplaceInputProfilePicture(TypedDict, total=False): 106 data: str | None 107 "Base64-encoded image payload. Must be a valid base64 string." 108 filename: str | None 109 'Original filename of the image, e.g. `"avatar.png"`. Used for storage metadata.' 110 mime_type: str | None 111 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.' 112 113 114class ThreadReplaceInput(TypedDict, total=False): 115 "Update a thread" 116 117 description: str | None 118 "Optional longer text describing the thread's purpose. Replaces the existing description when provided." 119 metadata: dict[str, Any] | None 120 "Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata." 121 muted: bool | None 122 "When `true`, suppresses notifications for new messages in this thread for the authenticated user." 123 profile_picture: ThreadReplaceInputProfilePicture | None 124 "New profile picture for the thread. Provide all three inner fields to replace the existing image." 125 title: str | None 126 "Human-readable display name for the thread. Replaces the existing title when provided." 127 visibility: Literal["private", "restricted", "team"] | None 128 "Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed." 129 130 131class ThreadMarkReadInput(TypedDict, total=False): 132 "Mark a thread as read" 133 134 last_read_message: str | None 135 "Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`." 136 use_latest_message: bool | None 137 "When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`." 138 user: str | None 139 "User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token." 140 141 142class ThreadPictureInputPicture(TypedDict): 143 data: str 144 "Base64-encoded binary content of the image file." 145 filename: str 146 'Original filename of the image, e.g. `"avatar.png"`. Used for storage and display.' 147 mime_type: str 148 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.' 149 150 151class ThreadPictureInput(TypedDict): 152 "Update a thread's profile picture" 153 154 picture: ThreadPictureInputPicture 155 "Profile picture payload. Must include the base64-encoded image data and its MIME type." 156 157 158class ThreadMemberListResponseDataItemAgent(BaseModel): 159 email: str | None = Field( 160 default=None, description="Agent email address. `null` if not configured." 161 ) 162 id: str = Field(..., description="Agent ID (`agi_...`).") 163 name: str | None = Field( 164 default=None, description="Human-readable agent name. `null` if not set." 165 ) 166 org: str | None = Field( 167 default=None, 168 description="Organization that owns this agent (`org_...`). `null` if not org-scoped.", 169 ) 170 team: str | None = Field( 171 default=None, 172 description="Team that owns this agent (`tem_...`). `null` if not team-scoped.", 173 ) 174 user: str | None = Field( 175 default=None, 176 description="User that owns this agent (`usr_...`). `null` if not user-scoped.", 177 ) 178 179 180class ThreadMemberListResponseDataItemUser(BaseModel): 181 email: str | None = Field(default=None, description="User's email address. `null` if not set.") 182 full_name: str | None = Field( 183 default=None, description="Backward-compatible alias of `name`. `null` if not set." 184 ) 185 id: str = Field(..., description="User ID (`usr_...`).") 186 name: str | None = Field( 187 default=None, description="Full display name of the user. `null` if not set." 188 ) 189 org: str | None = Field( 190 default=None, 191 description="Organization this user belongs to (`org_...`). `null` if the user is not org-scoped.", 192 ) 193 194 195class ThreadMemberListResponseDataItem(BaseModel): 196 agent: ThreadMemberListResponseDataItemAgent | None = Field( 197 default=None, 198 description="Roster-safe agent identity. Populated for agent members; `null` for users.", 199 ) 200 joined_at: datetime | None = Field( 201 default=None, description="When this member joined the thread (ISO 8601)." 202 ) 203 member_type: str | None = Field( 204 default=None, description="Backward-compatible alias of `type`." 205 ) 206 membership_type: str | None = Field( 207 default=None, description='Role of this member, commonly `"owner"` or `"member"`.' 208 ) 209 role: str | None = Field( 210 default=None, description="Backward-compatible alias of `membership_type`." 211 ) 212 type: str = Field(..., description='Kind of participant. One of `"user"` or `"agent"`.') 213 user: ThreadMemberListResponseDataItemUser | None = Field( 214 default=None, 215 description="Roster-safe user identity. Populated for user members; `null` for agents.", 216 ) 217 218 219class ThreadMemberListResponse(BaseModel): 220 """ 221 Successful response 222 """ 223 224 data: list[ThreadMemberListResponseDataItem] = Field( 225 ..., 226 description="Array of thread member objects representing all current members of the thread.", 227 ) 228 229 230class SettingListResponse(BaseModel): 231 """ 232 Successful response 233 """ 234 235 agent_enabled: bool | None = Field( 236 default=None, 237 description="Whether the AI agent is active for this thread. Defaults to `true` when no settings have been explicitly set.", 238 ) 239 240 241class ThreadAgentsResponse(BaseModel): 242 """ 243 Successful response 244 """ 245 246 data: list[dict[str, Any]] = Field( 247 ..., 248 description="Array of agent objects for the thread. Each object includes `id`, `name`, `alias`, `profile_picture`, and `metadata`. Thread owners also receive an `agent_config` object with the agent's policy type and context configuration.", 249 ) 250 251 252class ThreadArtifactsResponseDataItemAclAddItem(BaseModel): 253 actions: list[str] = Field( 254 ..., 255 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 256 ) 257 principal: str | None = Field( 258 default=None, 259 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 260 ) 261 principal_type: str = Field( 262 ..., 263 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 264 ) 265 266 267class ThreadArtifactsResponseDataItemAclGrantsItem(BaseModel): 268 actions: list[str] = Field( 269 ..., 270 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 271 ) 272 principal: str | None = Field( 273 default=None, 274 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 275 ) 276 principal_type: str = Field( 277 ..., 278 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 279 ) 280 281 282class ThreadArtifactsResponseDataItemAclRemoveItem(BaseModel): 283 principal: str | None = Field( 284 default=None, 285 description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', 286 ) 287 principal_type: str = Field( 288 ..., 289 description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 290 ) 291 292 293class ThreadArtifactsResponseDataItemAcl(BaseModel): 294 add: list[ThreadArtifactsResponseDataItemAclAddItem] | None = Field( 295 default=None, 296 description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", 297 ) 298 grants: list[ThreadArtifactsResponseDataItemAclGrantsItem] | None = Field( 299 default=None, 300 description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", 301 ) 302 remove: list[ThreadArtifactsResponseDataItemAclRemoveItem] | None = Field( 303 default=None, 304 description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", 305 ) 306 307 308class ThreadArtifactsResponseDataItemImageSource(BaseModel): 309 file: str | None = Field( 310 default=None, 311 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 312 ) 313 height: int | None = Field( 314 default=None, description="Height of the image in pixels. `null` if not known." 315 ) 316 media: str | None = Field( 317 default=None, 318 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 319 ) 320 mime_type: str | None = Field( 321 default=None, 322 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 323 ) 324 refresh_url: str | None = Field( 325 default=None, 326 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 327 ) 328 url: str | None = Field( 329 default=None, 330 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 331 ) 332 width: int | None = Field( 333 default=None, description="Width of the image in pixels. `null` if not known." 334 ) 335 336 337class ThreadArtifactsResponseDataItem(BaseModel): 338 acl: ThreadArtifactsResponseDataItemAcl | None = Field( 339 default=None, 340 description="Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", 341 ) 342 agent: str | None = Field( 343 default=None, 344 description="ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", 345 ) 346 content_type: str | None = Field( 347 default=None, 348 description='MIME type of the current version\'s file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached.', 349 ) 350 created_at: datetime | None = Field( 351 default=None, description="When the artifact was first created (ISO 8601)." 352 ) 353 current_version: str | None = Field( 354 default=None, 355 description="ID of the current (latest published) artifact version (`artv_...`). `null` if no version has been published.", 356 ) 357 description: str | None = Field( 358 default=None, 359 description="Optional longer description of the artifact's contents or purpose. `null` if not set.", 360 ) 361 file: str | None = Field( 362 default=None, 363 description="Storage file ID for the current version (`fil_...`). `null` if no file is attached.", 364 ) 365 file_name: str | None = Field( 366 default=None, 367 description='Original filename of the current version\'s file, e.g. `"output.csv"`. `null` if no file is attached.', 368 ) 369 file_url: str | None = Field( 370 default=None, 371 description="Short-lived signed URL for downloading the current version's file. `null` if no file is attached.", 372 ) 373 group_key: str | None = Field( 374 default=None, 375 description="Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Null when unset; belongs to the artifact, not a content version.", 376 ) 377 id: str = Field(..., description="Artifact ID (`art_...`).") 378 image_source: ThreadArtifactsResponseDataItemImageSource | None = Field( 379 default=None, 380 description='Image source metadata for rendering the current version\'s file inline. Present only when `content_type` starts with `"image/"`. `null` otherwise.', 381 ) 382 name: str | None = Field( 383 default=None, 384 description='Human-readable name for the artifact, e.g. `"Q2 Report"`. `null` if not set.', 385 ) 386 org: str | None = Field( 387 default=None, description="ID of the organization this artifact belongs to (`org_...`)." 388 ) 389 sandbox: str | None = Field( 390 default=None, 391 description="Identifier of the sandbox environment associated with this artifact. `null` if not sandbox-scoped.", 392 ) 393 system: bool | None = Field( 394 default=None, 395 description="True when the artifact has no user, team, or agent owner. An organization may own a system artifact.", 396 ) 397 team: str | None = Field( 398 default=None, 399 description="ID of the team that owns this artifact (`tea_...`). `null` if not team-scoped.", 400 ) 401 thread: str | None = Field( 402 default=None, 403 description="ID of the thread in which this artifact was created (`thr_...`). `null` if not thread-scoped.", 404 ) 405 updated_at: datetime | None = Field( 406 default=None, description="When the artifact record was last modified (ISO 8601)." 407 ) 408 user: str | None = Field( 409 default=None, 410 description="ID of the user who created this artifact (`usr_...`). `null` if not user-scoped.", 411 ) 412 version: int | None = Field( 413 default=None, 414 description="Current version number of the artifact. Increments each time a new version is published.", 415 ) 416 417 418class ThreadArtifactsResponse(BaseModel): 419 """ 420 Successful response 421 """ 422 423 data: list[ThreadArtifactsResponseDataItem] = Field( 424 ..., description="Array of artifact objects produced during the thread's conversation." 425 ) 426 427 428class ThreadMessagesResponseDataMessagesItemAclAddItem(BaseModel): 429 actions: list[str] = Field( 430 ..., 431 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 432 ) 433 principal: str | None = Field( 434 default=None, 435 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 436 ) 437 principal_type: str = Field( 438 ..., 439 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 440 ) 441 442 443class ThreadMessagesResponseDataMessagesItemAclGrantsItem(BaseModel): 444 actions: list[str] = Field( 445 ..., 446 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 447 ) 448 principal: str | None = Field( 449 default=None, 450 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 451 ) 452 principal_type: str = Field( 453 ..., 454 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 455 ) 456 457 458class ThreadMessagesResponseDataMessagesItemAclRemoveItem(BaseModel): 459 principal: str | None = Field( 460 default=None, 461 description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', 462 ) 463 principal_type: str = Field( 464 ..., 465 description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 466 ) 467 468 469class ThreadMessagesResponseDataMessagesItemAcl(BaseModel): 470 add: list[ThreadMessagesResponseDataMessagesItemAclAddItem] | None = Field( 471 default=None, 472 description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", 473 ) 474 grants: list[ThreadMessagesResponseDataMessagesItemAclGrantsItem] | None = Field( 475 default=None, 476 description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", 477 ) 478 remove: list[ThreadMessagesResponseDataMessagesItemAclRemoveItem] | None = Field( 479 default=None, 480 description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", 481 ) 482 483 484class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel): 485 file: str | None = Field( 486 default=None, 487 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 488 ) 489 height: int | None = Field( 490 default=None, description="Height of the image in pixels. `null` if not known." 491 ) 492 media: str | None = Field( 493 default=None, 494 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 495 ) 496 mime_type: str | None = Field( 497 default=None, 498 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 499 ) 500 refresh_url: str | None = Field( 501 default=None, 502 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 503 ) 504 url: str | None = Field( 505 default=None, 506 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 507 ) 508 width: int | None = Field( 509 default=None, description="Width of the image in pixels. `null` if not known." 510 ) 511 512 513class ThreadMessagesResponseDataMessagesItemActorsItem(BaseModel): 514 alias: str | None = Field( 515 default=None, 516 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 517 ) 518 id: str | None = Field( 519 default=None, 520 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 521 ) 522 name: str | None = Field( 523 default=None, 524 description="Display name of the actor shown in the UI. `null` if no name is set.", 525 ) 526 profile_picture: ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture | None = Field( 527 default=None, 528 description="Profile picture for the actor. `null` if the actor has no profile picture.", 529 ) 530 531 532class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(BaseModel): 533 file: str | None = Field( 534 default=None, 535 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 536 ) 537 height: int | None = Field( 538 default=None, description="Height of the image in pixels. `null` if not known." 539 ) 540 media: str | None = Field( 541 default=None, 542 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 543 ) 544 mime_type: str | None = Field( 545 default=None, 546 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 547 ) 548 refresh_url: str | None = Field( 549 default=None, 550 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 551 ) 552 url: str | None = Field( 553 default=None, 554 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 555 ) 556 width: int | None = Field( 557 default=None, description="Width of the image in pixels. `null` if not known." 558 ) 559 560 561class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(BaseModel): 562 file: str | None = Field( 563 default=None, 564 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 565 ) 566 height: int | None = Field( 567 default=None, description="Height of the image in pixels. `null` if not known." 568 ) 569 media: str | None = Field( 570 default=None, 571 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 572 ) 573 mime_type: str | None = Field( 574 default=None, 575 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 576 ) 577 refresh_url: str | None = Field( 578 default=None, 579 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 580 ) 581 url: str | None = Field( 582 default=None, 583 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 584 ) 585 width: int | None = Field( 586 default=None, description="Width of the image in pixels. `null` if not known." 587 ) 588 589 590class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(BaseModel): 591 byte_size: int | None = Field(default=None, description="Size of the stored bytes.") 592 content_type: str | None = Field( 593 default=None, 594 description='MIME type of this variant\'s file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded.', 595 ) 596 created_at: datetime | None = Field( 597 default=None, description="When this variant was created (ISO 8601)." 598 ) 599 duration_ms: int | None = Field( 600 default=None, 601 description="Client-declared video duration in milliseconds; not server-probed.", 602 ) 603 file: str | None = Field( 604 default=None, 605 description="ID of the underlying storage file that backs this variant (`fil_...`).", 606 ) 607 filename: str | None = Field( 608 default=None, 609 description="Original filename of the uploaded file for this variant. `null` if the file is not loaded.", 610 ) 611 height: int | None = Field( 612 default=None, description="Height of this variant in pixels. `null` if not recorded." 613 ) 614 id: str = Field(..., description="Media variant ID (`mvr_...`).") 615 image_source: ( 616 ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource | None 617 ) = Field( 618 default=None, 619 description="Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types.", 620 ) 621 sha256: str | None = Field(default=None, description="Lowercase SHA-256 of the stored bytes.") 622 updated_at: datetime | None = Field( 623 default=None, description="When this variant was last updated (ISO 8601)." 624 ) 625 url: str | None = Field( 626 default=None, 627 description="Signed download URL for this variant, resolved at request time. `null` if the file is unavailable.", 628 ) 629 url_expires_at: datetime | None = Field( 630 default=None, description="Expiry of this variant's playable URL." 631 ) 632 variant_key: str | None = Field( 633 default=None, 634 description='Identifier for this variant\'s processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview).', 635 ) 636 width: int | None = Field( 637 default=None, description="Width of this variant in pixels. `null` if not recorded." 638 ) 639 640 641class ThreadMessagesResponseDataMessagesItemAttachmentsItem(BaseModel): 642 content_type: str | None = Field( 643 default=None, 644 description='MIME type of the attached file, e.g. `"image/png"` or `"application/pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 645 ) 646 description: str | None = Field( 647 default=None, 648 description="Short description. The page meta-description for `scraped_link`, the artifact description for `artifact`, and the task description for `task` types. `null` on other types.", 649 ) 650 filename: str | None = Field( 651 default=None, 652 description='Original filename of the attached file, e.g. `"report.pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 653 ) 654 height: int | None = Field( 655 default=None, 656 description="Height in pixels of the media item. Present on `media` type only. `null` otherwise.", 657 ) 658 id: str = Field(..., description="Unique identifier for this attachment within the message.") 659 image_height: int | None = Field( 660 default=None, 661 description="Height in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 662 ) 663 image_source: ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource | None = Field( 664 default=None, 665 description="Image source metadata for inline rendering. Present on `file`, `scraped_link`, `artifact`, and `media` types when the content is an image. `null` otherwise.", 666 ) 667 image_url: str | None = Field( 668 default=None, 669 description="URL of the preview image extracted from the scraped page. Present on `scraped_link` type only. `null` otherwise.", 670 ) 671 image_width: int | None = Field( 672 default=None, 673 description="Width in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 674 ) 675 key: str | None = Field( 676 default=None, 677 description='For `structured_data` type, what the data is about as set by the sender (for example `"pr:14963"`), copied from the record so it can be read without `object`. Not unique. `null` when unset and on other types.', 678 ) 679 media_type: str | None = Field( 680 default=None, 681 description='The media category, e.g. `"video"` or `"audio"`. Present on `media` type only; omitted otherwise.', 682 ) 683 name: str | None = Field( 684 default=None, 685 description="Display name of the media item. Present on `media` type only. `null` otherwise.", 686 ) 687 object: dict[str, Any] | None = Field( 688 default=None, 689 description="The full embedded object payload. For `task` type, contains the task record. For `action` type, contains the action definition. For `chart` type, contains the chart with its inline `spec`. For `structured_data` type, contains the inline `data` and the `schema_url` or `schema_config` naming its JSON Schema. Omitted on other types.", 690 ) 691 title: str | None = Field( 692 default=None, 693 description="Display title. The page title for `scraped_link`, the artifact name for `artifact`, and the task title for `task` types. `null` on other types.", 694 ) 695 type: str = Field( 696 ..., 697 description='The attachment type. One of `"file"`, `"scraped_link"`, `"artifact"`, `"task"`, `"media"`, `"action"`, `"chart"`, or `"structured_data"`. Determines which additional fields are present.', 698 ) 699 url: str | None = Field( 700 default=None, 701 description="URL to access the resource. A signed download URL for `file` and `artifact` types; the original URL for `scraped_link`; a media playback URL for `media`. `null` on `task` and `action` types.", 702 ) 703 variants: list[ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem] | None = ( 704 Field( 705 default=None, 706 description="Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", 707 ) 708 ) 709 version: int | None = Field( 710 default=None, 711 description="Version number of the attached artifact at the time of attachment. Present on `artifact` type only. `null` otherwise.", 712 ) 713 width: int | None = Field( 714 default=None, 715 description="Width in pixels of the media item. Present on `media` type only. `null` otherwise.", 716 ) 717 718 719class ThreadMessagesResponseDataMessagesItemContextItem(BaseModel): 720 attributes: dict[str, Any] | None = Field( 721 default=None, 722 description="Scalar key-value fields describing the context, such as route, repository, or pull-request number.", 723 ) 724 content: str | None = Field( 725 default=None, 726 description="Optional context body. The model receives it as escaped XML data, not a system instruction.", 727 ) 728 title: str | None = Field( 729 default=None, description="Optional human-readable label for this context block." 730 ) 731 type: str = Field( 732 ..., 733 description="Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", 734 ) 735 736 737class ThreadMessagesResponseDataMessagesItemReactionsItem(BaseModel): 738 payload: dict[str, Any] | None = Field( 739 default=None, 740 description='Type-specific reaction data. For `"emoji_reaction"` reactions, contains an `emoji` key with the Unicode emoji string (e.g., `" "`).', 741 ) 742 type: str = Field( 743 ..., 744 description='Reaction type identifier. Currently always `"emoji_reaction"` for emoji-based reactions.', 745 ) 746 user: str | None = Field( 747 default=None, description="Public ID of the user who added the reaction (`usr_...`)." 748 ) 749 750 751class ThreadMessagesResponseDataMessagesItem(BaseModel): 752 acl: ThreadMessagesResponseDataMessagesItemAcl | None = Field( 753 default=None, 754 description="Access control list for private messages (grants with `read` action). Only returned to resource owners (and privileged/org-admin viewers) via server-side `field_redactions: [acl: :owner]`; `null` for everyone else.", 755 ) 756 actors: list[ThreadMessagesResponseDataMessagesItemActorsItem] | None = Field( 757 default=None, 758 description="Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.", 759 ) 760 agent: str | None = Field( 761 default=None, 762 description="ID of the agent user that sent this message (`agi_...`). `null` for messages sent by human users.", 763 ) 764 agent_mode: Literal["cli", "embedded"] | None = Field( 765 default=None, 766 description="Local agent execution mode for this message. One of `cli`, `embedded`, or `null` when the message was not created by a local agent execution path.", 767 ) 768 attachments: list[ThreadMessagesResponseDataMessagesItemAttachmentsItem] | None = Field( 769 default=None, 770 description="Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.", 771 ) 772 branched_thread: str | None = Field( 773 default=None, 774 description="ID of the thread that was branched from this message (`thr_...`). `null` if this message has not spawned a branch thread.", 775 ) 776 content: str | None = Field( 777 default=None, 778 description="Text content of the message. `null` for messages that contain only attachments.", 779 ) 780 context: list[ThreadMessagesResponseDataMessagesItemContextItem] | None = Field( 781 default=None, 782 description="Immutable structured context captured when the message was posted. Each entry has `type`, optional `title` and `content`, and scalar `attributes`. Always present; defaults to an empty array. Context is delivered to agents as escaped XML data, not as system instructions.", 783 ) 784 created_at: str | None = Field( 785 default=None, description="When the message was posted (ISO 8601)." 786 ) 787 has_replies: bool | None = Field( 788 default=None, 789 description="Whether this message has at least one reply. Only present when explicitly requested or computed by the server.", 790 ) 791 id: str = Field(..., description="Message ID (`msg_...`).") 792 idempotency_key: str | None = Field( 793 default=None, 794 description="Client-supplied idempotency key used to deduplicate message sends. `null` if the sender did not provide one.", 795 ) 796 is_deleted: bool | None = Field( 797 default=None, 798 description="Whether this message is a deletion tombstone. `true` only on the `message_updated` broadcast emitted when a message is deleted: the original content is replaced with a placeholder and the message no longer exists on the server. Always `false` for live messages.", 799 ) 800 legacy_agent: str | None = Field( 801 default=None, 802 description="Identifier of the legacy chat agent that sent this message, if applicable. `null` for messages sent by users or modern agent users.", 803 ) 804 metadata: dict[str, Any] | None = Field( 805 default=None, 806 description="Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.", 807 ) 808 org: str | None = Field( 809 default=None, description="ID of the organization that owns this message (`org_...`)." 810 ) 811 reactions: list[ThreadMessagesResponseDataMessagesItemReactionsItem] | None = Field( 812 default=None, 813 description="Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.", 814 ) 815 rendering_mode: str | None = Field( 816 default=None, 817 description='Display hint for how the message should be rendered. One of `"reply"`, `"direct"`, or `"inline"`. `null` for user-authored messages, which are always rendered as standard replies.', 818 ) 819 replies: list[dict[str, Any]] | None = Field( 820 default=None, 821 description="Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.", 822 ) 823 replies_after_cursor: str | None = Field( 824 default=None, 825 description="Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.", 826 ) 827 replies_before_cursor: str | None = Field( 828 default=None, 829 description="Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.", 830 ) 831 reply_count: int | None = Field( 832 default=None, 833 description="Total number of direct replies to this message. Only present when explicitly requested or computed by the server.", 834 ) 835 reply_to: dict[str, Any] | None = Field( 836 default=None, 837 description="The parent message this message is a reply to, expanded as a full message object when loaded. `null` if this is a top-level message or the association is not preloaded.", 838 ) 839 root_message_id: str | None = Field( 840 default=None, 841 description="ID of the root message in this reply chain (`msg_...`). `null` for a top-level message. The value is persisted when the reply is created, so callers can correlate a multi-turn session without walking parent messages.", 842 ) 843 sandbox: str | None = Field( 844 default=None, 845 description="ID of the developer sandbox this message belongs to (`dsb_...`). `null` for non-sandbox messages.", 846 ) 847 team: str | None = Field( 848 default=None, 849 description="ID of the team this message is scoped to (`tem_...`). `null` if the message is not team-scoped.", 850 ) 851 thread: str | None = Field( 852 default=None, description="ID of the thread this message belongs to (`thr_...`)." 853 ) 854 type: str | None = Field( 855 default=None, 856 description="Optional client-defined classification for the message (for example `note` or `status`). Free-form string up to 64 characters. The value `system` is reserved for platform-authored messages and cannot be set by clients. `null` when unset.", 857 ) 858 user: str | dict[str, Any] | None = Field( 859 default=None, 860 description="The human user who sent this message. Returns a public ID string (`usr_...`) when the association is not preloaded, or an expanded user object when it is. `null` for messages sent by agents.", 861 ) 862 visibility: Literal["default", "private"] | None = Field( 863 default=None, 864 description="Message-level visibility. `default` is visible to anyone who can see the parent thread. `private` is restricted to the sender and explicit ACL `read` grantees.", 865 ) 866 867 868class ThreadMessagesResponseData(BaseModel): 869 after_cursor: str | None = Field( 870 default=None, 871 description="Opaque cursor to pass as `after` to retrieve the page of messages newer than this result set. `null` when there are no later messages.", 872 ) 873 anchor: str | None = Field( 874 default=None, 875 description="Message ID used as the anchor for a windowed query. `null` for ordinary cursor pagination.", 876 ) 877 before_cursor: str | None = Field( 878 default=None, 879 description="Opaque cursor to pass as `before` to retrieve the page of messages older than this result set. `null` when there are no earlier messages.", 880 ) 881 messages: list[ThreadMessagesResponseDataMessagesItem] = Field( 882 ..., description="Ordered array of message objects for this page of results." 883 ) 884 885 886class ThreadMessagesResponse(BaseModel): 887 """ 888 Successful response 889 """ 890 891 data: ThreadMessagesResponseData = Field( 892 ..., 893 description="Pagination envelope containing the messages for this page along with cursors for adjacent pages.", 894 ) 895 896 897class ThreadSearchResponseDataItem(BaseModel): 898 agent: str | None = Field( 899 default=None, 900 description="Agent sender ID (`agi_...`), or `null` when a human sent the message.", 901 ) 902 content: str = Field( 903 ..., 904 description="A bounded snippet around the first matching occurrence (at most 240 characters).", 905 ) 906 created_at: datetime = Field(..., description="When the message was posted.") 907 evidence: dict[str, Any] = Field( 908 ..., 909 description="Bounded, allowlisted structured-post evidence such as source, lifecycle type, references, repository context, and addressee. Empty for ordinary messages.", 910 ) 911 id: str = Field(..., description="Message ID (`msg_...`).") 912 similarity_score: float | None = Field( 913 default=None, 914 description="Cosine similarity to the query when the result participated in embedding search, or `null` in text mode and for text-only hybrid matches.", 915 ) 916 user: str | None = Field( 917 default=None, 918 description="Human sender ID (`usr_...`), or `null` when an agent sent the message.", 919 ) 920 921 922class ThreadSearchResponse(BaseModel): 923 """ 924 Successful response 925 """ 926 927 after_cursor: str | None = Field( 928 default=None, 929 description="Text-mode cursor for the next page of newer matches, or `null` for ranked modes and empty pages.", 930 ) 931 before_cursor: str | None = Field( 932 default=None, 933 description="Text-mode cursor for the next page of older matches, or `null` for ranked modes and empty pages.", 934 ) 935 data: list[ThreadSearchResponseDataItem] = Field( 936 ..., 937 description="Matching messages ordered newest first in text mode and by relevance in embedding or hybrid mode.", 938 ) 939 has_more: bool = Field( 940 ..., description="`true` when at least one additional visible match exists." 941 ) 942 943 944class ThreadTrajectoriesResponseDataItem(BaseModel): 945 agent_message: str | None = Field( 946 default=None, 947 description="ID of the agent-authored reply message (`msg_...`). `null` if the trajectory has not yet produced a response message.", 948 ) 949 created_at: str | None = Field( 950 default=None, description="When this trajectory link was created (ISO 8601)." 951 ) 952 id: str = Field(..., description="Thread message trajectory ID (`tmt_...`).") 953 org: str | None = Field( 954 default=None, description="ID of the organization this trajectory belongs to (`org_...`)." 955 ) 956 sandbox: str | None = Field( 957 default=None, 958 description="ID of the sandbox environment in which this trajectory was produced (`dsb_...`). `null` in production contexts.", 959 ) 960 thread: str | None = Field( 961 default=None, description="ID of the thread containing the linked messages (`thr_...`)." 962 ) 963 trajectory: str | None = Field( 964 default=None, 965 description="ID of the AI trajectory record that captures the full model interaction for this exchange (`trj_...`).", 966 ) 967 updated_at: str | None = Field( 968 default=None, description="When this trajectory link was last modified (ISO 8601)." 969 ) 970 user_message: str | None = Field( 971 default=None, 972 description="ID of the user-authored message that triggered the agent response (`msg_...`). `null` if the agent turn was not preceded by a user message.", 973 ) 974 975 976class ThreadTrajectoriesResponse(BaseModel): 977 """ 978 Successful response 979 """ 980 981 after_cursor: str | None = Field( 982 default=None, 983 description="Opaque cursor to pass as `after_cursor` to retrieve the next page. `null` when no further pages exist.", 984 ) 985 before_cursor: str | None = Field( 986 default=None, 987 description="Opaque cursor to pass as `before_cursor` to retrieve the previous page. `null` when this is the first page.", 988 ) 989 data: list[ThreadTrajectoriesResponseDataItem] = Field( 990 ..., 991 description="Array of thread message trajectory objects for the current page. Empty when no trajectories match the query.", 992 ) 993 994 995class AsyncComputerResource: 996 def __init__(self, http: HttpClient): 997 self._http = http 998 999 async def list(self, thread: str) -> AgentComputerListResponse: 1000 """ 1001 List a thread's computers 1002 Returns all live computers in the visible thread, oldest first, without pagination. 1003 1004 Args: 1005 thread: Thread ID (`thr_...`). 1006 1007 Returns: 1008 The thread's live computers. 1009 """ 1010 return await self._http.request( 1011 f"/api/v1/threads/{thread}/computers", 1012 response_type=AgentComputerListResponse, 1013 ) 1014 1015 async def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: 1016 """ 1017 Provision a computer for a thread 1018 Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. 1019 1020 Args: 1021 thread: Thread ID (`thr_...`). 1022 input: Request body. 1023 input.acl: Initial access control list. 1024 input.config: Provider configuration; top-level provider takes precedence. 1025 input.key: Stable key unique within this thread. 1026 input.metadata: Arbitrary computer metadata. 1027 input.name: Human-readable computer name. 1028 input.provider: Compute backend: sprites (default), vercel or e2b. 1029 input.region: Provider region; defaults to iad. 1030 1031 Returns: 1032 The newly created computer. Returns HTTP 201. 1033 """ 1034 return await self._http.request( 1035 f"/api/v1/threads/{thread}/computers", 1036 method="POST", 1037 body=input, 1038 response_type=AgentComputer, 1039 ) 1040 1041 1042class AsyncThreadMemberResource: 1043 def __init__(self, http: HttpClient): 1044 self._http = http 1045 1046 async def remove(self, thread: str) -> None: 1047 """ 1048 Remove a member from a thread 1049 Removes a user or agent from the explicit roster of a private or restricted 1050 thread. Team-visible threads use implicit membership and reject individual 1051 removals. A member may remove themself; removing someone else requires 1052 permission to modify the thread. A successful removal returns HTTP 204 with 1053 no response body. 1054 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1055 if the thread or the membership record does not exist. 1056 1057 Args: 1058 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1059 1060 Returns: 1061 Empty response body. HTTP 204 on success. 1062 """ 1063 await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 1064 1065 async def list(self, thread: str) -> ThreadMemberListResponse: 1066 """ 1067 List members of a thread 1068 Returns all current user and agent members. Private and restricted threads 1069 return their explicit roster; team-visible threads return the owning team's 1070 implicit roster. The authenticated viewer must be able to see the thread. 1071 Results are returned as a flat array in the `data` field. The list is not 1072 paginated all members are returned in a single response. 1073 1074 Args: 1075 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1076 1077 Returns: 1078 Successful response 1079 """ 1080 return await self._http.request( 1081 f"/api/v1/threads/{thread}/members", 1082 response_type=ThreadMemberListResponse, 1083 ) 1084 1085 async def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember: 1086 """ 1087 Add a member to a thread 1088 Adds a user or agent to the explicit roster of a private or restricted 1089 thread. Team-visible threads use the owning team's implicit roster and reject 1090 explicit additions. On restricted threads, a team member may add themself; 1091 adding anyone else requires permission to modify the thread. 1092 Supply either `user` or `agent` depending on the value of `type`. Targets 1093 must be visible to the caller and, for an ordinary team-owned thread, must 1094 belong to the owning team. On success the membership record is returned with 1095 HTTP 201; repeated agent additions are idempotent. 1096 1097 Args: 1098 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1099 input: Request body. 1100 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1101 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1102 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1103 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1104 1105 Returns: 1106 The user or agent membership that was added to the thread. 1107 """ 1108 return await self._http.request( 1109 f"/api/v1/threads/{thread}/members", 1110 method="POST", 1111 body=input, 1112 response_type=ChatMember, 1113 ) 1114 1115 1116class AsyncSettingResource: 1117 def __init__(self, http: HttpClient): 1118 self._http = http 1119 1120 async def list(self, thread: str) -> SettingListResponse: 1121 """ 1122 Retrieve thread settings 1123 Returns the current settings for the specified thread. Settings control 1124 per-thread behavior such as whether the AI agent is enabled. 1125 The authenticated user must own the thread or be a member of its workspace. 1126 If settings have never been explicitly configured, defaults are returned 1127 (for example, `agent_enabled` defaults to `true`). 1128 1129 Args: 1130 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1131 1132 Returns: 1133 Successful response 1134 """ 1135 return await self._http.request( 1136 f"/api/v1/threads/{thread}/settings", 1137 response_type=SettingListResponse, 1138 ) 1139 1140 async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1141 """ 1142 Update thread settings 1143 Updates the settings for the specified thread. Only fields included in 1144 the `settings` map are modified; omitted fields retain their current values. 1145 The authenticated user must own the thread or be a member of its workspace. 1146 Returns the full settings object reflecting the state after the update. 1147 Validation errors are returned as `422 Unprocessable Entity`. 1148 1149 Args: 1150 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1151 input: Request body. 1152 input.settings: Map of settings fields to update. Include only the keys you want to change. 1153 1154 Returns: 1155 The thread settings object after the update has been applied. 1156 """ 1157 return await self._http.request( 1158 f"/api/v1/threads/{thread}/settings", 1159 method="PUT", 1160 body=input, 1161 response_type=ThreadSettings, 1162 ) 1163 1164 1165class AsyncTagResource: 1166 def __init__(self, http: HttpClient): 1167 self._http = http 1168 1169 async def remove(self, thread: str) -> Thread: 1170 """ 1171 Remove tags from a thread 1172 Removes one or more status tags from the thread and returns the updated 1173 thread. Removing a tag the thread does not have is a no-op. 1174 Any participant of the thread a human member or an agent member may edit 1175 tags. Supply the tags to remove as repeated query parameters, e.g. 1176 `?tags[]=blocked&tags[]=needs-review`. 1177 1178 Args: 1179 thread: Thread ID (`thr_...`) to untag. 1180 1181 Returns: 1182 The thread object after the tags were removed. 1183 """ 1184 return await self._http.request( 1185 f"/api/v1/threads/{thread}/tags", 1186 method="DELETE", 1187 response_type=Thread, 1188 ) 1189 1190 async def create(self, thread: str, input: TagCreateInput) -> Thread: 1191 """ 1192 Add tags to a thread 1193 Adds one or more status tags to the thread and returns the updated thread. 1194 Any participant of the thread a human member or an agent member may edit 1195 tags; this is broader than the owner/admin permission required to update other 1196 thread fields. Adding a tag the thread already has is a no-op. Tags are 1197 normalized (trimmed and lowercased) and may contain only lowercase letters, 1198 numbers, hyphens, and underscores. 1199 1200 Args: 1201 thread: Thread ID (`thr_...`) to untag. 1202 input: Request body. 1203 input.tags: Tags to add to the thread. 1204 1205 Returns: 1206 The thread object after the tags were added. 1207 """ 1208 return await self._http.request( 1209 f"/api/v1/threads/{thread}/tags", 1210 method="POST", 1211 body=input, 1212 response_type=Thread, 1213 ) 1214 1215 async def replace(self, thread: str, input: TagReplaceInput) -> Thread: 1216 """ 1217 Replace a thread's tags 1218 Replaces the thread's entire set of status tags with the provided list and 1219 returns the updated thread. Passing an empty array clears all tags. 1220 Any participant of the thread a human member or an agent member may edit 1221 tags. Tags are normalized (trimmed and lowercased) and may contain only 1222 lowercase letters, numbers, hyphens, and underscores. 1223 1224 Args: 1225 thread: Thread ID (`thr_...`) to untag. 1226 input: Request body. 1227 input.tags: The complete set of tags for the thread. An empty array clears all tags. 1228 1229 Returns: 1230 The thread object after its tags were replaced. 1231 """ 1232 return await self._http.request( 1233 f"/api/v1/threads/{thread}/tags", 1234 method="PUT", 1235 body=input, 1236 response_type=Thread, 1237 ) 1238 1239 1240class AsyncThreadResource: 1241 def __init__(self, http: HttpClient): 1242 self._http = http 1243 self.computers = AsyncComputerResource(http) 1244 self.members = AsyncThreadMemberResource(http) 1245 self.settings = AsyncSettingResource(http) 1246 self.tags = AsyncTagResource(http) 1247 1248 async def delete(self, thread: str) -> None: 1249 """ 1250 Delete a thread 1251 Permanently deletes a thread and all of its messages and artifacts. This action 1252 cannot be undone. 1253 The authenticated user must own the thread or be an owner of the team the thread 1254 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1255 1256 Args: 1257 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1258 1259 Returns: 1260 Empty response on successful deletion. 1261 """ 1262 await self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 1263 1264 async def get(self, thread: str) -> Thread: 1265 """ 1266 Retrieve a thread 1267 Returns the full thread record for the given thread ID. The authenticated user 1268 must own the thread or be a member of the workspace it belongs to. 1269 Use this endpoint to fetch the current state of a single thread, including its 1270 title, description, and metadata. To list many threads, use the list endpoint 1271 with cursor-based pagination. 1272 1273 Args: 1274 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1275 1276 Returns: 1277 The requested thread object. 1278 """ 1279 return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 1280 1281 async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1282 """ 1283 Update a thread 1284 Updates one or more mutable properties of the specified thread and returns 1285 the full thread object with the applied changes. Only the fields you provide 1286 are modified; omitted fields retain their current values. 1287 If `profile_picture` is supplied, the image is uploaded before the other 1288 fields are saved, after all ordinary thread fields have passed validation. 1289 Supplying invalid base64 picture data returns 422 and no other fields are 1290 updated. 1291 Visibility can only widen: `private` may become `restricted` or `team`, and 1292 `restricted` may become `team`. The authenticated viewer must have 1293 permission to modify the thread. 1294 Mirror-thread titles, descriptions, and notification state remain editable 1295 by privileged app viewers. Mirror metadata, visibility, and membership are 1296 provider-managed and cannot be changed through this endpoint. 1297 1298 Args: 1299 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1300 input: Request body. 1301 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1302 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1303 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1304 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1305 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1306 input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed. 1307 1308 Returns: 1309 The thread object after the update has been applied. 1310 """ 1311 return await self._http.request( 1312 f"/api/v1/threads/{thread}", 1313 method="PUT", 1314 body=input, 1315 response_type=Thread, 1316 ) 1317 1318 async def agents(self, thread: str) -> ThreadAgentsResponse: 1319 """ 1320 List agents in a thread 1321 Returns the agents participating in the specified thread. Only personal user 1322 threads (threads owned by a single user, not a team) expose agents through 1323 this endpoint; requests for team threads return 404. 1324 The authenticated user must have visibility into the thread. Each agent entry 1325 includes display information such as name and profile picture. Thread-level 1326 overrides (e.g. a custom name or profile picture set for this thread) take 1327 precedence over the agent's default values. When the caller is the thread 1328 owner, each entry also includes an `agent_config` object describing the 1329 agent's message policy and context configuration. 1330 1331 Args: 1332 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1333 1334 Returns: 1335 Successful response 1336 """ 1337 return await self._http.request( 1338 f"/api/v1/threads/{thread}/agents", 1339 response_type=ThreadAgentsResponse, 1340 ) 1341 1342 async def artifacts( 1343 self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None 1344 ) -> ThreadArtifactsResponse: 1345 """ 1346 List artifacts for a thread 1347 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1348 structured outputs such as code files, documents, or generated assets created 1349 by the AI agent in response to messages in the thread. 1350 The authenticated user must have access to the specified thread. Results are 1351 returned in a single page; there is no cursor-based pagination for this endpoint. 1352 1353 Args: 1354 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1355 group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match. 1356 group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. 1357 1358 Returns: 1359 Successful response 1360 """ 1361 query: dict[str, object] = {} 1362 if group_key is not None: 1363 query["group_key"] = group_key 1364 if group_key_prefix is not None: 1365 query["group_key_prefix"] = group_key_prefix 1366 return await self._http.request( 1367 f"/api/v1/threads/{thread}/artifacts", 1368 query=query, 1369 response_type=ThreadArtifactsResponse, 1370 ) 1371 1372 async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 1373 """ 1374 Mark a thread as read 1375 Records that a user has read up to a specific message in the thread. Unread 1376 indicators and badge counts are cleared up to the specified message. 1377 You must supply exactly one of `last_read_message` or `use_latest_message`. 1378 Omitting both returns 400. If `use_latest_message` is `true` and the thread 1379 has no messages, the request succeeds silently with no state change. 1380 For server-to-server (S2S) requests where no user identity is present in the 1381 token, the `user` param is required to identify whose read state to update. 1382 1383 Args: 1384 thread: Thread ID (`thr_...`). The thread to mark as read. 1385 input: Request body. 1386 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 1387 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 1388 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 1389 1390 Returns: 1391 Empty response on success. 1392 """ 1393 await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 1394 1395 async def messages( 1396 self, 1397 thread: str, 1398 *, 1399 before_cursor: str | None = None, 1400 after_cursor: str | None = None, 1401 metadata: dict[str, Any] | None = None, 1402 limit: int | None = None, 1403 include_replies: bool | None = None, 1404 anchor: str | None = None, 1405 direction: Literal["before", "after", "around"] | None = None, 1406 before_limit: int | None = None, 1407 after_limit: int | None = None, 1408 include_anchor: bool | None = None, 1409 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 1410 anchor_agent: str | None = None, 1411 include_reply_counts: bool | None = None, 1412 ) -> ThreadMessagesResponse: 1413 """ 1414 List messages in a thread 1415 Returns a cursor-paginated list of messages belonging to the specified thread, 1416 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 1417 to page through or bound the result set; omit both to receive the most recent page. 1418 Supply `anchor` and `direction` to fetch a window before, after, or around a 1419 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 1420 resolve the anchor from the latest embedded-agent message, and add 1421 `anchor_agent` to scope that resolution to a single sender agent. 1422 Supply `metadata` as a JSON-encoded structured expression to filter message 1423 metadata before cursor pagination or anchored window limits are applied. 1424 The authenticated user must have access to the thread's owner (workspace or user). 1425 A 403 is returned if the thread exists but is not accessible to the caller; a 404 1426 is returned if the thread does not exist or is not visible to the authenticated user. 1427 Threads with `kind: feed` return only top-level posts, each with its newest 1428 replies inline under `replies` and reply cursors for paging the rest. 1429 Set `include_replies: true` to page messages and replies together by creation 1430 order instead, without inline reply previews. Metadata filters and the page 1431 limit apply to the updates themselves, before any client-side grouping. 1432 Pass `include_reply_counts: true` to annotate each message with the number of 1433 threaded replies it has received. This adds a small amount of latency and should 1434 be omitted when reply counts are not needed. 1435 1436 Args: 1437 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1438 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 1439 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 1440 metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. 1441 limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100. 1442 include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. 1443 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 1444 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 1445 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. 1446 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. 1447 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 1448 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 1449 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 1450 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 1451 1452 Returns: 1453 Successful response 1454 """ 1455 query: dict[str, object] = {} 1456 if before_cursor is not None: 1457 query["before_cursor"] = before_cursor 1458 if after_cursor is not None: 1459 query["after_cursor"] = after_cursor 1460 if metadata is not None: 1461 query["metadata"] = metadata 1462 if limit is not None: 1463 query["limit"] = limit 1464 if include_replies is not None: 1465 query["include_replies"] = include_replies 1466 if anchor is not None: 1467 query["anchor"] = anchor 1468 if direction is not None: 1469 query["direction"] = direction 1470 if before_limit is not None: 1471 query["before_limit"] = before_limit 1472 if after_limit is not None: 1473 query["after_limit"] = after_limit 1474 if include_anchor is not None: 1475 query["include_anchor"] = include_anchor 1476 if anchor_agent_mode is not None: 1477 query["anchor_agent_mode"] = anchor_agent_mode 1478 if anchor_agent is not None: 1479 query["anchor_agent"] = anchor_agent 1480 if include_reply_counts is not None: 1481 query["include_reply_counts"] = include_reply_counts 1482 return await self._http.request( 1483 f"/api/v1/threads/{thread}/messages", 1484 query=query, 1485 response_type=ThreadMessagesResponse, 1486 ) 1487 1488 async def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 1489 """ 1490 Update a thread's profile picture 1491 Uploads a new profile picture for the specified thread and returns the updated 1492 thread object. The image must be supplied as a base64-encoded string with its 1493 MIME type. 1494 The authenticated user must own the thread or be a team owner of the workspace 1495 the thread belongs to. Supplying invalid base64 data returns 422. 1496 1497 Args: 1498 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1499 input: Request body. 1500 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1501 1502 Returns: 1503 The thread object after the profile picture has been updated. 1504 """ 1505 return await self._http.request( 1506 f"/api/v1/threads/{thread}/picture", 1507 method="PUT", 1508 body=input, 1509 response_type=Thread, 1510 ) 1511 1512 async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1513 """ 1514 Retrieve a thread's read status 1515 Returns the read status of a thread for the specified user, including the ID 1516 of the last message they have read and the number of unread messages remaining. 1517 For user-authenticated requests, the status is always returned for the 1518 authenticated user and the `user` parameter is ignored. For server-to-server 1519 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1520 Returns 404 if the thread does not exist or the caller does not have access 1521 to it. 1522 1523 Args: 1524 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1525 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1526 1527 Returns: 1528 The read status record for the requested thread and user. 1529 """ 1530 query: dict[str, object] = {} 1531 if user is not None: 1532 query["user"] = user 1533 return await self._http.request( 1534 f"/api/v1/threads/{thread}/read_status", 1535 query=query, 1536 response_type=ThreadReadStatus, 1537 ) 1538 1539 async def search( 1540 self, 1541 thread: str, 1542 q: str, 1543 *, 1544 app: str | None = None, 1545 limit: int | None = None, 1546 mode: Literal["text", "embedding", "hybrid"] | None = None, 1547 before_cursor: str | None = None, 1548 after_cursor: str | None = None, 1549 ) -> ThreadSearchResponse: 1550 """ 1551 Search messages in a thread 1552 Searches canonical message content in the specified thread. `"text"` mode 1553 performs the existing case-insensitive substring search, `"embedding"` ranks 1554 stored message embeddings by cosine similarity, and `"hybrid"` combines the 1555 text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages 1556 visible to the authenticated caller are considered. 1557 Results are intentionally lean: each row contains a bounded content snippet, 1558 sender identity, timestamp, and a small allowlisted structured-post evidence 1559 projection. Attachments, reactions, ACLs, and arbitrary metadata are neither 1560 hydrated nor serialized. At most 20 results are returned. Text results 1561 support chronological cursor pagination. Embedding and hybrid results are 1562 relevance-ranked single pages and return null cursors. 1563 1564 Args: 1565 thread: Thread ID (`thr_...`). Must be visible to the authenticated caller. 1566 app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount. 1567 q: Text or semantic search query. Must contain 3 to 200 characters after trimming. 1568 limit: Maximum number of results. Defaults to 20 and is capped at 20. 1569 mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings. 1570 before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches. 1571 after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches. 1572 1573 Returns: 1574 Successful response 1575 """ 1576 query: dict[str, object] = {} 1577 if app is not None: 1578 query["app"] = app 1579 query["q"] = q 1580 if limit is not None: 1581 query["limit"] = limit 1582 if mode is not None: 1583 query["mode"] = mode 1584 if before_cursor is not None: 1585 query["before_cursor"] = before_cursor 1586 if after_cursor is not None: 1587 query["after_cursor"] = after_cursor 1588 return await self._http.request( 1589 f"/api/v1/threads/{thread}/search", 1590 query=query, 1591 response_type=ThreadSearchResponse, 1592 ) 1593 1594 async def trajectories( 1595 self, 1596 thread: str, 1597 *, 1598 before_cursor: str | None = None, 1599 after_cursor: str | None = None, 1600 limit: int | None = None, 1601 message: str | None = None, 1602 ) -> ThreadTrajectoriesResponse: 1603 """ 1604 List trajectories for a thread 1605 Returns a cursor-paginated list of thread message trajectories associated with the 1606 specified thread. Each trajectory links a user message and its agent response to the 1607 underlying AI trajectory record that captured the model's reasoning steps. 1608 The authenticated user must own the thread or be a member of the workspace it belongs 1609 to. Results are returned in reverse chronological order by default. Use `before_cursor` 1610 and `after_cursor` to navigate pages; provide at most one cursor per request. 1611 Optionally filter results to trajectories produced in response to a specific message 1612 by supplying the `message` parameter. When no trajectories match the query, `data` 1613 is an empty array and both cursor fields are `null`. A cursor that cannot be decoded 1614 returns a 400 `invalid_cursor` error. 1615 1616 Args: 1617 thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace. 1618 before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position. 1619 after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position. 1620 limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100. 1621 message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message. 1622 1623 Returns: 1624 Successful response 1625 """ 1626 query: dict[str, object] = {} 1627 if before_cursor is not None: 1628 query["before_cursor"] = before_cursor 1629 if after_cursor is not None: 1630 query["after_cursor"] = after_cursor 1631 if limit is not None: 1632 query["limit"] = limit 1633 if message is not None: 1634 query["message"] = message 1635 return await self._http.request( 1636 f"/api/v1/threads/{thread}/trajectories", 1637 query=query, 1638 response_type=ThreadTrajectoriesResponse, 1639 ) 1640 1641 1642class ComputerResource: 1643 def __init__(self, http: SyncHttpClient): 1644 self._http = http 1645 1646 def list(self, thread: str) -> AgentComputerListResponse: 1647 """ 1648 List a thread's computers 1649 Returns all live computers in the visible thread, oldest first, without pagination. 1650 1651 Args: 1652 thread: Thread ID (`thr_...`). 1653 1654 Returns: 1655 The thread's live computers. 1656 """ 1657 return self._http.request( 1658 f"/api/v1/threads/{thread}/computers", 1659 response_type=AgentComputerListResponse, 1660 ) 1661 1662 def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: 1663 """ 1664 Provision a computer for a thread 1665 Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. 1666 1667 Args: 1668 thread: Thread ID (`thr_...`). 1669 input: Request body. 1670 input.acl: Initial access control list. 1671 input.config: Provider configuration; top-level provider takes precedence. 1672 input.key: Stable key unique within this thread. 1673 input.metadata: Arbitrary computer metadata. 1674 input.name: Human-readable computer name. 1675 input.provider: Compute backend: sprites (default), vercel or e2b. 1676 input.region: Provider region; defaults to iad. 1677 1678 Returns: 1679 The newly created computer. Returns HTTP 201. 1680 """ 1681 return self._http.request( 1682 f"/api/v1/threads/{thread}/computers", 1683 method="POST", 1684 body=input, 1685 response_type=AgentComputer, 1686 ) 1687 1688 1689class ThreadMemberResource: 1690 def __init__(self, http: SyncHttpClient): 1691 self._http = http 1692 1693 def remove(self, thread: str) -> None: 1694 """ 1695 Remove a member from a thread 1696 Removes a user or agent from the explicit roster of a private or restricted 1697 thread. Team-visible threads use implicit membership and reject individual 1698 removals. A member may remove themself; removing someone else requires 1699 permission to modify the thread. A successful removal returns HTTP 204 with 1700 no response body. 1701 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1702 if the thread or the membership record does not exist. 1703 1704 Args: 1705 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1706 1707 Returns: 1708 Empty response body. HTTP 204 on success. 1709 """ 1710 self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 1711 1712 def list(self, thread: str) -> ThreadMemberListResponse: 1713 """ 1714 List members of a thread 1715 Returns all current user and agent members. Private and restricted threads 1716 return their explicit roster; team-visible threads return the owning team's 1717 implicit roster. The authenticated viewer must be able to see the thread. 1718 Results are returned as a flat array in the `data` field. The list is not 1719 paginated all members are returned in a single response. 1720 1721 Args: 1722 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1723 1724 Returns: 1725 Successful response 1726 """ 1727 return self._http.request( 1728 f"/api/v1/threads/{thread}/members", 1729 response_type=ThreadMemberListResponse, 1730 ) 1731 1732 def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember: 1733 """ 1734 Add a member to a thread 1735 Adds a user or agent to the explicit roster of a private or restricted 1736 thread. Team-visible threads use the owning team's implicit roster and reject 1737 explicit additions. On restricted threads, a team member may add themself; 1738 adding anyone else requires permission to modify the thread. 1739 Supply either `user` or `agent` depending on the value of `type`. Targets 1740 must be visible to the caller and, for an ordinary team-owned thread, must 1741 belong to the owning team. On success the membership record is returned with 1742 HTTP 201; repeated agent additions are idempotent. 1743 1744 Args: 1745 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1746 input: Request body. 1747 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1748 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1749 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1750 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1751 1752 Returns: 1753 The user or agent membership that was added to the thread. 1754 """ 1755 return self._http.request( 1756 f"/api/v1/threads/{thread}/members", 1757 method="POST", 1758 body=input, 1759 response_type=ChatMember, 1760 ) 1761 1762 1763class SettingResource: 1764 def __init__(self, http: SyncHttpClient): 1765 self._http = http 1766 1767 def list(self, thread: str) -> SettingListResponse: 1768 """ 1769 Retrieve thread settings 1770 Returns the current settings for the specified thread. Settings control 1771 per-thread behavior such as whether the AI agent is enabled. 1772 The authenticated user must own the thread or be a member of its workspace. 1773 If settings have never been explicitly configured, defaults are returned 1774 (for example, `agent_enabled` defaults to `true`). 1775 1776 Args: 1777 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1778 1779 Returns: 1780 Successful response 1781 """ 1782 return self._http.request( 1783 f"/api/v1/threads/{thread}/settings", 1784 response_type=SettingListResponse, 1785 ) 1786 1787 def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1788 """ 1789 Update thread settings 1790 Updates the settings for the specified thread. Only fields included in 1791 the `settings` map are modified; omitted fields retain their current values. 1792 The authenticated user must own the thread or be a member of its workspace. 1793 Returns the full settings object reflecting the state after the update. 1794 Validation errors are returned as `422 Unprocessable Entity`. 1795 1796 Args: 1797 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1798 input: Request body. 1799 input.settings: Map of settings fields to update. Include only the keys you want to change. 1800 1801 Returns: 1802 The thread settings object after the update has been applied. 1803 """ 1804 return self._http.request( 1805 f"/api/v1/threads/{thread}/settings", 1806 method="PUT", 1807 body=input, 1808 response_type=ThreadSettings, 1809 ) 1810 1811 1812class TagResource: 1813 def __init__(self, http: SyncHttpClient): 1814 self._http = http 1815 1816 def remove(self, thread: str) -> Thread: 1817 """ 1818 Remove tags from a thread 1819 Removes one or more status tags from the thread and returns the updated 1820 thread. Removing a tag the thread does not have is a no-op. 1821 Any participant of the thread a human member or an agent member may edit 1822 tags. Supply the tags to remove as repeated query parameters, e.g. 1823 `?tags[]=blocked&tags[]=needs-review`. 1824 1825 Args: 1826 thread: Thread ID (`thr_...`) to untag. 1827 1828 Returns: 1829 The thread object after the tags were removed. 1830 """ 1831 return self._http.request( 1832 f"/api/v1/threads/{thread}/tags", 1833 method="DELETE", 1834 response_type=Thread, 1835 ) 1836 1837 def create(self, thread: str, input: TagCreateInput) -> Thread: 1838 """ 1839 Add tags to a thread 1840 Adds one or more status tags to the thread and returns the updated thread. 1841 Any participant of the thread a human member or an agent member may edit 1842 tags; this is broader than the owner/admin permission required to update other 1843 thread fields. Adding a tag the thread already has is a no-op. Tags are 1844 normalized (trimmed and lowercased) and may contain only lowercase letters, 1845 numbers, hyphens, and underscores. 1846 1847 Args: 1848 thread: Thread ID (`thr_...`) to untag. 1849 input: Request body. 1850 input.tags: Tags to add to the thread. 1851 1852 Returns: 1853 The thread object after the tags were added. 1854 """ 1855 return self._http.request( 1856 f"/api/v1/threads/{thread}/tags", 1857 method="POST", 1858 body=input, 1859 response_type=Thread, 1860 ) 1861 1862 def replace(self, thread: str, input: TagReplaceInput) -> Thread: 1863 """ 1864 Replace a thread's tags 1865 Replaces the thread's entire set of status tags with the provided list and 1866 returns the updated thread. Passing an empty array clears all tags. 1867 Any participant of the thread a human member or an agent member may edit 1868 tags. Tags are normalized (trimmed and lowercased) and may contain only 1869 lowercase letters, numbers, hyphens, and underscores. 1870 1871 Args: 1872 thread: Thread ID (`thr_...`) to untag. 1873 input: Request body. 1874 input.tags: The complete set of tags for the thread. An empty array clears all tags. 1875 1876 Returns: 1877 The thread object after its tags were replaced. 1878 """ 1879 return self._http.request( 1880 f"/api/v1/threads/{thread}/tags", 1881 method="PUT", 1882 body=input, 1883 response_type=Thread, 1884 ) 1885 1886 1887class ThreadResource: 1888 def __init__(self, http: SyncHttpClient): 1889 self._http = http 1890 self.computers = ComputerResource(http) 1891 self.members = ThreadMemberResource(http) 1892 self.settings = SettingResource(http) 1893 self.tags = TagResource(http) 1894 1895 def delete(self, thread: str) -> None: 1896 """ 1897 Delete a thread 1898 Permanently deletes a thread and all of its messages and artifacts. This action 1899 cannot be undone. 1900 The authenticated user must own the thread or be an owner of the team the thread 1901 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1902 1903 Args: 1904 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1905 1906 Returns: 1907 Empty response on successful deletion. 1908 """ 1909 self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 1910 1911 def get(self, thread: str) -> Thread: 1912 """ 1913 Retrieve a thread 1914 Returns the full thread record for the given thread ID. The authenticated user 1915 must own the thread or be a member of the workspace it belongs to. 1916 Use this endpoint to fetch the current state of a single thread, including its 1917 title, description, and metadata. To list many threads, use the list endpoint 1918 with cursor-based pagination. 1919 1920 Args: 1921 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1922 1923 Returns: 1924 The requested thread object. 1925 """ 1926 return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 1927 1928 def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1929 """ 1930 Update a thread 1931 Updates one or more mutable properties of the specified thread and returns 1932 the full thread object with the applied changes. Only the fields you provide 1933 are modified; omitted fields retain their current values. 1934 If `profile_picture` is supplied, the image is uploaded before the other 1935 fields are saved, after all ordinary thread fields have passed validation. 1936 Supplying invalid base64 picture data returns 422 and no other fields are 1937 updated. 1938 Visibility can only widen: `private` may become `restricted` or `team`, and 1939 `restricted` may become `team`. The authenticated viewer must have 1940 permission to modify the thread. 1941 Mirror-thread titles, descriptions, and notification state remain editable 1942 by privileged app viewers. Mirror metadata, visibility, and membership are 1943 provider-managed and cannot be changed through this endpoint. 1944 1945 Args: 1946 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1947 input: Request body. 1948 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1949 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1950 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1951 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1952 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1953 input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed. 1954 1955 Returns: 1956 The thread object after the update has been applied. 1957 """ 1958 return self._http.request( 1959 f"/api/v1/threads/{thread}", 1960 method="PUT", 1961 body=input, 1962 response_type=Thread, 1963 ) 1964 1965 def agents(self, thread: str) -> ThreadAgentsResponse: 1966 """ 1967 List agents in a thread 1968 Returns the agents participating in the specified thread. Only personal user 1969 threads (threads owned by a single user, not a team) expose agents through 1970 this endpoint; requests for team threads return 404. 1971 The authenticated user must have visibility into the thread. Each agent entry 1972 includes display information such as name and profile picture. Thread-level 1973 overrides (e.g. a custom name or profile picture set for this thread) take 1974 precedence over the agent's default values. When the caller is the thread 1975 owner, each entry also includes an `agent_config` object describing the 1976 agent's message policy and context configuration. 1977 1978 Args: 1979 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1980 1981 Returns: 1982 Successful response 1983 """ 1984 return self._http.request( 1985 f"/api/v1/threads/{thread}/agents", 1986 response_type=ThreadAgentsResponse, 1987 ) 1988 1989 def artifacts( 1990 self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None 1991 ) -> ThreadArtifactsResponse: 1992 """ 1993 List artifacts for a thread 1994 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1995 structured outputs such as code files, documents, or generated assets created 1996 by the AI agent in response to messages in the thread. 1997 The authenticated user must have access to the specified thread. Results are 1998 returned in a single page; there is no cursor-based pagination for this endpoint. 1999 2000 Args: 2001 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 2002 group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match. 2003 group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. 2004 2005 Returns: 2006 Successful response 2007 """ 2008 query: dict[str, object] = {} 2009 if group_key is not None: 2010 query["group_key"] = group_key 2011 if group_key_prefix is not None: 2012 query["group_key_prefix"] = group_key_prefix 2013 return self._http.request( 2014 f"/api/v1/threads/{thread}/artifacts", 2015 query=query, 2016 response_type=ThreadArtifactsResponse, 2017 ) 2018 2019 def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 2020 """ 2021 Mark a thread as read 2022 Records that a user has read up to a specific message in the thread. Unread 2023 indicators and badge counts are cleared up to the specified message. 2024 You must supply exactly one of `last_read_message` or `use_latest_message`. 2025 Omitting both returns 400. If `use_latest_message` is `true` and the thread 2026 has no messages, the request succeeds silently with no state change. 2027 For server-to-server (S2S) requests where no user identity is present in the 2028 token, the `user` param is required to identify whose read state to update. 2029 2030 Args: 2031 thread: Thread ID (`thr_...`). The thread to mark as read. 2032 input: Request body. 2033 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 2034 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 2035 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 2036 2037 Returns: 2038 Empty response on success. 2039 """ 2040 self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 2041 2042 def messages( 2043 self, 2044 thread: str, 2045 *, 2046 before_cursor: str | None = None, 2047 after_cursor: str | None = None, 2048 metadata: dict[str, Any] | None = None, 2049 limit: int | None = None, 2050 include_replies: bool | None = None, 2051 anchor: str | None = None, 2052 direction: Literal["before", "after", "around"] | None = None, 2053 before_limit: int | None = None, 2054 after_limit: int | None = None, 2055 include_anchor: bool | None = None, 2056 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 2057 anchor_agent: str | None = None, 2058 include_reply_counts: bool | None = None, 2059 ) -> ThreadMessagesResponse: 2060 """ 2061 List messages in a thread 2062 Returns a cursor-paginated list of messages belonging to the specified thread, 2063 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 2064 to page through or bound the result set; omit both to receive the most recent page. 2065 Supply `anchor` and `direction` to fetch a window before, after, or around a 2066 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 2067 resolve the anchor from the latest embedded-agent message, and add 2068 `anchor_agent` to scope that resolution to a single sender agent. 2069 Supply `metadata` as a JSON-encoded structured expression to filter message 2070 metadata before cursor pagination or anchored window limits are applied. 2071 The authenticated user must have access to the thread's owner (workspace or user). 2072 A 403 is returned if the thread exists but is not accessible to the caller; a 404 2073 is returned if the thread does not exist or is not visible to the authenticated user. 2074 Threads with `kind: feed` return only top-level posts, each with its newest 2075 replies inline under `replies` and reply cursors for paging the rest. 2076 Set `include_replies: true` to page messages and replies together by creation 2077 order instead, without inline reply previews. Metadata filters and the page 2078 limit apply to the updates themselves, before any client-side grouping. 2079 Pass `include_reply_counts: true` to annotate each message with the number of 2080 threaded replies it has received. This adds a small amount of latency and should 2081 be omitted when reply counts are not needed. 2082 2083 Args: 2084 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 2085 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 2086 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 2087 metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. 2088 limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100. 2089 include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. 2090 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 2091 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 2092 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. 2093 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. 2094 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 2095 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 2096 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 2097 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 2098 2099 Returns: 2100 Successful response 2101 """ 2102 query: dict[str, object] = {} 2103 if before_cursor is not None: 2104 query["before_cursor"] = before_cursor 2105 if after_cursor is not None: 2106 query["after_cursor"] = after_cursor 2107 if metadata is not None: 2108 query["metadata"] = metadata 2109 if limit is not None: 2110 query["limit"] = limit 2111 if include_replies is not None: 2112 query["include_replies"] = include_replies 2113 if anchor is not None: 2114 query["anchor"] = anchor 2115 if direction is not None: 2116 query["direction"] = direction 2117 if before_limit is not None: 2118 query["before_limit"] = before_limit 2119 if after_limit is not None: 2120 query["after_limit"] = after_limit 2121 if include_anchor is not None: 2122 query["include_anchor"] = include_anchor 2123 if anchor_agent_mode is not None: 2124 query["anchor_agent_mode"] = anchor_agent_mode 2125 if anchor_agent is not None: 2126 query["anchor_agent"] = anchor_agent 2127 if include_reply_counts is not None: 2128 query["include_reply_counts"] = include_reply_counts 2129 return self._http.request( 2130 f"/api/v1/threads/{thread}/messages", 2131 query=query, 2132 response_type=ThreadMessagesResponse, 2133 ) 2134 2135 def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 2136 """ 2137 Update a thread's profile picture 2138 Uploads a new profile picture for the specified thread and returns the updated 2139 thread object. The image must be supplied as a base64-encoded string with its 2140 MIME type. 2141 The authenticated user must own the thread or be a team owner of the workspace 2142 the thread belongs to. Supplying invalid base64 data returns 422. 2143 2144 Args: 2145 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 2146 input: Request body. 2147 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 2148 2149 Returns: 2150 The thread object after the profile picture has been updated. 2151 """ 2152 return self._http.request( 2153 f"/api/v1/threads/{thread}/picture", 2154 method="PUT", 2155 body=input, 2156 response_type=Thread, 2157 ) 2158 2159 def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 2160 """ 2161 Retrieve a thread's read status 2162 Returns the read status of a thread for the specified user, including the ID 2163 of the last message they have read and the number of unread messages remaining. 2164 For user-authenticated requests, the status is always returned for the 2165 authenticated user and the `user` parameter is ignored. For server-to-server 2166 (S2S) requests, the `user` parameter is required and must be a valid user ID. 2167 Returns 404 if the thread does not exist or the caller does not have access 2168 to it. 2169 2170 Args: 2171 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 2172 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 2173 2174 Returns: 2175 The read status record for the requested thread and user. 2176 """ 2177 query: dict[str, object] = {} 2178 if user is not None: 2179 query["user"] = user 2180 return self._http.request( 2181 f"/api/v1/threads/{thread}/read_status", 2182 query=query, 2183 response_type=ThreadReadStatus, 2184 ) 2185 2186 def search( 2187 self, 2188 thread: str, 2189 q: str, 2190 *, 2191 app: str | None = None, 2192 limit: int | None = None, 2193 mode: Literal["text", "embedding", "hybrid"] | None = None, 2194 before_cursor: str | None = None, 2195 after_cursor: str | None = None, 2196 ) -> ThreadSearchResponse: 2197 """ 2198 Search messages in a thread 2199 Searches canonical message content in the specified thread. `"text"` mode 2200 performs the existing case-insensitive substring search, `"embedding"` ranks 2201 stored message embeddings by cosine similarity, and `"hybrid"` combines the 2202 text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages 2203 visible to the authenticated caller are considered. 2204 Results are intentionally lean: each row contains a bounded content snippet, 2205 sender identity, timestamp, and a small allowlisted structured-post evidence 2206 projection. Attachments, reactions, ACLs, and arbitrary metadata are neither 2207 hydrated nor serialized. At most 20 results are returned. Text results 2208 support chronological cursor pagination. Embedding and hybrid results are 2209 relevance-ranked single pages and return null cursors. 2210 2211 Args: 2212 thread: Thread ID (`thr_...`). Must be visible to the authenticated caller. 2213 app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount. 2214 q: Text or semantic search query. Must contain 3 to 200 characters after trimming. 2215 limit: Maximum number of results. Defaults to 20 and is capped at 20. 2216 mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings. 2217 before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches. 2218 after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches. 2219 2220 Returns: 2221 Successful response 2222 """ 2223 query: dict[str, object] = {} 2224 if app is not None: 2225 query["app"] = app 2226 query["q"] = q 2227 if limit is not None: 2228 query["limit"] = limit 2229 if mode is not None: 2230 query["mode"] = mode 2231 if before_cursor is not None: 2232 query["before_cursor"] = before_cursor 2233 if after_cursor is not None: 2234 query["after_cursor"] = after_cursor 2235 return self._http.request( 2236 f"/api/v1/threads/{thread}/search", 2237 query=query, 2238 response_type=ThreadSearchResponse, 2239 ) 2240 2241 def trajectories( 2242 self, 2243 thread: str, 2244 *, 2245 before_cursor: str | None = None, 2246 after_cursor: str | None = None, 2247 limit: int | None = None, 2248 message: str | None = None, 2249 ) -> ThreadTrajectoriesResponse: 2250 """ 2251 List trajectories for a thread 2252 Returns a cursor-paginated list of thread message trajectories associated with the 2253 specified thread. Each trajectory links a user message and its agent response to the 2254 underlying AI trajectory record that captured the model's reasoning steps. 2255 The authenticated user must own the thread or be a member of the workspace it belongs 2256 to. Results are returned in reverse chronological order by default. Use `before_cursor` 2257 and `after_cursor` to navigate pages; provide at most one cursor per request. 2258 Optionally filter results to trajectories produced in response to a specific message 2259 by supplying the `message` parameter. When no trajectories match the query, `data` 2260 is an empty array and both cursor fields are `null`. A cursor that cannot be decoded 2261 returns a 400 `invalid_cursor` error. 2262 2263 Args: 2264 thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace. 2265 before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position. 2266 after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position. 2267 limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100. 2268 message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message. 2269 2270 Returns: 2271 Successful response 2272 """ 2273 query: dict[str, object] = {} 2274 if before_cursor is not None: 2275 query["before_cursor"] = before_cursor 2276 if after_cursor is not None: 2277 query["after_cursor"] = after_cursor 2278 if limit is not None: 2279 query["limit"] = limit 2280 if message is not None: 2281 query["message"] = message 2282 return self._http.request( 2283 f"/api/v1/threads/{thread}/trajectories", 2284 query=query, 2285 response_type=ThreadTrajectoriesResponse, 2286 )
19class ComputerCreateInputAclAddItem(TypedDict, total=False): 20 actions: Required[list[str]] 21 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 22 principal: str | None 23 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' 24 principal_type: Required[str] 25 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".
28class ComputerCreateInputAclGrantsItem(TypedDict, total=False): 29 actions: Required[list[str]] 30 'Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.' 31 principal: str | None 32 'The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.' 33 principal_type: Required[str] 34 'The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".
37class ComputerCreateInputAclRemoveItem(TypedDict, total=False): 38 principal: str | None 39 'The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.' 40 principal_type: Required[str] 41 'The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.'
The identifier of the principal to remove. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role". Omit when principal_type is "everyone".
44class ComputerCreateInputAcl(TypedDict, total=False): 45 add: list[ComputerCreateInputAclAddItem] | None 46 "Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`." 47 grants: list[ComputerCreateInputAclGrantsItem] | None 48 "Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`." 49 remove: list[ComputerCreateInputAclRemoveItem] | None 50 "Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`."
Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.
Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.
53class ComputerCreateInput(TypedDict, total=False): 54 "Provision a computer for a thread" 55 56 acl: ComputerCreateInputAcl | None 57 "Initial access control list." 58 config: dict[str, Any] | None 59 "Provider configuration; top-level provider takes precedence." 60 key: str | None 61 "Stable key unique within this thread." 62 metadata: dict[str, Any] | None 63 "Arbitrary computer metadata." 64 name: Required[str] 65 "Human-readable computer name." 66 provider: str | None 67 "Compute backend: sprites (default), vercel or e2b." 68 region: str | None 69 "Provider region; defaults to iad."
Provision a computer for a thread
72class ThreadMemberCreateInput(TypedDict, total=False): 73 "Add a member to a thread" 74 75 agent: str | None 76 'Agent ID of the principal to add. Required when `type` is `"agent"`.' 77 membership_type: str | None 78 'Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`.' 79 type: Required[str] 80 'Kind of principal being added. Must be `"user"` or `"agent"`.' 81 user: str | None 82 'User ID of the principal to add. Required when `type` is `"user"`.'
Add a member to a thread
85class SettingReplaceInput(TypedDict): 86 "Update thread settings" 87 88 settings: dict[str, Any] 89 "Map of settings fields to update. Include only the keys you want to change."
Update thread settings
92class TagCreateInput(TypedDict): 93 "Add tags to a thread" 94 95 tags: list[str] 96 "Tags to add to the thread."
Add tags to a thread
99class TagReplaceInput(TypedDict): 100 "Replace a thread's tags" 101 102 tags: list[str] 103 "The complete set of tags for the thread. An empty array clears all tags."
Replace a thread's tags
106class ThreadReplaceInputProfilePicture(TypedDict, total=False): 107 data: str | None 108 "Base64-encoded image payload. Must be a valid base64 string." 109 filename: str | None 110 'Original filename of the image, e.g. `"avatar.png"`. Used for storage metadata.' 111 mime_type: str | None 112 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.'
115class ThreadReplaceInput(TypedDict, total=False): 116 "Update a thread" 117 118 description: str | None 119 "Optional longer text describing the thread's purpose. Replaces the existing description when provided." 120 metadata: dict[str, Any] | None 121 "Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata." 122 muted: bool | None 123 "When `true`, suppresses notifications for new messages in this thread for the authenticated user." 124 profile_picture: ThreadReplaceInputProfilePicture | None 125 "New profile picture for the thread. Provide all three inner fields to replace the existing image." 126 title: str | None 127 "Human-readable display name for the thread. Replaces the existing title when provided." 128 visibility: Literal["private", "restricted", "team"] | None 129 "Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed."
Update a thread
Optional longer text describing the thread's purpose. Replaces the existing description when provided.
Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
When true, suppresses notifications for new messages in this thread for the authenticated user.
New profile picture for the thread. Provide all three inner fields to replace the existing image.
132class ThreadMarkReadInput(TypedDict, total=False): 133 "Mark a thread as read" 134 135 last_read_message: str | None 136 "Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`." 137 use_latest_message: bool | None 138 "When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`." 139 user: str | None 140 "User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token."
Mark a thread as read
Message ID (msg_...) to record as the last read message. Mutually exclusive with use_latest_message.
When true, marks the thread as read up to the latest message. Mutually exclusive with last_read_message.
143class ThreadPictureInputPicture(TypedDict): 144 data: str 145 "Base64-encoded binary content of the image file." 146 filename: str 147 'Original filename of the image, e.g. `"avatar.png"`. Used for storage and display.' 148 mime_type: str 149 'MIME type of the image, e.g. `"image/jpeg"` or `"image/png"`.'
152class ThreadPictureInput(TypedDict): 153 "Update a thread's profile picture" 154 155 picture: ThreadPictureInputPicture 156 "Profile picture payload. Must include the base64-encoded image data and its MIME type."
Update a thread's profile picture
Profile picture payload. Must include the base64-encoded image data and its MIME type.
159class ThreadMemberListResponseDataItemAgent(BaseModel): 160 email: str | None = Field( 161 default=None, description="Agent email address. `null` if not configured." 162 ) 163 id: str = Field(..., description="Agent ID (`agi_...`).") 164 name: str | None = Field( 165 default=None, description="Human-readable agent name. `null` if not set." 166 ) 167 org: str | None = Field( 168 default=None, 169 description="Organization that owns this agent (`org_...`). `null` if not org-scoped.", 170 ) 171 team: str | None = Field( 172 default=None, 173 description="Team that owns this agent (`tem_...`). `null` if not team-scoped.", 174 ) 175 user: str | None = Field( 176 default=None, 177 description="User that owns this agent (`usr_...`). `null` if not user-scoped.", 178 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
181class ThreadMemberListResponseDataItemUser(BaseModel): 182 email: str | None = Field(default=None, description="User's email address. `null` if not set.") 183 full_name: str | None = Field( 184 default=None, description="Backward-compatible alias of `name`. `null` if not set." 185 ) 186 id: str = Field(..., description="User ID (`usr_...`).") 187 name: str | None = Field( 188 default=None, description="Full display name of the user. `null` if not set." 189 ) 190 org: str | None = Field( 191 default=None, 192 description="Organization this user belongs to (`org_...`). `null` if the user is not org-scoped.", 193 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
196class ThreadMemberListResponseDataItem(BaseModel): 197 agent: ThreadMemberListResponseDataItemAgent | None = Field( 198 default=None, 199 description="Roster-safe agent identity. Populated for agent members; `null` for users.", 200 ) 201 joined_at: datetime | None = Field( 202 default=None, description="When this member joined the thread (ISO 8601)." 203 ) 204 member_type: str | None = Field( 205 default=None, description="Backward-compatible alias of `type`." 206 ) 207 membership_type: str | None = Field( 208 default=None, description='Role of this member, commonly `"owner"` or `"member"`.' 209 ) 210 role: str | None = Field( 211 default=None, description="Backward-compatible alias of `membership_type`." 212 ) 213 type: str = Field(..., description='Kind of participant. One of `"user"` or `"agent"`.') 214 user: ThreadMemberListResponseDataItemUser | None = Field( 215 default=None, 216 description="Roster-safe user identity. Populated for user members; `null` for agents.", 217 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
220class ThreadMemberListResponse(BaseModel): 221 """ 222 Successful response 223 """ 224 225 data: list[ThreadMemberListResponseDataItem] = Field( 226 ..., 227 description="Array of thread member objects representing all current members of the thread.", 228 )
Successful response
231class SettingListResponse(BaseModel): 232 """ 233 Successful response 234 """ 235 236 agent_enabled: bool | None = Field( 237 default=None, 238 description="Whether the AI agent is active for this thread. Defaults to `true` when no settings have been explicitly set.", 239 )
Successful response
242class ThreadAgentsResponse(BaseModel): 243 """ 244 Successful response 245 """ 246 247 data: list[dict[str, Any]] = Field( 248 ..., 249 description="Array of agent objects for the thread. Each object includes `id`, `name`, `alias`, `profile_picture`, and `metadata`. Thread owners also receive an `agent_config` object with the agent's policy type and context configuration.", 250 )
Successful response
253class ThreadArtifactsResponseDataItemAclAddItem(BaseModel): 254 actions: list[str] = Field( 255 ..., 256 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 257 ) 258 principal: str | None = Field( 259 default=None, 260 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 261 ) 262 principal_type: str = Field( 263 ..., 264 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 265 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".
268class ThreadArtifactsResponseDataItemAclGrantsItem(BaseModel): 269 actions: list[str] = Field( 270 ..., 271 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 272 ) 273 principal: str | None = Field( 274 default=None, 275 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 276 ) 277 principal_type: str = Field( 278 ..., 279 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 280 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".
283class ThreadArtifactsResponseDataItemAclRemoveItem(BaseModel): 284 principal: str | None = Field( 285 default=None, 286 description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', 287 ) 288 principal_type: str = Field( 289 ..., 290 description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 291 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
The identifier of the principal to remove. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role". Omit when principal_type is "everyone".
294class ThreadArtifactsResponseDataItemAcl(BaseModel): 295 add: list[ThreadArtifactsResponseDataItemAclAddItem] | None = Field( 296 default=None, 297 description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", 298 ) 299 grants: list[ThreadArtifactsResponseDataItemAclGrantsItem] | None = Field( 300 default=None, 301 description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", 302 ) 303 remove: list[ThreadArtifactsResponseDataItemAclRemoveItem] | None = Field( 304 default=None, 305 description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", 306 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.
Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.
309class ThreadArtifactsResponseDataItemImageSource(BaseModel): 310 file: str | None = Field( 311 default=None, 312 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 313 ) 314 height: int | None = Field( 315 default=None, description="Height of the image in pixels. `null` if not known." 316 ) 317 media: str | None = Field( 318 default=None, 319 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 320 ) 321 mime_type: str | None = Field( 322 default=None, 323 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 324 ) 325 refresh_url: str | None = Field( 326 default=None, 327 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 328 ) 329 url: str | None = Field( 330 default=None, 331 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 332 ) 333 width: int | None = Field( 334 default=None, description="Width of the image in pixels. `null` if not known." 335 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
338class ThreadArtifactsResponseDataItem(BaseModel): 339 acl: ThreadArtifactsResponseDataItemAcl | None = Field( 340 default=None, 341 description="Access control list for the artifact. Contains a `grants` array where each entry specifies `principal_type`, `principal`, and `actions` (`read`, `write`). `null` when the artifact has no grants or the viewer is not its owner.", 342 ) 343 agent: str | None = Field( 344 default=None, 345 description="ID of the agent that produced this artifact (`agt_...`). `null` if not agent-produced.", 346 ) 347 content_type: str | None = Field( 348 default=None, 349 description='MIME type of the current version\'s file, e.g. `"text/csv"` or `"image/png"`. `null` if no file is attached.', 350 ) 351 created_at: datetime | None = Field( 352 default=None, description="When the artifact was first created (ISO 8601)." 353 ) 354 current_version: str | None = Field( 355 default=None, 356 description="ID of the current (latest published) artifact version (`artv_...`). `null` if no version has been published.", 357 ) 358 description: str | None = Field( 359 default=None, 360 description="Optional longer description of the artifact's contents or purpose. `null` if not set.", 361 ) 362 file: str | None = Field( 363 default=None, 364 description="Storage file ID for the current version (`fil_...`). `null` if no file is attached.", 365 ) 366 file_name: str | None = Field( 367 default=None, 368 description='Original filename of the current version\'s file, e.g. `"output.csv"`. `null` if no file is attached.', 369 ) 370 file_url: str | None = Field( 371 default=None, 372 description="Short-lived signed URL for downloading the current version's file. `null` if no file is attached.", 373 ) 374 group_key: str | None = Field( 375 default=None, 376 description="Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Null when unset; belongs to the artifact, not a content version.", 377 ) 378 id: str = Field(..., description="Artifact ID (`art_...`).") 379 image_source: ThreadArtifactsResponseDataItemImageSource | None = Field( 380 default=None, 381 description='Image source metadata for rendering the current version\'s file inline. Present only when `content_type` starts with `"image/"`. `null` otherwise.', 382 ) 383 name: str | None = Field( 384 default=None, 385 description='Human-readable name for the artifact, e.g. `"Q2 Report"`. `null` if not set.', 386 ) 387 org: str | None = Field( 388 default=None, description="ID of the organization this artifact belongs to (`org_...`)." 389 ) 390 sandbox: str | None = Field( 391 default=None, 392 description="Identifier of the sandbox environment associated with this artifact. `null` if not sandbox-scoped.", 393 ) 394 system: bool | None = Field( 395 default=None, 396 description="True when the artifact has no user, team, or agent owner. An organization may own a system artifact.", 397 ) 398 team: str | None = Field( 399 default=None, 400 description="ID of the team that owns this artifact (`tea_...`). `null` if not team-scoped.", 401 ) 402 thread: str | None = Field( 403 default=None, 404 description="ID of the thread in which this artifact was created (`thr_...`). `null` if not thread-scoped.", 405 ) 406 updated_at: datetime | None = Field( 407 default=None, description="When the artifact record was last modified (ISO 8601)." 408 ) 409 user: str | None = Field( 410 default=None, 411 description="ID of the user who created this artifact (`usr_...`). `null` if not user-scoped.", 412 ) 413 version: int | None = Field( 414 default=None, 415 description="Current version number of the artifact. Increments each time a new version is published.", 416 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Access control list for the artifact. Contains a grants array where each entry specifies principal_type, principal, and actions (read, write). null when the artifact has no grants or the viewer is not its owner.
ID of the agent that produced this artifact (agt_...). null if not agent-produced.
MIME type of the current version's file, e.g. "text/csv" or "image/png". null if no file is attached.
ID of the current (latest published) artifact version (artv_...). null if no version has been published.
Optional longer description of the artifact's contents or purpose. null if not set.
Storage file ID for the current version (fil_...). null if no file is attached.
Original filename of the current version's file, e.g. "output.csv". null if no file is attached.
Short-lived signed URL for downloading the current version's file. null if no file is attached.
Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Null when unset; belongs to the artifact, not a content version.
Image source metadata for rendering the current version's file inline. Present only when content_type starts with "image/". null otherwise.
Identifier of the sandbox environment associated with this artifact. null if not sandbox-scoped.
True when the artifact has no user, team, or agent owner. An organization may own a system artifact.
ID of the thread in which this artifact was created (thr_...). null if not thread-scoped.
419class ThreadArtifactsResponse(BaseModel): 420 """ 421 Successful response 422 """ 423 424 data: list[ThreadArtifactsResponseDataItem] = Field( 425 ..., description="Array of artifact objects produced during the thread's conversation." 426 )
Successful response
429class ThreadMessagesResponseDataMessagesItemAclAddItem(BaseModel): 430 actions: list[str] = Field( 431 ..., 432 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 433 ) 434 principal: str | None = Field( 435 default=None, 436 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 437 ) 438 principal_type: str = Field( 439 ..., 440 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 441 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".
444class ThreadMessagesResponseDataMessagesItemAclGrantsItem(BaseModel): 445 actions: list[str] = Field( 446 ..., 447 description='Array of action strings the principal is permitted to perform, e.g. `["read", "write"]`. Must contain at least one entry.', 448 ) 449 principal: str | None = Field( 450 default=None, 451 description='The identifier of the principal. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`; omit entirely when `principal_type` is `"everyone"`.', 452 ) 453 principal_type: str = Field( 454 ..., 455 description='The kind of principal receiving the grant. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 456 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.
The identifier of the principal. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role"; omit entirely when principal_type is "everyone".
459class ThreadMessagesResponseDataMessagesItemAclRemoveItem(BaseModel): 460 principal: str | None = Field( 461 default=None, 462 description='The identifier of the principal to remove. A string ID for `"user"`, `"team"`, `"org"`, and `"agent"` types; one of `"admin"`, `"member"`, or `"viewer"` for `"org_role"`. Omit when `principal_type` is `"everyone"`.', 463 ) 464 principal_type: str = Field( 465 ..., 466 description='The kind of principal to remove. One of `"user"`, `"team"`, `"org"`, `"org_role"`, `"agent"`, or `"everyone"`.', 467 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
The identifier of the principal to remove. A string ID for "user", "team", "org", and "agent" types; one of "admin", "member", or "viewer" for "org_role". Omit when principal_type is "everyone".
470class ThreadMessagesResponseDataMessagesItemAcl(BaseModel): 471 add: list[ThreadMessagesResponseDataMessagesItemAclAddItem] | None = Field( 472 default=None, 473 description="Patch mode: grants to add or merge into the existing list. Cannot be combined with `grants`.", 474 ) 475 grants: list[ThreadMessagesResponseDataMessagesItemAclGrantsItem] | None = Field( 476 default=None, 477 description="Replace mode: the complete new list of grants that replaces all existing entries. Send an empty array (`[]`) to clear all grants. Cannot be combined with `add` or `remove`.", 478 ) 479 remove: list[ThreadMessagesResponseDataMessagesItemAclRemoveItem] | None = Field( 480 default=None, 481 description="Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with `grants`.", 482 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.
Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.
485class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(BaseModel): 486 file: str | None = Field( 487 default=None, 488 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 489 ) 490 height: int | None = Field( 491 default=None, description="Height of the image in pixels. `null` if not known." 492 ) 493 media: str | None = Field( 494 default=None, 495 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 496 ) 497 mime_type: str | None = Field( 498 default=None, 499 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 500 ) 501 refresh_url: str | None = Field( 502 default=None, 503 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 504 ) 505 url: str | None = Field( 506 default=None, 507 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 508 ) 509 width: int | None = Field( 510 default=None, description="Width of the image in pixels. `null` if not known." 511 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
514class ThreadMessagesResponseDataMessagesItemActorsItem(BaseModel): 515 alias: str | None = Field( 516 default=None, 517 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 518 ) 519 id: str | None = Field( 520 default=None, 521 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 522 ) 523 name: str | None = Field( 524 default=None, 525 description="Display name of the actor shown in the UI. `null` if no name is set.", 526 ) 527 profile_picture: ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture | None = Field( 528 default=None, 529 description="Profile picture for the actor. `null` if the actor has no profile picture.", 530 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
533class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(BaseModel): 534 file: str | None = Field( 535 default=None, 536 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 537 ) 538 height: int | None = Field( 539 default=None, description="Height of the image in pixels. `null` if not known." 540 ) 541 media: str | None = Field( 542 default=None, 543 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 544 ) 545 mime_type: str | None = Field( 546 default=None, 547 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 548 ) 549 refresh_url: str | None = Field( 550 default=None, 551 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 552 ) 553 url: str | None = Field( 554 default=None, 555 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 556 ) 557 width: int | None = Field( 558 default=None, description="Width of the image in pixels. `null` if not known." 559 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
562class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(BaseModel): 563 file: str | None = Field( 564 default=None, 565 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 566 ) 567 height: int | None = Field( 568 default=None, description="Height of the image in pixels. `null` if not known." 569 ) 570 media: str | None = Field( 571 default=None, 572 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 573 ) 574 mime_type: str | None = Field( 575 default=None, 576 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 577 ) 578 refresh_url: str | None = Field( 579 default=None, 580 description="Endpoint URL you can call to obtain a fresh signed `url` when the current one has expired. `null` if the URL does not require refreshing.", 581 ) 582 url: str | None = Field( 583 default=None, 584 description="Signed or public URL for downloading the image. May be time-limited; use `refresh_url` to obtain a new URL when this one expires.", 585 ) 586 width: int | None = Field( 587 default=None, description="Width of the image in pixels. `null` if not known." 588 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
591class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(BaseModel): 592 byte_size: int | None = Field(default=None, description="Size of the stored bytes.") 593 content_type: str | None = Field( 594 default=None, 595 description='MIME type of this variant\'s file (e.g., `"image/jpeg"`, `"video/mp4"`). `null` if the file is not loaded.', 596 ) 597 created_at: datetime | None = Field( 598 default=None, description="When this variant was created (ISO 8601)." 599 ) 600 duration_ms: int | None = Field( 601 default=None, 602 description="Client-declared video duration in milliseconds; not server-probed.", 603 ) 604 file: str | None = Field( 605 default=None, 606 description="ID of the underlying storage file that backs this variant (`fil_...`).", 607 ) 608 filename: str | None = Field( 609 default=None, 610 description="Original filename of the uploaded file for this variant. `null` if the file is not loaded.", 611 ) 612 height: int | None = Field( 613 default=None, description="Height of this variant in pixels. `null` if not recorded." 614 ) 615 id: str = Field(..., description="Media variant ID (`mvr_...`).") 616 image_source: ( 617 ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource | None 618 ) = Field( 619 default=None, 620 description="Resolved image delivery metadata for this variant, including dimensions and CDN URL. `null` for non-image content types.", 621 ) 622 sha256: str | None = Field(default=None, description="Lowercase SHA-256 of the stored bytes.") 623 updated_at: datetime | None = Field( 624 default=None, description="When this variant was last updated (ISO 8601)." 625 ) 626 url: str | None = Field( 627 default=None, 628 description="Signed download URL for this variant, resolved at request time. `null` if the file is unavailable.", 629 ) 630 url_expires_at: datetime | None = Field( 631 default=None, description="Expiry of this variant's playable URL." 632 ) 633 variant_key: str | None = Field( 634 default=None, 635 description='Identifier for this variant\'s processing tier. Common values include `"original"` (the unmodified upload) and `"thumbnail"` (a resized preview).', 636 ) 637 width: int | None = Field( 638 default=None, description="Width of this variant in pixels. `null` if not recorded." 639 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
MIME type of this variant's file (e.g., "image/jpeg", "video/mp4"). null if the file is not loaded.
Original filename of the uploaded file for this variant. null if the file is not loaded.
Resolved image delivery metadata for this variant, including dimensions and CDN URL. null for non-image content types.
Signed download URL for this variant, resolved at request time. null if the file is unavailable.
642class ThreadMessagesResponseDataMessagesItemAttachmentsItem(BaseModel): 643 content_type: str | None = Field( 644 default=None, 645 description='MIME type of the attached file, e.g. `"image/png"` or `"application/pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 646 ) 647 description: str | None = Field( 648 default=None, 649 description="Short description. The page meta-description for `scraped_link`, the artifact description for `artifact`, and the task description for `task` types. `null` on other types.", 650 ) 651 filename: str | None = Field( 652 default=None, 653 description='Original filename of the attached file, e.g. `"report.pdf"`. Present on `file`, `artifact`, and `media` types. `null` otherwise.', 654 ) 655 height: int | None = Field( 656 default=None, 657 description="Height in pixels of the media item. Present on `media` type only. `null` otherwise.", 658 ) 659 id: str = Field(..., description="Unique identifier for this attachment within the message.") 660 image_height: int | None = Field( 661 default=None, 662 description="Height in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 663 ) 664 image_source: ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource | None = Field( 665 default=None, 666 description="Image source metadata for inline rendering. Present on `file`, `scraped_link`, `artifact`, and `media` types when the content is an image. `null` otherwise.", 667 ) 668 image_url: str | None = Field( 669 default=None, 670 description="URL of the preview image extracted from the scraped page. Present on `scraped_link` type only. `null` otherwise.", 671 ) 672 image_width: int | None = Field( 673 default=None, 674 description="Width in pixels of the scraped preview image. Present on `scraped_link` type only. `null` otherwise.", 675 ) 676 key: str | None = Field( 677 default=None, 678 description='For `structured_data` type, what the data is about as set by the sender (for example `"pr:14963"`), copied from the record so it can be read without `object`. Not unique. `null` when unset and on other types.', 679 ) 680 media_type: str | None = Field( 681 default=None, 682 description='The media category, e.g. `"video"` or `"audio"`. Present on `media` type only; omitted otherwise.', 683 ) 684 name: str | None = Field( 685 default=None, 686 description="Display name of the media item. Present on `media` type only. `null` otherwise.", 687 ) 688 object: dict[str, Any] | None = Field( 689 default=None, 690 description="The full embedded object payload. For `task` type, contains the task record. For `action` type, contains the action definition. For `chart` type, contains the chart with its inline `spec`. For `structured_data` type, contains the inline `data` and the `schema_url` or `schema_config` naming its JSON Schema. Omitted on other types.", 691 ) 692 title: str | None = Field( 693 default=None, 694 description="Display title. The page title for `scraped_link`, the artifact name for `artifact`, and the task title for `task` types. `null` on other types.", 695 ) 696 type: str = Field( 697 ..., 698 description='The attachment type. One of `"file"`, `"scraped_link"`, `"artifact"`, `"task"`, `"media"`, `"action"`, `"chart"`, or `"structured_data"`. Determines which additional fields are present.', 699 ) 700 url: str | None = Field( 701 default=None, 702 description="URL to access the resource. A signed download URL for `file` and `artifact` types; the original URL for `scraped_link`; a media playback URL for `media`. `null` on `task` and `action` types.", 703 ) 704 variants: list[ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem] | None = ( 705 Field( 706 default=None, 707 description="Array of available encoding variants for the media item (e.g. different resolutions). Present on `media` type only; omitted otherwise.", 708 ) 709 ) 710 version: int | None = Field( 711 default=None, 712 description="Version number of the attached artifact at the time of attachment. Present on `artifact` type only. `null` otherwise.", 713 ) 714 width: int | None = Field( 715 default=None, 716 description="Width in pixels of the media item. Present on `media` type only. `null` otherwise.", 717 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
MIME type of the attached file, e.g. "image/png" or "application/pdf". Present on file, artifact, and media types. null otherwise.
Short description. The page meta-description for scraped_link, the artifact description for artifact, and the task description for task types. null on other types.
Original filename of the attached file, e.g. "report.pdf". Present on file, artifact, and media types. null otherwise.
Height in pixels of the media item. Present on media type only. null otherwise.
Height in pixels of the scraped preview image. Present on scraped_link type only. null otherwise.
Image source metadata for inline rendering. Present on file, scraped_link, artifact, and media types when the content is an image. null otherwise.
URL of the preview image extracted from the scraped page. Present on scraped_link type only. null otherwise.
Width in pixels of the scraped preview image. Present on scraped_link type only. null otherwise.
For structured_data type, what the data is about as set by the sender (for example "pr:14963"), copied from the record so it can be read without object. Not unique. null when unset and on other types.
The media category, e.g. "video" or "audio". Present on media type only; omitted otherwise.
The full embedded object payload. For task type, contains the task record. For action type, contains the action definition. For chart type, contains the chart with its inline spec. For structured_data type, contains the inline data and the schema_url or schema_config naming its JSON Schema. Omitted on other types.
Display title. The page title for scraped_link, the artifact name for artifact, and the task title for task types. null on other types.
The attachment type. One of "file", "scraped_link", "artifact", "task", "media", "action", "chart", or "structured_data". Determines which additional fields are present.
URL to access the resource. A signed download URL for file and artifact types; the original URL for scraped_link; a media playback URL for media. null on task and action types.
Array of available encoding variants for the media item (e.g. different resolutions). Present on media type only; omitted otherwise.
720class ThreadMessagesResponseDataMessagesItemContextItem(BaseModel): 721 attributes: dict[str, Any] | None = Field( 722 default=None, 723 description="Scalar key-value fields describing the context, such as route, repository, or pull-request number.", 724 ) 725 content: str | None = Field( 726 default=None, 727 description="Optional context body. The model receives it as escaped XML data, not a system instruction.", 728 ) 729 title: str | None = Field( 730 default=None, description="Optional human-readable label for this context block." 731 ) 732 type: str = Field( 733 ..., 734 description="Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.", 735 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Scalar key-value fields describing the context, such as route, repository, or pull-request number.
738class ThreadMessagesResponseDataMessagesItemReactionsItem(BaseModel): 739 payload: dict[str, Any] | None = Field( 740 default=None, 741 description='Type-specific reaction data. For `"emoji_reaction"` reactions, contains an `emoji` key with the Unicode emoji string (e.g., `" "`).', 742 ) 743 type: str = Field( 744 ..., 745 description='Reaction type identifier. Currently always `"emoji_reaction"` for emoji-based reactions.', 746 ) 747 user: str | None = Field( 748 default=None, description="Public ID of the user who added the reaction (`usr_...`)." 749 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Type-specific reaction data. For "emoji_reaction" reactions, contains an emoji key with the Unicode emoji string (e.g., " ").
752class ThreadMessagesResponseDataMessagesItem(BaseModel): 753 acl: ThreadMessagesResponseDataMessagesItemAcl | None = Field( 754 default=None, 755 description="Access control list for private messages (grants with `read` action). Only returned to resource owners (and privileged/org-admin viewers) via server-side `field_redactions: [acl: :owner]`; `null` for everyone else.", 756 ) 757 actors: list[ThreadMessagesResponseDataMessagesItemActorsItem] | None = Field( 758 default=None, 759 description="Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.", 760 ) 761 agent: str | None = Field( 762 default=None, 763 description="ID of the agent user that sent this message (`agi_...`). `null` for messages sent by human users.", 764 ) 765 agent_mode: Literal["cli", "embedded"] | None = Field( 766 default=None, 767 description="Local agent execution mode for this message. One of `cli`, `embedded`, or `null` when the message was not created by a local agent execution path.", 768 ) 769 attachments: list[ThreadMessagesResponseDataMessagesItemAttachmentsItem] | None = Field( 770 default=None, 771 description="Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.", 772 ) 773 branched_thread: str | None = Field( 774 default=None, 775 description="ID of the thread that was branched from this message (`thr_...`). `null` if this message has not spawned a branch thread.", 776 ) 777 content: str | None = Field( 778 default=None, 779 description="Text content of the message. `null` for messages that contain only attachments.", 780 ) 781 context: list[ThreadMessagesResponseDataMessagesItemContextItem] | None = Field( 782 default=None, 783 description="Immutable structured context captured when the message was posted. Each entry has `type`, optional `title` and `content`, and scalar `attributes`. Always present; defaults to an empty array. Context is delivered to agents as escaped XML data, not as system instructions.", 784 ) 785 created_at: str | None = Field( 786 default=None, description="When the message was posted (ISO 8601)." 787 ) 788 has_replies: bool | None = Field( 789 default=None, 790 description="Whether this message has at least one reply. Only present when explicitly requested or computed by the server.", 791 ) 792 id: str = Field(..., description="Message ID (`msg_...`).") 793 idempotency_key: str | None = Field( 794 default=None, 795 description="Client-supplied idempotency key used to deduplicate message sends. `null` if the sender did not provide one.", 796 ) 797 is_deleted: bool | None = Field( 798 default=None, 799 description="Whether this message is a deletion tombstone. `true` only on the `message_updated` broadcast emitted when a message is deleted: the original content is replaced with a placeholder and the message no longer exists on the server. Always `false` for live messages.", 800 ) 801 legacy_agent: str | None = Field( 802 default=None, 803 description="Identifier of the legacy chat agent that sent this message, if applicable. `null` for messages sent by users or modern agent users.", 804 ) 805 metadata: dict[str, Any] | None = Field( 806 default=None, 807 description="Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.", 808 ) 809 org: str | None = Field( 810 default=None, description="ID of the organization that owns this message (`org_...`)." 811 ) 812 reactions: list[ThreadMessagesResponseDataMessagesItemReactionsItem] | None = Field( 813 default=None, 814 description="Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.", 815 ) 816 rendering_mode: str | None = Field( 817 default=None, 818 description='Display hint for how the message should be rendered. One of `"reply"`, `"direct"`, or `"inline"`. `null` for user-authored messages, which are always rendered as standard replies.', 819 ) 820 replies: list[dict[str, Any]] | None = Field( 821 default=None, 822 description="Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.", 823 ) 824 replies_after_cursor: str | None = Field( 825 default=None, 826 description="Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.", 827 ) 828 replies_before_cursor: str | None = Field( 829 default=None, 830 description="Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.", 831 ) 832 reply_count: int | None = Field( 833 default=None, 834 description="Total number of direct replies to this message. Only present when explicitly requested or computed by the server.", 835 ) 836 reply_to: dict[str, Any] | None = Field( 837 default=None, 838 description="The parent message this message is a reply to, expanded as a full message object when loaded. `null` if this is a top-level message or the association is not preloaded.", 839 ) 840 root_message_id: str | None = Field( 841 default=None, 842 description="ID of the root message in this reply chain (`msg_...`). `null` for a top-level message. The value is persisted when the reply is created, so callers can correlate a multi-turn session without walking parent messages.", 843 ) 844 sandbox: str | None = Field( 845 default=None, 846 description="ID of the developer sandbox this message belongs to (`dsb_...`). `null` for non-sandbox messages.", 847 ) 848 team: str | None = Field( 849 default=None, 850 description="ID of the team this message is scoped to (`tem_...`). `null` if the message is not team-scoped.", 851 ) 852 thread: str | None = Field( 853 default=None, description="ID of the thread this message belongs to (`thr_...`)." 854 ) 855 type: str | None = Field( 856 default=None, 857 description="Optional client-defined classification for the message (for example `note` or `status`). Free-form string up to 64 characters. The value `system` is reserved for platform-authored messages and cannot be set by clients. `null` when unset.", 858 ) 859 user: str | dict[str, Any] | None = Field( 860 default=None, 861 description="The human user who sent this message. Returns a public ID string (`usr_...`) when the association is not preloaded, or an expanded user object when it is. `null` for messages sent by agents.", 862 ) 863 visibility: Literal["default", "private"] | None = Field( 864 default=None, 865 description="Message-level visibility. `default` is visible to anyone who can see the parent thread. `private` is restricted to the sender and explicit ACL `read` grantees.", 866 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Access control list for private messages (grants with read action). Only returned to resource owners (and privileged/org-admin viewers) via server-side field_redactions: [acl: :owner]; null for everyone else.
Resolved actor descriptors for the message sender, combining identity and display metadata. Always contains exactly one entry.
ID of the agent user that sent this message (agi_...). null for messages sent by human users.
Local agent execution mode for this message. One of cli, embedded, or null when the message was not created by a local agent execution path.
Files, links, tasks, media, artifacts, and actions attached to this message. Empty array if there are no attachments.
ID of the thread that was branched from this message (thr_...). null if this message has not spawned a branch thread.
Text content of the message. null for messages that contain only attachments.
Whether this message has at least one reply. Only present when explicitly requested or computed by the server.
Client-supplied idempotency key used to deduplicate message sends. null if the sender did not provide one.
Whether this message is a deletion tombstone. true only on the message_updated broadcast emitted when a message is deleted: the original content is replaced with a placeholder and the message no longer exists on the server. Always false for live messages.
Identifier of the legacy chat agent that sent this message, if applicable. null for messages sent by users or modern agent users.
Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.
Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.
Display hint for how the message should be rendered. One of "reply", "direct", or "inline". null for user-authored messages, which are always rendered as standard replies.
Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.
Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.
Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.
Total number of direct replies to this message. Only present when explicitly requested or computed by the server.
The parent message this message is a reply to, expanded as a full message object when loaded. null if this is a top-level message or the association is not preloaded.
ID of the root message in this reply chain (msg_...). null for a top-level message. The value is persisted when the reply is created, so callers can correlate a multi-turn session without walking parent messages.
ID of the developer sandbox this message belongs to (dsb_...). null for non-sandbox messages.
ID of the team this message is scoped to (tem_...). null if the message is not team-scoped.
Optional client-defined classification for the message (for example note or status). Free-form string up to 64 characters. The value system is reserved for platform-authored messages and cannot be set by clients. null when unset.
869class ThreadMessagesResponseData(BaseModel): 870 after_cursor: str | None = Field( 871 default=None, 872 description="Opaque cursor to pass as `after` to retrieve the page of messages newer than this result set. `null` when there are no later messages.", 873 ) 874 anchor: str | None = Field( 875 default=None, 876 description="Message ID used as the anchor for a windowed query. `null` for ordinary cursor pagination.", 877 ) 878 before_cursor: str | None = Field( 879 default=None, 880 description="Opaque cursor to pass as `before` to retrieve the page of messages older than this result set. `null` when there are no earlier messages.", 881 ) 882 messages: list[ThreadMessagesResponseDataMessagesItem] = Field( 883 ..., description="Ordered array of message objects for this page of results." 884 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Opaque cursor to pass as after to retrieve the page of messages newer than this result set. null when there are no later messages.
Message ID used as the anchor for a windowed query. null for ordinary cursor pagination.
Opaque cursor to pass as before to retrieve the page of messages older than this result set. null when there are no earlier messages.
887class ThreadMessagesResponse(BaseModel): 888 """ 889 Successful response 890 """ 891 892 data: ThreadMessagesResponseData = Field( 893 ..., 894 description="Pagination envelope containing the messages for this page along with cursors for adjacent pages.", 895 )
Successful response
898class ThreadSearchResponseDataItem(BaseModel): 899 agent: str | None = Field( 900 default=None, 901 description="Agent sender ID (`agi_...`), or `null` when a human sent the message.", 902 ) 903 content: str = Field( 904 ..., 905 description="A bounded snippet around the first matching occurrence (at most 240 characters).", 906 ) 907 created_at: datetime = Field(..., description="When the message was posted.") 908 evidence: dict[str, Any] = Field( 909 ..., 910 description="Bounded, allowlisted structured-post evidence such as source, lifecycle type, references, repository context, and addressee. Empty for ordinary messages.", 911 ) 912 id: str = Field(..., description="Message ID (`msg_...`).") 913 similarity_score: float | None = Field( 914 default=None, 915 description="Cosine similarity to the query when the result participated in embedding search, or `null` in text mode and for text-only hybrid matches.", 916 ) 917 user: str | None = Field( 918 default=None, 919 description="Human sender ID (`usr_...`), or `null` when an agent sent the message.", 920 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
A bounded snippet around the first matching occurrence (at most 240 characters).
Bounded, allowlisted structured-post evidence such as source, lifecycle type, references, repository context, and addressee. Empty for ordinary messages.
923class ThreadSearchResponse(BaseModel): 924 """ 925 Successful response 926 """ 927 928 after_cursor: str | None = Field( 929 default=None, 930 description="Text-mode cursor for the next page of newer matches, or `null` for ranked modes and empty pages.", 931 ) 932 before_cursor: str | None = Field( 933 default=None, 934 description="Text-mode cursor for the next page of older matches, or `null` for ranked modes and empty pages.", 935 ) 936 data: list[ThreadSearchResponseDataItem] = Field( 937 ..., 938 description="Matching messages ordered newest first in text mode and by relevance in embedding or hybrid mode.", 939 ) 940 has_more: bool = Field( 941 ..., description="`true` when at least one additional visible match exists." 942 )
Successful response
Text-mode cursor for the next page of newer matches, or null for ranked modes and empty pages.
Text-mode cursor for the next page of older matches, or null for ranked modes and empty pages.
945class ThreadTrajectoriesResponseDataItem(BaseModel): 946 agent_message: str | None = Field( 947 default=None, 948 description="ID of the agent-authored reply message (`msg_...`). `null` if the trajectory has not yet produced a response message.", 949 ) 950 created_at: str | None = Field( 951 default=None, description="When this trajectory link was created (ISO 8601)." 952 ) 953 id: str = Field(..., description="Thread message trajectory ID (`tmt_...`).") 954 org: str | None = Field( 955 default=None, description="ID of the organization this trajectory belongs to (`org_...`)." 956 ) 957 sandbox: str | None = Field( 958 default=None, 959 description="ID of the sandbox environment in which this trajectory was produced (`dsb_...`). `null` in production contexts.", 960 ) 961 thread: str | None = Field( 962 default=None, description="ID of the thread containing the linked messages (`thr_...`)." 963 ) 964 trajectory: str | None = Field( 965 default=None, 966 description="ID of the AI trajectory record that captures the full model interaction for this exchange (`trj_...`).", 967 ) 968 updated_at: str | None = Field( 969 default=None, description="When this trajectory link was last modified (ISO 8601)." 970 ) 971 user_message: str | None = Field( 972 default=None, 973 description="ID of the user-authored message that triggered the agent response (`msg_...`). `null` if the agent turn was not preceded by a user message.", 974 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the agent-authored reply message (msg_...). null if the trajectory has not yet produced a response message.
ID of the sandbox environment in which this trajectory was produced (dsb_...). null in production contexts.
977class ThreadTrajectoriesResponse(BaseModel): 978 """ 979 Successful response 980 """ 981 982 after_cursor: str | None = Field( 983 default=None, 984 description="Opaque cursor to pass as `after_cursor` to retrieve the next page. `null` when no further pages exist.", 985 ) 986 before_cursor: str | None = Field( 987 default=None, 988 description="Opaque cursor to pass as `before_cursor` to retrieve the previous page. `null` when this is the first page.", 989 ) 990 data: list[ThreadTrajectoriesResponseDataItem] = Field( 991 ..., 992 description="Array of thread message trajectory objects for the current page. Empty when no trajectories match the query.", 993 )
Successful response
Opaque cursor to pass as after_cursor to retrieve the next page. null when no further pages exist.
Opaque cursor to pass as before_cursor to retrieve the previous page. null when this is the first page.
996class AsyncComputerResource: 997 def __init__(self, http: HttpClient): 998 self._http = http 999 1000 async def list(self, thread: str) -> AgentComputerListResponse: 1001 """ 1002 List a thread's computers 1003 Returns all live computers in the visible thread, oldest first, without pagination. 1004 1005 Args: 1006 thread: Thread ID (`thr_...`). 1007 1008 Returns: 1009 The thread's live computers. 1010 """ 1011 return await self._http.request( 1012 f"/api/v1/threads/{thread}/computers", 1013 response_type=AgentComputerListResponse, 1014 ) 1015 1016 async def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: 1017 """ 1018 Provision a computer for a thread 1019 Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. 1020 1021 Args: 1022 thread: Thread ID (`thr_...`). 1023 input: Request body. 1024 input.acl: Initial access control list. 1025 input.config: Provider configuration; top-level provider takes precedence. 1026 input.key: Stable key unique within this thread. 1027 input.metadata: Arbitrary computer metadata. 1028 input.name: Human-readable computer name. 1029 input.provider: Compute backend: sprites (default), vercel or e2b. 1030 input.region: Provider region; defaults to iad. 1031 1032 Returns: 1033 The newly created computer. Returns HTTP 201. 1034 """ 1035 return await self._http.request( 1036 f"/api/v1/threads/{thread}/computers", 1037 method="POST", 1038 body=input, 1039 response_type=AgentComputer, 1040 )
1000 async def list(self, thread: str) -> AgentComputerListResponse: 1001 """ 1002 List a thread's computers 1003 Returns all live computers in the visible thread, oldest first, without pagination. 1004 1005 Args: 1006 thread: Thread ID (`thr_...`). 1007 1008 Returns: 1009 The thread's live computers. 1010 """ 1011 return await self._http.request( 1012 f"/api/v1/threads/{thread}/computers", 1013 response_type=AgentComputerListResponse, 1014 )
List a thread's computers Returns all live computers in the visible thread, oldest first, without pagination.
Arguments:
- thread: Thread ID (
thr_...).
Returns:
The thread's live computers.
1016 async def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: 1017 """ 1018 Provision a computer for a thread 1019 Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. 1020 1021 Args: 1022 thread: Thread ID (`thr_...`). 1023 input: Request body. 1024 input.acl: Initial access control list. 1025 input.config: Provider configuration; top-level provider takes precedence. 1026 input.key: Stable key unique within this thread. 1027 input.metadata: Arbitrary computer metadata. 1028 input.name: Human-readable computer name. 1029 input.provider: Compute backend: sprites (default), vercel or e2b. 1030 input.region: Provider region; defaults to iad. 1031 1032 Returns: 1033 The newly created computer. Returns HTTP 201. 1034 """ 1035 return await self._http.request( 1036 f"/api/v1/threads/{thread}/computers", 1037 method="POST", 1038 body=input, 1039 response_type=AgentComputer, 1040 )
Provision a computer for a thread Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer.
Arguments:
- thread: Thread ID (
thr_...). - input: Request body.
- input.acl: Initial access control list.
- input.config: Provider configuration; top-level provider takes precedence.
- input.key: Stable key unique within this thread.
- input.metadata: Arbitrary computer metadata.
- input.name: Human-readable computer name.
- input.provider: Compute backend: sprites (default), vercel or e2b.
- input.region: Provider region; defaults to iad.
Returns:
The newly created computer. Returns HTTP 201.
1043class AsyncThreadMemberResource: 1044 def __init__(self, http: HttpClient): 1045 self._http = http 1046 1047 async def remove(self, thread: str) -> None: 1048 """ 1049 Remove a member from a thread 1050 Removes a user or agent from the explicit roster of a private or restricted 1051 thread. Team-visible threads use implicit membership and reject individual 1052 removals. A member may remove themself; removing someone else requires 1053 permission to modify the thread. A successful removal returns HTTP 204 with 1054 no response body. 1055 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1056 if the thread or the membership record does not exist. 1057 1058 Args: 1059 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1060 1061 Returns: 1062 Empty response body. HTTP 204 on success. 1063 """ 1064 await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 1065 1066 async def list(self, thread: str) -> ThreadMemberListResponse: 1067 """ 1068 List members of a thread 1069 Returns all current user and agent members. Private and restricted threads 1070 return their explicit roster; team-visible threads return the owning team's 1071 implicit roster. The authenticated viewer must be able to see the thread. 1072 Results are returned as a flat array in the `data` field. The list is not 1073 paginated all members are returned in a single response. 1074 1075 Args: 1076 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1077 1078 Returns: 1079 Successful response 1080 """ 1081 return await self._http.request( 1082 f"/api/v1/threads/{thread}/members", 1083 response_type=ThreadMemberListResponse, 1084 ) 1085 1086 async def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember: 1087 """ 1088 Add a member to a thread 1089 Adds a user or agent to the explicit roster of a private or restricted 1090 thread. Team-visible threads use the owning team's implicit roster and reject 1091 explicit additions. On restricted threads, a team member may add themself; 1092 adding anyone else requires permission to modify the thread. 1093 Supply either `user` or `agent` depending on the value of `type`. Targets 1094 must be visible to the caller and, for an ordinary team-owned thread, must 1095 belong to the owning team. On success the membership record is returned with 1096 HTTP 201; repeated agent additions are idempotent. 1097 1098 Args: 1099 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1100 input: Request body. 1101 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1102 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1103 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1104 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1105 1106 Returns: 1107 The user or agent membership that was added to the thread. 1108 """ 1109 return await self._http.request( 1110 f"/api/v1/threads/{thread}/members", 1111 method="POST", 1112 body=input, 1113 response_type=ChatMember, 1114 )
1047 async def remove(self, thread: str) -> None: 1048 """ 1049 Remove a member from a thread 1050 Removes a user or agent from the explicit roster of a private or restricted 1051 thread. Team-visible threads use implicit membership and reject individual 1052 removals. A member may remove themself; removing someone else requires 1053 permission to modify the thread. A successful removal returns HTTP 204 with 1054 no response body. 1055 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1056 if the thread or the membership record does not exist. 1057 1058 Args: 1059 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1060 1061 Returns: 1062 Empty response body. HTTP 204 on success. 1063 """ 1064 await self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
Remove a member from a thread
Removes a user or agent from the explicit roster of a private or restricted
thread. Team-visible threads use implicit membership and reject individual
removals. A member may remove themself; removing someone else requires
permission to modify the thread. A successful removal returns HTTP 204 with
no response body.
Supply either user or agent depending on the value of type. Returns 404
if the thread or the membership record does not exist.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Empty response body. HTTP 204 on success.
1066 async def list(self, thread: str) -> ThreadMemberListResponse: 1067 """ 1068 List members of a thread 1069 Returns all current user and agent members. Private and restricted threads 1070 return their explicit roster; team-visible threads return the owning team's 1071 implicit roster. The authenticated viewer must be able to see the thread. 1072 Results are returned as a flat array in the `data` field. The list is not 1073 paginated all members are returned in a single response. 1074 1075 Args: 1076 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1077 1078 Returns: 1079 Successful response 1080 """ 1081 return await self._http.request( 1082 f"/api/v1/threads/{thread}/members", 1083 response_type=ThreadMemberListResponse, 1084 )
List members of a thread
Returns all current user and agent members. Private and restricted threads
return their explicit roster; team-visible threads return the owning team's
implicit roster. The authenticated viewer must be able to see the thread.
Results are returned as a flat array in the data field. The list is not
paginated all members are returned in a single response.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Successful response
1086 async def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember: 1087 """ 1088 Add a member to a thread 1089 Adds a user or agent to the explicit roster of a private or restricted 1090 thread. Team-visible threads use the owning team's implicit roster and reject 1091 explicit additions. On restricted threads, a team member may add themself; 1092 adding anyone else requires permission to modify the thread. 1093 Supply either `user` or `agent` depending on the value of `type`. Targets 1094 must be visible to the caller and, for an ordinary team-owned thread, must 1095 belong to the owning team. On success the membership record is returned with 1096 HTTP 201; repeated agent additions are idempotent. 1097 1098 Args: 1099 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1100 input: Request body. 1101 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1102 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1103 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1104 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1105 1106 Returns: 1107 The user or agent membership that was added to the thread. 1108 """ 1109 return await self._http.request( 1110 f"/api/v1/threads/{thread}/members", 1111 method="POST", 1112 body=input, 1113 response_type=ChatMember, 1114 )
Add a member to a thread
Adds a user or agent to the explicit roster of a private or restricted
thread. Team-visible threads use the owning team's implicit roster and reject
explicit additions. On restricted threads, a team member may add themself;
adding anyone else requires permission to modify the thread.
Supply either user or agent depending on the value of type. Targets
must be visible to the caller and, for an ordinary team-owned thread, must
belong to the owning team. On success the membership record is returned with
HTTP 201; repeated agent additions are idempotent.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from. - input: Request body.
- input.agent: Agent ID of the principal to add. Required when
typeis"agent". - input.membership_type: Role granted to the new member. One of
"owner"or"member". Defaults to"member". - input.type: Kind of principal being added. Must be
"user"or"agent". - input.user: User ID of the principal to add. Required when
typeis"user".
Returns:
The user or agent membership that was added to the thread.
1117class AsyncSettingResource: 1118 def __init__(self, http: HttpClient): 1119 self._http = http 1120 1121 async def list(self, thread: str) -> SettingListResponse: 1122 """ 1123 Retrieve thread settings 1124 Returns the current settings for the specified thread. Settings control 1125 per-thread behavior such as whether the AI agent is enabled. 1126 The authenticated user must own the thread or be a member of its workspace. 1127 If settings have never been explicitly configured, defaults are returned 1128 (for example, `agent_enabled` defaults to `true`). 1129 1130 Args: 1131 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1132 1133 Returns: 1134 Successful response 1135 """ 1136 return await self._http.request( 1137 f"/api/v1/threads/{thread}/settings", 1138 response_type=SettingListResponse, 1139 ) 1140 1141 async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1142 """ 1143 Update thread settings 1144 Updates the settings for the specified thread. Only fields included in 1145 the `settings` map are modified; omitted fields retain their current values. 1146 The authenticated user must own the thread or be a member of its workspace. 1147 Returns the full settings object reflecting the state after the update. 1148 Validation errors are returned as `422 Unprocessable Entity`. 1149 1150 Args: 1151 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1152 input: Request body. 1153 input.settings: Map of settings fields to update. Include only the keys you want to change. 1154 1155 Returns: 1156 The thread settings object after the update has been applied. 1157 """ 1158 return await self._http.request( 1159 f"/api/v1/threads/{thread}/settings", 1160 method="PUT", 1161 body=input, 1162 response_type=ThreadSettings, 1163 )
1121 async def list(self, thread: str) -> SettingListResponse: 1122 """ 1123 Retrieve thread settings 1124 Returns the current settings for the specified thread. Settings control 1125 per-thread behavior such as whether the AI agent is enabled. 1126 The authenticated user must own the thread or be a member of its workspace. 1127 If settings have never been explicitly configured, defaults are returned 1128 (for example, `agent_enabled` defaults to `true`). 1129 1130 Args: 1131 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1132 1133 Returns: 1134 Successful response 1135 """ 1136 return await self._http.request( 1137 f"/api/v1/threads/{thread}/settings", 1138 response_type=SettingListResponse, 1139 )
Retrieve thread settings
Returns the current settings for the specified thread. Settings control
per-thread behavior such as whether the AI agent is enabled.
The authenticated user must own the thread or be a member of its workspace.
If settings have never been explicitly configured, defaults are returned
(for example, agent_enabled defaults to true).
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace.
Returns:
Successful response
1141 async def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1142 """ 1143 Update thread settings 1144 Updates the settings for the specified thread. Only fields included in 1145 the `settings` map are modified; omitted fields retain their current values. 1146 The authenticated user must own the thread or be a member of its workspace. 1147 Returns the full settings object reflecting the state after the update. 1148 Validation errors are returned as `422 Unprocessable Entity`. 1149 1150 Args: 1151 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1152 input: Request body. 1153 input.settings: Map of settings fields to update. Include only the keys you want to change. 1154 1155 Returns: 1156 The thread settings object after the update has been applied. 1157 """ 1158 return await self._http.request( 1159 f"/api/v1/threads/{thread}/settings", 1160 method="PUT", 1161 body=input, 1162 response_type=ThreadSettings, 1163 )
Update thread settings
Updates the settings for the specified thread. Only fields included in
the settings map are modified; omitted fields retain their current values.
The authenticated user must own the thread or be a member of its workspace.
Returns the full settings object reflecting the state after the update.
Validation errors are returned as 422 Unprocessable Entity.
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace. - input: Request body.
- input.settings: Map of settings fields to update. Include only the keys you want to change.
Returns:
The thread settings object after the update has been applied.
1166class AsyncTagResource: 1167 def __init__(self, http: HttpClient): 1168 self._http = http 1169 1170 async def remove(self, thread: str) -> Thread: 1171 """ 1172 Remove tags from a thread 1173 Removes one or more status tags from the thread and returns the updated 1174 thread. Removing a tag the thread does not have is a no-op. 1175 Any participant of the thread a human member or an agent member may edit 1176 tags. Supply the tags to remove as repeated query parameters, e.g. 1177 `?tags[]=blocked&tags[]=needs-review`. 1178 1179 Args: 1180 thread: Thread ID (`thr_...`) to untag. 1181 1182 Returns: 1183 The thread object after the tags were removed. 1184 """ 1185 return await self._http.request( 1186 f"/api/v1/threads/{thread}/tags", 1187 method="DELETE", 1188 response_type=Thread, 1189 ) 1190 1191 async def create(self, thread: str, input: TagCreateInput) -> Thread: 1192 """ 1193 Add tags to a thread 1194 Adds one or more status tags to the thread and returns the updated thread. 1195 Any participant of the thread a human member or an agent member may edit 1196 tags; this is broader than the owner/admin permission required to update other 1197 thread fields. Adding a tag the thread already has is a no-op. Tags are 1198 normalized (trimmed and lowercased) and may contain only lowercase letters, 1199 numbers, hyphens, and underscores. 1200 1201 Args: 1202 thread: Thread ID (`thr_...`) to untag. 1203 input: Request body. 1204 input.tags: Tags to add to the thread. 1205 1206 Returns: 1207 The thread object after the tags were added. 1208 """ 1209 return await self._http.request( 1210 f"/api/v1/threads/{thread}/tags", 1211 method="POST", 1212 body=input, 1213 response_type=Thread, 1214 ) 1215 1216 async def replace(self, thread: str, input: TagReplaceInput) -> Thread: 1217 """ 1218 Replace a thread's tags 1219 Replaces the thread's entire set of status tags with the provided list and 1220 returns the updated thread. Passing an empty array clears all tags. 1221 Any participant of the thread a human member or an agent member may edit 1222 tags. Tags are normalized (trimmed and lowercased) and may contain only 1223 lowercase letters, numbers, hyphens, and underscores. 1224 1225 Args: 1226 thread: Thread ID (`thr_...`) to untag. 1227 input: Request body. 1228 input.tags: The complete set of tags for the thread. An empty array clears all tags. 1229 1230 Returns: 1231 The thread object after its tags were replaced. 1232 """ 1233 return await self._http.request( 1234 f"/api/v1/threads/{thread}/tags", 1235 method="PUT", 1236 body=input, 1237 response_type=Thread, 1238 )
1170 async def remove(self, thread: str) -> Thread: 1171 """ 1172 Remove tags from a thread 1173 Removes one or more status tags from the thread and returns the updated 1174 thread. Removing a tag the thread does not have is a no-op. 1175 Any participant of the thread a human member or an agent member may edit 1176 tags. Supply the tags to remove as repeated query parameters, e.g. 1177 `?tags[]=blocked&tags[]=needs-review`. 1178 1179 Args: 1180 thread: Thread ID (`thr_...`) to untag. 1181 1182 Returns: 1183 The thread object after the tags were removed. 1184 """ 1185 return await self._http.request( 1186 f"/api/v1/threads/{thread}/tags", 1187 method="DELETE", 1188 response_type=Thread, 1189 )
Remove tags from a thread
Removes one or more status tags from the thread and returns the updated
thread. Removing a tag the thread does not have is a no-op.
Any participant of the thread a human member or an agent member may edit
tags. Supply the tags to remove as repeated query parameters, e.g.
?tags[]=blocked&tags[]=needs-review.
Arguments:
- thread: Thread ID (
thr_...) to untag.
Returns:
The thread object after the tags were removed.
1191 async def create(self, thread: str, input: TagCreateInput) -> Thread: 1192 """ 1193 Add tags to a thread 1194 Adds one or more status tags to the thread and returns the updated thread. 1195 Any participant of the thread a human member or an agent member may edit 1196 tags; this is broader than the owner/admin permission required to update other 1197 thread fields. Adding a tag the thread already has is a no-op. Tags are 1198 normalized (trimmed and lowercased) and may contain only lowercase letters, 1199 numbers, hyphens, and underscores. 1200 1201 Args: 1202 thread: Thread ID (`thr_...`) to untag. 1203 input: Request body. 1204 input.tags: Tags to add to the thread. 1205 1206 Returns: 1207 The thread object after the tags were added. 1208 """ 1209 return await self._http.request( 1210 f"/api/v1/threads/{thread}/tags", 1211 method="POST", 1212 body=input, 1213 response_type=Thread, 1214 )
Add tags to a thread Adds one or more status tags to the thread and returns the updated thread. Any participant of the thread a human member or an agent member may edit tags; this is broader than the owner/admin permission required to update other thread fields. Adding a tag the thread already has is a no-op. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.
Arguments:
- thread: Thread ID (
thr_...) to untag. - input: Request body.
- input.tags: Tags to add to the thread.
Returns:
The thread object after the tags were added.
1216 async def replace(self, thread: str, input: TagReplaceInput) -> Thread: 1217 """ 1218 Replace a thread's tags 1219 Replaces the thread's entire set of status tags with the provided list and 1220 returns the updated thread. Passing an empty array clears all tags. 1221 Any participant of the thread a human member or an agent member may edit 1222 tags. Tags are normalized (trimmed and lowercased) and may contain only 1223 lowercase letters, numbers, hyphens, and underscores. 1224 1225 Args: 1226 thread: Thread ID (`thr_...`) to untag. 1227 input: Request body. 1228 input.tags: The complete set of tags for the thread. An empty array clears all tags. 1229 1230 Returns: 1231 The thread object after its tags were replaced. 1232 """ 1233 return await self._http.request( 1234 f"/api/v1/threads/{thread}/tags", 1235 method="PUT", 1236 body=input, 1237 response_type=Thread, 1238 )
Replace a thread's tags Replaces the thread's entire set of status tags with the provided list and returns the updated thread. Passing an empty array clears all tags. Any participant of the thread a human member or an agent member may edit tags. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.
Arguments:
- thread: Thread ID (
thr_...) to untag. - input: Request body.
- input.tags: The complete set of tags for the thread. An empty array clears all tags.
Returns:
The thread object after its tags were replaced.
1241class AsyncThreadResource: 1242 def __init__(self, http: HttpClient): 1243 self._http = http 1244 self.computers = AsyncComputerResource(http) 1245 self.members = AsyncThreadMemberResource(http) 1246 self.settings = AsyncSettingResource(http) 1247 self.tags = AsyncTagResource(http) 1248 1249 async def delete(self, thread: str) -> None: 1250 """ 1251 Delete a thread 1252 Permanently deletes a thread and all of its messages and artifacts. This action 1253 cannot be undone. 1254 The authenticated user must own the thread or be an owner of the team the thread 1255 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1256 1257 Args: 1258 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1259 1260 Returns: 1261 Empty response on successful deletion. 1262 """ 1263 await self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 1264 1265 async def get(self, thread: str) -> Thread: 1266 """ 1267 Retrieve a thread 1268 Returns the full thread record for the given thread ID. The authenticated user 1269 must own the thread or be a member of the workspace it belongs to. 1270 Use this endpoint to fetch the current state of a single thread, including its 1271 title, description, and metadata. To list many threads, use the list endpoint 1272 with cursor-based pagination. 1273 1274 Args: 1275 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1276 1277 Returns: 1278 The requested thread object. 1279 """ 1280 return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 1281 1282 async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1283 """ 1284 Update a thread 1285 Updates one or more mutable properties of the specified thread and returns 1286 the full thread object with the applied changes. Only the fields you provide 1287 are modified; omitted fields retain their current values. 1288 If `profile_picture` is supplied, the image is uploaded before the other 1289 fields are saved, after all ordinary thread fields have passed validation. 1290 Supplying invalid base64 picture data returns 422 and no other fields are 1291 updated. 1292 Visibility can only widen: `private` may become `restricted` or `team`, and 1293 `restricted` may become `team`. The authenticated viewer must have 1294 permission to modify the thread. 1295 Mirror-thread titles, descriptions, and notification state remain editable 1296 by privileged app viewers. Mirror metadata, visibility, and membership are 1297 provider-managed and cannot be changed through this endpoint. 1298 1299 Args: 1300 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1301 input: Request body. 1302 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1303 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1304 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1305 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1306 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1307 input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed. 1308 1309 Returns: 1310 The thread object after the update has been applied. 1311 """ 1312 return await self._http.request( 1313 f"/api/v1/threads/{thread}", 1314 method="PUT", 1315 body=input, 1316 response_type=Thread, 1317 ) 1318 1319 async def agents(self, thread: str) -> ThreadAgentsResponse: 1320 """ 1321 List agents in a thread 1322 Returns the agents participating in the specified thread. Only personal user 1323 threads (threads owned by a single user, not a team) expose agents through 1324 this endpoint; requests for team threads return 404. 1325 The authenticated user must have visibility into the thread. Each agent entry 1326 includes display information such as name and profile picture. Thread-level 1327 overrides (e.g. a custom name or profile picture set for this thread) take 1328 precedence over the agent's default values. When the caller is the thread 1329 owner, each entry also includes an `agent_config` object describing the 1330 agent's message policy and context configuration. 1331 1332 Args: 1333 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1334 1335 Returns: 1336 Successful response 1337 """ 1338 return await self._http.request( 1339 f"/api/v1/threads/{thread}/agents", 1340 response_type=ThreadAgentsResponse, 1341 ) 1342 1343 async def artifacts( 1344 self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None 1345 ) -> ThreadArtifactsResponse: 1346 """ 1347 List artifacts for a thread 1348 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1349 structured outputs such as code files, documents, or generated assets created 1350 by the AI agent in response to messages in the thread. 1351 The authenticated user must have access to the specified thread. Results are 1352 returned in a single page; there is no cursor-based pagination for this endpoint. 1353 1354 Args: 1355 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1356 group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match. 1357 group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. 1358 1359 Returns: 1360 Successful response 1361 """ 1362 query: dict[str, object] = {} 1363 if group_key is not None: 1364 query["group_key"] = group_key 1365 if group_key_prefix is not None: 1366 query["group_key_prefix"] = group_key_prefix 1367 return await self._http.request( 1368 f"/api/v1/threads/{thread}/artifacts", 1369 query=query, 1370 response_type=ThreadArtifactsResponse, 1371 ) 1372 1373 async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 1374 """ 1375 Mark a thread as read 1376 Records that a user has read up to a specific message in the thread. Unread 1377 indicators and badge counts are cleared up to the specified message. 1378 You must supply exactly one of `last_read_message` or `use_latest_message`. 1379 Omitting both returns 400. If `use_latest_message` is `true` and the thread 1380 has no messages, the request succeeds silently with no state change. 1381 For server-to-server (S2S) requests where no user identity is present in the 1382 token, the `user` param is required to identify whose read state to update. 1383 1384 Args: 1385 thread: Thread ID (`thr_...`). The thread to mark as read. 1386 input: Request body. 1387 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 1388 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 1389 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 1390 1391 Returns: 1392 Empty response on success. 1393 """ 1394 await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 1395 1396 async def messages( 1397 self, 1398 thread: str, 1399 *, 1400 before_cursor: str | None = None, 1401 after_cursor: str | None = None, 1402 metadata: dict[str, Any] | None = None, 1403 limit: int | None = None, 1404 include_replies: bool | None = None, 1405 anchor: str | None = None, 1406 direction: Literal["before", "after", "around"] | None = None, 1407 before_limit: int | None = None, 1408 after_limit: int | None = None, 1409 include_anchor: bool | None = None, 1410 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 1411 anchor_agent: str | None = None, 1412 include_reply_counts: bool | None = None, 1413 ) -> ThreadMessagesResponse: 1414 """ 1415 List messages in a thread 1416 Returns a cursor-paginated list of messages belonging to the specified thread, 1417 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 1418 to page through or bound the result set; omit both to receive the most recent page. 1419 Supply `anchor` and `direction` to fetch a window before, after, or around a 1420 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 1421 resolve the anchor from the latest embedded-agent message, and add 1422 `anchor_agent` to scope that resolution to a single sender agent. 1423 Supply `metadata` as a JSON-encoded structured expression to filter message 1424 metadata before cursor pagination or anchored window limits are applied. 1425 The authenticated user must have access to the thread's owner (workspace or user). 1426 A 403 is returned if the thread exists but is not accessible to the caller; a 404 1427 is returned if the thread does not exist or is not visible to the authenticated user. 1428 Threads with `kind: feed` return only top-level posts, each with its newest 1429 replies inline under `replies` and reply cursors for paging the rest. 1430 Set `include_replies: true` to page messages and replies together by creation 1431 order instead, without inline reply previews. Metadata filters and the page 1432 limit apply to the updates themselves, before any client-side grouping. 1433 Pass `include_reply_counts: true` to annotate each message with the number of 1434 threaded replies it has received. This adds a small amount of latency and should 1435 be omitted when reply counts are not needed. 1436 1437 Args: 1438 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1439 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 1440 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 1441 metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. 1442 limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100. 1443 include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. 1444 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 1445 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 1446 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. 1447 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. 1448 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 1449 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 1450 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 1451 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 1452 1453 Returns: 1454 Successful response 1455 """ 1456 query: dict[str, object] = {} 1457 if before_cursor is not None: 1458 query["before_cursor"] = before_cursor 1459 if after_cursor is not None: 1460 query["after_cursor"] = after_cursor 1461 if metadata is not None: 1462 query["metadata"] = metadata 1463 if limit is not None: 1464 query["limit"] = limit 1465 if include_replies is not None: 1466 query["include_replies"] = include_replies 1467 if anchor is not None: 1468 query["anchor"] = anchor 1469 if direction is not None: 1470 query["direction"] = direction 1471 if before_limit is not None: 1472 query["before_limit"] = before_limit 1473 if after_limit is not None: 1474 query["after_limit"] = after_limit 1475 if include_anchor is not None: 1476 query["include_anchor"] = include_anchor 1477 if anchor_agent_mode is not None: 1478 query["anchor_agent_mode"] = anchor_agent_mode 1479 if anchor_agent is not None: 1480 query["anchor_agent"] = anchor_agent 1481 if include_reply_counts is not None: 1482 query["include_reply_counts"] = include_reply_counts 1483 return await self._http.request( 1484 f"/api/v1/threads/{thread}/messages", 1485 query=query, 1486 response_type=ThreadMessagesResponse, 1487 ) 1488 1489 async def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 1490 """ 1491 Update a thread's profile picture 1492 Uploads a new profile picture for the specified thread and returns the updated 1493 thread object. The image must be supplied as a base64-encoded string with its 1494 MIME type. 1495 The authenticated user must own the thread or be a team owner of the workspace 1496 the thread belongs to. Supplying invalid base64 data returns 422. 1497 1498 Args: 1499 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1500 input: Request body. 1501 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1502 1503 Returns: 1504 The thread object after the profile picture has been updated. 1505 """ 1506 return await self._http.request( 1507 f"/api/v1/threads/{thread}/picture", 1508 method="PUT", 1509 body=input, 1510 response_type=Thread, 1511 ) 1512 1513 async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1514 """ 1515 Retrieve a thread's read status 1516 Returns the read status of a thread for the specified user, including the ID 1517 of the last message they have read and the number of unread messages remaining. 1518 For user-authenticated requests, the status is always returned for the 1519 authenticated user and the `user` parameter is ignored. For server-to-server 1520 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1521 Returns 404 if the thread does not exist or the caller does not have access 1522 to it. 1523 1524 Args: 1525 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1526 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1527 1528 Returns: 1529 The read status record for the requested thread and user. 1530 """ 1531 query: dict[str, object] = {} 1532 if user is not None: 1533 query["user"] = user 1534 return await self._http.request( 1535 f"/api/v1/threads/{thread}/read_status", 1536 query=query, 1537 response_type=ThreadReadStatus, 1538 ) 1539 1540 async def search( 1541 self, 1542 thread: str, 1543 q: str, 1544 *, 1545 app: str | None = None, 1546 limit: int | None = None, 1547 mode: Literal["text", "embedding", "hybrid"] | None = None, 1548 before_cursor: str | None = None, 1549 after_cursor: str | None = None, 1550 ) -> ThreadSearchResponse: 1551 """ 1552 Search messages in a thread 1553 Searches canonical message content in the specified thread. `"text"` mode 1554 performs the existing case-insensitive substring search, `"embedding"` ranks 1555 stored message embeddings by cosine similarity, and `"hybrid"` combines the 1556 text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages 1557 visible to the authenticated caller are considered. 1558 Results are intentionally lean: each row contains a bounded content snippet, 1559 sender identity, timestamp, and a small allowlisted structured-post evidence 1560 projection. Attachments, reactions, ACLs, and arbitrary metadata are neither 1561 hydrated nor serialized. At most 20 results are returned. Text results 1562 support chronological cursor pagination. Embedding and hybrid results are 1563 relevance-ranked single pages and return null cursors. 1564 1565 Args: 1566 thread: Thread ID (`thr_...`). Must be visible to the authenticated caller. 1567 app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount. 1568 q: Text or semantic search query. Must contain 3 to 200 characters after trimming. 1569 limit: Maximum number of results. Defaults to 20 and is capped at 20. 1570 mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings. 1571 before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches. 1572 after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches. 1573 1574 Returns: 1575 Successful response 1576 """ 1577 query: dict[str, object] = {} 1578 if app is not None: 1579 query["app"] = app 1580 query["q"] = q 1581 if limit is not None: 1582 query["limit"] = limit 1583 if mode is not None: 1584 query["mode"] = mode 1585 if before_cursor is not None: 1586 query["before_cursor"] = before_cursor 1587 if after_cursor is not None: 1588 query["after_cursor"] = after_cursor 1589 return await self._http.request( 1590 f"/api/v1/threads/{thread}/search", 1591 query=query, 1592 response_type=ThreadSearchResponse, 1593 ) 1594 1595 async def trajectories( 1596 self, 1597 thread: str, 1598 *, 1599 before_cursor: str | None = None, 1600 after_cursor: str | None = None, 1601 limit: int | None = None, 1602 message: str | None = None, 1603 ) -> ThreadTrajectoriesResponse: 1604 """ 1605 List trajectories for a thread 1606 Returns a cursor-paginated list of thread message trajectories associated with the 1607 specified thread. Each trajectory links a user message and its agent response to the 1608 underlying AI trajectory record that captured the model's reasoning steps. 1609 The authenticated user must own the thread or be a member of the workspace it belongs 1610 to. Results are returned in reverse chronological order by default. Use `before_cursor` 1611 and `after_cursor` to navigate pages; provide at most one cursor per request. 1612 Optionally filter results to trajectories produced in response to a specific message 1613 by supplying the `message` parameter. When no trajectories match the query, `data` 1614 is an empty array and both cursor fields are `null`. A cursor that cannot be decoded 1615 returns a 400 `invalid_cursor` error. 1616 1617 Args: 1618 thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace. 1619 before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position. 1620 after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position. 1621 limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100. 1622 message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message. 1623 1624 Returns: 1625 Successful response 1626 """ 1627 query: dict[str, object] = {} 1628 if before_cursor is not None: 1629 query["before_cursor"] = before_cursor 1630 if after_cursor is not None: 1631 query["after_cursor"] = after_cursor 1632 if limit is not None: 1633 query["limit"] = limit 1634 if message is not None: 1635 query["message"] = message 1636 return await self._http.request( 1637 f"/api/v1/threads/{thread}/trajectories", 1638 query=query, 1639 response_type=ThreadTrajectoriesResponse, 1640 )
1249 async def delete(self, thread: str) -> None: 1250 """ 1251 Delete a thread 1252 Permanently deletes a thread and all of its messages and artifacts. This action 1253 cannot be undone. 1254 The authenticated user must own the thread or be an owner of the team the thread 1255 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1256 1257 Args: 1258 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1259 1260 Returns: 1261 Empty response on successful deletion. 1262 """ 1263 await self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
Delete a thread Permanently deletes a thread and all of its messages and artifacts. This action cannot be undone. The authenticated user must own the thread or be an owner of the team the thread belongs to. Attempting to delete a thread owned by another user or team returns 403.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must own this thread.
Returns:
Empty response on successful deletion.
1265 async def get(self, thread: str) -> Thread: 1266 """ 1267 Retrieve a thread 1268 Returns the full thread record for the given thread ID. The authenticated user 1269 must own the thread or be a member of the workspace it belongs to. 1270 Use this endpoint to fetch the current state of a single thread, including its 1271 title, description, and metadata. To list many threads, use the list endpoint 1272 with cursor-based pagination. 1273 1274 Args: 1275 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1276 1277 Returns: 1278 The requested thread object. 1279 """ 1280 return await self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
Retrieve a thread Returns the full thread record for the given thread ID. The authenticated user must own the thread or be a member of the workspace it belongs to. Use this endpoint to fetch the current state of a single thread, including its title, description, and metadata. To list many threads, use the list endpoint with cursor-based pagination.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread.
Returns:
The requested thread object.
1282 async def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1283 """ 1284 Update a thread 1285 Updates one or more mutable properties of the specified thread and returns 1286 the full thread object with the applied changes. Only the fields you provide 1287 are modified; omitted fields retain their current values. 1288 If `profile_picture` is supplied, the image is uploaded before the other 1289 fields are saved, after all ordinary thread fields have passed validation. 1290 Supplying invalid base64 picture data returns 422 and no other fields are 1291 updated. 1292 Visibility can only widen: `private` may become `restricted` or `team`, and 1293 `restricted` may become `team`. The authenticated viewer must have 1294 permission to modify the thread. 1295 Mirror-thread titles, descriptions, and notification state remain editable 1296 by privileged app viewers. Mirror metadata, visibility, and membership are 1297 provider-managed and cannot be changed through this endpoint. 1298 1299 Args: 1300 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1301 input: Request body. 1302 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1303 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1304 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1305 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1306 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1307 input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed. 1308 1309 Returns: 1310 The thread object after the update has been applied. 1311 """ 1312 return await self._http.request( 1313 f"/api/v1/threads/{thread}", 1314 method="PUT", 1315 body=input, 1316 response_type=Thread, 1317 )
Update a thread
Updates one or more mutable properties of the specified thread and returns
the full thread object with the applied changes. Only the fields you provide
are modified; omitted fields retain their current values.
If profile_picture is supplied, the image is uploaded before the other
fields are saved, after all ordinary thread fields have passed validation.
Supplying invalid base64 picture data returns 422 and no other fields are
updated.
Visibility can only widen: private may become restricted or team, and
restricted may become team. The authenticated viewer must have
permission to modify the thread.
Mirror-thread titles, descriptions, and notification state remain editable
by privileged app viewers. Mirror metadata, visibility, and membership are
provider-managed and cannot be changed through this endpoint.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
- input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
- input.muted: When
true, suppresses notifications for new messages in this thread for the authenticated user. - input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
- input.title: Human-readable display name for the thread. Replaces the existing title when provided.
- input.visibility: Widen a team-owned thread:
privatemay becomerestrictedorteam, andrestrictedmay becometeam. Visibility cannot be narrowed.
Returns:
The thread object after the update has been applied.
1319 async def agents(self, thread: str) -> ThreadAgentsResponse: 1320 """ 1321 List agents in a thread 1322 Returns the agents participating in the specified thread. Only personal user 1323 threads (threads owned by a single user, not a team) expose agents through 1324 this endpoint; requests for team threads return 404. 1325 The authenticated user must have visibility into the thread. Each agent entry 1326 includes display information such as name and profile picture. Thread-level 1327 overrides (e.g. a custom name or profile picture set for this thread) take 1328 precedence over the agent's default values. When the caller is the thread 1329 owner, each entry also includes an `agent_config` object describing the 1330 agent's message policy and context configuration. 1331 1332 Args: 1333 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1334 1335 Returns: 1336 Successful response 1337 """ 1338 return await self._http.request( 1339 f"/api/v1/threads/{thread}/agents", 1340 response_type=ThreadAgentsResponse, 1341 )
List agents in a thread
Returns the agents participating in the specified thread. Only personal user
threads (threads owned by a single user, not a team) expose agents through
this endpoint; requests for team threads return 404.
The authenticated user must have visibility into the thread. Each agent entry
includes display information such as name and profile picture. Thread-level
overrides (e.g. a custom name or profile picture set for this thread) take
precedence over the agent's default values. When the caller is the thread
owner, each entry also includes an agent_config object describing the
agent's message policy and context configuration.
Arguments:
- thread: Thread ID (
thr_...). Must be a personal user thread visible to the authenticated user.
Returns:
Successful response
1343 async def artifacts( 1344 self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None 1345 ) -> ThreadArtifactsResponse: 1346 """ 1347 List artifacts for a thread 1348 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1349 structured outputs such as code files, documents, or generated assets created 1350 by the AI agent in response to messages in the thread. 1351 The authenticated user must have access to the specified thread. Results are 1352 returned in a single page; there is no cursor-based pagination for this endpoint. 1353 1354 Args: 1355 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 1356 group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match. 1357 group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. 1358 1359 Returns: 1360 Successful response 1361 """ 1362 query: dict[str, object] = {} 1363 if group_key is not None: 1364 query["group_key"] = group_key 1365 if group_key_prefix is not None: 1366 query["group_key_prefix"] = group_key_prefix 1367 return await self._http.request( 1368 f"/api/v1/threads/{thread}/artifacts", 1369 query=query, 1370 response_type=ThreadArtifactsResponse, 1371 )
List artifacts for a thread Returns all artifacts produced during a thread's AI conversation. Artifacts are structured outputs such as code files, documents, or generated assets created by the AI agent in response to messages in the thread. The authenticated user must have access to the specified thread. Results are returned in a single page; there is no cursor-based pagination for this endpoint.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user. - group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match.
- group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key.
Returns:
Successful response
1373 async def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 1374 """ 1375 Mark a thread as read 1376 Records that a user has read up to a specific message in the thread. Unread 1377 indicators and badge counts are cleared up to the specified message. 1378 You must supply exactly one of `last_read_message` or `use_latest_message`. 1379 Omitting both returns 400. If `use_latest_message` is `true` and the thread 1380 has no messages, the request succeeds silently with no state change. 1381 For server-to-server (S2S) requests where no user identity is present in the 1382 token, the `user` param is required to identify whose read state to update. 1383 1384 Args: 1385 thread: Thread ID (`thr_...`). The thread to mark as read. 1386 input: Request body. 1387 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 1388 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 1389 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 1390 1391 Returns: 1392 Empty response on success. 1393 """ 1394 await self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
Mark a thread as read
Records that a user has read up to a specific message in the thread. Unread
indicators and badge counts are cleared up to the specified message.
You must supply exactly one of last_read_message or use_latest_message.
Omitting both returns 400. If use_latest_message is true and the thread
has no messages, the request succeeds silently with no state change.
For server-to-server (S2S) requests where no user identity is present in the
token, the user param is required to identify whose read state to update.
Arguments:
- thread: Thread ID (
thr_...). The thread to mark as read. - input: Request body.
- input.last_read_message: Message ID (
msg_...) to record as the last read message. Mutually exclusive withuse_latest_message. - input.use_latest_message: When
true, marks the thread as read up to the latest message. Mutually exclusive withlast_read_message. - input.user: User ID (
usr_...) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
Returns:
Empty response on success.
1396 async def messages( 1397 self, 1398 thread: str, 1399 *, 1400 before_cursor: str | None = None, 1401 after_cursor: str | None = None, 1402 metadata: dict[str, Any] | None = None, 1403 limit: int | None = None, 1404 include_replies: bool | None = None, 1405 anchor: str | None = None, 1406 direction: Literal["before", "after", "around"] | None = None, 1407 before_limit: int | None = None, 1408 after_limit: int | None = None, 1409 include_anchor: bool | None = None, 1410 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 1411 anchor_agent: str | None = None, 1412 include_reply_counts: bool | None = None, 1413 ) -> ThreadMessagesResponse: 1414 """ 1415 List messages in a thread 1416 Returns a cursor-paginated list of messages belonging to the specified thread, 1417 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 1418 to page through or bound the result set; omit both to receive the most recent page. 1419 Supply `anchor` and `direction` to fetch a window before, after, or around a 1420 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 1421 resolve the anchor from the latest embedded-agent message, and add 1422 `anchor_agent` to scope that resolution to a single sender agent. 1423 Supply `metadata` as a JSON-encoded structured expression to filter message 1424 metadata before cursor pagination or anchored window limits are applied. 1425 The authenticated user must have access to the thread's owner (workspace or user). 1426 A 403 is returned if the thread exists but is not accessible to the caller; a 404 1427 is returned if the thread does not exist or is not visible to the authenticated user. 1428 Threads with `kind: feed` return only top-level posts, each with its newest 1429 replies inline under `replies` and reply cursors for paging the rest. 1430 Set `include_replies: true` to page messages and replies together by creation 1431 order instead, without inline reply previews. Metadata filters and the page 1432 limit apply to the updates themselves, before any client-side grouping. 1433 Pass `include_reply_counts: true` to annotate each message with the number of 1434 threaded replies it has received. This adds a small amount of latency and should 1435 be omitted when reply counts are not needed. 1436 1437 Args: 1438 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1439 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 1440 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 1441 metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. 1442 limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100. 1443 include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. 1444 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 1445 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 1446 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. 1447 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. 1448 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 1449 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 1450 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 1451 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 1452 1453 Returns: 1454 Successful response 1455 """ 1456 query: dict[str, object] = {} 1457 if before_cursor is not None: 1458 query["before_cursor"] = before_cursor 1459 if after_cursor is not None: 1460 query["after_cursor"] = after_cursor 1461 if metadata is not None: 1462 query["metadata"] = metadata 1463 if limit is not None: 1464 query["limit"] = limit 1465 if include_replies is not None: 1466 query["include_replies"] = include_replies 1467 if anchor is not None: 1468 query["anchor"] = anchor 1469 if direction is not None: 1470 query["direction"] = direction 1471 if before_limit is not None: 1472 query["before_limit"] = before_limit 1473 if after_limit is not None: 1474 query["after_limit"] = after_limit 1475 if include_anchor is not None: 1476 query["include_anchor"] = include_anchor 1477 if anchor_agent_mode is not None: 1478 query["anchor_agent_mode"] = anchor_agent_mode 1479 if anchor_agent is not None: 1480 query["anchor_agent"] = anchor_agent 1481 if include_reply_counts is not None: 1482 query["include_reply_counts"] = include_reply_counts 1483 return await self._http.request( 1484 f"/api/v1/threads/{thread}/messages", 1485 query=query, 1486 response_type=ThreadMessagesResponse, 1487 )
List messages in a thread
Returns a cursor-paginated list of messages belonging to the specified thread,
ordered from oldest to newest. Supply before_cursor, after_cursor, or both
to page through or bound the result set; omit both to receive the most recent page.
Supply anchor and direction to fetch a window before, after, or around a
specific message. Use anchor=last_matching&anchor_agent_mode=embedded to
resolve the anchor from the latest embedded-agent message, and add
anchor_agent to scope that resolution to a single sender agent.
Supply metadata as a JSON-encoded structured expression to filter message
metadata before cursor pagination or anchored window limits are applied.
The authenticated user must have access to the thread's owner (workspace or user).
A 403 is returned if the thread exists but is not accessible to the caller; a 404
is returned if the thread does not exist or is not visible to the authenticated user.
Threads with kind: feed return only top-level posts, each with its newest
replies inline under replies and reply cursors for paging the rest.
Set include_replies: true to page messages and replies together by creation
order instead, without inline reply previews. Metadata filters and the page
limit apply to the updates themselves, before any client-side grouping.
Pass include_reply_counts: true to annotate each message with the number of
threaded replies it has received. This adds a small amount of latency and should
be omitted when reply counts are not needed.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread. - before_cursor: Opaque cursor returned in a previous response's
before_cursorfield. When provided, returns messages immediately before that position. May be combined withafter_cursorto bound a range. - after_cursor: Opaque cursor returned in a previous response's
after_cursorfield. When provided, returns messages immediately after that position. May be combined withbefore_cursorto bound a range. - metadata: Structured metadata filter expression. Only messages whose
metadataobject satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. - limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
- include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false.
- anchor: Message ID (
msg_...) to use as a window anchor, orlast_matchingto resolve the anchor from the latest message matching the anchor filters. Cannot be combined withbefore_cursororafter_cursor. - direction: Window direction relative to
anchor.beforereturns older messages,afterreturns newer messages, andaroundreturns messages on both sides. Defaults toafterwhenanchoris supplied.direction=aroundcannot be combined with an explicitlimit; usebefore_limitandafter_limit. - before_limit: For
direction=around, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. - after_limit: For
direction=around, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. - include_anchor: Whether to include the anchor message in a window response. Defaults to
truefordirection=around; ignored for ordinary cursor pagination and one-sided windows. - anchor_agent_mode: When
anchor=last_matching, resolve the anchor from the latest message with this local agent execution mode. - anchor_agent: When
anchor=last_matching, scope the anchor resolution to messages sent by this agent (agi_...). Combine withanchor_agent_modeto resolve the latest message from a specific agent in a given mode. - include_reply_counts: When
true, each message in the response is annotated with its threaded reply count. Defaults tofalse. Adds latency; omit when reply counts are not needed.
Returns:
Successful response
1489 async def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 1490 """ 1491 Update a thread's profile picture 1492 Uploads a new profile picture for the specified thread and returns the updated 1493 thread object. The image must be supplied as a base64-encoded string with its 1494 MIME type. 1495 The authenticated user must own the thread or be a team owner of the workspace 1496 the thread belongs to. Supplying invalid base64 data returns 422. 1497 1498 Args: 1499 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1500 input: Request body. 1501 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 1502 1503 Returns: 1504 The thread object after the profile picture has been updated. 1505 """ 1506 return await self._http.request( 1507 f"/api/v1/threads/{thread}/picture", 1508 method="PUT", 1509 body=input, 1510 response_type=Thread, 1511 )
Update a thread's profile picture Uploads a new profile picture for the specified thread and returns the updated thread object. The image must be supplied as a base64-encoded string with its MIME type. The authenticated user must own the thread or be a team owner of the workspace the thread belongs to. Supplying invalid base64 data returns 422.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
Returns:
The thread object after the profile picture has been updated.
1513 async def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 1514 """ 1515 Retrieve a thread's read status 1516 Returns the read status of a thread for the specified user, including the ID 1517 of the last message they have read and the number of unread messages remaining. 1518 For user-authenticated requests, the status is always returned for the 1519 authenticated user and the `user` parameter is ignored. For server-to-server 1520 (S2S) requests, the `user` parameter is required and must be a valid user ID. 1521 Returns 404 if the thread does not exist or the caller does not have access 1522 to it. 1523 1524 Args: 1525 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 1526 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 1527 1528 Returns: 1529 The read status record for the requested thread and user. 1530 """ 1531 query: dict[str, object] = {} 1532 if user is not None: 1533 query["user"] = user 1534 return await self._http.request( 1535 f"/api/v1/threads/{thread}/read_status", 1536 query=query, 1537 response_type=ThreadReadStatus, 1538 )
Retrieve a thread's read status
Returns the read status of a thread for the specified user, including the ID
of the last message they have read and the number of unread messages remaining.
For user-authenticated requests, the status is always returned for the
authenticated user and the user parameter is ignored. For server-to-server
(S2S) requests, the user parameter is required and must be a valid user ID.
Returns 404 if the thread does not exist or the caller does not have access
to it.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user or, for S2S requests, to the specified user. - user: User ID (
usr_...) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user.
Returns:
The read status record for the requested thread and user.
1540 async def search( 1541 self, 1542 thread: str, 1543 q: str, 1544 *, 1545 app: str | None = None, 1546 limit: int | None = None, 1547 mode: Literal["text", "embedding", "hybrid"] | None = None, 1548 before_cursor: str | None = None, 1549 after_cursor: str | None = None, 1550 ) -> ThreadSearchResponse: 1551 """ 1552 Search messages in a thread 1553 Searches canonical message content in the specified thread. `"text"` mode 1554 performs the existing case-insensitive substring search, `"embedding"` ranks 1555 stored message embeddings by cosine similarity, and `"hybrid"` combines the 1556 text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages 1557 visible to the authenticated caller are considered. 1558 Results are intentionally lean: each row contains a bounded content snippet, 1559 sender identity, timestamp, and a small allowlisted structured-post evidence 1560 projection. Attachments, reactions, ACLs, and arbitrary metadata are neither 1561 hydrated nor serialized. At most 20 results are returned. Text results 1562 support chronological cursor pagination. Embedding and hybrid results are 1563 relevance-ranked single pages and return null cursors. 1564 1565 Args: 1566 thread: Thread ID (`thr_...`). Must be visible to the authenticated caller. 1567 app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount. 1568 q: Text or semantic search query. Must contain 3 to 200 characters after trimming. 1569 limit: Maximum number of results. Defaults to 20 and is capped at 20. 1570 mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings. 1571 before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches. 1572 after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches. 1573 1574 Returns: 1575 Successful response 1576 """ 1577 query: dict[str, object] = {} 1578 if app is not None: 1579 query["app"] = app 1580 query["q"] = q 1581 if limit is not None: 1582 query["limit"] = limit 1583 if mode is not None: 1584 query["mode"] = mode 1585 if before_cursor is not None: 1586 query["before_cursor"] = before_cursor 1587 if after_cursor is not None: 1588 query["after_cursor"] = after_cursor 1589 return await self._http.request( 1590 f"/api/v1/threads/{thread}/search", 1591 query=query, 1592 response_type=ThreadSearchResponse, 1593 )
Search messages in a thread
Searches canonical message content in the specified thread. "text" mode
performs the existing case-insensitive substring search, "embedding" ranks
stored message embeddings by cosine similarity, and "hybrid" combines the
text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
visible to the authenticated caller are considered.
Results are intentionally lean: each row contains a bounded content snippet,
sender identity, timestamp, and a small allowlisted structured-post evidence
projection. Attachments, reactions, ACLs, and arbitrary metadata are neither
hydrated nor serialized. At most 20 results are returned. Text results
support chronological cursor pagination. Embedding and hybrid results are
relevance-ranked single pages and return null cursors.
Arguments:
- thread: Thread ID (
thr_...). Must be visible to the authenticated caller. - app: App ID (
app_...). Required by the protected developer mount and omitted from the public mount. - q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
- limit: Maximum number of results. Defaults to 20 and is capped at 20.
- mode: Search algorithm:
textfor substring matching,embeddingfor cosine similarity, orhybridfor RRF over both rankings. - before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
- after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
Returns:
Successful response
1595 async def trajectories( 1596 self, 1597 thread: str, 1598 *, 1599 before_cursor: str | None = None, 1600 after_cursor: str | None = None, 1601 limit: int | None = None, 1602 message: str | None = None, 1603 ) -> ThreadTrajectoriesResponse: 1604 """ 1605 List trajectories for a thread 1606 Returns a cursor-paginated list of thread message trajectories associated with the 1607 specified thread. Each trajectory links a user message and its agent response to the 1608 underlying AI trajectory record that captured the model's reasoning steps. 1609 The authenticated user must own the thread or be a member of the workspace it belongs 1610 to. Results are returned in reverse chronological order by default. Use `before_cursor` 1611 and `after_cursor` to navigate pages; provide at most one cursor per request. 1612 Optionally filter results to trajectories produced in response to a specific message 1613 by supplying the `message` parameter. When no trajectories match the query, `data` 1614 is an empty array and both cursor fields are `null`. A cursor that cannot be decoded 1615 returns a 400 `invalid_cursor` error. 1616 1617 Args: 1618 thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace. 1619 before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position. 1620 after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position. 1621 limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100. 1622 message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message. 1623 1624 Returns: 1625 Successful response 1626 """ 1627 query: dict[str, object] = {} 1628 if before_cursor is not None: 1629 query["before_cursor"] = before_cursor 1630 if after_cursor is not None: 1631 query["after_cursor"] = after_cursor 1632 if limit is not None: 1633 query["limit"] = limit 1634 if message is not None: 1635 query["message"] = message 1636 return await self._http.request( 1637 f"/api/v1/threads/{thread}/trajectories", 1638 query=query, 1639 response_type=ThreadTrajectoriesResponse, 1640 )
List trajectories for a thread
Returns a cursor-paginated list of thread message trajectories associated with the
specified thread. Each trajectory links a user message and its agent response to the
underlying AI trajectory record that captured the model's reasoning steps.
The authenticated user must own the thread or be a member of the workspace it belongs
to. Results are returned in reverse chronological order by default. Use before_cursor
and after_cursor to navigate pages; provide at most one cursor per request.
Optionally filter results to trajectories produced in response to a specific message
by supplying the message parameter. When no trajectories match the query, data
is an empty array and both cursor fields are null. A cursor that cannot be decoded
returns a 400 invalid_cursor error.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must own this thread or belong to its workspace. - before_cursor: Opaque cursor from a previous response's
before_cursorfield. Returns the page of results preceding that cursor position. - after_cursor: Opaque cursor from a previous response's
after_cursorfield. Returns the page of results following that cursor position. - limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
- message: Message ID (
msg_...). When provided, limits results to trajectories associated with this specific message.
Returns:
Successful response
1643class ComputerResource: 1644 def __init__(self, http: SyncHttpClient): 1645 self._http = http 1646 1647 def list(self, thread: str) -> AgentComputerListResponse: 1648 """ 1649 List a thread's computers 1650 Returns all live computers in the visible thread, oldest first, without pagination. 1651 1652 Args: 1653 thread: Thread ID (`thr_...`). 1654 1655 Returns: 1656 The thread's live computers. 1657 """ 1658 return self._http.request( 1659 f"/api/v1/threads/{thread}/computers", 1660 response_type=AgentComputerListResponse, 1661 ) 1662 1663 def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: 1664 """ 1665 Provision a computer for a thread 1666 Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. 1667 1668 Args: 1669 thread: Thread ID (`thr_...`). 1670 input: Request body. 1671 input.acl: Initial access control list. 1672 input.config: Provider configuration; top-level provider takes precedence. 1673 input.key: Stable key unique within this thread. 1674 input.metadata: Arbitrary computer metadata. 1675 input.name: Human-readable computer name. 1676 input.provider: Compute backend: sprites (default), vercel or e2b. 1677 input.region: Provider region; defaults to iad. 1678 1679 Returns: 1680 The newly created computer. Returns HTTP 201. 1681 """ 1682 return self._http.request( 1683 f"/api/v1/threads/{thread}/computers", 1684 method="POST", 1685 body=input, 1686 response_type=AgentComputer, 1687 )
1647 def list(self, thread: str) -> AgentComputerListResponse: 1648 """ 1649 List a thread's computers 1650 Returns all live computers in the visible thread, oldest first, without pagination. 1651 1652 Args: 1653 thread: Thread ID (`thr_...`). 1654 1655 Returns: 1656 The thread's live computers. 1657 """ 1658 return self._http.request( 1659 f"/api/v1/threads/{thread}/computers", 1660 response_type=AgentComputerListResponse, 1661 )
List a thread's computers Returns all live computers in the visible thread, oldest first, without pagination.
Arguments:
- thread: Thread ID (
thr_...).
Returns:
The thread's live computers.
1663 def create(self, thread: str, input: ComputerCreateInput) -> AgentComputer: 1664 """ 1665 Provision a computer for a thread 1666 Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer. 1667 1668 Args: 1669 thread: Thread ID (`thr_...`). 1670 input: Request body. 1671 input.acl: Initial access control list. 1672 input.config: Provider configuration; top-level provider takes precedence. 1673 input.key: Stable key unique within this thread. 1674 input.metadata: Arbitrary computer metadata. 1675 input.name: Human-readable computer name. 1676 input.provider: Compute backend: sprites (default), vercel or e2b. 1677 input.region: Provider region; defaults to iad. 1678 1679 Returns: 1680 The newly created computer. Returns HTTP 201. 1681 """ 1682 return self._http.request( 1683 f"/api/v1/threads/{thread}/computers", 1684 method="POST", 1685 body=input, 1686 response_type=AgentComputer, 1687 )
Provision a computer for a thread Creates a computer owned by the thread's owner. Requires permission to manage the thread; every thread viewer may use the computer.
Arguments:
- thread: Thread ID (
thr_...). - input: Request body.
- input.acl: Initial access control list.
- input.config: Provider configuration; top-level provider takes precedence.
- input.key: Stable key unique within this thread.
- input.metadata: Arbitrary computer metadata.
- input.name: Human-readable computer name.
- input.provider: Compute backend: sprites (default), vercel or e2b.
- input.region: Provider region; defaults to iad.
Returns:
The newly created computer. Returns HTTP 201.
1690class ThreadMemberResource: 1691 def __init__(self, http: SyncHttpClient): 1692 self._http = http 1693 1694 def remove(self, thread: str) -> None: 1695 """ 1696 Remove a member from a thread 1697 Removes a user or agent from the explicit roster of a private or restricted 1698 thread. Team-visible threads use implicit membership and reject individual 1699 removals. A member may remove themself; removing someone else requires 1700 permission to modify the thread. A successful removal returns HTTP 204 with 1701 no response body. 1702 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1703 if the thread or the membership record does not exist. 1704 1705 Args: 1706 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1707 1708 Returns: 1709 Empty response body. HTTP 204 on success. 1710 """ 1711 self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE") 1712 1713 def list(self, thread: str) -> ThreadMemberListResponse: 1714 """ 1715 List members of a thread 1716 Returns all current user and agent members. Private and restricted threads 1717 return their explicit roster; team-visible threads return the owning team's 1718 implicit roster. The authenticated viewer must be able to see the thread. 1719 Results are returned as a flat array in the `data` field. The list is not 1720 paginated all members are returned in a single response. 1721 1722 Args: 1723 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1724 1725 Returns: 1726 Successful response 1727 """ 1728 return self._http.request( 1729 f"/api/v1/threads/{thread}/members", 1730 response_type=ThreadMemberListResponse, 1731 ) 1732 1733 def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember: 1734 """ 1735 Add a member to a thread 1736 Adds a user or agent to the explicit roster of a private or restricted 1737 thread. Team-visible threads use the owning team's implicit roster and reject 1738 explicit additions. On restricted threads, a team member may add themself; 1739 adding anyone else requires permission to modify the thread. 1740 Supply either `user` or `agent` depending on the value of `type`. Targets 1741 must be visible to the caller and, for an ordinary team-owned thread, must 1742 belong to the owning team. On success the membership record is returned with 1743 HTTP 201; repeated agent additions are idempotent. 1744 1745 Args: 1746 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1747 input: Request body. 1748 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1749 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1750 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1751 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1752 1753 Returns: 1754 The user or agent membership that was added to the thread. 1755 """ 1756 return self._http.request( 1757 f"/api/v1/threads/{thread}/members", 1758 method="POST", 1759 body=input, 1760 response_type=ChatMember, 1761 )
1694 def remove(self, thread: str) -> None: 1695 """ 1696 Remove a member from a thread 1697 Removes a user or agent from the explicit roster of a private or restricted 1698 thread. Team-visible threads use implicit membership and reject individual 1699 removals. A member may remove themself; removing someone else requires 1700 permission to modify the thread. A successful removal returns HTTP 204 with 1701 no response body. 1702 Supply either `user` or `agent` depending on the value of `type`. Returns 404 1703 if the thread or the membership record does not exist. 1704 1705 Args: 1706 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1707 1708 Returns: 1709 Empty response body. HTTP 204 on success. 1710 """ 1711 self._http.request(f"/api/v1/threads/{thread}/members", method="DELETE")
Remove a member from a thread
Removes a user or agent from the explicit roster of a private or restricted
thread. Team-visible threads use implicit membership and reject individual
removals. A member may remove themself; removing someone else requires
permission to modify the thread. A successful removal returns HTTP 204 with
no response body.
Supply either user or agent depending on the value of type. Returns 404
if the thread or the membership record does not exist.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Empty response body. HTTP 204 on success.
1713 def list(self, thread: str) -> ThreadMemberListResponse: 1714 """ 1715 List members of a thread 1716 Returns all current user and agent members. Private and restricted threads 1717 return their explicit roster; team-visible threads return the owning team's 1718 implicit roster. The authenticated viewer must be able to see the thread. 1719 Results are returned as a flat array in the `data` field. The list is not 1720 paginated all members are returned in a single response. 1721 1722 Args: 1723 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1724 1725 Returns: 1726 Successful response 1727 """ 1728 return self._http.request( 1729 f"/api/v1/threads/{thread}/members", 1730 response_type=ThreadMemberListResponse, 1731 )
List members of a thread
Returns all current user and agent members. Private and restricted threads
return their explicit roster; team-visible threads return the owning team's
implicit roster. The authenticated viewer must be able to see the thread.
Results are returned as a flat array in the data field. The list is not
paginated all members are returned in a single response.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from.
Returns:
Successful response
1733 def create(self, thread: str, input: ThreadMemberCreateInput) -> ChatMember: 1734 """ 1735 Add a member to a thread 1736 Adds a user or agent to the explicit roster of a private or restricted 1737 thread. Team-visible threads use the owning team's implicit roster and reject 1738 explicit additions. On restricted threads, a team member may add themself; 1739 adding anyone else requires permission to modify the thread. 1740 Supply either `user` or `agent` depending on the value of `type`. Targets 1741 must be visible to the caller and, for an ordinary team-owned thread, must 1742 belong to the owning team. On success the membership record is returned with 1743 HTTP 201; repeated agent additions are idempotent. 1744 1745 Args: 1746 thread: Thread ID (`thr_...`) identifying the thread to remove the member from. 1747 input: Request body. 1748 input.agent: Agent ID of the principal to add. Required when `type` is `"agent"`. 1749 input.membership_type: Role granted to the new member. One of `"owner"` or `"member"`. Defaults to `"member"`. 1750 input.type: Kind of principal being added. Must be `"user"` or `"agent"`. 1751 input.user: User ID of the principal to add. Required when `type` is `"user"`. 1752 1753 Returns: 1754 The user or agent membership that was added to the thread. 1755 """ 1756 return self._http.request( 1757 f"/api/v1/threads/{thread}/members", 1758 method="POST", 1759 body=input, 1760 response_type=ChatMember, 1761 )
Add a member to a thread
Adds a user or agent to the explicit roster of a private or restricted
thread. Team-visible threads use the owning team's implicit roster and reject
explicit additions. On restricted threads, a team member may add themself;
adding anyone else requires permission to modify the thread.
Supply either user or agent depending on the value of type. Targets
must be visible to the caller and, for an ordinary team-owned thread, must
belong to the owning team. On success the membership record is returned with
HTTP 201; repeated agent additions are idempotent.
Arguments:
- thread: Thread ID (
thr_...) identifying the thread to remove the member from. - input: Request body.
- input.agent: Agent ID of the principal to add. Required when
typeis"agent". - input.membership_type: Role granted to the new member. One of
"owner"or"member". Defaults to"member". - input.type: Kind of principal being added. Must be
"user"or"agent". - input.user: User ID of the principal to add. Required when
typeis"user".
Returns:
The user or agent membership that was added to the thread.
1764class SettingResource: 1765 def __init__(self, http: SyncHttpClient): 1766 self._http = http 1767 1768 def list(self, thread: str) -> SettingListResponse: 1769 """ 1770 Retrieve thread settings 1771 Returns the current settings for the specified thread. Settings control 1772 per-thread behavior such as whether the AI agent is enabled. 1773 The authenticated user must own the thread or be a member of its workspace. 1774 If settings have never been explicitly configured, defaults are returned 1775 (for example, `agent_enabled` defaults to `true`). 1776 1777 Args: 1778 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1779 1780 Returns: 1781 Successful response 1782 """ 1783 return self._http.request( 1784 f"/api/v1/threads/{thread}/settings", 1785 response_type=SettingListResponse, 1786 ) 1787 1788 def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1789 """ 1790 Update thread settings 1791 Updates the settings for the specified thread. Only fields included in 1792 the `settings` map are modified; omitted fields retain their current values. 1793 The authenticated user must own the thread or be a member of its workspace. 1794 Returns the full settings object reflecting the state after the update. 1795 Validation errors are returned as `422 Unprocessable Entity`. 1796 1797 Args: 1798 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1799 input: Request body. 1800 input.settings: Map of settings fields to update. Include only the keys you want to change. 1801 1802 Returns: 1803 The thread settings object after the update has been applied. 1804 """ 1805 return self._http.request( 1806 f"/api/v1/threads/{thread}/settings", 1807 method="PUT", 1808 body=input, 1809 response_type=ThreadSettings, 1810 )
1768 def list(self, thread: str) -> SettingListResponse: 1769 """ 1770 Retrieve thread settings 1771 Returns the current settings for the specified thread. Settings control 1772 per-thread behavior such as whether the AI agent is enabled. 1773 The authenticated user must own the thread or be a member of its workspace. 1774 If settings have never been explicitly configured, defaults are returned 1775 (for example, `agent_enabled` defaults to `true`). 1776 1777 Args: 1778 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1779 1780 Returns: 1781 Successful response 1782 """ 1783 return self._http.request( 1784 f"/api/v1/threads/{thread}/settings", 1785 response_type=SettingListResponse, 1786 )
Retrieve thread settings
Returns the current settings for the specified thread. Settings control
per-thread behavior such as whether the AI agent is enabled.
The authenticated user must own the thread or be a member of its workspace.
If settings have never been explicitly configured, defaults are returned
(for example, agent_enabled defaults to true).
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace.
Returns:
Successful response
1788 def replace(self, thread: str, input: SettingReplaceInput) -> ThreadSettings: 1789 """ 1790 Update thread settings 1791 Updates the settings for the specified thread. Only fields included in 1792 the `settings` map are modified; omitted fields retain their current values. 1793 The authenticated user must own the thread or be a member of its workspace. 1794 Returns the full settings object reflecting the state after the update. 1795 Validation errors are returned as `422 Unprocessable Entity`. 1796 1797 Args: 1798 thread: Thread ID (`thr_...`). Must belong to the authenticated user's workspace. 1799 input: Request body. 1800 input.settings: Map of settings fields to update. Include only the keys you want to change. 1801 1802 Returns: 1803 The thread settings object after the update has been applied. 1804 """ 1805 return self._http.request( 1806 f"/api/v1/threads/{thread}/settings", 1807 method="PUT", 1808 body=input, 1809 response_type=ThreadSettings, 1810 )
Update thread settings
Updates the settings for the specified thread. Only fields included in
the settings map are modified; omitted fields retain their current values.
The authenticated user must own the thread or be a member of its workspace.
Returns the full settings object reflecting the state after the update.
Validation errors are returned as 422 Unprocessable Entity.
Arguments:
- thread: Thread ID (
thr_...). Must belong to the authenticated user's workspace. - input: Request body.
- input.settings: Map of settings fields to update. Include only the keys you want to change.
Returns:
The thread settings object after the update has been applied.
1813class TagResource: 1814 def __init__(self, http: SyncHttpClient): 1815 self._http = http 1816 1817 def remove(self, thread: str) -> Thread: 1818 """ 1819 Remove tags from a thread 1820 Removes one or more status tags from the thread and returns the updated 1821 thread. Removing a tag the thread does not have is a no-op. 1822 Any participant of the thread a human member or an agent member may edit 1823 tags. Supply the tags to remove as repeated query parameters, e.g. 1824 `?tags[]=blocked&tags[]=needs-review`. 1825 1826 Args: 1827 thread: Thread ID (`thr_...`) to untag. 1828 1829 Returns: 1830 The thread object after the tags were removed. 1831 """ 1832 return self._http.request( 1833 f"/api/v1/threads/{thread}/tags", 1834 method="DELETE", 1835 response_type=Thread, 1836 ) 1837 1838 def create(self, thread: str, input: TagCreateInput) -> Thread: 1839 """ 1840 Add tags to a thread 1841 Adds one or more status tags to the thread and returns the updated thread. 1842 Any participant of the thread a human member or an agent member may edit 1843 tags; this is broader than the owner/admin permission required to update other 1844 thread fields. Adding a tag the thread already has is a no-op. Tags are 1845 normalized (trimmed and lowercased) and may contain only lowercase letters, 1846 numbers, hyphens, and underscores. 1847 1848 Args: 1849 thread: Thread ID (`thr_...`) to untag. 1850 input: Request body. 1851 input.tags: Tags to add to the thread. 1852 1853 Returns: 1854 The thread object after the tags were added. 1855 """ 1856 return self._http.request( 1857 f"/api/v1/threads/{thread}/tags", 1858 method="POST", 1859 body=input, 1860 response_type=Thread, 1861 ) 1862 1863 def replace(self, thread: str, input: TagReplaceInput) -> Thread: 1864 """ 1865 Replace a thread's tags 1866 Replaces the thread's entire set of status tags with the provided list and 1867 returns the updated thread. Passing an empty array clears all tags. 1868 Any participant of the thread a human member or an agent member may edit 1869 tags. Tags are normalized (trimmed and lowercased) and may contain only 1870 lowercase letters, numbers, hyphens, and underscores. 1871 1872 Args: 1873 thread: Thread ID (`thr_...`) to untag. 1874 input: Request body. 1875 input.tags: The complete set of tags for the thread. An empty array clears all tags. 1876 1877 Returns: 1878 The thread object after its tags were replaced. 1879 """ 1880 return self._http.request( 1881 f"/api/v1/threads/{thread}/tags", 1882 method="PUT", 1883 body=input, 1884 response_type=Thread, 1885 )
1817 def remove(self, thread: str) -> Thread: 1818 """ 1819 Remove tags from a thread 1820 Removes one or more status tags from the thread and returns the updated 1821 thread. Removing a tag the thread does not have is a no-op. 1822 Any participant of the thread a human member or an agent member may edit 1823 tags. Supply the tags to remove as repeated query parameters, e.g. 1824 `?tags[]=blocked&tags[]=needs-review`. 1825 1826 Args: 1827 thread: Thread ID (`thr_...`) to untag. 1828 1829 Returns: 1830 The thread object after the tags were removed. 1831 """ 1832 return self._http.request( 1833 f"/api/v1/threads/{thread}/tags", 1834 method="DELETE", 1835 response_type=Thread, 1836 )
Remove tags from a thread
Removes one or more status tags from the thread and returns the updated
thread. Removing a tag the thread does not have is a no-op.
Any participant of the thread a human member or an agent member may edit
tags. Supply the tags to remove as repeated query parameters, e.g.
?tags[]=blocked&tags[]=needs-review.
Arguments:
- thread: Thread ID (
thr_...) to untag.
Returns:
The thread object after the tags were removed.
1838 def create(self, thread: str, input: TagCreateInput) -> Thread: 1839 """ 1840 Add tags to a thread 1841 Adds one or more status tags to the thread and returns the updated thread. 1842 Any participant of the thread a human member or an agent member may edit 1843 tags; this is broader than the owner/admin permission required to update other 1844 thread fields. Adding a tag the thread already has is a no-op. Tags are 1845 normalized (trimmed and lowercased) and may contain only lowercase letters, 1846 numbers, hyphens, and underscores. 1847 1848 Args: 1849 thread: Thread ID (`thr_...`) to untag. 1850 input: Request body. 1851 input.tags: Tags to add to the thread. 1852 1853 Returns: 1854 The thread object after the tags were added. 1855 """ 1856 return self._http.request( 1857 f"/api/v1/threads/{thread}/tags", 1858 method="POST", 1859 body=input, 1860 response_type=Thread, 1861 )
Add tags to a thread Adds one or more status tags to the thread and returns the updated thread. Any participant of the thread a human member or an agent member may edit tags; this is broader than the owner/admin permission required to update other thread fields. Adding a tag the thread already has is a no-op. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.
Arguments:
- thread: Thread ID (
thr_...) to untag. - input: Request body.
- input.tags: Tags to add to the thread.
Returns:
The thread object after the tags were added.
1863 def replace(self, thread: str, input: TagReplaceInput) -> Thread: 1864 """ 1865 Replace a thread's tags 1866 Replaces the thread's entire set of status tags with the provided list and 1867 returns the updated thread. Passing an empty array clears all tags. 1868 Any participant of the thread a human member or an agent member may edit 1869 tags. Tags are normalized (trimmed and lowercased) and may contain only 1870 lowercase letters, numbers, hyphens, and underscores. 1871 1872 Args: 1873 thread: Thread ID (`thr_...`) to untag. 1874 input: Request body. 1875 input.tags: The complete set of tags for the thread. An empty array clears all tags. 1876 1877 Returns: 1878 The thread object after its tags were replaced. 1879 """ 1880 return self._http.request( 1881 f"/api/v1/threads/{thread}/tags", 1882 method="PUT", 1883 body=input, 1884 response_type=Thread, 1885 )
Replace a thread's tags Replaces the thread's entire set of status tags with the provided list and returns the updated thread. Passing an empty array clears all tags. Any participant of the thread a human member or an agent member may edit tags. Tags are normalized (trimmed and lowercased) and may contain only lowercase letters, numbers, hyphens, and underscores.
Arguments:
- thread: Thread ID (
thr_...) to untag. - input: Request body.
- input.tags: The complete set of tags for the thread. An empty array clears all tags.
Returns:
The thread object after its tags were replaced.
1888class ThreadResource: 1889 def __init__(self, http: SyncHttpClient): 1890 self._http = http 1891 self.computers = ComputerResource(http) 1892 self.members = ThreadMemberResource(http) 1893 self.settings = SettingResource(http) 1894 self.tags = TagResource(http) 1895 1896 def delete(self, thread: str) -> None: 1897 """ 1898 Delete a thread 1899 Permanently deletes a thread and all of its messages and artifacts. This action 1900 cannot be undone. 1901 The authenticated user must own the thread or be an owner of the team the thread 1902 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1903 1904 Args: 1905 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1906 1907 Returns: 1908 Empty response on successful deletion. 1909 """ 1910 self._http.request(f"/api/v1/threads/{thread}", method="DELETE") 1911 1912 def get(self, thread: str) -> Thread: 1913 """ 1914 Retrieve a thread 1915 Returns the full thread record for the given thread ID. The authenticated user 1916 must own the thread or be a member of the workspace it belongs to. 1917 Use this endpoint to fetch the current state of a single thread, including its 1918 title, description, and metadata. To list many threads, use the list endpoint 1919 with cursor-based pagination. 1920 1921 Args: 1922 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1923 1924 Returns: 1925 The requested thread object. 1926 """ 1927 return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread) 1928 1929 def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1930 """ 1931 Update a thread 1932 Updates one or more mutable properties of the specified thread and returns 1933 the full thread object with the applied changes. Only the fields you provide 1934 are modified; omitted fields retain their current values. 1935 If `profile_picture` is supplied, the image is uploaded before the other 1936 fields are saved, after all ordinary thread fields have passed validation. 1937 Supplying invalid base64 picture data returns 422 and no other fields are 1938 updated. 1939 Visibility can only widen: `private` may become `restricted` or `team`, and 1940 `restricted` may become `team`. The authenticated viewer must have 1941 permission to modify the thread. 1942 Mirror-thread titles, descriptions, and notification state remain editable 1943 by privileged app viewers. Mirror metadata, visibility, and membership are 1944 provider-managed and cannot be changed through this endpoint. 1945 1946 Args: 1947 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1948 input: Request body. 1949 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1950 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1951 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1952 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1953 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1954 input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed. 1955 1956 Returns: 1957 The thread object after the update has been applied. 1958 """ 1959 return self._http.request( 1960 f"/api/v1/threads/{thread}", 1961 method="PUT", 1962 body=input, 1963 response_type=Thread, 1964 ) 1965 1966 def agents(self, thread: str) -> ThreadAgentsResponse: 1967 """ 1968 List agents in a thread 1969 Returns the agents participating in the specified thread. Only personal user 1970 threads (threads owned by a single user, not a team) expose agents through 1971 this endpoint; requests for team threads return 404. 1972 The authenticated user must have visibility into the thread. Each agent entry 1973 includes display information such as name and profile picture. Thread-level 1974 overrides (e.g. a custom name or profile picture set for this thread) take 1975 precedence over the agent's default values. When the caller is the thread 1976 owner, each entry also includes an `agent_config` object describing the 1977 agent's message policy and context configuration. 1978 1979 Args: 1980 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1981 1982 Returns: 1983 Successful response 1984 """ 1985 return self._http.request( 1986 f"/api/v1/threads/{thread}/agents", 1987 response_type=ThreadAgentsResponse, 1988 ) 1989 1990 def artifacts( 1991 self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None 1992 ) -> ThreadArtifactsResponse: 1993 """ 1994 List artifacts for a thread 1995 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1996 structured outputs such as code files, documents, or generated assets created 1997 by the AI agent in response to messages in the thread. 1998 The authenticated user must have access to the specified thread. Results are 1999 returned in a single page; there is no cursor-based pagination for this endpoint. 2000 2001 Args: 2002 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 2003 group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match. 2004 group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. 2005 2006 Returns: 2007 Successful response 2008 """ 2009 query: dict[str, object] = {} 2010 if group_key is not None: 2011 query["group_key"] = group_key 2012 if group_key_prefix is not None: 2013 query["group_key_prefix"] = group_key_prefix 2014 return self._http.request( 2015 f"/api/v1/threads/{thread}/artifacts", 2016 query=query, 2017 response_type=ThreadArtifactsResponse, 2018 ) 2019 2020 def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 2021 """ 2022 Mark a thread as read 2023 Records that a user has read up to a specific message in the thread. Unread 2024 indicators and badge counts are cleared up to the specified message. 2025 You must supply exactly one of `last_read_message` or `use_latest_message`. 2026 Omitting both returns 400. If `use_latest_message` is `true` and the thread 2027 has no messages, the request succeeds silently with no state change. 2028 For server-to-server (S2S) requests where no user identity is present in the 2029 token, the `user` param is required to identify whose read state to update. 2030 2031 Args: 2032 thread: Thread ID (`thr_...`). The thread to mark as read. 2033 input: Request body. 2034 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 2035 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 2036 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 2037 2038 Returns: 2039 Empty response on success. 2040 """ 2041 self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input) 2042 2043 def messages( 2044 self, 2045 thread: str, 2046 *, 2047 before_cursor: str | None = None, 2048 after_cursor: str | None = None, 2049 metadata: dict[str, Any] | None = None, 2050 limit: int | None = None, 2051 include_replies: bool | None = None, 2052 anchor: str | None = None, 2053 direction: Literal["before", "after", "around"] | None = None, 2054 before_limit: int | None = None, 2055 after_limit: int | None = None, 2056 include_anchor: bool | None = None, 2057 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 2058 anchor_agent: str | None = None, 2059 include_reply_counts: bool | None = None, 2060 ) -> ThreadMessagesResponse: 2061 """ 2062 List messages in a thread 2063 Returns a cursor-paginated list of messages belonging to the specified thread, 2064 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 2065 to page through or bound the result set; omit both to receive the most recent page. 2066 Supply `anchor` and `direction` to fetch a window before, after, or around a 2067 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 2068 resolve the anchor from the latest embedded-agent message, and add 2069 `anchor_agent` to scope that resolution to a single sender agent. 2070 Supply `metadata` as a JSON-encoded structured expression to filter message 2071 metadata before cursor pagination or anchored window limits are applied. 2072 The authenticated user must have access to the thread's owner (workspace or user). 2073 A 403 is returned if the thread exists but is not accessible to the caller; a 404 2074 is returned if the thread does not exist or is not visible to the authenticated user. 2075 Threads with `kind: feed` return only top-level posts, each with its newest 2076 replies inline under `replies` and reply cursors for paging the rest. 2077 Set `include_replies: true` to page messages and replies together by creation 2078 order instead, without inline reply previews. Metadata filters and the page 2079 limit apply to the updates themselves, before any client-side grouping. 2080 Pass `include_reply_counts: true` to annotate each message with the number of 2081 threaded replies it has received. This adds a small amount of latency and should 2082 be omitted when reply counts are not needed. 2083 2084 Args: 2085 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 2086 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 2087 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 2088 metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. 2089 limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100. 2090 include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. 2091 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 2092 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 2093 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. 2094 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. 2095 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 2096 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 2097 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 2098 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 2099 2100 Returns: 2101 Successful response 2102 """ 2103 query: dict[str, object] = {} 2104 if before_cursor is not None: 2105 query["before_cursor"] = before_cursor 2106 if after_cursor is not None: 2107 query["after_cursor"] = after_cursor 2108 if metadata is not None: 2109 query["metadata"] = metadata 2110 if limit is not None: 2111 query["limit"] = limit 2112 if include_replies is not None: 2113 query["include_replies"] = include_replies 2114 if anchor is not None: 2115 query["anchor"] = anchor 2116 if direction is not None: 2117 query["direction"] = direction 2118 if before_limit is not None: 2119 query["before_limit"] = before_limit 2120 if after_limit is not None: 2121 query["after_limit"] = after_limit 2122 if include_anchor is not None: 2123 query["include_anchor"] = include_anchor 2124 if anchor_agent_mode is not None: 2125 query["anchor_agent_mode"] = anchor_agent_mode 2126 if anchor_agent is not None: 2127 query["anchor_agent"] = anchor_agent 2128 if include_reply_counts is not None: 2129 query["include_reply_counts"] = include_reply_counts 2130 return self._http.request( 2131 f"/api/v1/threads/{thread}/messages", 2132 query=query, 2133 response_type=ThreadMessagesResponse, 2134 ) 2135 2136 def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 2137 """ 2138 Update a thread's profile picture 2139 Uploads a new profile picture for the specified thread and returns the updated 2140 thread object. The image must be supplied as a base64-encoded string with its 2141 MIME type. 2142 The authenticated user must own the thread or be a team owner of the workspace 2143 the thread belongs to. Supplying invalid base64 data returns 422. 2144 2145 Args: 2146 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 2147 input: Request body. 2148 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 2149 2150 Returns: 2151 The thread object after the profile picture has been updated. 2152 """ 2153 return self._http.request( 2154 f"/api/v1/threads/{thread}/picture", 2155 method="PUT", 2156 body=input, 2157 response_type=Thread, 2158 ) 2159 2160 def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 2161 """ 2162 Retrieve a thread's read status 2163 Returns the read status of a thread for the specified user, including the ID 2164 of the last message they have read and the number of unread messages remaining. 2165 For user-authenticated requests, the status is always returned for the 2166 authenticated user and the `user` parameter is ignored. For server-to-server 2167 (S2S) requests, the `user` parameter is required and must be a valid user ID. 2168 Returns 404 if the thread does not exist or the caller does not have access 2169 to it. 2170 2171 Args: 2172 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 2173 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 2174 2175 Returns: 2176 The read status record for the requested thread and user. 2177 """ 2178 query: dict[str, object] = {} 2179 if user is not None: 2180 query["user"] = user 2181 return self._http.request( 2182 f"/api/v1/threads/{thread}/read_status", 2183 query=query, 2184 response_type=ThreadReadStatus, 2185 ) 2186 2187 def search( 2188 self, 2189 thread: str, 2190 q: str, 2191 *, 2192 app: str | None = None, 2193 limit: int | None = None, 2194 mode: Literal["text", "embedding", "hybrid"] | None = None, 2195 before_cursor: str | None = None, 2196 after_cursor: str | None = None, 2197 ) -> ThreadSearchResponse: 2198 """ 2199 Search messages in a thread 2200 Searches canonical message content in the specified thread. `"text"` mode 2201 performs the existing case-insensitive substring search, `"embedding"` ranks 2202 stored message embeddings by cosine similarity, and `"hybrid"` combines the 2203 text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages 2204 visible to the authenticated caller are considered. 2205 Results are intentionally lean: each row contains a bounded content snippet, 2206 sender identity, timestamp, and a small allowlisted structured-post evidence 2207 projection. Attachments, reactions, ACLs, and arbitrary metadata are neither 2208 hydrated nor serialized. At most 20 results are returned. Text results 2209 support chronological cursor pagination. Embedding and hybrid results are 2210 relevance-ranked single pages and return null cursors. 2211 2212 Args: 2213 thread: Thread ID (`thr_...`). Must be visible to the authenticated caller. 2214 app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount. 2215 q: Text or semantic search query. Must contain 3 to 200 characters after trimming. 2216 limit: Maximum number of results. Defaults to 20 and is capped at 20. 2217 mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings. 2218 before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches. 2219 after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches. 2220 2221 Returns: 2222 Successful response 2223 """ 2224 query: dict[str, object] = {} 2225 if app is not None: 2226 query["app"] = app 2227 query["q"] = q 2228 if limit is not None: 2229 query["limit"] = limit 2230 if mode is not None: 2231 query["mode"] = mode 2232 if before_cursor is not None: 2233 query["before_cursor"] = before_cursor 2234 if after_cursor is not None: 2235 query["after_cursor"] = after_cursor 2236 return self._http.request( 2237 f"/api/v1/threads/{thread}/search", 2238 query=query, 2239 response_type=ThreadSearchResponse, 2240 ) 2241 2242 def trajectories( 2243 self, 2244 thread: str, 2245 *, 2246 before_cursor: str | None = None, 2247 after_cursor: str | None = None, 2248 limit: int | None = None, 2249 message: str | None = None, 2250 ) -> ThreadTrajectoriesResponse: 2251 """ 2252 List trajectories for a thread 2253 Returns a cursor-paginated list of thread message trajectories associated with the 2254 specified thread. Each trajectory links a user message and its agent response to the 2255 underlying AI trajectory record that captured the model's reasoning steps. 2256 The authenticated user must own the thread or be a member of the workspace it belongs 2257 to. Results are returned in reverse chronological order by default. Use `before_cursor` 2258 and `after_cursor` to navigate pages; provide at most one cursor per request. 2259 Optionally filter results to trajectories produced in response to a specific message 2260 by supplying the `message` parameter. When no trajectories match the query, `data` 2261 is an empty array and both cursor fields are `null`. A cursor that cannot be decoded 2262 returns a 400 `invalid_cursor` error. 2263 2264 Args: 2265 thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace. 2266 before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position. 2267 after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position. 2268 limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100. 2269 message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message. 2270 2271 Returns: 2272 Successful response 2273 """ 2274 query: dict[str, object] = {} 2275 if before_cursor is not None: 2276 query["before_cursor"] = before_cursor 2277 if after_cursor is not None: 2278 query["after_cursor"] = after_cursor 2279 if limit is not None: 2280 query["limit"] = limit 2281 if message is not None: 2282 query["message"] = message 2283 return self._http.request( 2284 f"/api/v1/threads/{thread}/trajectories", 2285 query=query, 2286 response_type=ThreadTrajectoriesResponse, 2287 )
1896 def delete(self, thread: str) -> None: 1897 """ 1898 Delete a thread 1899 Permanently deletes a thread and all of its messages and artifacts. This action 1900 cannot be undone. 1901 The authenticated user must own the thread or be an owner of the team the thread 1902 belongs to. Attempting to delete a thread owned by another user or team returns 403. 1903 1904 Args: 1905 thread: Thread ID (`thr_...`). The authenticated user must own this thread. 1906 1907 Returns: 1908 Empty response on successful deletion. 1909 """ 1910 self._http.request(f"/api/v1/threads/{thread}", method="DELETE")
Delete a thread Permanently deletes a thread and all of its messages and artifacts. This action cannot be undone. The authenticated user must own the thread or be an owner of the team the thread belongs to. Attempting to delete a thread owned by another user or team returns 403.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must own this thread.
Returns:
Empty response on successful deletion.
1912 def get(self, thread: str) -> Thread: 1913 """ 1914 Retrieve a thread 1915 Returns the full thread record for the given thread ID. The authenticated user 1916 must own the thread or be a member of the workspace it belongs to. 1917 Use this endpoint to fetch the current state of a single thread, including its 1918 title, description, and metadata. To list many threads, use the list endpoint 1919 with cursor-based pagination. 1920 1921 Args: 1922 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 1923 1924 Returns: 1925 The requested thread object. 1926 """ 1927 return self._http.request(f"/api/v1/threads/{thread}", response_type=Thread)
Retrieve a thread Returns the full thread record for the given thread ID. The authenticated user must own the thread or be a member of the workspace it belongs to. Use this endpoint to fetch the current state of a single thread, including its title, description, and metadata. To list many threads, use the list endpoint with cursor-based pagination.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread.
Returns:
The requested thread object.
1929 def replace(self, thread: str, input: ThreadReplaceInput) -> Thread: 1930 """ 1931 Update a thread 1932 Updates one or more mutable properties of the specified thread and returns 1933 the full thread object with the applied changes. Only the fields you provide 1934 are modified; omitted fields retain their current values. 1935 If `profile_picture` is supplied, the image is uploaded before the other 1936 fields are saved, after all ordinary thread fields have passed validation. 1937 Supplying invalid base64 picture data returns 422 and no other fields are 1938 updated. 1939 Visibility can only widen: `private` may become `restricted` or `team`, and 1940 `restricted` may become `team`. The authenticated viewer must have 1941 permission to modify the thread. 1942 Mirror-thread titles, descriptions, and notification state remain editable 1943 by privileged app viewers. Mirror metadata, visibility, and membership are 1944 provider-managed and cannot be changed through this endpoint. 1945 1946 Args: 1947 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 1948 input: Request body. 1949 input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided. 1950 input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata. 1951 input.muted: When `true`, suppresses notifications for new messages in this thread for the authenticated user. 1952 input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image. 1953 input.title: Human-readable display name for the thread. Replaces the existing title when provided. 1954 input.visibility: Widen a team-owned thread: `private` may become `restricted` or `team`, and `restricted` may become `team`. Visibility cannot be narrowed. 1955 1956 Returns: 1957 The thread object after the update has been applied. 1958 """ 1959 return self._http.request( 1960 f"/api/v1/threads/{thread}", 1961 method="PUT", 1962 body=input, 1963 response_type=Thread, 1964 )
Update a thread
Updates one or more mutable properties of the specified thread and returns
the full thread object with the applied changes. Only the fields you provide
are modified; omitted fields retain their current values.
If profile_picture is supplied, the image is uploaded before the other
fields are saved, after all ordinary thread fields have passed validation.
Supplying invalid base64 picture data returns 422 and no other fields are
updated.
Visibility can only widen: private may become restricted or team, and
restricted may become team. The authenticated viewer must have
permission to modify the thread.
Mirror-thread titles, descriptions, and notification state remain editable
by privileged app viewers. Mirror metadata, visibility, and membership are
provider-managed and cannot be changed through this endpoint.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.description: Optional longer text describing the thread's purpose. Replaces the existing description when provided.
- input.metadata: Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.
- input.muted: When
true, suppresses notifications for new messages in this thread for the authenticated user. - input.profile_picture: New profile picture for the thread. Provide all three inner fields to replace the existing image.
- input.title: Human-readable display name for the thread. Replaces the existing title when provided.
- input.visibility: Widen a team-owned thread:
privatemay becomerestrictedorteam, andrestrictedmay becometeam. Visibility cannot be narrowed.
Returns:
The thread object after the update has been applied.
1966 def agents(self, thread: str) -> ThreadAgentsResponse: 1967 """ 1968 List agents in a thread 1969 Returns the agents participating in the specified thread. Only personal user 1970 threads (threads owned by a single user, not a team) expose agents through 1971 this endpoint; requests for team threads return 404. 1972 The authenticated user must have visibility into the thread. Each agent entry 1973 includes display information such as name and profile picture. Thread-level 1974 overrides (e.g. a custom name or profile picture set for this thread) take 1975 precedence over the agent's default values. When the caller is the thread 1976 owner, each entry also includes an `agent_config` object describing the 1977 agent's message policy and context configuration. 1978 1979 Args: 1980 thread: Thread ID (`thr_...`). Must be a personal user thread visible to the authenticated user. 1981 1982 Returns: 1983 Successful response 1984 """ 1985 return self._http.request( 1986 f"/api/v1/threads/{thread}/agents", 1987 response_type=ThreadAgentsResponse, 1988 )
List agents in a thread
Returns the agents participating in the specified thread. Only personal user
threads (threads owned by a single user, not a team) expose agents through
this endpoint; requests for team threads return 404.
The authenticated user must have visibility into the thread. Each agent entry
includes display information such as name and profile picture. Thread-level
overrides (e.g. a custom name or profile picture set for this thread) take
precedence over the agent's default values. When the caller is the thread
owner, each entry also includes an agent_config object describing the
agent's message policy and context configuration.
Arguments:
- thread: Thread ID (
thr_...). Must be a personal user thread visible to the authenticated user.
Returns:
Successful response
1990 def artifacts( 1991 self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None 1992 ) -> ThreadArtifactsResponse: 1993 """ 1994 List artifacts for a thread 1995 Returns all artifacts produced during a thread's AI conversation. Artifacts are 1996 structured outputs such as code files, documents, or generated assets created 1997 by the AI agent in response to messages in the thread. 1998 The authenticated user must have access to the specified thread. Results are 1999 returned in a single page; there is no cursor-based pagination for this endpoint. 2000 2001 Args: 2002 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user. 2003 group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match. 2004 group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key. 2005 2006 Returns: 2007 Successful response 2008 """ 2009 query: dict[str, object] = {} 2010 if group_key is not None: 2011 query["group_key"] = group_key 2012 if group_key_prefix is not None: 2013 query["group_key_prefix"] = group_key_prefix 2014 return self._http.request( 2015 f"/api/v1/threads/{thread}/artifacts", 2016 query=query, 2017 response_type=ThreadArtifactsResponse, 2018 )
List artifacts for a thread Returns all artifacts produced during a thread's AI conversation. Artifacts are structured outputs such as code files, documents, or generated assets created by the AI agent in response to messages in the thread. The authenticated user must have access to the specified thread. Results are returned in a single page; there is no cursor-based pagination for this endpoint.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user. - group_key: Case-sensitive exact group key. Mutually exclusive with group_key_prefix; null keys do not match.
- group_key_prefix: Nonempty case-sensitive literal prefix (percent, underscore and backslash are literal). Mutually exclusive with group_key.
Returns:
Successful response
2020 def mark_read(self, thread: str, input: ThreadMarkReadInput) -> None: 2021 """ 2022 Mark a thread as read 2023 Records that a user has read up to a specific message in the thread. Unread 2024 indicators and badge counts are cleared up to the specified message. 2025 You must supply exactly one of `last_read_message` or `use_latest_message`. 2026 Omitting both returns 400. If `use_latest_message` is `true` and the thread 2027 has no messages, the request succeeds silently with no state change. 2028 For server-to-server (S2S) requests where no user identity is present in the 2029 token, the `user` param is required to identify whose read state to update. 2030 2031 Args: 2032 thread: Thread ID (`thr_...`). The thread to mark as read. 2033 input: Request body. 2034 input.last_read_message: Message ID (`msg_...`) to record as the last read message. Mutually exclusive with `use_latest_message`. 2035 input.use_latest_message: When `true`, marks the thread as read up to the latest message. Mutually exclusive with `last_read_message`. 2036 input.user: User ID (`usr_...`) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token. 2037 2038 Returns: 2039 Empty response on success. 2040 """ 2041 self._http.request(f"/api/v1/threads/{thread}/mark_read", method="POST", body=input)
Mark a thread as read
Records that a user has read up to a specific message in the thread. Unread
indicators and badge counts are cleared up to the specified message.
You must supply exactly one of last_read_message or use_latest_message.
Omitting both returns 400. If use_latest_message is true and the thread
has no messages, the request succeeds silently with no state change.
For server-to-server (S2S) requests where no user identity is present in the
token, the user param is required to identify whose read state to update.
Arguments:
- thread: Thread ID (
thr_...). The thread to mark as read. - input: Request body.
- input.last_read_message: Message ID (
msg_...) to record as the last read message. Mutually exclusive withuse_latest_message. - input.use_latest_message: When
true, marks the thread as read up to the latest message. Mutually exclusive withlast_read_message. - input.user: User ID (
usr_...) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.
Returns:
Empty response on success.
2043 def messages( 2044 self, 2045 thread: str, 2046 *, 2047 before_cursor: str | None = None, 2048 after_cursor: str | None = None, 2049 metadata: dict[str, Any] | None = None, 2050 limit: int | None = None, 2051 include_replies: bool | None = None, 2052 anchor: str | None = None, 2053 direction: Literal["before", "after", "around"] | None = None, 2054 before_limit: int | None = None, 2055 after_limit: int | None = None, 2056 include_anchor: bool | None = None, 2057 anchor_agent_mode: Literal["cli", "embedded"] | None = None, 2058 anchor_agent: str | None = None, 2059 include_reply_counts: bool | None = None, 2060 ) -> ThreadMessagesResponse: 2061 """ 2062 List messages in a thread 2063 Returns a cursor-paginated list of messages belonging to the specified thread, 2064 ordered from oldest to newest. Supply `before_cursor`, `after_cursor`, or both 2065 to page through or bound the result set; omit both to receive the most recent page. 2066 Supply `anchor` and `direction` to fetch a window before, after, or around a 2067 specific message. Use `anchor=last_matching&anchor_agent_mode=embedded` to 2068 resolve the anchor from the latest embedded-agent message, and add 2069 `anchor_agent` to scope that resolution to a single sender agent. 2070 Supply `metadata` as a JSON-encoded structured expression to filter message 2071 metadata before cursor pagination or anchored window limits are applied. 2072 The authenticated user must have access to the thread's owner (workspace or user). 2073 A 403 is returned if the thread exists but is not accessible to the caller; a 404 2074 is returned if the thread does not exist or is not visible to the authenticated user. 2075 Threads with `kind: feed` return only top-level posts, each with its newest 2076 replies inline under `replies` and reply cursors for paging the rest. 2077 Set `include_replies: true` to page messages and replies together by creation 2078 order instead, without inline reply previews. Metadata filters and the page 2079 limit apply to the updates themselves, before any client-side grouping. 2080 Pass `include_reply_counts: true` to annotate each message with the number of 2081 threaded replies it has received. This adds a small amount of latency and should 2082 be omitted when reply counts are not needed. 2083 2084 Args: 2085 thread: Thread ID (`thr_...`). The authenticated user must have access to this thread. 2086 before_cursor: Opaque cursor returned in a previous response's `before_cursor` field. When provided, returns messages immediately before that position. May be combined with `after_cursor` to bound a range. 2087 after_cursor: Opaque cursor returned in a previous response's `after_cursor` field. When provided, returns messages immediately after that position. May be combined with `before_cursor` to bound a range. 2088 metadata: Structured metadata filter expression. Only messages whose `metadata` object satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. 2089 limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100. 2090 include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false. 2091 anchor: Message ID (`msg_...`) to use as a window anchor, or `last_matching` to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with `before_cursor` or `after_cursor`. 2092 direction: Window direction relative to `anchor`. `before` returns older messages, `after` returns newer messages, and `around` returns messages on both sides. Defaults to `after` when `anchor` is supplied. `direction=around` cannot be combined with an explicit `limit`; use `before_limit` and `after_limit`. 2093 before_limit: For `direction=around`, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. 2094 after_limit: For `direction=around`, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. 2095 include_anchor: Whether to include the anchor message in a window response. Defaults to `true` for `direction=around`; ignored for ordinary cursor pagination and one-sided windows. 2096 anchor_agent_mode: When `anchor=last_matching`, resolve the anchor from the latest message with this local agent execution mode. 2097 anchor_agent: When `anchor=last_matching`, scope the anchor resolution to messages sent by this agent (`agi_...`). Combine with `anchor_agent_mode` to resolve the latest message from a specific agent in a given mode. 2098 include_reply_counts: When `true`, each message in the response is annotated with its threaded reply count. Defaults to `false`. Adds latency; omit when reply counts are not needed. 2099 2100 Returns: 2101 Successful response 2102 """ 2103 query: dict[str, object] = {} 2104 if before_cursor is not None: 2105 query["before_cursor"] = before_cursor 2106 if after_cursor is not None: 2107 query["after_cursor"] = after_cursor 2108 if metadata is not None: 2109 query["metadata"] = metadata 2110 if limit is not None: 2111 query["limit"] = limit 2112 if include_replies is not None: 2113 query["include_replies"] = include_replies 2114 if anchor is not None: 2115 query["anchor"] = anchor 2116 if direction is not None: 2117 query["direction"] = direction 2118 if before_limit is not None: 2119 query["before_limit"] = before_limit 2120 if after_limit is not None: 2121 query["after_limit"] = after_limit 2122 if include_anchor is not None: 2123 query["include_anchor"] = include_anchor 2124 if anchor_agent_mode is not None: 2125 query["anchor_agent_mode"] = anchor_agent_mode 2126 if anchor_agent is not None: 2127 query["anchor_agent"] = anchor_agent 2128 if include_reply_counts is not None: 2129 query["include_reply_counts"] = include_reply_counts 2130 return self._http.request( 2131 f"/api/v1/threads/{thread}/messages", 2132 query=query, 2133 response_type=ThreadMessagesResponse, 2134 )
List messages in a thread
Returns a cursor-paginated list of messages belonging to the specified thread,
ordered from oldest to newest. Supply before_cursor, after_cursor, or both
to page through or bound the result set; omit both to receive the most recent page.
Supply anchor and direction to fetch a window before, after, or around a
specific message. Use anchor=last_matching&anchor_agent_mode=embedded to
resolve the anchor from the latest embedded-agent message, and add
anchor_agent to scope that resolution to a single sender agent.
Supply metadata as a JSON-encoded structured expression to filter message
metadata before cursor pagination or anchored window limits are applied.
The authenticated user must have access to the thread's owner (workspace or user).
A 403 is returned if the thread exists but is not accessible to the caller; a 404
is returned if the thread does not exist or is not visible to the authenticated user.
Threads with kind: feed return only top-level posts, each with its newest
replies inline under replies and reply cursors for paging the rest.
Set include_replies: true to page messages and replies together by creation
order instead, without inline reply previews. Metadata filters and the page
limit apply to the updates themselves, before any client-side grouping.
Pass include_reply_counts: true to annotate each message with the number of
threaded replies it has received. This adds a small amount of latency and should
be omitted when reply counts are not needed.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have access to this thread. - before_cursor: Opaque cursor returned in a previous response's
before_cursorfield. When provided, returns messages immediately before that position. May be combined withafter_cursorto bound a range. - after_cursor: Opaque cursor returned in a previous response's
after_cursorfield. When provided, returns messages immediately after that position. May be combined withbefore_cursorto bound a range. - metadata: Structured metadata filter expression. Only messages whose
metadataobject satisfies the expression are returned. The filter is applied before cursor pagination and anchored window limits. - limit: Maximum number of messages to return per page. Defaults to 20; maximum is 100.
- include_replies: Include replies in feed message pagination instead of returning root posts with inline replies. Defaults to false.
- anchor: Message ID (
msg_...) to use as a window anchor, orlast_matchingto resolve the anchor from the latest message matching the anchor filters. Cannot be combined withbefore_cursororafter_cursor. - direction: Window direction relative to
anchor.beforereturns older messages,afterreturns newer messages, andaroundreturns messages on both sides. Defaults toafterwhenanchoris supplied.direction=aroundcannot be combined with an explicitlimit; usebefore_limitandafter_limit. - before_limit: For
direction=around, maximum number of messages older than the anchor. Defaults to 20; maximum is 100. - after_limit: For
direction=around, maximum number of messages newer than the anchor. Defaults to 20; maximum is 100. - include_anchor: Whether to include the anchor message in a window response. Defaults to
truefordirection=around; ignored for ordinary cursor pagination and one-sided windows. - anchor_agent_mode: When
anchor=last_matching, resolve the anchor from the latest message with this local agent execution mode. - anchor_agent: When
anchor=last_matching, scope the anchor resolution to messages sent by this agent (agi_...). Combine withanchor_agent_modeto resolve the latest message from a specific agent in a given mode. - include_reply_counts: When
true, each message in the response is annotated with its threaded reply count. Defaults tofalse. Adds latency; omit when reply counts are not needed.
Returns:
Successful response
2136 def picture(self, thread: str, input: ThreadPictureInput) -> Thread: 2137 """ 2138 Update a thread's profile picture 2139 Uploads a new profile picture for the specified thread and returns the updated 2140 thread object. The image must be supplied as a base64-encoded string with its 2141 MIME type. 2142 The authenticated user must own the thread or be a team owner of the workspace 2143 the thread belongs to. Supplying invalid base64 data returns 422. 2144 2145 Args: 2146 thread: Thread ID (`thr_...`). The authenticated user must have permission to update this thread. 2147 input: Request body. 2148 input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type. 2149 2150 Returns: 2151 The thread object after the profile picture has been updated. 2152 """ 2153 return self._http.request( 2154 f"/api/v1/threads/{thread}/picture", 2155 method="PUT", 2156 body=input, 2157 response_type=Thread, 2158 )
Update a thread's profile picture Uploads a new profile picture for the specified thread and returns the updated thread object. The image must be supplied as a base64-encoded string with its MIME type. The authenticated user must own the thread or be a team owner of the workspace the thread belongs to. Supplying invalid base64 data returns 422.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must have permission to update this thread. - input: Request body.
- input.picture: Profile picture payload. Must include the base64-encoded image data and its MIME type.
Returns:
The thread object after the profile picture has been updated.
2160 def read_status(self, thread: str, *, user: str | None = None) -> ThreadReadStatus: 2161 """ 2162 Retrieve a thread's read status 2163 Returns the read status of a thread for the specified user, including the ID 2164 of the last message they have read and the number of unread messages remaining. 2165 For user-authenticated requests, the status is always returned for the 2166 authenticated user and the `user` parameter is ignored. For server-to-server 2167 (S2S) requests, the `user` parameter is required and must be a valid user ID. 2168 Returns 404 if the thread does not exist or the caller does not have access 2169 to it. 2170 2171 Args: 2172 thread: Thread ID (`thr_...`). Must be accessible to the authenticated user or, for S2S requests, to the specified user. 2173 user: User ID (`usr_...`) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user. 2174 2175 Returns: 2176 The read status record for the requested thread and user. 2177 """ 2178 query: dict[str, object] = {} 2179 if user is not None: 2180 query["user"] = user 2181 return self._http.request( 2182 f"/api/v1/threads/{thread}/read_status", 2183 query=query, 2184 response_type=ThreadReadStatus, 2185 )
Retrieve a thread's read status
Returns the read status of a thread for the specified user, including the ID
of the last message they have read and the number of unread messages remaining.
For user-authenticated requests, the status is always returned for the
authenticated user and the user parameter is ignored. For server-to-server
(S2S) requests, the user parameter is required and must be a valid user ID.
Returns 404 if the thread does not exist or the caller does not have access
to it.
Arguments:
- thread: Thread ID (
thr_...). Must be accessible to the authenticated user or, for S2S requests, to the specified user. - user: User ID (
usr_...) whose read status to retrieve. Required for S2S requests; ignored for user-authenticated requests, which always return the status for the authenticated user.
Returns:
The read status record for the requested thread and user.
2187 def search( 2188 self, 2189 thread: str, 2190 q: str, 2191 *, 2192 app: str | None = None, 2193 limit: int | None = None, 2194 mode: Literal["text", "embedding", "hybrid"] | None = None, 2195 before_cursor: str | None = None, 2196 after_cursor: str | None = None, 2197 ) -> ThreadSearchResponse: 2198 """ 2199 Search messages in a thread 2200 Searches canonical message content in the specified thread. `"text"` mode 2201 performs the existing case-insensitive substring search, `"embedding"` ranks 2202 stored message embeddings by cosine similarity, and `"hybrid"` combines the 2203 text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages 2204 visible to the authenticated caller are considered. 2205 Results are intentionally lean: each row contains a bounded content snippet, 2206 sender identity, timestamp, and a small allowlisted structured-post evidence 2207 projection. Attachments, reactions, ACLs, and arbitrary metadata are neither 2208 hydrated nor serialized. At most 20 results are returned. Text results 2209 support chronological cursor pagination. Embedding and hybrid results are 2210 relevance-ranked single pages and return null cursors. 2211 2212 Args: 2213 thread: Thread ID (`thr_...`). Must be visible to the authenticated caller. 2214 app: App ID (`app_...`). Required by the protected developer mount and omitted from the public mount. 2215 q: Text or semantic search query. Must contain 3 to 200 characters after trimming. 2216 limit: Maximum number of results. Defaults to 20 and is capped at 20. 2217 mode: Search algorithm: `text` for substring matching, `embedding` for cosine similarity, or `hybrid` for RRF over both rankings. 2218 before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches. 2219 after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches. 2220 2221 Returns: 2222 Successful response 2223 """ 2224 query: dict[str, object] = {} 2225 if app is not None: 2226 query["app"] = app 2227 query["q"] = q 2228 if limit is not None: 2229 query["limit"] = limit 2230 if mode is not None: 2231 query["mode"] = mode 2232 if before_cursor is not None: 2233 query["before_cursor"] = before_cursor 2234 if after_cursor is not None: 2235 query["after_cursor"] = after_cursor 2236 return self._http.request( 2237 f"/api/v1/threads/{thread}/search", 2238 query=query, 2239 response_type=ThreadSearchResponse, 2240 )
Search messages in a thread
Searches canonical message content in the specified thread. "text" mode
performs the existing case-insensitive substring search, "embedding" ranks
stored message embeddings by cosine similarity, and "hybrid" combines the
text and embedding rankings with Reciprocal Rank Fusion (RRF). Only messages
visible to the authenticated caller are considered.
Results are intentionally lean: each row contains a bounded content snippet,
sender identity, timestamp, and a small allowlisted structured-post evidence
projection. Attachments, reactions, ACLs, and arbitrary metadata are neither
hydrated nor serialized. At most 20 results are returned. Text results
support chronological cursor pagination. Embedding and hybrid results are
relevance-ranked single pages and return null cursors.
Arguments:
- thread: Thread ID (
thr_...). Must be visible to the authenticated caller. - app: App ID (
app_...). Required by the protected developer mount and omitted from the public mount. - q: Text or semantic search query. Must contain 3 to 200 characters after trimming.
- limit: Maximum number of results. Defaults to 20 and is capped at 20.
- mode: Search algorithm:
textfor substring matching,embeddingfor cosine similarity, orhybridfor RRF over both rankings. - before_cursor: Text mode only. Opaque cursor returned by a previous page; fetches older matches.
- after_cursor: Text mode only. Opaque cursor returned by a previous page; fetches newer matches.
Returns:
Successful response
2242 def trajectories( 2243 self, 2244 thread: str, 2245 *, 2246 before_cursor: str | None = None, 2247 after_cursor: str | None = None, 2248 limit: int | None = None, 2249 message: str | None = None, 2250 ) -> ThreadTrajectoriesResponse: 2251 """ 2252 List trajectories for a thread 2253 Returns a cursor-paginated list of thread message trajectories associated with the 2254 specified thread. Each trajectory links a user message and its agent response to the 2255 underlying AI trajectory record that captured the model's reasoning steps. 2256 The authenticated user must own the thread or be a member of the workspace it belongs 2257 to. Results are returned in reverse chronological order by default. Use `before_cursor` 2258 and `after_cursor` to navigate pages; provide at most one cursor per request. 2259 Optionally filter results to trajectories produced in response to a specific message 2260 by supplying the `message` parameter. When no trajectories match the query, `data` 2261 is an empty array and both cursor fields are `null`. A cursor that cannot be decoded 2262 returns a 400 `invalid_cursor` error. 2263 2264 Args: 2265 thread: Thread ID (`thr_...`). The authenticated user must own this thread or belong to its workspace. 2266 before_cursor: Opaque cursor from a previous response's `before_cursor` field. Returns the page of results preceding that cursor position. 2267 after_cursor: Opaque cursor from a previous response's `after_cursor` field. Returns the page of results following that cursor position. 2268 limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100. 2269 message: Message ID (`msg_...`). When provided, limits results to trajectories associated with this specific message. 2270 2271 Returns: 2272 Successful response 2273 """ 2274 query: dict[str, object] = {} 2275 if before_cursor is not None: 2276 query["before_cursor"] = before_cursor 2277 if after_cursor is not None: 2278 query["after_cursor"] = after_cursor 2279 if limit is not None: 2280 query["limit"] = limit 2281 if message is not None: 2282 query["message"] = message 2283 return self._http.request( 2284 f"/api/v1/threads/{thread}/trajectories", 2285 query=query, 2286 response_type=ThreadTrajectoriesResponse, 2287 )
List trajectories for a thread
Returns a cursor-paginated list of thread message trajectories associated with the
specified thread. Each trajectory links a user message and its agent response to the
underlying AI trajectory record that captured the model's reasoning steps.
The authenticated user must own the thread or be a member of the workspace it belongs
to. Results are returned in reverse chronological order by default. Use before_cursor
and after_cursor to navigate pages; provide at most one cursor per request.
Optionally filter results to trajectories produced in response to a specific message
by supplying the message parameter. When no trajectories match the query, data
is an empty array and both cursor fields are null. A cursor that cannot be decoded
returns a 400 invalid_cursor error.
Arguments:
- thread: Thread ID (
thr_...). The authenticated user must own this thread or belong to its workspace. - before_cursor: Opaque cursor from a previous response's
before_cursorfield. Returns the page of results preceding that cursor position. - after_cursor: Opaque cursor from a previous response's
after_cursorfield. Returns the page of results following that cursor position. - limit: Maximum number of trajectories to return per page. Defaults to 20; maximum is 100.
- message: Message ID (
msg_...). When provided, limits results to trajectories associated with this specific message.
Returns:
Successful response