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        )
class ComputerCreateInputAclAddItem(typing.TypedDict):
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"`.'
actions: Required[list[str]]

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None

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".

principal_type: Required[str]

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ComputerCreateInputAclGrantsItem(typing.TypedDict):
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"`.'
actions: Required[list[str]]

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None

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".

principal_type: Required[str]

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ComputerCreateInputAclRemoveItem(typing.TypedDict):
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"`.'
principal: str | None

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".

principal_type: Required[str]

The kind of principal to remove. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ComputerCreateInputAcl(typing.TypedDict):
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`."
add: list[ComputerCreateInputAclAddItem] | None

Patch mode: grants to add or merge into the existing list. Cannot be combined with grants.

grants: list[ComputerCreateInputAclGrantsItem] | None

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.

remove: list[ComputerCreateInputAclRemoveItem] | None

Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.

class ComputerCreateInput(typing.TypedDict):
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

Initial access control list.

config: dict[str, typing.Any] | None

Provider configuration; top-level provider takes precedence.

key: str | None

Stable key unique within this thread.

metadata: dict[str, typing.Any] | None

Arbitrary computer metadata.

name: Required[str]

Human-readable computer name.

provider: str | None

Compute backend: sprites (default), vercel or e2b.

region: str | None

Provider region; defaults to iad.

class ThreadMemberCreateInput(typing.TypedDict):
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

agent: str | None

Agent ID of the principal to add. Required when type is "agent".

membership_type: str | None

Role granted to the new member. One of "owner" or "member". Defaults to "member".

type: Required[str]

Kind of principal being added. Must be "user" or "agent".

user: str | None

User ID of the principal to add. Required when type is "user".

class SettingReplaceInput(typing.TypedDict):
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

settings: dict[str, typing.Any]

Map of settings fields to update. Include only the keys you want to change.

class TagCreateInput(typing.TypedDict):
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

tags: list[str]

Tags to add to the thread.

class TagReplaceInput(typing.TypedDict):
 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

tags: list[str]

The complete set of tags for the thread. An empty array clears all tags.

class ThreadReplaceInputProfilePicture(typing.TypedDict):
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"`.'
data: str | None

Base64-encoded image payload. Must be a valid base64 string.

filename: str | None

Original filename of the image, e.g. "avatar.png". Used for storage metadata.

mime_type: str | None

MIME type of the image, e.g. "image/jpeg" or "image/png".

class ThreadReplaceInput(typing.TypedDict):
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

description: str | None

Optional longer text describing the thread's purpose. Replaces the existing description when provided.

metadata: dict[str, typing.Any] | None

Arbitrary key-value metadata to store on the thread. Merged with or replaces existing metadata.

muted: bool | None

When true, suppresses notifications for new messages in this thread for the authenticated user.

profile_picture: ThreadReplaceInputProfilePicture | None

New profile picture for the thread. Provide all three inner fields to replace the existing image.

title: str | None

Human-readable display name for the thread. Replaces the existing title when provided.

visibility: Optional[Literal['private', 'restricted', 'team']]

Widen a team-owned thread: private may become restricted or team, and restricted may become team. Visibility cannot be narrowed.

class ThreadMarkReadInput(typing.TypedDict):
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

last_read_message: str | None

Message ID (msg_...) to record as the last read message. Mutually exclusive with use_latest_message.

use_latest_message: bool | None

When true, marks the thread as read up to the latest message. Mutually exclusive with last_read_message.

user: str | None

User ID (usr_...) whose read state to update. Required for S2S requests; ignored when an authenticated user is present in the token.

class ThreadPictureInputPicture(typing.TypedDict):
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"`.'
data: str

Base64-encoded binary content of the image file.

filename: str

Original filename of the image, e.g. "avatar.png". Used for storage and display.

mime_type: str

MIME type of the image, e.g. "image/jpeg" or "image/png".

class ThreadPictureInput(typing.TypedDict):
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.

class ThreadMemberListResponseDataItemAgent(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
email: str | None = None

Agent email address. null if not configured.

id: str = PydanticUndefined

Agent ID (agi_...).

name: str | None = None

Human-readable agent name. null if not set.

org: str | None = None

Organization that owns this agent (org_...). null if not org-scoped.

team: str | None = None

Team that owns this agent (tem_...). null if not team-scoped.

user: str | None = None

User that owns this agent (usr_...). null if not user-scoped.

class ThreadMemberListResponseDataItemUser(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
email: str | None = None

User's email address. null if not set.

full_name: str | None = None

Backward-compatible alias of name. null if not set.

id: str = PydanticUndefined

User ID (usr_...).

name: str | None = None

Full display name of the user. null if not set.

org: str | None = None

Organization this user belongs to (org_...). null if the user is not org-scoped.

class ThreadMemberListResponseDataItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.

Roster-safe agent identity. Populated for agent members; null for users.

joined_at: datetime.datetime | None = None

When this member joined the thread (ISO 8601).

member_type: str | None = None

Backward-compatible alias of type.

membership_type: str | None = None

Role of this member, commonly "owner" or "member".

role: str | None = None

Backward-compatible alias of membership_type.

type: str = PydanticUndefined

Kind of participant. One of "user" or "agent".

Roster-safe user identity. Populated for user members; null for agents.

class ThreadMemberListResponse(pydantic.main.BaseModel):
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

data: list[ThreadMemberListResponseDataItem] = PydanticUndefined

Array of thread member objects representing all current members of the thread.

class SettingListResponse(pydantic.main.BaseModel):
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

agent_enabled: bool | None = None

Whether the AI agent is active for this thread. Defaults to true when no settings have been explicitly set.

class ThreadAgentsResponse(pydantic.main.BaseModel):
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

data: list[dict[str, typing.Any]] = PydanticUndefined

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.

class ThreadArtifactsResponseDataItemAclAddItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
actions: list[str] = PydanticUndefined

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None = None

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".

principal_type: str = PydanticUndefined

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadArtifactsResponseDataItemAclGrantsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
actions: list[str] = PydanticUndefined

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None = None

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".

principal_type: str = PydanticUndefined

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadArtifactsResponseDataItemAclRemoveItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
principal: str | None = None

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".

principal_type: str = PydanticUndefined

The kind of principal to remove. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadArtifactsResponseDataItemAcl(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.

grants: list[ThreadArtifactsResponseDataItemAclGrantsItem] | None = None

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.

remove: list[ThreadArtifactsResponseDataItemAclRemoveItem] | None = None

Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.

class ThreadArtifactsResponseDataItemImageSource(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadArtifactsResponseDataItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.

agent: str | None = None

ID of the agent that produced this artifact (agt_...). null if not agent-produced.

content_type: str | None = None

MIME type of the current version's file, e.g. "text/csv" or "image/png". null if no file is attached.

created_at: datetime.datetime | None = None

When the artifact was first created (ISO 8601).

current_version: str | None = None

ID of the current (latest published) artifact version (artv_...). null if no version has been published.

description: str | None = None

Optional longer description of the artifact's contents or purpose. null if not set.

file: str | None = None

Storage file ID for the current version (fil_...). null if no file is attached.

file_name: str | None = None

Original filename of the current version's file, e.g. "output.csv". null if no file is attached.

file_url: str | None = None

Short-lived signed URL for downloading the current version's file. null if no file is attached.

group_key: str | None = None

Optional nonunique, case-sensitive grouping key, limited to 1024 UTF-8 bytes. Null when unset; belongs to the artifact, not a content version.

id: str = PydanticUndefined

Artifact ID (art_...).

image_source: ThreadArtifactsResponseDataItemImageSource | None = None

Image source metadata for rendering the current version's file inline. Present only when content_type starts with "image/". null otherwise.

name: str | None = None

Human-readable name for the artifact, e.g. "Q2 Report". null if not set.

org: str | None = None

ID of the organization this artifact belongs to (org_...).

sandbox: str | None = None

Identifier of the sandbox environment associated with this artifact. null if not sandbox-scoped.

system: bool | None = None

True when the artifact has no user, team, or agent owner. An organization may own a system artifact.

team: str | None = None

ID of the team that owns this artifact (tea_...). null if not team-scoped.

thread: str | None = None

ID of the thread in which this artifact was created (thr_...). null if not thread-scoped.

updated_at: datetime.datetime | None = None

When the artifact record was last modified (ISO 8601).

user: str | None = None

ID of the user who created this artifact (usr_...). null if not user-scoped.

version: int | None = None

Current version number of the artifact. Increments each time a new version is published.

class ThreadArtifactsResponse(pydantic.main.BaseModel):
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

data: list[ThreadArtifactsResponseDataItem] = PydanticUndefined

Array of artifact objects produced during the thread's conversation.

class ThreadMessagesResponseDataMessagesItemAclAddItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
actions: list[str] = PydanticUndefined

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None = None

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".

principal_type: str = PydanticUndefined

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadMessagesResponseDataMessagesItemAclGrantsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
actions: list[str] = PydanticUndefined

Array of action strings the principal is permitted to perform, e.g. ["read", "write"]. Must contain at least one entry.

principal: str | None = None

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".

principal_type: str = PydanticUndefined

The kind of principal receiving the grant. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadMessagesResponseDataMessagesItemAclRemoveItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
principal: str | None = None

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".

principal_type: str = PydanticUndefined

The kind of principal to remove. One of "user", "team", "org", "org_role", "agent", or "everyone".

class ThreadMessagesResponseDataMessagesItemAcl(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.

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.

Patch mode: principals whose grants should be removed from the existing list. Cannot be combined with grants.

class ThreadMessagesResponseDataMessagesItemActorsItemProfilePicture(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadMessagesResponseDataMessagesItemActorsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
alias: str | None = None

Short handle or alias for the actor, used as an alternate display identifier. null if not configured.

id: str | None = None

Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.

name: str | None = None

Display name of the actor shown in the UI. null if no name is set.

Profile picture for the actor. null if the actor has no profile picture.

class ThreadMessagesResponseDataMessagesItemAttachmentsItemImageSource(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItemImageSource(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
file: str | None = None

ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.

height: int | None = None

Height of the image in pixels. null if not known.

media: str | None = None

ID of the associated media record (med_...). null when the image is not linked to a media entity.

mime_type: str | None = None

MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.

refresh_url: str | None = None

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.

url: str | None = None

Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.

width: int | None = None

Width of the image in pixels. null if not known.

class ThreadMessagesResponseDataMessagesItemAttachmentsItemVariantsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
byte_size: int | None = None

Size of the stored bytes.

content_type: str | None = None

MIME type of this variant's file (e.g., "image/jpeg", "video/mp4"). null if the file is not loaded.

created_at: datetime.datetime | None = None

When this variant was created (ISO 8601).

duration_ms: int | None = None

Client-declared video duration in milliseconds; not server-probed.

file: str | None = None

ID of the underlying storage file that backs this variant (fil_...).

filename: str | None = None

Original filename of the uploaded file for this variant. null if the file is not loaded.

height: int | None = None

Height of this variant in pixels. null if not recorded.

id: str = PydanticUndefined

Media variant ID (mvr_...).

Resolved image delivery metadata for this variant, including dimensions and CDN URL. null for non-image content types.

sha256: str | None = None

Lowercase SHA-256 of the stored bytes.

updated_at: datetime.datetime | None = None

When this variant was last updated (ISO 8601).

url: str | None = None

Signed download URL for this variant, resolved at request time. null if the file is unavailable.

url_expires_at: datetime.datetime | None = None

Expiry of this variant's playable URL.

variant_key: str | None = None

Identifier for this variant's processing tier. Common values include "original" (the unmodified upload) and "thumbnail" (a resized preview).

width: int | None = None

Width of this variant in pixels. null if not recorded.

class ThreadMessagesResponseDataMessagesItemAttachmentsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
content_type: str | None = None

MIME type of the attached file, e.g. "image/png" or "application/pdf". Present on file, artifact, and media types. null otherwise.

description: str | None = None

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.

filename: str | None = None

Original filename of the attached file, e.g. "report.pdf". Present on file, artifact, and media types. null otherwise.

height: int | None = None

Height in pixels of the media item. Present on media type only. null otherwise.

id: str = PydanticUndefined

Unique identifier for this attachment within the message.

image_height: int | None = None

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.

image_url: str | None = None

URL of the preview image extracted from the scraped page. Present on scraped_link type only. null otherwise.

image_width: int | None = None

Width in pixels of the scraped preview image. Present on scraped_link type only. null otherwise.

key: str | None = None

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.

media_type: str | None = None

The media category, e.g. "video" or "audio". Present on media type only; omitted otherwise.

name: str | None = None

Display name of the media item. Present on media type only. null otherwise.

object: dict[str, typing.Any] | None = None

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.

title: str | None = None

Display title. The page title for scraped_link, the artifact name for artifact, and the task title for task types. null on other types.

type: str = PydanticUndefined

The attachment type. One of "file", "scraped_link", "artifact", "task", "media", "action", "chart", or "structured_data". Determines which additional fields are present.

url: str | None = None

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.

version: int | None = None

Version number of the attached artifact at the time of attachment. Present on artifact type only. null otherwise.

width: int | None = None

Width in pixels of the media item. Present on media type only. null otherwise.

class ThreadMessagesResponseDataMessagesItemContextItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
attributes: dict[str, typing.Any] | None = None

Scalar key-value fields describing the context, such as route, repository, or pull-request number.

content: str | None = None

Optional context body. The model receives it as escaped XML data, not a system instruction.

title: str | None = None

Optional human-readable label for this context block.

type: str = PydanticUndefined

Stable context kind. Must start with a lowercase letter and contain only lowercase letters, numbers, dots, dashes, or underscores.

class ThreadMessagesResponseDataMessagesItemReactionsItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
payload: dict[str, typing.Any] | None = None

Type-specific reaction data. For "emoji_reaction" reactions, contains an emoji key with the Unicode emoji string (e.g., " ").

type: str = PydanticUndefined

Reaction type identifier. Currently always "emoji_reaction" for emoji-based reactions.

user: str | None = None

Public ID of the user who added the reaction (usr_...).

class ThreadMessagesResponseDataMessagesItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.

agent: str | None = None

ID of the agent user that sent this message (agi_...). null for messages sent by human users.

agent_mode: Optional[Literal['cli', 'embedded']] = None

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.

branched_thread: str | None = None

ID of the thread that was branched from this message (thr_...). null if this message has not spawned a branch thread.

content: str | None = None

Text content of the message. null for messages that contain only attachments.

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.

created_at: str | None = None

When the message was posted (ISO 8601).

has_replies: bool | None = None

Whether this message has at least one reply. Only present when explicitly requested or computed by the server.

id: str = PydanticUndefined

Message ID (msg_...).

idempotency_key: str | None = None

Client-supplied idempotency key used to deduplicate message sends. null if the sender did not provide one.

is_deleted: bool | None = None

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.

legacy_agent: str | None = None

Identifier of the legacy chat agent that sent this message, if applicable. null for messages sent by users or modern agent users.

metadata: dict[str, typing.Any] | None = None

Arbitrary key-value metadata attached to the message. Always present; defaults to an empty object when no metadata has been set.

org: str | None = None

ID of the organization that owns this message (org_...).

Emoji and other reactions added to this message by users. Empty array if no reactions have been added or the association is not preloaded.

rendering_mode: str | None = None

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.

replies: list[dict[str, typing.Any]] | None = None

Inline array of reply messages, each serialized as a full message object. Only present when the server has preloaded replies for this message.

replies_after_cursor: str | None = None

Opaque pagination cursor to fetch replies posted after the current page. Only present when inline replies are included in the response.

replies_before_cursor: str | None = None

Opaque pagination cursor to fetch replies posted before the current page. Only present when inline replies are included in the response.

reply_count: int | None = None

Total number of direct replies to this message. Only present when explicitly requested or computed by the server.

reply_to: dict[str, typing.Any] | None = None

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.

root_message_id: str | None = None

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.

sandbox: str | None = None

ID of the developer sandbox this message belongs to (dsb_...). null for non-sandbox messages.

team: str | None = None

ID of the team this message is scoped to (tem_...). null if the message is not team-scoped.

thread: str | None = None

ID of the thread this message belongs to (thr_...).

type: str | None = None

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.

user: str | dict[str, typing.Any] | None = None

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.

visibility: Optional[Literal['default', 'private']] = None

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.

class ThreadMessagesResponseData(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
after_cursor: str | None = None

Opaque cursor to pass as after to retrieve the page of messages newer than this result set. null when there are no later messages.

anchor: str | None = None

Message ID used as the anchor for a windowed query. null for ordinary cursor pagination.

before_cursor: str | None = None

Opaque cursor to pass as before to retrieve the page of messages older than this result set. null when there are no earlier messages.

messages: list[ThreadMessagesResponseDataMessagesItem] = PydanticUndefined

Ordered array of message objects for this page of results.

class ThreadMessagesResponse(pydantic.main.BaseModel):
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

data: ThreadMessagesResponseData = PydanticUndefined

Pagination envelope containing the messages for this page along with cursors for adjacent pages.

class ThreadSearchResponseDataItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
agent: str | None = None

Agent sender ID (agi_...), or null when a human sent the message.

content: str = PydanticUndefined

A bounded snippet around the first matching occurrence (at most 240 characters).

created_at: datetime.datetime = PydanticUndefined

When the message was posted.

evidence: dict[str, typing.Any] = PydanticUndefined

Bounded, allowlisted structured-post evidence such as source, lifecycle type, references, repository context, and addressee. Empty for ordinary messages.

id: str = PydanticUndefined

Message ID (msg_...).

similarity_score: float | None = None

Cosine similarity to the query when the result participated in embedding search, or null in text mode and for text-only hybrid matches.

user: str | None = None

Human sender ID (usr_...), or null when an agent sent the message.

class ThreadSearchResponse(pydantic.main.BaseModel):
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

after_cursor: str | None = None

Text-mode cursor for the next page of newer matches, or null for ranked modes and empty pages.

before_cursor: str | None = None

Text-mode cursor for the next page of older matches, or null for ranked modes and empty pages.

data: list[ThreadSearchResponseDataItem] = PydanticUndefined

Matching messages ordered newest first in text mode and by relevance in embedding or hybrid mode.

has_more: bool = PydanticUndefined

true when at least one additional visible match exists.

class ThreadTrajectoriesResponseDataItem(pydantic.main.BaseModel):
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__ and Model.__root_validators__ from Pydantic V1.
  • __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models. The origin and args items map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and the parameter item 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-core SchemaSerializer used to dump instances of the model.
  • __pydantic_validator__: The pydantic-core SchemaValidator used 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.
agent_message: str | None = None

ID of the agent-authored reply message (msg_...). null if the trajectory has not yet produced a response message.

created_at: str | None = None

When this trajectory link was created (ISO 8601).

id: str = PydanticUndefined

Thread message trajectory ID (tmt_...).

org: str | None = None

ID of the organization this trajectory belongs to (org_...).

sandbox: str | None = None

ID of the sandbox environment in which this trajectory was produced (dsb_...). null in production contexts.

thread: str | None = None

ID of the thread containing the linked messages (thr_...).

trajectory: str | None = None

ID of the AI trajectory record that captures the full model interaction for this exchange (trj_...).

updated_at: str | None = None

When this trajectory link was last modified (ISO 8601).

user_message: str | None = None

ID of the user-authored message that triggered the agent response (msg_...). null if the agent turn was not preceded by a user message.

class ThreadTrajectoriesResponse(pydantic.main.BaseModel):
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

after_cursor: str | None = None

Opaque cursor to pass as after_cursor to retrieve the next page. null when no further pages exist.

before_cursor: str | None = None

Opaque cursor to pass as before_cursor to retrieve the previous page. null when this is the first page.

data: list[ThreadTrajectoriesResponseDataItem] = PydanticUndefined

Array of thread message trajectory objects for the current page. Empty when no trajectories match the query.

class AsyncComputerResource:
 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        )
AsyncComputerResource(http: archastro.platform.runtime.http_client.HttpClient)
997    def __init__(self, http: HttpClient):
998        self._http = http
async def list( self, thread: str) -> archastro.platform.types.common.AgentComputerListResponse:
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.

async def create( self, thread: str, input: ComputerCreateInput) -> archastro.platform.types.common.AgentComputer:
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.

class AsyncThreadMemberResource:
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        )
AsyncThreadMemberResource(http: archastro.platform.runtime.http_client.HttpClient)
1044    def __init__(self, http: HttpClient):
1045        self._http = http
async def remove(self, thread: str) -> None:
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.

async def list( self, thread: str) -> ThreadMemberListResponse:
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

async def create( self, thread: str, input: ThreadMemberCreateInput) -> archastro.platform.types.chat.ChatMember:
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 type is "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 type is "user".
Returns:

The user or agent membership that was added to the thread.

class AsyncSettingResource:
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        )
AsyncSettingResource(http: archastro.platform.runtime.http_client.HttpClient)
1118    def __init__(self, http: HttpClient):
1119        self._http = http
async def list( self, thread: str) -> SettingListResponse:
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

async def replace( self, thread: str, input: SettingReplaceInput) -> archastro.platform.types.threads.ThreadSettings:
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.

class AsyncTagResource:
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        )
AsyncTagResource(http: archastro.platform.runtime.http_client.HttpClient)
1167    def __init__(self, http: HttpClient):
1168        self._http = http
async def remove(self, thread: str) -> archastro.platform.types.threads.Thread:
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.

async def create( self, thread: str, input: TagCreateInput) -> archastro.platform.types.threads.Thread:
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.

async def replace( self, thread: str, input: TagReplaceInput) -> archastro.platform.types.threads.Thread:
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.

class AsyncThreadResource:
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        )
AsyncThreadResource(http: archastro.platform.runtime.http_client.HttpClient)
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)
computers
members
settings
tags
async def delete(self, thread: str) -> None:
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.

async def get(self, thread: str) -> archastro.platform.types.threads.Thread:
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.

async def replace( self, thread: str, input: ThreadReplaceInput) -> archastro.platform.types.threads.Thread:
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: private may become restricted or team, and restricted may become team. Visibility cannot be narrowed.
Returns:

The thread object after the update has been applied.

async def agents( self, thread: str) -> ThreadAgentsResponse:
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

async def artifacts( self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None) -> ThreadArtifactsResponse:
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

async def mark_read( self, thread: str, input: ThreadMarkReadInput) -> None:
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 with use_latest_message.
  • input.use_latest_message: When true, marks the thread as read up to the latest message. Mutually exclusive with last_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.

async def messages( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, metadata: dict[str, typing.Any] | None = None, limit: int | None = None, include_replies: bool | None = None, anchor: str | None = None, direction: Optional[Literal['before', 'after', 'around']] = None, before_limit: int | None = None, after_limit: int | None = None, include_anchor: bool | None = None, anchor_agent_mode: Optional[Literal['cli', 'embedded']] = None, anchor_agent: str | None = None, include_reply_counts: bool | None = None) -> ThreadMessagesResponse:
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_cursor field. When provided, returns messages immediately before that position. May be combined with after_cursor to bound a range.
  • 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.
  • 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.
  • 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, or last_matching to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with before_cursor or after_cursor.
  • 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.
  • 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 true for direction=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 with anchor_agent_mode to 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 to false. Adds latency; omit when reply counts are not needed.
Returns:

Successful response

async def picture( self, thread: str, input: ThreadPictureInput) -> archastro.platform.types.threads.Thread:
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.

async def read_status( self, thread: str, *, user: str | None = None) -> archastro.platform.types.threads.ThreadReadStatus:
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.

async def search( self, thread: str, q: str, *, app: str | None = None, limit: int | None = None, mode: Optional[Literal['text', 'embedding', 'hybrid']] = None, before_cursor: str | None = None, after_cursor: str | None = None) -> ThreadSearchResponse:
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: text for substring matching, embedding for cosine similarity, or hybrid for 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

async def trajectories( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, limit: int | None = None, message: str | None = None) -> ThreadTrajectoriesResponse:
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_cursor field. Returns the page of results preceding that cursor position.
  • after_cursor: Opaque cursor from a previous response's after_cursor field. 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

class ComputerResource:
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        )
ComputerResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1644    def __init__(self, http: SyncHttpClient):
1645        self._http = http
def list( self, thread: str) -> archastro.platform.types.common.AgentComputerListResponse:
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.

def create( self, thread: str, input: ComputerCreateInput) -> archastro.platform.types.common.AgentComputer:
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.

class ThreadMemberResource:
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        )
ThreadMemberResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1691    def __init__(self, http: SyncHttpClient):
1692        self._http = http
def remove(self, thread: str) -> None:
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.

def list( self, thread: str) -> ThreadMemberListResponse:
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

def create( self, thread: str, input: ThreadMemberCreateInput) -> archastro.platform.types.chat.ChatMember:
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 type is "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 type is "user".
Returns:

The user or agent membership that was added to the thread.

class SettingResource:
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        )
SettingResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
1765    def __init__(self, http: SyncHttpClient):
1766        self._http = http
def list( self, thread: str) -> SettingListResponse:
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

def replace( self, thread: str, input: SettingReplaceInput) -> archastro.platform.types.threads.ThreadSettings:
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.

class TagResource:
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        )
1814    def __init__(self, http: SyncHttpClient):
1815        self._http = http
def remove(self, thread: str) -> archastro.platform.types.threads.Thread:
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.

def create( self, thread: str, input: TagCreateInput) -> archastro.platform.types.threads.Thread:
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.

def replace( self, thread: str, input: TagReplaceInput) -> archastro.platform.types.threads.Thread:
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.

class ThreadResource:
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        )
ThreadResource(http: archastro.platform.runtime.http_client.SyncHttpClient)
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)
computers
members
settings
tags
def delete(self, thread: str) -> None:
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.

def get(self, thread: str) -> archastro.platform.types.threads.Thread:
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.

def replace( self, thread: str, input: ThreadReplaceInput) -> archastro.platform.types.threads.Thread:
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: private may become restricted or team, and restricted may become team. Visibility cannot be narrowed.
Returns:

The thread object after the update has been applied.

def agents( self, thread: str) -> ThreadAgentsResponse:
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

def artifacts( self, thread: str, *, group_key: str | None = None, group_key_prefix: str | None = None) -> ThreadArtifactsResponse:
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

def mark_read( self, thread: str, input: ThreadMarkReadInput) -> None:
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 with use_latest_message.
  • input.use_latest_message: When true, marks the thread as read up to the latest message. Mutually exclusive with last_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.

def messages( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, metadata: dict[str, typing.Any] | None = None, limit: int | None = None, include_replies: bool | None = None, anchor: str | None = None, direction: Optional[Literal['before', 'after', 'around']] = None, before_limit: int | None = None, after_limit: int | None = None, include_anchor: bool | None = None, anchor_agent_mode: Optional[Literal['cli', 'embedded']] = None, anchor_agent: str | None = None, include_reply_counts: bool | None = None) -> ThreadMessagesResponse:
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_cursor field. When provided, returns messages immediately before that position. May be combined with after_cursor to bound a range.
  • 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.
  • 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.
  • 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, or last_matching to resolve the anchor from the latest message matching the anchor filters. Cannot be combined with before_cursor or after_cursor.
  • 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.
  • 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 true for direction=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 with anchor_agent_mode to 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 to false. Adds latency; omit when reply counts are not needed.
Returns:

Successful response

def picture( self, thread: str, input: ThreadPictureInput) -> archastro.platform.types.threads.Thread:
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.

def read_status( self, thread: str, *, user: str | None = None) -> archastro.platform.types.threads.ThreadReadStatus:
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.

def search( self, thread: str, q: str, *, app: str | None = None, limit: int | None = None, mode: Optional[Literal['text', 'embedding', 'hybrid']] = None, before_cursor: str | None = None, after_cursor: str | None = None) -> ThreadSearchResponse:
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: text for substring matching, embedding for cosine similarity, or hybrid for 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

def trajectories( self, thread: str, *, before_cursor: str | None = None, after_cursor: str | None = None, limit: int | None = None, message: str | None = None) -> ThreadTrajectoriesResponse:
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_cursor field. Returns the page of results preceding that cursor position.
  • after_cursor: Opaque cursor from a previous response's after_cursor field. 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