archastro.platform.v1.resources.tasks
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: 929c29305abf 4 5from __future__ import annotations 6 7from datetime import datetime 8from typing import Any, Required, TypedDict 9 10from pydantic import BaseModel, Field 11 12from ...runtime.http_client import HttpClient, SyncHttpClient 13from ...types.tasks import ( 14 Task, 15 TaskComment, 16 TaskExternalLink, 17 TaskOwnershipJob, 18 TaskSessionLease, 19 TaskSessionLeaseSummary, 20) 21 22 23class BlockerCreateInput(TypedDict, total=False): 24 "Mark a task as blocked by another task" 25 26 agent: str | None 27 "Explicit owning agent (`agi_...`) for privileged calls." 28 blocker: Required[str] 29 "ID of the task that blocks this task (`tsk_...`)." 30 org: str | None 31 "Explicit organization (`org_...`) for privileged calls; pass null when unscoped." 32 team: str | None 33 "Explicit owning team (`tem_...`) for privileged calls." 34 user: str | None 35 "Explicit owning user (`usr_...`) for privileged calls." 36 37 38class CommentCreateInputComment(TypedDict): 39 body: str 40 "The plain-text content of the comment. Must be a non-empty string." 41 42 43class CommentCreateInput(TypedDict, total=False): 44 "Create a comment on a task" 45 46 comment: Required[CommentCreateInputComment] 47 "Parameters for the comment to create, including its body." 48 expected_version: int | None 49 "Reject the comment if the task changed since this version." 50 51 52class CommentReplaceInput(TypedDict): 53 "Update a task comment" 54 55 body: str 56 "Replacement body for the comment. Must be non-empty." 57 58 59class LeaseCreateInput(TypedDict, total=False): 60 "Claim a task for a coding session" 61 62 force: bool | None 63 "Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim." 64 harness: Required[str] 65 "Bounded harness identifier." 66 lease_duration_seconds: int | None 67 "Requested lease lifetime in seconds; the task aggregate enforces its bounds." 68 lease_id: Required[str] 69 "Caller-generated lease UUID." 70 require_ready: bool | None 71 "Conservatively reject the claim when the current task projection has unfinished blockers." 72 session_id: Required[str] 73 "Caller-generated coding-session UUID." 74 session_name: Required[str] 75 "Human-readable coding-session label." 76 77 78class LeaseRenewInput(TypedDict, total=False): 79 "Renew a task session lease" 80 81 lease_duration_seconds: int | None 82 "Requested renewed lifetime in seconds; the task aggregate enforces its bounds." 83 lease_id: Required[str] 84 "Current caller-held lease UUID." 85 session_id: Required[str] 86 "Current coding-session UUID." 87 88 89class LinkCreateInput(TypedDict): 90 "Add an external link to a task" 91 92 external_scope: str 93 "External container ID." 94 object_id: str 95 "External object ID." 96 object_type: str 97 "External object type." 98 99 100class TaskReplaceInput(TypedDict, total=False): 101 "Update a task" 102 103 agent: str | None 104 "Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal." 105 description: str | None 106 "Updated long-form description." 107 due_date: datetime | None 108 "Updated due date in ISO 8601 format, or null to clear it." 109 epic: str | None 110 "Replacement grouping label. Pass null to clear it." 111 expected_version: int | None 112 "Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first." 113 lease_id: str | None 114 "Current caller-held lease UUID. Must be paired with `lease_session_id`." 115 lease_session_id: str | None 116 "Current coding-session UUID. Must be paired with `lease_id`." 117 links: dict[str, Any] | None 118 "Replacement related-links object." 119 metadata: dict[str, Any] | None 120 "Replacement task metadata object." 121 name: str | None 122 "Updated display name for the task." 123 org: str | None 124 "Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization." 125 owner_agent: str | None 126 "Assign to an agent by public ID (`agi_...`)." 127 owner_user: str | None 128 "Assign to a user by public ID (`usr_...`)." 129 parent: str | None 130 "Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one." 131 priority: int | None 132 "Updated priority from 0 (highest) to 4 (lowest)." 133 project_id: str | None 134 "Project ID (`prj_...`). Omit to preserve; pass null to clear." 135 require_status_lease: bool | None 136 "Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available." 137 source_id: str | None 138 "Replacement source object identity. Must be supplied with the other source fields." 139 source_scope: str | None 140 "Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source." 141 source_type: str | None 142 "Replacement source object kind. Must be supplied with the other source fields." 143 status: str | None 144 "Updated status: `open`, `in_progress`, `in_review`, or `done`." 145 tags: list[str] | None 146 "Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags." 147 target_binary: str | None 148 "Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target." 149 target_version: str | None 150 "Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`." 151 team: str | None 152 "Explicit owning team (`tem_...`) for a developer or server-to-server call." 153 user: str | None 154 "Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member." 155 156 157class TaskOwnershipConversionsInput(TypedDict, total=False): 158 "Convert ownership of a connected task graph" 159 160 dest_agent: str | None 161 "Destination agent (`agi_...`)." 162 dest_org: str | None 163 "Destination organization (`org_...`)." 164 dest_team: str | None 165 "Destination team (`tem_...`)." 166 dest_user: str | None 167 "Destination user (`usr_...`). Supply exactly one destination." 168 169 170class TaskTransferOwnershipInput(TypedDict, total=False): 171 "Transfer one task to a different owner" 172 173 dest_agent: str | None 174 "Destination agent (`agi_...`)." 175 dest_org: str | None 176 "Destination organization (`org_...`)." 177 dest_team: str | None 178 "Destination team (`tem_...`)." 179 dest_user: str | None 180 "Destination user (`usr_...`). Supply exactly one destination." 181 expected_version: Required[int] 182 "The task version reviewed by the caller." 183 184 185class BlockerListResponseDataItemCreatedByActorProfilePicture(BaseModel): 186 file: str | None = Field( 187 default=None, 188 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 189 ) 190 height: int | None = Field( 191 default=None, description="Height of the image in pixels. `null` if not known." 192 ) 193 media: str | None = Field( 194 default=None, 195 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 196 ) 197 mime_type: str | None = Field( 198 default=None, 199 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 200 ) 201 refresh_url: str | None = Field( 202 default=None, 203 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.", 204 ) 205 url: str | None = Field( 206 default=None, 207 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.", 208 ) 209 width: int | None = Field( 210 default=None, description="Width of the image in pixels. `null` if not known." 211 ) 212 213 214class BlockerListResponseDataItemCreatedByActor(BaseModel): 215 alias: str | None = Field( 216 default=None, 217 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 218 ) 219 id: str | None = Field( 220 default=None, 221 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 222 ) 223 name: str | None = Field( 224 default=None, 225 description="Display name of the actor shown in the UI. `null` if no name is set.", 226 ) 227 profile_picture: BlockerListResponseDataItemCreatedByActorProfilePicture | None = Field( 228 default=None, 229 description="Profile picture for the actor. `null` if the actor has no profile picture.", 230 ) 231 232 233class BlockerListResponseDataItemCurrentLease(BaseModel): 234 expires_at: datetime = Field( 235 ..., description="Server-calculated lease expiry in ISO 8601 format." 236 ) 237 harness: str = Field(..., description="Bounded harness identifier for the coding session.") 238 session_name: str = Field( 239 ..., description="Display name supplied by the coding session that holds the lease." 240 ) 241 242 243class BlockerListResponseDataItemOwnerActorProfilePicture(BaseModel): 244 file: str | None = Field( 245 default=None, 246 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 247 ) 248 height: int | None = Field( 249 default=None, description="Height of the image in pixels. `null` if not known." 250 ) 251 media: str | None = Field( 252 default=None, 253 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 254 ) 255 mime_type: str | None = Field( 256 default=None, 257 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 258 ) 259 refresh_url: str | None = Field( 260 default=None, 261 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.", 262 ) 263 url: str | None = Field( 264 default=None, 265 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.", 266 ) 267 width: int | None = Field( 268 default=None, description="Width of the image in pixels. `null` if not known." 269 ) 270 271 272class BlockerListResponseDataItemOwnerActor(BaseModel): 273 alias: str | None = Field( 274 default=None, 275 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 276 ) 277 id: str | None = Field( 278 default=None, 279 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 280 ) 281 name: str | None = Field( 282 default=None, 283 description="Display name of the actor shown in the UI. `null` if no name is set.", 284 ) 285 profile_picture: BlockerListResponseDataItemOwnerActorProfilePicture | None = Field( 286 default=None, 287 description="Profile picture for the actor. `null` if the actor has no profile picture.", 288 ) 289 290 291class BlockerListResponseDataItem(BaseModel): 292 agent: str | None = Field( 293 default=None, 294 description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", 295 ) 296 aggregate_version: int | None = Field( 297 default=None, 298 description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", 299 ) 300 blocked_by_count: int | None = Field( 301 default=None, 302 description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", 303 ) 304 closed_at: datetime | None = Field( 305 default=None, 306 description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", 307 ) 308 comments_count: int | None = Field( 309 default=None, description="Total number of comments posted on this task." 310 ) 311 created_at: datetime | None = Field( 312 default=None, description="When the task was created (ISO 8601)." 313 ) 314 created_by_actor: BlockerListResponseDataItemCreatedByActor | None = Field( 315 default=None, 316 description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", 317 ) 318 created_by_agent: str | None = Field( 319 default=None, 320 description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", 321 ) 322 created_by_user: str | None = Field( 323 default=None, 324 description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", 325 ) 326 current_lease: BlockerListResponseDataItemCurrentLease | None = Field( 327 default=None, 328 description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", 329 ) 330 description: str | None = Field( 331 default=None, 332 description="Long-form description or notes for the task. `null` if no description has been provided.", 333 ) 334 due_date: datetime | None = Field( 335 default=None, 336 description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", 337 ) 338 epic: str | None = Field( 339 default=None, 340 description="Free-form grouping label. `null` when the task is not in an epic.", 341 ) 342 id: str = Field(..., description="Task ID (`tsk_...`).") 343 is_blocked: bool | None = Field( 344 default=None, 345 description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", 346 ) 347 is_stalled: bool | None = Field( 348 default=None, 349 description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", 350 ) 351 links: dict[str, Any] | None = Field( 352 default=None, 353 description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", 354 ) 355 metadata: dict[str, Any] | None = Field( 356 default=None, 357 description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", 358 ) 359 name: str = Field(..., description="Human-readable title of the task.") 360 org: str | None = Field( 361 default=None, 362 description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", 363 ) 364 owner_actor: BlockerListResponseDataItemOwnerActor | None = Field( 365 default=None, 366 description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", 367 ) 368 owner_agent: str | None = Field( 369 default=None, 370 description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", 371 ) 372 owner_user: str | None = Field( 373 default=None, 374 description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", 375 ) 376 parent: str | None = Field( 377 default=None, 378 description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", 379 ) 380 priority: int | None = Field( 381 default=None, 382 description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", 383 ) 384 project_id: str | None = Field( 385 default=None, 386 description="Optional project ID (`prj_...`). Membership does not change task visibility.", 387 ) 388 sandbox: str | None = Field( 389 default=None, 390 description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", 391 ) 392 source_id: str | None = Field( 393 default=None, 394 description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", 395 ) 396 source_scope: str | None = Field( 397 default=None, 398 description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", 399 ) 400 source_type: str | None = Field( 401 default=None, 402 description="Kind of source object (for example `repository`). `null` when the task has no source.", 403 ) 404 stalled_since: datetime | None = Field( 405 default=None, 406 description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", 407 ) 408 status: str = Field( 409 ..., 410 description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', 411 ) 412 subtasks_count: int | None = Field( 413 default=None, 414 description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", 415 ) 416 tags: list[str] | None = Field( 417 default=None, 418 description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", 419 ) 420 target_binary: str | None = Field( 421 default=None, 422 description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", 423 ) 424 target_version: str | None = Field( 425 default=None, 426 description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", 427 ) 428 team: str | None = Field( 429 default=None, 430 description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", 431 ) 432 thread: str | None = Field( 433 default=None, 434 description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", 435 ) 436 updated_at: datetime | None = Field( 437 default=None, description="When the task was last modified (ISO 8601)." 438 ) 439 user: str | None = Field( 440 default=None, 441 description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", 442 ) 443 444 445class BlockerListResponse(BaseModel): 446 """ 447 Successful response 448 """ 449 450 after_cursor: str | None = None 451 before_cursor: str | None = None 452 data: list[BlockerListResponseDataItem] 453 has_more: bool 454 455 456class CommentListResponseDataItemAuthorActorProfilePicture(BaseModel): 457 file: str | None = Field( 458 default=None, 459 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 460 ) 461 height: int | None = Field( 462 default=None, description="Height of the image in pixels. `null` if not known." 463 ) 464 media: str | None = Field( 465 default=None, 466 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 467 ) 468 mime_type: str | None = Field( 469 default=None, 470 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 471 ) 472 refresh_url: str | None = Field( 473 default=None, 474 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.", 475 ) 476 url: str | None = Field( 477 default=None, 478 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.", 479 ) 480 width: int | None = Field( 481 default=None, description="Width of the image in pixels. `null` if not known." 482 ) 483 484 485class CommentListResponseDataItemAuthorActor(BaseModel): 486 alias: str | None = Field( 487 default=None, 488 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 489 ) 490 id: str | None = Field( 491 default=None, 492 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 493 ) 494 name: str | None = Field( 495 default=None, 496 description="Display name of the actor shown in the UI. `null` if no name is set.", 497 ) 498 profile_picture: CommentListResponseDataItemAuthorActorProfilePicture | None = Field( 499 default=None, 500 description="Profile picture for the actor. `null` if the actor has no profile picture.", 501 ) 502 503 504class CommentListResponseDataItem(BaseModel): 505 author_actor: CommentListResponseDataItemAuthorActor | None = Field( 506 default=None, 507 description="Resolved author details including `id`, `name`, `alias`, and `profile_picture`. `null` if no author is set or the author cannot be resolved (e.g. authoring agent was deleted).", 508 ) 509 author_agent: str | None = Field( 510 default=None, 511 description="ID of the agent that posted this comment (`agi_...`). `null` if the author is a human user, or if the authoring agent was later deleted.", 512 ) 513 author_user: str | None = Field( 514 default=None, 515 description="ID of the user who posted this comment (`usr_...`). `null` if the author is an agent, or if author provenance was cleared after the authoring agent was deleted.", 516 ) 517 body: str = Field(..., description="Plain-text body of the comment.") 518 created_at: datetime | None = Field( 519 default=None, description="When this comment was posted (ISO 8601)." 520 ) 521 id: str = Field(..., description="Comment ID (`tcmt_...`).") 522 org: str | None = Field( 523 default=None, description="ID of the organization that owns this comment (`org_...`)." 524 ) 525 sandbox: str | None = Field( 526 default=None, 527 description="Sandbox ID this comment is scoped to. `null` for comments outside a sandbox environment.", 528 ) 529 task: str | None = Field( 530 default=None, description="ID of the task this comment belongs to (`tsk_...`)." 531 ) 532 team: str | None = Field( 533 default=None, 534 description="ID of the team the task belongs to (`tem_...`). `null` if not scoped to a team.", 535 ) 536 updated_at: datetime | None = Field( 537 default=None, description="When this comment was last edited (ISO 8601)." 538 ) 539 540 541class CommentListResponse(BaseModel): 542 """ 543 Successful response 544 """ 545 546 after_cursor: str | None = None 547 before_cursor: str | None = None 548 data: list[CommentListResponseDataItem] 549 has_more: bool 550 551 552class LinkListResponseDataItem(BaseModel): 553 external_scope: str = Field(..., description="External container identity.") 554 object_id: str = Field(..., description="Object identity within that container.") 555 object_type: str = Field(..., description="External object kind.") 556 557 558class LinkListResponse(BaseModel): 559 """ 560 Successful response 561 """ 562 563 after_cursor: str | None = None 564 before_cursor: str | None = None 565 data: list[LinkListResponseDataItem] 566 has_more: bool 567 568 569class TaskActivityResponseDataItem(BaseModel): 570 event_type: str | None = Field( 571 default=None, 572 description='Machine-readable type of the event, e.g. `"task.status_changed"` or `"task.comment_added"`.', 573 ) 574 sentence: str | None = Field( 575 default=None, 576 description="Human-readable sentence describing the activity, suitable for display in an activity feed.", 577 ) 578 timestamp: datetime | None = Field( 579 default=None, description="When this activity event occurred (ISO 8601)." 580 ) 581 582 583class TaskActivityResponse(BaseModel): 584 """ 585 Successful response 586 """ 587 588 after_cursor: str | None = None 589 before_cursor: str | None = None 590 data: list[TaskActivityResponseDataItem] 591 has_more: bool 592 593 594class TaskBlockingResponseDataItemCreatedByActorProfilePicture(BaseModel): 595 file: str | None = Field( 596 default=None, 597 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 598 ) 599 height: int | None = Field( 600 default=None, description="Height of the image in pixels. `null` if not known." 601 ) 602 media: str | None = Field( 603 default=None, 604 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 605 ) 606 mime_type: str | None = Field( 607 default=None, 608 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 609 ) 610 refresh_url: str | None = Field( 611 default=None, 612 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.", 613 ) 614 url: str | None = Field( 615 default=None, 616 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.", 617 ) 618 width: int | None = Field( 619 default=None, description="Width of the image in pixels. `null` if not known." 620 ) 621 622 623class TaskBlockingResponseDataItemCreatedByActor(BaseModel): 624 alias: str | None = Field( 625 default=None, 626 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 627 ) 628 id: str | None = Field( 629 default=None, 630 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 631 ) 632 name: str | None = Field( 633 default=None, 634 description="Display name of the actor shown in the UI. `null` if no name is set.", 635 ) 636 profile_picture: TaskBlockingResponseDataItemCreatedByActorProfilePicture | None = Field( 637 default=None, 638 description="Profile picture for the actor. `null` if the actor has no profile picture.", 639 ) 640 641 642class TaskBlockingResponseDataItemCurrentLease(BaseModel): 643 expires_at: datetime = Field( 644 ..., description="Server-calculated lease expiry in ISO 8601 format." 645 ) 646 harness: str = Field(..., description="Bounded harness identifier for the coding session.") 647 session_name: str = Field( 648 ..., description="Display name supplied by the coding session that holds the lease." 649 ) 650 651 652class TaskBlockingResponseDataItemOwnerActorProfilePicture(BaseModel): 653 file: str | None = Field( 654 default=None, 655 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 656 ) 657 height: int | None = Field( 658 default=None, description="Height of the image in pixels. `null` if not known." 659 ) 660 media: str | None = Field( 661 default=None, 662 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 663 ) 664 mime_type: str | None = Field( 665 default=None, 666 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 667 ) 668 refresh_url: str | None = Field( 669 default=None, 670 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.", 671 ) 672 url: str | None = Field( 673 default=None, 674 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.", 675 ) 676 width: int | None = Field( 677 default=None, description="Width of the image in pixels. `null` if not known." 678 ) 679 680 681class TaskBlockingResponseDataItemOwnerActor(BaseModel): 682 alias: str | None = Field( 683 default=None, 684 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 685 ) 686 id: str | None = Field( 687 default=None, 688 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 689 ) 690 name: str | None = Field( 691 default=None, 692 description="Display name of the actor shown in the UI. `null` if no name is set.", 693 ) 694 profile_picture: TaskBlockingResponseDataItemOwnerActorProfilePicture | None = Field( 695 default=None, 696 description="Profile picture for the actor. `null` if the actor has no profile picture.", 697 ) 698 699 700class TaskBlockingResponseDataItem(BaseModel): 701 agent: str | None = Field( 702 default=None, 703 description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", 704 ) 705 aggregate_version: int | None = Field( 706 default=None, 707 description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", 708 ) 709 blocked_by_count: int | None = Field( 710 default=None, 711 description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", 712 ) 713 closed_at: datetime | None = Field( 714 default=None, 715 description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", 716 ) 717 comments_count: int | None = Field( 718 default=None, description="Total number of comments posted on this task." 719 ) 720 created_at: datetime | None = Field( 721 default=None, description="When the task was created (ISO 8601)." 722 ) 723 created_by_actor: TaskBlockingResponseDataItemCreatedByActor | None = Field( 724 default=None, 725 description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", 726 ) 727 created_by_agent: str | None = Field( 728 default=None, 729 description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", 730 ) 731 created_by_user: str | None = Field( 732 default=None, 733 description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", 734 ) 735 current_lease: TaskBlockingResponseDataItemCurrentLease | None = Field( 736 default=None, 737 description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", 738 ) 739 description: str | None = Field( 740 default=None, 741 description="Long-form description or notes for the task. `null` if no description has been provided.", 742 ) 743 due_date: datetime | None = Field( 744 default=None, 745 description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", 746 ) 747 epic: str | None = Field( 748 default=None, 749 description="Free-form grouping label. `null` when the task is not in an epic.", 750 ) 751 id: str = Field(..., description="Task ID (`tsk_...`).") 752 is_blocked: bool | None = Field( 753 default=None, 754 description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", 755 ) 756 is_stalled: bool | None = Field( 757 default=None, 758 description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", 759 ) 760 links: dict[str, Any] | None = Field( 761 default=None, 762 description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", 763 ) 764 metadata: dict[str, Any] | None = Field( 765 default=None, 766 description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", 767 ) 768 name: str = Field(..., description="Human-readable title of the task.") 769 org: str | None = Field( 770 default=None, 771 description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", 772 ) 773 owner_actor: TaskBlockingResponseDataItemOwnerActor | None = Field( 774 default=None, 775 description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", 776 ) 777 owner_agent: str | None = Field( 778 default=None, 779 description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", 780 ) 781 owner_user: str | None = Field( 782 default=None, 783 description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", 784 ) 785 parent: str | None = Field( 786 default=None, 787 description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", 788 ) 789 priority: int | None = Field( 790 default=None, 791 description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", 792 ) 793 project_id: str | None = Field( 794 default=None, 795 description="Optional project ID (`prj_...`). Membership does not change task visibility.", 796 ) 797 sandbox: str | None = Field( 798 default=None, 799 description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", 800 ) 801 source_id: str | None = Field( 802 default=None, 803 description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", 804 ) 805 source_scope: str | None = Field( 806 default=None, 807 description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", 808 ) 809 source_type: str | None = Field( 810 default=None, 811 description="Kind of source object (for example `repository`). `null` when the task has no source.", 812 ) 813 stalled_since: datetime | None = Field( 814 default=None, 815 description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", 816 ) 817 status: str = Field( 818 ..., 819 description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', 820 ) 821 subtasks_count: int | None = Field( 822 default=None, 823 description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", 824 ) 825 tags: list[str] | None = Field( 826 default=None, 827 description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", 828 ) 829 target_binary: str | None = Field( 830 default=None, 831 description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", 832 ) 833 target_version: str | None = Field( 834 default=None, 835 description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", 836 ) 837 team: str | None = Field( 838 default=None, 839 description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", 840 ) 841 thread: str | None = Field( 842 default=None, 843 description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", 844 ) 845 updated_at: datetime | None = Field( 846 default=None, description="When the task was last modified (ISO 8601)." 847 ) 848 user: str | None = Field( 849 default=None, 850 description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", 851 ) 852 853 854class TaskBlockingResponse(BaseModel): 855 """ 856 Successful response 857 """ 858 859 after_cursor: str | None = None 860 before_cursor: str | None = None 861 data: list[TaskBlockingResponseDataItem] 862 has_more: bool 863 864 865class TaskSubtasksResponseDataItemCreatedByActorProfilePicture(BaseModel): 866 file: str | None = Field( 867 default=None, 868 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 869 ) 870 height: int | None = Field( 871 default=None, description="Height of the image in pixels. `null` if not known." 872 ) 873 media: str | None = Field( 874 default=None, 875 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 876 ) 877 mime_type: str | None = Field( 878 default=None, 879 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 880 ) 881 refresh_url: str | None = Field( 882 default=None, 883 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.", 884 ) 885 url: str | None = Field( 886 default=None, 887 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.", 888 ) 889 width: int | None = Field( 890 default=None, description="Width of the image in pixels. `null` if not known." 891 ) 892 893 894class TaskSubtasksResponseDataItemCreatedByActor(BaseModel): 895 alias: str | None = Field( 896 default=None, 897 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 898 ) 899 id: str | None = Field( 900 default=None, 901 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 902 ) 903 name: str | None = Field( 904 default=None, 905 description="Display name of the actor shown in the UI. `null` if no name is set.", 906 ) 907 profile_picture: TaskSubtasksResponseDataItemCreatedByActorProfilePicture | None = Field( 908 default=None, 909 description="Profile picture for the actor. `null` if the actor has no profile picture.", 910 ) 911 912 913class TaskSubtasksResponseDataItemCurrentLease(BaseModel): 914 expires_at: datetime = Field( 915 ..., description="Server-calculated lease expiry in ISO 8601 format." 916 ) 917 harness: str = Field(..., description="Bounded harness identifier for the coding session.") 918 session_name: str = Field( 919 ..., description="Display name supplied by the coding session that holds the lease." 920 ) 921 922 923class TaskSubtasksResponseDataItemOwnerActorProfilePicture(BaseModel): 924 file: str | None = Field( 925 default=None, 926 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 927 ) 928 height: int | None = Field( 929 default=None, description="Height of the image in pixels. `null` if not known." 930 ) 931 media: str | None = Field( 932 default=None, 933 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 934 ) 935 mime_type: str | None = Field( 936 default=None, 937 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 938 ) 939 refresh_url: str | None = Field( 940 default=None, 941 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.", 942 ) 943 url: str | None = Field( 944 default=None, 945 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.", 946 ) 947 width: int | None = Field( 948 default=None, description="Width of the image in pixels. `null` if not known." 949 ) 950 951 952class TaskSubtasksResponseDataItemOwnerActor(BaseModel): 953 alias: str | None = Field( 954 default=None, 955 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 956 ) 957 id: str | None = Field( 958 default=None, 959 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 960 ) 961 name: str | None = Field( 962 default=None, 963 description="Display name of the actor shown in the UI. `null` if no name is set.", 964 ) 965 profile_picture: TaskSubtasksResponseDataItemOwnerActorProfilePicture | None = Field( 966 default=None, 967 description="Profile picture for the actor. `null` if the actor has no profile picture.", 968 ) 969 970 971class TaskSubtasksResponseDataItem(BaseModel): 972 agent: str | None = Field( 973 default=None, 974 description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", 975 ) 976 aggregate_version: int | None = Field( 977 default=None, 978 description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", 979 ) 980 blocked_by_count: int | None = Field( 981 default=None, 982 description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", 983 ) 984 closed_at: datetime | None = Field( 985 default=None, 986 description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", 987 ) 988 comments_count: int | None = Field( 989 default=None, description="Total number of comments posted on this task." 990 ) 991 created_at: datetime | None = Field( 992 default=None, description="When the task was created (ISO 8601)." 993 ) 994 created_by_actor: TaskSubtasksResponseDataItemCreatedByActor | None = Field( 995 default=None, 996 description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", 997 ) 998 created_by_agent: str | None = Field( 999 default=None, 1000 description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", 1001 ) 1002 created_by_user: str | None = Field( 1003 default=None, 1004 description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", 1005 ) 1006 current_lease: TaskSubtasksResponseDataItemCurrentLease | None = Field( 1007 default=None, 1008 description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", 1009 ) 1010 description: str | None = Field( 1011 default=None, 1012 description="Long-form description or notes for the task. `null` if no description has been provided.", 1013 ) 1014 due_date: datetime | None = Field( 1015 default=None, 1016 description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", 1017 ) 1018 epic: str | None = Field( 1019 default=None, 1020 description="Free-form grouping label. `null` when the task is not in an epic.", 1021 ) 1022 id: str = Field(..., description="Task ID (`tsk_...`).") 1023 is_blocked: bool | None = Field( 1024 default=None, 1025 description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", 1026 ) 1027 is_stalled: bool | None = Field( 1028 default=None, 1029 description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", 1030 ) 1031 links: dict[str, Any] | None = Field( 1032 default=None, 1033 description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", 1034 ) 1035 metadata: dict[str, Any] | None = Field( 1036 default=None, 1037 description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", 1038 ) 1039 name: str = Field(..., description="Human-readable title of the task.") 1040 org: str | None = Field( 1041 default=None, 1042 description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", 1043 ) 1044 owner_actor: TaskSubtasksResponseDataItemOwnerActor | None = Field( 1045 default=None, 1046 description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", 1047 ) 1048 owner_agent: str | None = Field( 1049 default=None, 1050 description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", 1051 ) 1052 owner_user: str | None = Field( 1053 default=None, 1054 description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", 1055 ) 1056 parent: str | None = Field( 1057 default=None, 1058 description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", 1059 ) 1060 priority: int | None = Field( 1061 default=None, 1062 description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", 1063 ) 1064 project_id: str | None = Field( 1065 default=None, 1066 description="Optional project ID (`prj_...`). Membership does not change task visibility.", 1067 ) 1068 sandbox: str | None = Field( 1069 default=None, 1070 description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", 1071 ) 1072 source_id: str | None = Field( 1073 default=None, 1074 description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", 1075 ) 1076 source_scope: str | None = Field( 1077 default=None, 1078 description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", 1079 ) 1080 source_type: str | None = Field( 1081 default=None, 1082 description="Kind of source object (for example `repository`). `null` when the task has no source.", 1083 ) 1084 stalled_since: datetime | None = Field( 1085 default=None, 1086 description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", 1087 ) 1088 status: str = Field( 1089 ..., 1090 description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', 1091 ) 1092 subtasks_count: int | None = Field( 1093 default=None, 1094 description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", 1095 ) 1096 tags: list[str] | None = Field( 1097 default=None, 1098 description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", 1099 ) 1100 target_binary: str | None = Field( 1101 default=None, 1102 description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", 1103 ) 1104 target_version: str | None = Field( 1105 default=None, 1106 description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", 1107 ) 1108 team: str | None = Field( 1109 default=None, 1110 description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", 1111 ) 1112 thread: str | None = Field( 1113 default=None, 1114 description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", 1115 ) 1116 updated_at: datetime | None = Field( 1117 default=None, description="When the task was last modified (ISO 8601)." 1118 ) 1119 user: str | None = Field( 1120 default=None, 1121 description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", 1122 ) 1123 1124 1125class TaskSubtasksResponse(BaseModel): 1126 """ 1127 Successful response 1128 """ 1129 1130 after_cursor: str | None = None 1131 before_cursor: str | None = None 1132 data: list[TaskSubtasksResponseDataItem] 1133 has_more: bool 1134 1135 1136class AsyncBlockerResource: 1137 def __init__(self, http: HttpClient): 1138 self._http = http 1139 1140 async def list( 1141 self, 1142 task: str, 1143 *, 1144 team: str | None = None, 1145 user: str | None = None, 1146 agent: str | None = None, 1147 org: str | None = None, 1148 limit: int | None = None, 1149 after_cursor: str | None = None, 1150 ) -> BlockerListResponse: 1151 """ 1152 List a task's blockers 1153 Returns a bounded page of the tasks currently marked as blocking the 1154 specified task, newest first. Blocking is informational: a blocked task 1155 can still change status, and it stops counting as blocked as soon as 1156 every blocker is done. The task's owner is resolved from the task itself. 1157 1158 Args: 1159 task: Blocked task ID (`tsk_...`). 1160 team: Explicit owning team (`tem_...`) for privileged calls. 1161 user: Explicit owning user (`usr_...`) for privileged calls. 1162 agent: Explicit owning agent (`agi_...`) for privileged calls. 1163 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1164 limit: Maximum blockers to return. Capped at 100. 1165 after_cursor: Opaque cursor returned by the previous page. 1166 1167 Returns: 1168 Successful response 1169 """ 1170 query: dict[str, object] = {} 1171 if team is not None: 1172 query["team"] = team 1173 if user is not None: 1174 query["user"] = user 1175 if agent is not None: 1176 query["agent"] = agent 1177 if org is not None: 1178 query["org"] = org 1179 if limit is not None: 1180 query["limit"] = limit 1181 if after_cursor is not None: 1182 query["after_cursor"] = after_cursor 1183 return await self._http.request( 1184 f"/api/v1/tasks/{task}/blockers", 1185 query=query, 1186 response_type=BlockerListResponse, 1187 ) 1188 1189 async def create(self, task: str, input: BlockerCreateInput) -> Task: 1190 """ 1191 Mark a task as blocked by another task 1192 Records that the task in `blocker` blocks the specified task and returns 1193 the updated task. Blocking is informational the blocked task can still 1194 change status and derived at read time, so the task stops reporting 1195 `is_blocked` as soon as every blocker is done. The blocker must belong to 1196 the same owner (team or user) as the task; self-blocking and blocking a 1197 task that already blocks the blocker (a direct cycle) are rejected. 1198 1199 Args: 1200 task: Blocked task ID (`tsk_...`). 1201 input: Request body. 1202 input.agent: Explicit owning agent (`agi_...`) for privileged calls. 1203 input.blocker: ID of the task that blocks this task (`tsk_...`). 1204 input.org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1205 input.team: Explicit owning team (`tem_...`) for privileged calls. 1206 input.user: Explicit owning user (`usr_...`) for privileged calls. 1207 1208 Returns: 1209 The updated (blocked) task. 1210 """ 1211 return await self._http.request( 1212 f"/api/v1/tasks/{task}/blockers", 1213 method="POST", 1214 body=input, 1215 response_type=Task, 1216 ) 1217 1218 async def delete(self, task: str, blocker: str) -> None: 1219 """ 1220 Remove a blocker from a task 1221 Removes the blocking relationship between the task in `blocker` and the 1222 specified task. Returns 204 No Content on success, or 404 if the given 1223 task is not currently marked as blocking this task. 1224 1225 Args: 1226 task: Blocked task ID (`tsk_...`). 1227 blocker: ID of the blocking task to remove (`tsk_...`). 1228 1229 Returns: 1230 Empty response body. HTTP 204 No Content on success. 1231 """ 1232 await self._http.request(f"/api/v1/tasks/{task}/blockers/{blocker}", method="DELETE") 1233 1234 1235class AsyncCommentResource: 1236 def __init__(self, http: HttpClient): 1237 self._http = http 1238 1239 async def list( 1240 self, 1241 task: str, 1242 *, 1243 team: str | None = None, 1244 user: str | None = None, 1245 agent: str | None = None, 1246 org: str | None = None, 1247 limit: int | None = None, 1248 after_cursor: str | None = None, 1249 ) -> CommentListResponse: 1250 """ 1251 List comments on a task 1252 Returns a bounded page of comments on the specified task, ordered by creation 1253 time ascending. App-scoped developer and server-to-server callers explicitly 1254 provide the owning `team`, `user`, or `agent` and `org`. 1255 1256 Args: 1257 task: Task ID (`tsk_...`). 1258 team: Explicit owning team (`tem_...`) for privileged calls. 1259 user: Explicit owning user (`usr_...`) for privileged calls. 1260 agent: Explicit owning agent (`agi_...`) for privileged calls. 1261 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1262 limit: Maximum comments to return. Capped at 100. 1263 after_cursor: Opaque cursor returned by the previous page. 1264 1265 Returns: 1266 Successful response 1267 """ 1268 query: dict[str, object] = {} 1269 if team is not None: 1270 query["team"] = team 1271 if user is not None: 1272 query["user"] = user 1273 if agent is not None: 1274 query["agent"] = agent 1275 if org is not None: 1276 query["org"] = org 1277 if limit is not None: 1278 query["limit"] = limit 1279 if after_cursor is not None: 1280 query["after_cursor"] = after_cursor 1281 return await self._http.request( 1282 f"/api/v1/tasks/{task}/comments", 1283 query=query, 1284 response_type=CommentListResponse, 1285 ) 1286 1287 async def create(self, task: str, input: CommentCreateInput) -> TaskComment: 1288 """ 1289 Create a comment on a task 1290 Posts a new comment on the specified task and returns the created comment. 1291 The task's owner is resolved from the task itself. 1292 1293 Args: 1294 task: Task ID (`tsk_...`). 1295 input: Request body. 1296 input.comment: Parameters for the comment to create, including its body. 1297 input.expected_version: Reject the comment if the task changed since this version. 1298 1299 Returns: 1300 The newly created comment. 1301 """ 1302 return await self._http.request( 1303 f"/api/v1/tasks/{task}/comments", 1304 method="POST", 1305 body=input, 1306 response_type=TaskComment, 1307 ) 1308 1309 async def delete(self, task: str, comment: str) -> None: 1310 """ 1311 Delete a task comment 1312 Permanently removes a comment from its task. This action cannot be undone. 1313 The task's owner is resolved from the task itself. 1314 Only the comment's author, an admin of the comment's organization, or an 1315 admin of the owning team may delete a comment. Returns `403 Forbidden` 1316 otherwise. 1317 1318 Args: 1319 task: Task ID (`tsk_...`). 1320 comment: Comment ID (`tcm_...`). 1321 1322 Returns: 1323 Empty body. The server responds with HTTP 204 No Content on success. 1324 """ 1325 await self._http.request(f"/api/v1/tasks/{task}/comments/{comment}", method="DELETE") 1326 1327 async def replace(self, task: str, comment: str, input: CommentReplaceInput) -> TaskComment: 1328 """ 1329 Update a task comment 1330 Replaces the body of an existing comment and returns the updated comment. 1331 The task's owner is resolved from the task itself. 1332 Only the comment's author, an admin of the comment's organization, or an 1333 admin of the owning team may edit a comment. Returns `403 Forbidden` 1334 otherwise. 1335 1336 Args: 1337 task: Task ID (`tsk_...`). 1338 comment: Comment ID (`tcm_...`). 1339 input: Request body. 1340 input.body: Replacement body for the comment. Must be non-empty. 1341 1342 Returns: 1343 The updated comment. 1344 """ 1345 return await self._http.request( 1346 f"/api/v1/tasks/{task}/comments/{comment}", 1347 method="PUT", 1348 body=input, 1349 response_type=TaskComment, 1350 ) 1351 1352 1353class AsyncLeaseResource: 1354 def __init__(self, http: HttpClient): 1355 self._http = http 1356 1357 async def remove(self, task: str) -> None: 1358 """ 1359 Release a task session lease 1360 Releases the authenticated assignee's matching live task lease. Repeating a 1361 release after the lease is absent succeeds. A different live successor lease 1362 returns a mismatch. 1363 1364 Args: 1365 task: Task ID (`tsk_...`). 1366 1367 Returns: 1368 Empty response. HTTP 204 is returned after release is accepted. 1369 """ 1370 await self._http.request(f"/api/v1/tasks/{task}/lease", method="DELETE") 1371 1372 async def list(self, task: str) -> TaskSessionLeaseSummary | None: 1373 """ 1374 Retrieve a task's current session lease 1375 Returns the authenticated assignee's viewer-safe live lease summary, or null 1376 when no live lease exists. Fencing and opaque session identifiers are never 1377 included. 1378 1379 Args: 1380 task: Task ID (`tsk_...`). 1381 1382 Returns: 1383 Viewer-safe live lease summary, or null. 1384 """ 1385 return await self._http.request( 1386 f"/api/v1/tasks/{task}/lease", 1387 response_type=TaskSessionLeaseSummary | None, 1388 ) 1389 1390 async def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: 1391 """ 1392 Claim a task for a coding session 1393 Atomically claims a user-assigned task for the authenticated user's coding 1394 session. The caller generates and retains both UUIDs. An exact retry returns 1395 the existing lease without extending it; another live holder produces a 1396 conflict. Developer and server-to-server credentials cannot impersonate the 1397 assigned user. 1398 1399 Args: 1400 task: Task ID (`tsk_...`). 1401 input: Request body. 1402 input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. 1403 input.harness: Bounded harness identifier. 1404 input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. 1405 input.lease_id: Caller-generated lease UUID. 1406 input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers. 1407 input.session_id: Caller-generated coding-session UUID. 1408 input.session_name: Human-readable coding-session label. 1409 1410 Returns: 1411 The caller-held lease, including its fencing token. 1412 """ 1413 return await self._http.request( 1414 f"/api/v1/tasks/{task}/lease", 1415 method="POST", 1416 body=input, 1417 response_type=TaskSessionLease, 1418 ) 1419 1420 async def renew(self, task: str, input: LeaseRenewInput) -> TaskSessionLease: 1421 """ 1422 Renew a task session lease 1423 Renews the authenticated assignee's matching live task lease. Both 1424 caller-generated UUIDs must match the aggregate's current lease. 1425 1426 Args: 1427 task: Task ID (`tsk_...`). 1428 input: Request body. 1429 input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds. 1430 input.lease_id: Current caller-held lease UUID. 1431 input.session_id: Current coding-session UUID. 1432 1433 Returns: 1434 The renewed caller-held lease. 1435 """ 1436 return await self._http.request( 1437 f"/api/v1/tasks/{task}/lease/renew", 1438 method="POST", 1439 body=input, 1440 response_type=TaskSessionLease, 1441 ) 1442 1443 1444class AsyncLinkResource: 1445 def __init__(self, http: HttpClient): 1446 self._http = http 1447 1448 async def remove(self, task: str) -> None: 1449 """ 1450 Remove an external link from a task 1451 1452 Args: 1453 task: Task ID (`tsk_...`). 1454 1455 Returns: 1456 HTTP 204 on success. 1457 """ 1458 await self._http.request(f"/api/v1/tasks/{task}/links", method="DELETE") 1459 1460 async def list( 1461 self, 1462 task: str, 1463 *, 1464 team: str | None = None, 1465 user: str | None = None, 1466 agent: str | None = None, 1467 org: str | None = None, 1468 limit: int | None = None, 1469 after_cursor: str | None = None, 1470 ) -> LinkListResponse: 1471 """ 1472 List a task's external links 1473 Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map. 1474 1475 Args: 1476 task: Task ID (`tsk_...`). 1477 team: Explicit owning team for privileged calls. 1478 user: Explicit owning user for privileged calls. 1479 agent: Explicit owning agent for privileged calls. 1480 org: Explicit organization for privileged calls; must agree with owner. 1481 limit: Maximum links to return. Capped at 100. 1482 after_cursor: Opaque cursor returned by the previous page. 1483 1484 Returns: 1485 Successful response 1486 """ 1487 query: dict[str, object] = {} 1488 if team is not None: 1489 query["team"] = team 1490 if user is not None: 1491 query["user"] = user 1492 if agent is not None: 1493 query["agent"] = agent 1494 if org is not None: 1495 query["org"] = org 1496 if limit is not None: 1497 query["limit"] = limit 1498 if after_cursor is not None: 1499 query["after_cursor"] = after_cursor 1500 return await self._http.request( 1501 f"/api/v1/tasks/{task}/links", 1502 query=query, 1503 response_type=LinkListResponse, 1504 ) 1505 1506 async def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: 1507 """ 1508 Add an external link to a task 1509 Adds an indexed identity without changing the referenced object's ownership or ACL. 1510 For private files, upload with POST /api/v1/files, then pass external_scope=platform, 1511 object_type=file and object_id=fil_.... The reserved platform namespace means the 1512 authenticated current backend/app/sandbox, not a hostname or stored URL. 1513 File attachment requires both task mutation permission and current file read access. 1514 List and reverse lookup omit files that are missing or no longer readable, including 1515 thread-restricted files. Generic identities are not resolved as local files. 1516 GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; 1517 never persist that URL as the link identity. Existing signed URLs remain usable until 1518 their expiry. Task activity and replay may retain opaque file IDs, not file metadata, 1519 and confer no file access. 1520 Retain the upload response's file ID if attachment fails and retry the link request. 1521 Detaching or deleting a task does not delete the file. Deleting a file leaves historical 1522 link events intact; replay does not restore bytes or access. No ACL grant is implicit. 1523 Agent-owned uploads use an authorized human session; agent-only file credentials 1524 remain unsupported. 1525 Download URLs depend on the configured storage provider. The development local 1526 provider returns a local URL prefix plus a storage path, but Platform does not 1527 serve that path over HTTP. Local-provider verification reads bytes from the 1528 running Platform's configured storage directory after authorized metadata reads; 1529 it does not prove HTTP download authorization. Serving local downloads through 1530 an authorization-preserving route is a separate follow-up, not a public /storage 1531 mount. Served providers are verified through their HTTP download URLs. 1532 1533 Args: 1534 task: Task ID (`tsk_...`). 1535 input: Request body. 1536 input.external_scope: External container ID. 1537 input.object_id: External object ID. 1538 input.object_type: External object type. 1539 1540 Returns: 1541 The created external link, with its identity normalized. 1542 """ 1543 return await self._http.request( 1544 f"/api/v1/tasks/{task}/links", 1545 method="POST", 1546 body=input, 1547 response_type=TaskExternalLink, 1548 ) 1549 1550 1551class AsyncTaskResource: 1552 def __init__(self, http: HttpClient): 1553 self._http = http 1554 self.blockers = AsyncBlockerResource(http) 1555 self.comments = AsyncCommentResource(http) 1556 self.lease = AsyncLeaseResource(http) 1557 self.links = AsyncLinkResource(http) 1558 1559 async def delete(self, task: str) -> None: 1560 """ 1561 Delete a task 1562 Deletes a task from task lists and detail views. The task event stream is 1563 retained for auditability, while comments are removed and direct subtasks 1564 are promoted to top-level tasks. 1565 The delete event is accepted before the read model is updated. Clients 1566 should remove the task from local collections immediately; subsequent reads 1567 converge once the projection processes the event. 1568 Authenticated users may delete tasks they can access using their session 1569 identity. App-scoped developer and server-to-server callers must explicitly 1570 supply the task's `org` and owner. `team` or `user` identifies that owner; 1571 when neither is present, `agent` identifies an agent-owned task. With a team 1572 or user owner, `agent` identifies the acting principal. Each reference is 1573 validated before deletion. 1574 1575 Args: 1576 task: Task ID (`tsk_...`). 1577 1578 Returns: 1579 Empty response. HTTP 204 is returned after the delete event is accepted. 1580 """ 1581 await self._http.request(f"/api/v1/tasks/{task}", method="DELETE") 1582 1583 async def get( 1584 self, 1585 task: str, 1586 *, 1587 team: str | None = None, 1588 user: str | None = None, 1589 agent: str | None = None, 1590 org: str | None = None, 1591 ) -> Task: 1592 """ 1593 Retrieve a task 1594 Returns the full task object for the specified task ID. Authenticated users 1595 and agents resolve access through their session. App-scoped developer and 1596 server-to-server callers explicitly provide the owning `team`, `user`, or `agent` and 1597 `org`. Callers without access receive a 404. 1598 1599 Args: 1600 task: Task ID (`tsk_...`). 1601 team: Explicit owning team (`tem_...`) for privileged calls. 1602 user: Explicit owning user (`usr_...`) for privileged calls. 1603 agent: Explicit owning agent (`agi_...`) for privileged calls. 1604 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1605 1606 Returns: 1607 The requested task. 1608 """ 1609 query: dict[str, object] = {} 1610 if team is not None: 1611 query["team"] = team 1612 if user is not None: 1613 query["user"] = user 1614 if agent is not None: 1615 query["agent"] = agent 1616 if org is not None: 1617 query["org"] = org 1618 return await self._http.request(f"/api/v1/tasks/{task}", query=query, response_type=Task) 1619 1620 async def replace(self, task: str, input: TaskReplaceInput) -> Task: 1621 """ 1622 Update a task 1623 Updates the supplied fields on a task and returns the complete updated task. 1624 Authenticated users use their session identity. App-scoped developer and 1625 server-to-server callers must explicitly supply the task's `org` and owner. 1626 `team` or `user` identifies that owner; when neither is present, `agent` 1627 identifies an agent-owned task. With a team or user owner, `agent` identifies 1628 the acting principal. Every reference is validated before the update. 1629 A cooperating coding-session client may supply both `lease_id` and 1630 `lease_session_id`. The task aggregate fences that update against the live 1631 lease and records server-sourced session provenance. Omitting both remains a 1632 normal authorized human/API update. 1633 Supply `expected_version` from the latest task representation to make the 1634 update conditional. A concurrent write returns `task_version_conflict`. 1635 1636 Args: 1637 task: Task ID (`tsk_...`). 1638 input: Request body. 1639 input.agent: Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal. 1640 input.description: Updated long-form description. 1641 input.due_date: Updated due date in ISO 8601 format, or null to clear it. 1642 input.epic: Replacement grouping label. Pass null to clear it. 1643 input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. 1644 input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. 1645 input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. 1646 input.links: Replacement related-links object. 1647 input.metadata: Replacement task metadata object. 1648 input.name: Updated display name for the task. 1649 input.org: Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization. 1650 input.owner_agent: Assign to an agent by public ID (`agi_...`). 1651 input.owner_user: Assign to a user by public ID (`usr_...`). 1652 input.parent: Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. 1653 input.priority: Updated priority from 0 (highest) to 4 (lowest). 1654 input.project_id: Project ID (`prj_...`). Omit to preserve; pass null to clear. 1655 input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. 1656 input.source_id: Replacement source object identity. Must be supplied with the other source fields. 1657 input.source_scope: Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. 1658 input.source_type: Replacement source object kind. Must be supplied with the other source fields. 1659 input.status: Updated status: `open`, `in_progress`, `in_review`, or `done`. 1660 input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. 1661 input.target_binary: Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. 1662 input.target_version: Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. 1663 input.team: Explicit owning team (`tem_...`) for a developer or server-to-server call. 1664 input.user: Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. 1665 1666 Returns: 1667 The updated task. 1668 """ 1669 return await self._http.request( 1670 f"/api/v1/tasks/{task}", 1671 method="PUT", 1672 body=input, 1673 response_type=Task, 1674 ) 1675 1676 async def activity( 1677 self, 1678 task: str, 1679 *, 1680 team: str | None = None, 1681 user: str | None = None, 1682 agent: str | None = None, 1683 org: str | None = None, 1684 limit: int | None = None, 1685 after_cursor: str | None = None, 1686 ) -> TaskActivityResponse: 1687 """ 1688 List a task's activity 1689 Returns a bounded chronological page of activity for the specified task. 1690 App-scoped developer and server-to-server callers explicitly provide the 1691 owning `team`, `user`, or `agent` and `org`. 1692 1693 Args: 1694 task: Task ID (`tsk_...`). 1695 team: Explicit owning team (`tem_...`) for privileged calls. 1696 user: Explicit owning user (`usr_...`) for privileged calls. 1697 agent: Explicit owning agent (`agi_...`) for privileged calls. 1698 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1699 limit: Maximum entries to return. Capped at 100. 1700 after_cursor: Opaque cursor returned by the previous page. 1701 1702 Returns: 1703 Successful response 1704 """ 1705 query: dict[str, object] = {} 1706 if team is not None: 1707 query["team"] = team 1708 if user is not None: 1709 query["user"] = user 1710 if agent is not None: 1711 query["agent"] = agent 1712 if org is not None: 1713 query["org"] = org 1714 if limit is not None: 1715 query["limit"] = limit 1716 if after_cursor is not None: 1717 query["after_cursor"] = after_cursor 1718 return await self._http.request( 1719 f"/api/v1/tasks/{task}/activity", 1720 query=query, 1721 response_type=TaskActivityResponse, 1722 ) 1723 1724 async def blocking( 1725 self, 1726 task: str, 1727 *, 1728 team: str | None = None, 1729 user: str | None = None, 1730 agent: str | None = None, 1731 org: str | None = None, 1732 limit: int | None = None, 1733 after_cursor: str | None = None, 1734 ) -> TaskBlockingResponse: 1735 """ 1736 List the tasks a task blocks 1737 Returns a bounded page of the tasks that the specified task is marked as 1738 blocking (the inverse of `GET /tasks/{task}/blockers`), newest first. 1739 The task's owner is resolved from the task itself. 1740 1741 Args: 1742 task: Blocking task ID (`tsk_...`). 1743 team: Explicit owning team (`tem_...`) for privileged calls. 1744 user: Explicit owning user (`usr_...`) for privileged calls. 1745 agent: Explicit owning agent (`agi_...`) for privileged calls. 1746 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1747 limit: Maximum tasks to return. Capped at 100. 1748 after_cursor: Opaque cursor returned by the previous page. 1749 1750 Returns: 1751 Successful response 1752 """ 1753 query: dict[str, object] = {} 1754 if team is not None: 1755 query["team"] = team 1756 if user is not None: 1757 query["user"] = user 1758 if agent is not None: 1759 query["agent"] = agent 1760 if org is not None: 1761 query["org"] = org 1762 if limit is not None: 1763 query["limit"] = limit 1764 if after_cursor is not None: 1765 query["after_cursor"] = after_cursor 1766 return await self._http.request( 1767 f"/api/v1/tasks/{task}/blocking", 1768 query=query, 1769 response_type=TaskBlockingResponse, 1770 ) 1771 1772 async def ownership_conversions( 1773 self, task: str, input: TaskOwnershipConversionsInput 1774 ) -> TaskOwnershipJob: 1775 """ 1776 Convert ownership of a connected task graph 1777 Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. 1778 1779 Args: 1780 task: Root task (`tsk_...`). 1781 input: Request body. 1782 input.dest_agent: Destination agent (`agi_...`). 1783 input.dest_org: Destination organization (`org_...`). 1784 input.dest_team: Destination team (`tem_...`). 1785 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 1786 1787 Returns: 1788 The queued background job. 1789 """ 1790 return await self._http.request( 1791 f"/api/v1/tasks/{task}/ownership_conversions", 1792 method="POST", 1793 body=input, 1794 response_type=TaskOwnershipJob, 1795 ) 1796 1797 async def subtasks( 1798 self, 1799 task: str, 1800 *, 1801 team: str | None = None, 1802 user: str | None = None, 1803 agent: str | None = None, 1804 org: str | None = None, 1805 limit: int | None = None, 1806 after_cursor: str | None = None, 1807 ) -> TaskSubtasksResponse: 1808 """ 1809 List a task's subtasks 1810 Returns a bounded page of the specified task's subtasks (tasks whose 1811 `parent` is this task), newest first. Subtasks nest exactly one level, so 1812 entries never have subtasks of their own. Privileged callers explicitly 1813 provide the owning `team`, `user`, or `agent` and `org`. 1814 1815 Args: 1816 task: Parent task ID (`tsk_...`). 1817 team: Explicit owning team (`tem_...`) for privileged calls. 1818 user: Explicit owning user (`usr_...`) for privileged calls. 1819 agent: Explicit owning agent (`agi_...`) for privileged calls. 1820 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1821 limit: Maximum subtasks to return. Capped at 100. 1822 after_cursor: Opaque cursor returned by the previous page. 1823 1824 Returns: 1825 Successful response 1826 """ 1827 query: dict[str, object] = {} 1828 if team is not None: 1829 query["team"] = team 1830 if user is not None: 1831 query["user"] = user 1832 if agent is not None: 1833 query["agent"] = agent 1834 if org is not None: 1835 query["org"] = org 1836 if limit is not None: 1837 query["limit"] = limit 1838 if after_cursor is not None: 1839 query["after_cursor"] = after_cursor 1840 return await self._http.request( 1841 f"/api/v1/tasks/{task}/subtasks", 1842 query=query, 1843 response_type=TaskSubtasksResponse, 1844 ) 1845 1846 async def transfer_ownership(self, task: str, input: TaskTransferOwnershipInput) -> Task: 1847 """ 1848 Transfer one task to a different owner 1849 Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. 1850 1851 Args: 1852 task: Task (`tsk_...`). 1853 input: Request body. 1854 input.dest_agent: Destination agent (`agi_...`). 1855 input.dest_org: Destination organization (`org_...`). 1856 input.dest_team: Destination team (`tem_...`). 1857 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 1858 input.expected_version: The task version reviewed by the caller. 1859 1860 Returns: 1861 The task with its new owner. 1862 """ 1863 return await self._http.request( 1864 f"/api/v1/tasks/{task}/transfer_ownership", 1865 method="POST", 1866 body=input, 1867 response_type=Task, 1868 ) 1869 1870 1871class BlockerResource: 1872 def __init__(self, http: SyncHttpClient): 1873 self._http = http 1874 1875 def list( 1876 self, 1877 task: str, 1878 *, 1879 team: str | None = None, 1880 user: str | None = None, 1881 agent: str | None = None, 1882 org: str | None = None, 1883 limit: int | None = None, 1884 after_cursor: str | None = None, 1885 ) -> BlockerListResponse: 1886 """ 1887 List a task's blockers 1888 Returns a bounded page of the tasks currently marked as blocking the 1889 specified task, newest first. Blocking is informational: a blocked task 1890 can still change status, and it stops counting as blocked as soon as 1891 every blocker is done. The task's owner is resolved from the task itself. 1892 1893 Args: 1894 task: Blocked task ID (`tsk_...`). 1895 team: Explicit owning team (`tem_...`) for privileged calls. 1896 user: Explicit owning user (`usr_...`) for privileged calls. 1897 agent: Explicit owning agent (`agi_...`) for privileged calls. 1898 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1899 limit: Maximum blockers to return. Capped at 100. 1900 after_cursor: Opaque cursor returned by the previous page. 1901 1902 Returns: 1903 Successful response 1904 """ 1905 query: dict[str, object] = {} 1906 if team is not None: 1907 query["team"] = team 1908 if user is not None: 1909 query["user"] = user 1910 if agent is not None: 1911 query["agent"] = agent 1912 if org is not None: 1913 query["org"] = org 1914 if limit is not None: 1915 query["limit"] = limit 1916 if after_cursor is not None: 1917 query["after_cursor"] = after_cursor 1918 return self._http.request( 1919 f"/api/v1/tasks/{task}/blockers", 1920 query=query, 1921 response_type=BlockerListResponse, 1922 ) 1923 1924 def create(self, task: str, input: BlockerCreateInput) -> Task: 1925 """ 1926 Mark a task as blocked by another task 1927 Records that the task in `blocker` blocks the specified task and returns 1928 the updated task. Blocking is informational the blocked task can still 1929 change status and derived at read time, so the task stops reporting 1930 `is_blocked` as soon as every blocker is done. The blocker must belong to 1931 the same owner (team or user) as the task; self-blocking and blocking a 1932 task that already blocks the blocker (a direct cycle) are rejected. 1933 1934 Args: 1935 task: Blocked task ID (`tsk_...`). 1936 input: Request body. 1937 input.agent: Explicit owning agent (`agi_...`) for privileged calls. 1938 input.blocker: ID of the task that blocks this task (`tsk_...`). 1939 input.org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1940 input.team: Explicit owning team (`tem_...`) for privileged calls. 1941 input.user: Explicit owning user (`usr_...`) for privileged calls. 1942 1943 Returns: 1944 The updated (blocked) task. 1945 """ 1946 return self._http.request( 1947 f"/api/v1/tasks/{task}/blockers", 1948 method="POST", 1949 body=input, 1950 response_type=Task, 1951 ) 1952 1953 def delete(self, task: str, blocker: str) -> None: 1954 """ 1955 Remove a blocker from a task 1956 Removes the blocking relationship between the task in `blocker` and the 1957 specified task. Returns 204 No Content on success, or 404 if the given 1958 task is not currently marked as blocking this task. 1959 1960 Args: 1961 task: Blocked task ID (`tsk_...`). 1962 blocker: ID of the blocking task to remove (`tsk_...`). 1963 1964 Returns: 1965 Empty response body. HTTP 204 No Content on success. 1966 """ 1967 self._http.request(f"/api/v1/tasks/{task}/blockers/{blocker}", method="DELETE") 1968 1969 1970class CommentResource: 1971 def __init__(self, http: SyncHttpClient): 1972 self._http = http 1973 1974 def list( 1975 self, 1976 task: str, 1977 *, 1978 team: str | None = None, 1979 user: str | None = None, 1980 agent: str | None = None, 1981 org: str | None = None, 1982 limit: int | None = None, 1983 after_cursor: str | None = None, 1984 ) -> CommentListResponse: 1985 """ 1986 List comments on a task 1987 Returns a bounded page of comments on the specified task, ordered by creation 1988 time ascending. App-scoped developer and server-to-server callers explicitly 1989 provide the owning `team`, `user`, or `agent` and `org`. 1990 1991 Args: 1992 task: Task ID (`tsk_...`). 1993 team: Explicit owning team (`tem_...`) for privileged calls. 1994 user: Explicit owning user (`usr_...`) for privileged calls. 1995 agent: Explicit owning agent (`agi_...`) for privileged calls. 1996 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1997 limit: Maximum comments to return. Capped at 100. 1998 after_cursor: Opaque cursor returned by the previous page. 1999 2000 Returns: 2001 Successful response 2002 """ 2003 query: dict[str, object] = {} 2004 if team is not None: 2005 query["team"] = team 2006 if user is not None: 2007 query["user"] = user 2008 if agent is not None: 2009 query["agent"] = agent 2010 if org is not None: 2011 query["org"] = org 2012 if limit is not None: 2013 query["limit"] = limit 2014 if after_cursor is not None: 2015 query["after_cursor"] = after_cursor 2016 return self._http.request( 2017 f"/api/v1/tasks/{task}/comments", 2018 query=query, 2019 response_type=CommentListResponse, 2020 ) 2021 2022 def create(self, task: str, input: CommentCreateInput) -> TaskComment: 2023 """ 2024 Create a comment on a task 2025 Posts a new comment on the specified task and returns the created comment. 2026 The task's owner is resolved from the task itself. 2027 2028 Args: 2029 task: Task ID (`tsk_...`). 2030 input: Request body. 2031 input.comment: Parameters for the comment to create, including its body. 2032 input.expected_version: Reject the comment if the task changed since this version. 2033 2034 Returns: 2035 The newly created comment. 2036 """ 2037 return self._http.request( 2038 f"/api/v1/tasks/{task}/comments", 2039 method="POST", 2040 body=input, 2041 response_type=TaskComment, 2042 ) 2043 2044 def delete(self, task: str, comment: str) -> None: 2045 """ 2046 Delete a task comment 2047 Permanently removes a comment from its task. This action cannot be undone. 2048 The task's owner is resolved from the task itself. 2049 Only the comment's author, an admin of the comment's organization, or an 2050 admin of the owning team may delete a comment. Returns `403 Forbidden` 2051 otherwise. 2052 2053 Args: 2054 task: Task ID (`tsk_...`). 2055 comment: Comment ID (`tcm_...`). 2056 2057 Returns: 2058 Empty body. The server responds with HTTP 204 No Content on success. 2059 """ 2060 self._http.request(f"/api/v1/tasks/{task}/comments/{comment}", method="DELETE") 2061 2062 def replace(self, task: str, comment: str, input: CommentReplaceInput) -> TaskComment: 2063 """ 2064 Update a task comment 2065 Replaces the body of an existing comment and returns the updated comment. 2066 The task's owner is resolved from the task itself. 2067 Only the comment's author, an admin of the comment's organization, or an 2068 admin of the owning team may edit a comment. Returns `403 Forbidden` 2069 otherwise. 2070 2071 Args: 2072 task: Task ID (`tsk_...`). 2073 comment: Comment ID (`tcm_...`). 2074 input: Request body. 2075 input.body: Replacement body for the comment. Must be non-empty. 2076 2077 Returns: 2078 The updated comment. 2079 """ 2080 return self._http.request( 2081 f"/api/v1/tasks/{task}/comments/{comment}", 2082 method="PUT", 2083 body=input, 2084 response_type=TaskComment, 2085 ) 2086 2087 2088class LeaseResource: 2089 def __init__(self, http: SyncHttpClient): 2090 self._http = http 2091 2092 def remove(self, task: str) -> None: 2093 """ 2094 Release a task session lease 2095 Releases the authenticated assignee's matching live task lease. Repeating a 2096 release after the lease is absent succeeds. A different live successor lease 2097 returns a mismatch. 2098 2099 Args: 2100 task: Task ID (`tsk_...`). 2101 2102 Returns: 2103 Empty response. HTTP 204 is returned after release is accepted. 2104 """ 2105 self._http.request(f"/api/v1/tasks/{task}/lease", method="DELETE") 2106 2107 def list(self, task: str) -> TaskSessionLeaseSummary | None: 2108 """ 2109 Retrieve a task's current session lease 2110 Returns the authenticated assignee's viewer-safe live lease summary, or null 2111 when no live lease exists. Fencing and opaque session identifiers are never 2112 included. 2113 2114 Args: 2115 task: Task ID (`tsk_...`). 2116 2117 Returns: 2118 Viewer-safe live lease summary, or null. 2119 """ 2120 return self._http.request( 2121 f"/api/v1/tasks/{task}/lease", 2122 response_type=TaskSessionLeaseSummary | None, 2123 ) 2124 2125 def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: 2126 """ 2127 Claim a task for a coding session 2128 Atomically claims a user-assigned task for the authenticated user's coding 2129 session. The caller generates and retains both UUIDs. An exact retry returns 2130 the existing lease without extending it; another live holder produces a 2131 conflict. Developer and server-to-server credentials cannot impersonate the 2132 assigned user. 2133 2134 Args: 2135 task: Task ID (`tsk_...`). 2136 input: Request body. 2137 input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. 2138 input.harness: Bounded harness identifier. 2139 input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. 2140 input.lease_id: Caller-generated lease UUID. 2141 input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers. 2142 input.session_id: Caller-generated coding-session UUID. 2143 input.session_name: Human-readable coding-session label. 2144 2145 Returns: 2146 The caller-held lease, including its fencing token. 2147 """ 2148 return self._http.request( 2149 f"/api/v1/tasks/{task}/lease", 2150 method="POST", 2151 body=input, 2152 response_type=TaskSessionLease, 2153 ) 2154 2155 def renew(self, task: str, input: LeaseRenewInput) -> TaskSessionLease: 2156 """ 2157 Renew a task session lease 2158 Renews the authenticated assignee's matching live task lease. Both 2159 caller-generated UUIDs must match the aggregate's current lease. 2160 2161 Args: 2162 task: Task ID (`tsk_...`). 2163 input: Request body. 2164 input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds. 2165 input.lease_id: Current caller-held lease UUID. 2166 input.session_id: Current coding-session UUID. 2167 2168 Returns: 2169 The renewed caller-held lease. 2170 """ 2171 return self._http.request( 2172 f"/api/v1/tasks/{task}/lease/renew", 2173 method="POST", 2174 body=input, 2175 response_type=TaskSessionLease, 2176 ) 2177 2178 2179class LinkResource: 2180 def __init__(self, http: SyncHttpClient): 2181 self._http = http 2182 2183 def remove(self, task: str) -> None: 2184 """ 2185 Remove an external link from a task 2186 2187 Args: 2188 task: Task ID (`tsk_...`). 2189 2190 Returns: 2191 HTTP 204 on success. 2192 """ 2193 self._http.request(f"/api/v1/tasks/{task}/links", method="DELETE") 2194 2195 def list( 2196 self, 2197 task: str, 2198 *, 2199 team: str | None = None, 2200 user: str | None = None, 2201 agent: str | None = None, 2202 org: str | None = None, 2203 limit: int | None = None, 2204 after_cursor: str | None = None, 2205 ) -> LinkListResponse: 2206 """ 2207 List a task's external links 2208 Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map. 2209 2210 Args: 2211 task: Task ID (`tsk_...`). 2212 team: Explicit owning team for privileged calls. 2213 user: Explicit owning user for privileged calls. 2214 agent: Explicit owning agent for privileged calls. 2215 org: Explicit organization for privileged calls; must agree with owner. 2216 limit: Maximum links to return. Capped at 100. 2217 after_cursor: Opaque cursor returned by the previous page. 2218 2219 Returns: 2220 Successful response 2221 """ 2222 query: dict[str, object] = {} 2223 if team is not None: 2224 query["team"] = team 2225 if user is not None: 2226 query["user"] = user 2227 if agent is not None: 2228 query["agent"] = agent 2229 if org is not None: 2230 query["org"] = org 2231 if limit is not None: 2232 query["limit"] = limit 2233 if after_cursor is not None: 2234 query["after_cursor"] = after_cursor 2235 return self._http.request( 2236 f"/api/v1/tasks/{task}/links", 2237 query=query, 2238 response_type=LinkListResponse, 2239 ) 2240 2241 def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: 2242 """ 2243 Add an external link to a task 2244 Adds an indexed identity without changing the referenced object's ownership or ACL. 2245 For private files, upload with POST /api/v1/files, then pass external_scope=platform, 2246 object_type=file and object_id=fil_.... The reserved platform namespace means the 2247 authenticated current backend/app/sandbox, not a hostname or stored URL. 2248 File attachment requires both task mutation permission and current file read access. 2249 List and reverse lookup omit files that are missing or no longer readable, including 2250 thread-restricted files. Generic identities are not resolved as local files. 2251 GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; 2252 never persist that URL as the link identity. Existing signed URLs remain usable until 2253 their expiry. Task activity and replay may retain opaque file IDs, not file metadata, 2254 and confer no file access. 2255 Retain the upload response's file ID if attachment fails and retry the link request. 2256 Detaching or deleting a task does not delete the file. Deleting a file leaves historical 2257 link events intact; replay does not restore bytes or access. No ACL grant is implicit. 2258 Agent-owned uploads use an authorized human session; agent-only file credentials 2259 remain unsupported. 2260 Download URLs depend on the configured storage provider. The development local 2261 provider returns a local URL prefix plus a storage path, but Platform does not 2262 serve that path over HTTP. Local-provider verification reads bytes from the 2263 running Platform's configured storage directory after authorized metadata reads; 2264 it does not prove HTTP download authorization. Serving local downloads through 2265 an authorization-preserving route is a separate follow-up, not a public /storage 2266 mount. Served providers are verified through their HTTP download URLs. 2267 2268 Args: 2269 task: Task ID (`tsk_...`). 2270 input: Request body. 2271 input.external_scope: External container ID. 2272 input.object_id: External object ID. 2273 input.object_type: External object type. 2274 2275 Returns: 2276 The created external link, with its identity normalized. 2277 """ 2278 return self._http.request( 2279 f"/api/v1/tasks/{task}/links", 2280 method="POST", 2281 body=input, 2282 response_type=TaskExternalLink, 2283 ) 2284 2285 2286class TaskResource: 2287 def __init__(self, http: SyncHttpClient): 2288 self._http = http 2289 self.blockers = BlockerResource(http) 2290 self.comments = CommentResource(http) 2291 self.lease = LeaseResource(http) 2292 self.links = LinkResource(http) 2293 2294 def delete(self, task: str) -> None: 2295 """ 2296 Delete a task 2297 Deletes a task from task lists and detail views. The task event stream is 2298 retained for auditability, while comments are removed and direct subtasks 2299 are promoted to top-level tasks. 2300 The delete event is accepted before the read model is updated. Clients 2301 should remove the task from local collections immediately; subsequent reads 2302 converge once the projection processes the event. 2303 Authenticated users may delete tasks they can access using their session 2304 identity. App-scoped developer and server-to-server callers must explicitly 2305 supply the task's `org` and owner. `team` or `user` identifies that owner; 2306 when neither is present, `agent` identifies an agent-owned task. With a team 2307 or user owner, `agent` identifies the acting principal. Each reference is 2308 validated before deletion. 2309 2310 Args: 2311 task: Task ID (`tsk_...`). 2312 2313 Returns: 2314 Empty response. HTTP 204 is returned after the delete event is accepted. 2315 """ 2316 self._http.request(f"/api/v1/tasks/{task}", method="DELETE") 2317 2318 def get( 2319 self, 2320 task: str, 2321 *, 2322 team: str | None = None, 2323 user: str | None = None, 2324 agent: str | None = None, 2325 org: str | None = None, 2326 ) -> Task: 2327 """ 2328 Retrieve a task 2329 Returns the full task object for the specified task ID. Authenticated users 2330 and agents resolve access through their session. App-scoped developer and 2331 server-to-server callers explicitly provide the owning `team`, `user`, or `agent` and 2332 `org`. Callers without access receive a 404. 2333 2334 Args: 2335 task: Task ID (`tsk_...`). 2336 team: Explicit owning team (`tem_...`) for privileged calls. 2337 user: Explicit owning user (`usr_...`) for privileged calls. 2338 agent: Explicit owning agent (`agi_...`) for privileged calls. 2339 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2340 2341 Returns: 2342 The requested task. 2343 """ 2344 query: dict[str, object] = {} 2345 if team is not None: 2346 query["team"] = team 2347 if user is not None: 2348 query["user"] = user 2349 if agent is not None: 2350 query["agent"] = agent 2351 if org is not None: 2352 query["org"] = org 2353 return self._http.request(f"/api/v1/tasks/{task}", query=query, response_type=Task) 2354 2355 def replace(self, task: str, input: TaskReplaceInput) -> Task: 2356 """ 2357 Update a task 2358 Updates the supplied fields on a task and returns the complete updated task. 2359 Authenticated users use their session identity. App-scoped developer and 2360 server-to-server callers must explicitly supply the task's `org` and owner. 2361 `team` or `user` identifies that owner; when neither is present, `agent` 2362 identifies an agent-owned task. With a team or user owner, `agent` identifies 2363 the acting principal. Every reference is validated before the update. 2364 A cooperating coding-session client may supply both `lease_id` and 2365 `lease_session_id`. The task aggregate fences that update against the live 2366 lease and records server-sourced session provenance. Omitting both remains a 2367 normal authorized human/API update. 2368 Supply `expected_version` from the latest task representation to make the 2369 update conditional. A concurrent write returns `task_version_conflict`. 2370 2371 Args: 2372 task: Task ID (`tsk_...`). 2373 input: Request body. 2374 input.agent: Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal. 2375 input.description: Updated long-form description. 2376 input.due_date: Updated due date in ISO 8601 format, or null to clear it. 2377 input.epic: Replacement grouping label. Pass null to clear it. 2378 input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. 2379 input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. 2380 input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. 2381 input.links: Replacement related-links object. 2382 input.metadata: Replacement task metadata object. 2383 input.name: Updated display name for the task. 2384 input.org: Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization. 2385 input.owner_agent: Assign to an agent by public ID (`agi_...`). 2386 input.owner_user: Assign to a user by public ID (`usr_...`). 2387 input.parent: Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. 2388 input.priority: Updated priority from 0 (highest) to 4 (lowest). 2389 input.project_id: Project ID (`prj_...`). Omit to preserve; pass null to clear. 2390 input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. 2391 input.source_id: Replacement source object identity. Must be supplied with the other source fields. 2392 input.source_scope: Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. 2393 input.source_type: Replacement source object kind. Must be supplied with the other source fields. 2394 input.status: Updated status: `open`, `in_progress`, `in_review`, or `done`. 2395 input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. 2396 input.target_binary: Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. 2397 input.target_version: Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. 2398 input.team: Explicit owning team (`tem_...`) for a developer or server-to-server call. 2399 input.user: Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. 2400 2401 Returns: 2402 The updated task. 2403 """ 2404 return self._http.request( 2405 f"/api/v1/tasks/{task}", 2406 method="PUT", 2407 body=input, 2408 response_type=Task, 2409 ) 2410 2411 def activity( 2412 self, 2413 task: str, 2414 *, 2415 team: str | None = None, 2416 user: str | None = None, 2417 agent: str | None = None, 2418 org: str | None = None, 2419 limit: int | None = None, 2420 after_cursor: str | None = None, 2421 ) -> TaskActivityResponse: 2422 """ 2423 List a task's activity 2424 Returns a bounded chronological page of activity for the specified task. 2425 App-scoped developer and server-to-server callers explicitly provide the 2426 owning `team`, `user`, or `agent` and `org`. 2427 2428 Args: 2429 task: Task ID (`tsk_...`). 2430 team: Explicit owning team (`tem_...`) for privileged calls. 2431 user: Explicit owning user (`usr_...`) for privileged calls. 2432 agent: Explicit owning agent (`agi_...`) for privileged calls. 2433 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2434 limit: Maximum entries to return. Capped at 100. 2435 after_cursor: Opaque cursor returned by the previous page. 2436 2437 Returns: 2438 Successful response 2439 """ 2440 query: dict[str, object] = {} 2441 if team is not None: 2442 query["team"] = team 2443 if user is not None: 2444 query["user"] = user 2445 if agent is not None: 2446 query["agent"] = agent 2447 if org is not None: 2448 query["org"] = org 2449 if limit is not None: 2450 query["limit"] = limit 2451 if after_cursor is not None: 2452 query["after_cursor"] = after_cursor 2453 return self._http.request( 2454 f"/api/v1/tasks/{task}/activity", 2455 query=query, 2456 response_type=TaskActivityResponse, 2457 ) 2458 2459 def blocking( 2460 self, 2461 task: str, 2462 *, 2463 team: str | None = None, 2464 user: str | None = None, 2465 agent: str | None = None, 2466 org: str | None = None, 2467 limit: int | None = None, 2468 after_cursor: str | None = None, 2469 ) -> TaskBlockingResponse: 2470 """ 2471 List the tasks a task blocks 2472 Returns a bounded page of the tasks that the specified task is marked as 2473 blocking (the inverse of `GET /tasks/{task}/blockers`), newest first. 2474 The task's owner is resolved from the task itself. 2475 2476 Args: 2477 task: Blocking task ID (`tsk_...`). 2478 team: Explicit owning team (`tem_...`) for privileged calls. 2479 user: Explicit owning user (`usr_...`) for privileged calls. 2480 agent: Explicit owning agent (`agi_...`) for privileged calls. 2481 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2482 limit: Maximum tasks to return. Capped at 100. 2483 after_cursor: Opaque cursor returned by the previous page. 2484 2485 Returns: 2486 Successful response 2487 """ 2488 query: dict[str, object] = {} 2489 if team is not None: 2490 query["team"] = team 2491 if user is not None: 2492 query["user"] = user 2493 if agent is not None: 2494 query["agent"] = agent 2495 if org is not None: 2496 query["org"] = org 2497 if limit is not None: 2498 query["limit"] = limit 2499 if after_cursor is not None: 2500 query["after_cursor"] = after_cursor 2501 return self._http.request( 2502 f"/api/v1/tasks/{task}/blocking", 2503 query=query, 2504 response_type=TaskBlockingResponse, 2505 ) 2506 2507 def ownership_conversions( 2508 self, task: str, input: TaskOwnershipConversionsInput 2509 ) -> TaskOwnershipJob: 2510 """ 2511 Convert ownership of a connected task graph 2512 Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. 2513 2514 Args: 2515 task: Root task (`tsk_...`). 2516 input: Request body. 2517 input.dest_agent: Destination agent (`agi_...`). 2518 input.dest_org: Destination organization (`org_...`). 2519 input.dest_team: Destination team (`tem_...`). 2520 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 2521 2522 Returns: 2523 The queued background job. 2524 """ 2525 return self._http.request( 2526 f"/api/v1/tasks/{task}/ownership_conversions", 2527 method="POST", 2528 body=input, 2529 response_type=TaskOwnershipJob, 2530 ) 2531 2532 def subtasks( 2533 self, 2534 task: str, 2535 *, 2536 team: str | None = None, 2537 user: str | None = None, 2538 agent: str | None = None, 2539 org: str | None = None, 2540 limit: int | None = None, 2541 after_cursor: str | None = None, 2542 ) -> TaskSubtasksResponse: 2543 """ 2544 List a task's subtasks 2545 Returns a bounded page of the specified task's subtasks (tasks whose 2546 `parent` is this task), newest first. Subtasks nest exactly one level, so 2547 entries never have subtasks of their own. Privileged callers explicitly 2548 provide the owning `team`, `user`, or `agent` and `org`. 2549 2550 Args: 2551 task: Parent task ID (`tsk_...`). 2552 team: Explicit owning team (`tem_...`) for privileged calls. 2553 user: Explicit owning user (`usr_...`) for privileged calls. 2554 agent: Explicit owning agent (`agi_...`) for privileged calls. 2555 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2556 limit: Maximum subtasks to return. Capped at 100. 2557 after_cursor: Opaque cursor returned by the previous page. 2558 2559 Returns: 2560 Successful response 2561 """ 2562 query: dict[str, object] = {} 2563 if team is not None: 2564 query["team"] = team 2565 if user is not None: 2566 query["user"] = user 2567 if agent is not None: 2568 query["agent"] = agent 2569 if org is not None: 2570 query["org"] = org 2571 if limit is not None: 2572 query["limit"] = limit 2573 if after_cursor is not None: 2574 query["after_cursor"] = after_cursor 2575 return self._http.request( 2576 f"/api/v1/tasks/{task}/subtasks", 2577 query=query, 2578 response_type=TaskSubtasksResponse, 2579 ) 2580 2581 def transfer_ownership(self, task: str, input: TaskTransferOwnershipInput) -> Task: 2582 """ 2583 Transfer one task to a different owner 2584 Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. 2585 2586 Args: 2587 task: Task (`tsk_...`). 2588 input: Request body. 2589 input.dest_agent: Destination agent (`agi_...`). 2590 input.dest_org: Destination organization (`org_...`). 2591 input.dest_team: Destination team (`tem_...`). 2592 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 2593 input.expected_version: The task version reviewed by the caller. 2594 2595 Returns: 2596 The task with its new owner. 2597 """ 2598 return self._http.request( 2599 f"/api/v1/tasks/{task}/transfer_ownership", 2600 method="POST", 2601 body=input, 2602 response_type=Task, 2603 )
24class BlockerCreateInput(TypedDict, total=False): 25 "Mark a task as blocked by another task" 26 27 agent: str | None 28 "Explicit owning agent (`agi_...`) for privileged calls." 29 blocker: Required[str] 30 "ID of the task that blocks this task (`tsk_...`)." 31 org: str | None 32 "Explicit organization (`org_...`) for privileged calls; pass null when unscoped." 33 team: str | None 34 "Explicit owning team (`tem_...`) for privileged calls." 35 user: str | None 36 "Explicit owning user (`usr_...`) for privileged calls."
Mark a task as blocked by another task
44class CommentCreateInput(TypedDict, total=False): 45 "Create a comment on a task" 46 47 comment: Required[CommentCreateInputComment] 48 "Parameters for the comment to create, including its body." 49 expected_version: int | None 50 "Reject the comment if the task changed since this version."
Create a comment on a task
Parameters for the comment to create, including its body.
53class CommentReplaceInput(TypedDict): 54 "Update a task comment" 55 56 body: str 57 "Replacement body for the comment. Must be non-empty."
Update a task comment
60class LeaseCreateInput(TypedDict, total=False): 61 "Claim a task for a coding session" 62 63 force: bool | None 64 "Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim." 65 harness: Required[str] 66 "Bounded harness identifier." 67 lease_duration_seconds: int | None 68 "Requested lease lifetime in seconds; the task aggregate enforces its bounds." 69 lease_id: Required[str] 70 "Caller-generated lease UUID." 71 require_ready: bool | None 72 "Conservatively reject the claim when the current task projection has unfinished blockers." 73 session_id: Required[str] 74 "Caller-generated coding-session UUID." 75 session_name: Required[str] 76 "Human-readable coding-session label."
Claim a task for a coding session
Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim.
Requested lease lifetime in seconds; the task aggregate enforces its bounds.
79class LeaseRenewInput(TypedDict, total=False): 80 "Renew a task session lease" 81 82 lease_duration_seconds: int | None 83 "Requested renewed lifetime in seconds; the task aggregate enforces its bounds." 84 lease_id: Required[str] 85 "Current caller-held lease UUID." 86 session_id: Required[str] 87 "Current coding-session UUID."
Renew a task session lease
90class LinkCreateInput(TypedDict): 91 "Add an external link to a task" 92 93 external_scope: str 94 "External container ID." 95 object_id: str 96 "External object ID." 97 object_type: str 98 "External object type."
Add an external link to a task
101class TaskReplaceInput(TypedDict, total=False): 102 "Update a task" 103 104 agent: str | None 105 "Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal." 106 description: str | None 107 "Updated long-form description." 108 due_date: datetime | None 109 "Updated due date in ISO 8601 format, or null to clear it." 110 epic: str | None 111 "Replacement grouping label. Pass null to clear it." 112 expected_version: int | None 113 "Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first." 114 lease_id: str | None 115 "Current caller-held lease UUID. Must be paired with `lease_session_id`." 116 lease_session_id: str | None 117 "Current coding-session UUID. Must be paired with `lease_id`." 118 links: dict[str, Any] | None 119 "Replacement related-links object." 120 metadata: dict[str, Any] | None 121 "Replacement task metadata object." 122 name: str | None 123 "Updated display name for the task." 124 org: str | None 125 "Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization." 126 owner_agent: str | None 127 "Assign to an agent by public ID (`agi_...`)." 128 owner_user: str | None 129 "Assign to a user by public ID (`usr_...`)." 130 parent: str | None 131 "Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one." 132 priority: int | None 133 "Updated priority from 0 (highest) to 4 (lowest)." 134 project_id: str | None 135 "Project ID (`prj_...`). Omit to preserve; pass null to clear." 136 require_status_lease: bool | None 137 "Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available." 138 source_id: str | None 139 "Replacement source object identity. Must be supplied with the other source fields." 140 source_scope: str | None 141 "Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source." 142 source_type: str | None 143 "Replacement source object kind. Must be supplied with the other source fields." 144 status: str | None 145 "Updated status: `open`, `in_progress`, `in_review`, or `done`." 146 tags: list[str] | None 147 "Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags." 148 target_binary: str | None 149 "Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target." 150 target_version: str | None 151 "Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`." 152 team: str | None 153 "Explicit owning team (`tem_...`) for a developer or server-to-server call." 154 user: str | None 155 "Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member."
Update a task
Aggregate version returned by the latest task read. The update fails with task_version_conflict if the task changed first.
Explicit organization (org_...) for a developer or server-to-server call. Pass null for an owner outside an organization.
Move this task under a top-level parent (tsk_...), or pass null to promote it to a top-level task. A task that has subtasks cannot become one.
Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available.
Replacement source object identity. Must be supplied with the other source fields.
Replacement source container. Pass together with source_type and source_id, or pass all three as null to clear the source.
Replacement source object kind. Must be supplied with the other source fields.
Replacement target binary (for example my-cli): a lowercase identifier of 1-64 characters. Pass together with target_version, or pass both as null to clear the target.
Replacement minimum semantic version of target_binary (for example 0.48.9). Must be supplied with target_binary.
Explicit user (usr_...) for a developer or server-to-server call. With team, this identifies the acting team member.
158class TaskOwnershipConversionsInput(TypedDict, total=False): 159 "Convert ownership of a connected task graph" 160 161 dest_agent: str | None 162 "Destination agent (`agi_...`)." 163 dest_org: str | None 164 "Destination organization (`org_...`)." 165 dest_team: str | None 166 "Destination team (`tem_...`)." 167 dest_user: str | None 168 "Destination user (`usr_...`). Supply exactly one destination."
Convert ownership of a connected task graph
171class TaskTransferOwnershipInput(TypedDict, total=False): 172 "Transfer one task to a different owner" 173 174 dest_agent: str | None 175 "Destination agent (`agi_...`)." 176 dest_org: str | None 177 "Destination organization (`org_...`)." 178 dest_team: str | None 179 "Destination team (`tem_...`)." 180 dest_user: str | None 181 "Destination user (`usr_...`). Supply exactly one destination." 182 expected_version: Required[int] 183 "The task version reviewed by the caller."
Transfer one task to a different owner
186class BlockerListResponseDataItemCreatedByActorProfilePicture(BaseModel): 187 file: str | None = Field( 188 default=None, 189 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 190 ) 191 height: int | None = Field( 192 default=None, description="Height of the image in pixels. `null` if not known." 193 ) 194 media: str | None = Field( 195 default=None, 196 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 197 ) 198 mime_type: str | None = Field( 199 default=None, 200 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 201 ) 202 refresh_url: str | None = Field( 203 default=None, 204 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.", 205 ) 206 url: str | None = Field( 207 default=None, 208 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.", 209 ) 210 width: int | None = Field( 211 default=None, description="Width of the image in pixels. `null` if not known." 212 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
215class BlockerListResponseDataItemCreatedByActor(BaseModel): 216 alias: str | None = Field( 217 default=None, 218 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 219 ) 220 id: str | None = Field( 221 default=None, 222 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 223 ) 224 name: str | None = Field( 225 default=None, 226 description="Display name of the actor shown in the UI. `null` if no name is set.", 227 ) 228 profile_picture: BlockerListResponseDataItemCreatedByActorProfilePicture | None = Field( 229 default=None, 230 description="Profile picture for the actor. `null` if the actor has no profile picture.", 231 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
234class BlockerListResponseDataItemCurrentLease(BaseModel): 235 expires_at: datetime = Field( 236 ..., description="Server-calculated lease expiry in ISO 8601 format." 237 ) 238 harness: str = Field(..., description="Bounded harness identifier for the coding session.") 239 session_name: str = Field( 240 ..., description="Display name supplied by the coding session that holds the lease." 241 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
244class BlockerListResponseDataItemOwnerActorProfilePicture(BaseModel): 245 file: str | None = Field( 246 default=None, 247 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 248 ) 249 height: int | None = Field( 250 default=None, description="Height of the image in pixels. `null` if not known." 251 ) 252 media: str | None = Field( 253 default=None, 254 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 255 ) 256 mime_type: str | None = Field( 257 default=None, 258 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 259 ) 260 refresh_url: str | None = Field( 261 default=None, 262 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.", 263 ) 264 url: str | None = Field( 265 default=None, 266 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.", 267 ) 268 width: int | None = Field( 269 default=None, description="Width of the image in pixels. `null` if not known." 270 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
273class BlockerListResponseDataItemOwnerActor(BaseModel): 274 alias: str | None = Field( 275 default=None, 276 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 277 ) 278 id: str | None = Field( 279 default=None, 280 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 281 ) 282 name: str | None = Field( 283 default=None, 284 description="Display name of the actor shown in the UI. `null` if no name is set.", 285 ) 286 profile_picture: BlockerListResponseDataItemOwnerActorProfilePicture | None = Field( 287 default=None, 288 description="Profile picture for the actor. `null` if the actor has no profile picture.", 289 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
292class BlockerListResponseDataItem(BaseModel): 293 agent: str | None = Field( 294 default=None, 295 description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", 296 ) 297 aggregate_version: int | None = Field( 298 default=None, 299 description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", 300 ) 301 blocked_by_count: int | None = Field( 302 default=None, 303 description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", 304 ) 305 closed_at: datetime | None = Field( 306 default=None, 307 description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", 308 ) 309 comments_count: int | None = Field( 310 default=None, description="Total number of comments posted on this task." 311 ) 312 created_at: datetime | None = Field( 313 default=None, description="When the task was created (ISO 8601)." 314 ) 315 created_by_actor: BlockerListResponseDataItemCreatedByActor | None = Field( 316 default=None, 317 description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", 318 ) 319 created_by_agent: str | None = Field( 320 default=None, 321 description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", 322 ) 323 created_by_user: str | None = Field( 324 default=None, 325 description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", 326 ) 327 current_lease: BlockerListResponseDataItemCurrentLease | None = Field( 328 default=None, 329 description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", 330 ) 331 description: str | None = Field( 332 default=None, 333 description="Long-form description or notes for the task. `null` if no description has been provided.", 334 ) 335 due_date: datetime | None = Field( 336 default=None, 337 description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", 338 ) 339 epic: str | None = Field( 340 default=None, 341 description="Free-form grouping label. `null` when the task is not in an epic.", 342 ) 343 id: str = Field(..., description="Task ID (`tsk_...`).") 344 is_blocked: bool | None = Field( 345 default=None, 346 description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", 347 ) 348 is_stalled: bool | None = Field( 349 default=None, 350 description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", 351 ) 352 links: dict[str, Any] | None = Field( 353 default=None, 354 description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", 355 ) 356 metadata: dict[str, Any] | None = Field( 357 default=None, 358 description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", 359 ) 360 name: str = Field(..., description="Human-readable title of the task.") 361 org: str | None = Field( 362 default=None, 363 description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", 364 ) 365 owner_actor: BlockerListResponseDataItemOwnerActor | None = Field( 366 default=None, 367 description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", 368 ) 369 owner_agent: str | None = Field( 370 default=None, 371 description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", 372 ) 373 owner_user: str | None = Field( 374 default=None, 375 description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", 376 ) 377 parent: str | None = Field( 378 default=None, 379 description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", 380 ) 381 priority: int | None = Field( 382 default=None, 383 description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", 384 ) 385 project_id: str | None = Field( 386 default=None, 387 description="Optional project ID (`prj_...`). Membership does not change task visibility.", 388 ) 389 sandbox: str | None = Field( 390 default=None, 391 description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", 392 ) 393 source_id: str | None = Field( 394 default=None, 395 description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", 396 ) 397 source_scope: str | None = Field( 398 default=None, 399 description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", 400 ) 401 source_type: str | None = Field( 402 default=None, 403 description="Kind of source object (for example `repository`). `null` when the task has no source.", 404 ) 405 stalled_since: datetime | None = Field( 406 default=None, 407 description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", 408 ) 409 status: str = Field( 410 ..., 411 description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', 412 ) 413 subtasks_count: int | None = Field( 414 default=None, 415 description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", 416 ) 417 tags: list[str] | None = Field( 418 default=None, 419 description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", 420 ) 421 target_binary: str | None = Field( 422 default=None, 423 description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", 424 ) 425 target_version: str | None = Field( 426 default=None, 427 description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", 428 ) 429 team: str | None = Field( 430 default=None, 431 description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", 432 ) 433 thread: str | None = Field( 434 default=None, 435 description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", 436 ) 437 updated_at: datetime | None = Field( 438 default=None, description="When the task was last modified (ISO 8601)." 439 ) 440 user: str | None = Field( 441 default=None, 442 description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", 443 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the agent that owns this task (agi_...). null if the task is scoped to a team or user.
Event-stream version for optimistic update fencing. Pass this value as expected_version on an update to reject concurrent writes.
Number of readable tasks marked as blocking this task, whether or not they are done (see GET /tasks/{task}/blockers). Computed on list/show reads; create/update responses may lag one read behind.
When the task was marked as done or otherwise closed (ISO 8601). null if the task is still open.
ID of the agent that created this task (agi_...). null if the task was created by a human user, or if the creating agent was later deleted.
ID of the user who created this task (usr_...). null if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.
Viewer-safe live coding-session lease summary. null when the task is unleased or the projected lease has expired. Fencing identifiers are never included.
Long-form description or notes for the task. null if no description has been provided.
Date and time by which the task should be completed (ISO 8601). null if no due date is set.
true while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.
True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.
Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.
Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.
ID of the organization this task belongs to (org_...). null for tasks outside an org context.
ID of the agent assigned as owner (agi_...). null if the owner is a human user, the task is unassigned, or the assigned agent was deleted.
ID of the user assigned as owner (usr_...). null if the owner is an agent, the task is unassigned, or the assigned agent was deleted.
ID of the parent task when this task is a subtask (tsk_...). null for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.
Priority level of the task from 0 (highest) to 4 (lowest). Defaults to 2 (medium) when not explicitly set.
Optional project ID (prj_...). Membership does not change task visibility.
ID of the developer sandbox this task is scoped to (dsb_...). null for tasks outside a sandbox environment.
Source object identity (for example ArchAstro/firstlanding). null when the task has no source.
Container of the work this task is about (for example github.com). null when the task has no source. Set together with source_type and source_id.
Kind of source object (for example repository). null when the task has no source.
Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.
Current status of the task. One of "open", "in_progress", "in_review", "paused", "failed", "superseding", "done", or "cancelled".
Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.
Binary that must run this work (for example my-cli). A worker should take the task only when its own target_binary build is at least target_version. null when the task has no target. Set together with target_version.
Minimum semantic version of target_binary that can run this work (for example 0.48.9), in canonical MAJOR.MINOR.PATCH[-prerelease][+build] form. null when the task has no target.
ID of the team that owns this task (tem_...). null if the task is not scoped to a team.
446class BlockerListResponse(BaseModel): 447 """ 448 Successful response 449 """ 450 451 after_cursor: str | None = None 452 before_cursor: str | None = None 453 data: list[BlockerListResponseDataItem] 454 has_more: bool
Successful response
457class CommentListResponseDataItemAuthorActorProfilePicture(BaseModel): 458 file: str | None = Field( 459 default=None, 460 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 461 ) 462 height: int | None = Field( 463 default=None, description="Height of the image in pixels. `null` if not known." 464 ) 465 media: str | None = Field( 466 default=None, 467 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 468 ) 469 mime_type: str | None = Field( 470 default=None, 471 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 472 ) 473 refresh_url: str | None = Field( 474 default=None, 475 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.", 476 ) 477 url: str | None = Field( 478 default=None, 479 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.", 480 ) 481 width: int | None = Field( 482 default=None, description="Width of the image in pixels. `null` if not known." 483 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
486class CommentListResponseDataItemAuthorActor(BaseModel): 487 alias: str | None = Field( 488 default=None, 489 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 490 ) 491 id: str | None = Field( 492 default=None, 493 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 494 ) 495 name: str | None = Field( 496 default=None, 497 description="Display name of the actor shown in the UI. `null` if no name is set.", 498 ) 499 profile_picture: CommentListResponseDataItemAuthorActorProfilePicture | None = Field( 500 default=None, 501 description="Profile picture for the actor. `null` if the actor has no profile picture.", 502 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
505class CommentListResponseDataItem(BaseModel): 506 author_actor: CommentListResponseDataItemAuthorActor | None = Field( 507 default=None, 508 description="Resolved author details including `id`, `name`, `alias`, and `profile_picture`. `null` if no author is set or the author cannot be resolved (e.g. authoring agent was deleted).", 509 ) 510 author_agent: str | None = Field( 511 default=None, 512 description="ID of the agent that posted this comment (`agi_...`). `null` if the author is a human user, or if the authoring agent was later deleted.", 513 ) 514 author_user: str | None = Field( 515 default=None, 516 description="ID of the user who posted this comment (`usr_...`). `null` if the author is an agent, or if author provenance was cleared after the authoring agent was deleted.", 517 ) 518 body: str = Field(..., description="Plain-text body of the comment.") 519 created_at: datetime | None = Field( 520 default=None, description="When this comment was posted (ISO 8601)." 521 ) 522 id: str = Field(..., description="Comment ID (`tcmt_...`).") 523 org: str | None = Field( 524 default=None, description="ID of the organization that owns this comment (`org_...`)." 525 ) 526 sandbox: str | None = Field( 527 default=None, 528 description="Sandbox ID this comment is scoped to. `null` for comments outside a sandbox environment.", 529 ) 530 task: str | None = Field( 531 default=None, description="ID of the task this comment belongs to (`tsk_...`)." 532 ) 533 team: str | None = Field( 534 default=None, 535 description="ID of the team the task belongs to (`tem_...`). `null` if not scoped to a team.", 536 ) 537 updated_at: datetime | None = Field( 538 default=None, description="When this comment was last edited (ISO 8601)." 539 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
542class CommentListResponse(BaseModel): 543 """ 544 Successful response 545 """ 546 547 after_cursor: str | None = None 548 before_cursor: str | None = None 549 data: list[CommentListResponseDataItem] 550 has_more: bool
Successful response
553class LinkListResponseDataItem(BaseModel): 554 external_scope: str = Field(..., description="External container identity.") 555 object_id: str = Field(..., description="Object identity within that container.") 556 object_type: str = Field(..., description="External object kind.")
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
559class LinkListResponse(BaseModel): 560 """ 561 Successful response 562 """ 563 564 after_cursor: str | None = None 565 before_cursor: str | None = None 566 data: list[LinkListResponseDataItem] 567 has_more: bool
Successful response
570class TaskActivityResponseDataItem(BaseModel): 571 event_type: str | None = Field( 572 default=None, 573 description='Machine-readable type of the event, e.g. `"task.status_changed"` or `"task.comment_added"`.', 574 ) 575 sentence: str | None = Field( 576 default=None, 577 description="Human-readable sentence describing the activity, suitable for display in an activity feed.", 578 ) 579 timestamp: datetime | None = Field( 580 default=None, description="When this activity event occurred (ISO 8601)." 581 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Machine-readable type of the event, e.g. "task.status_changed" or "task.comment_added".
584class TaskActivityResponse(BaseModel): 585 """ 586 Successful response 587 """ 588 589 after_cursor: str | None = None 590 before_cursor: str | None = None 591 data: list[TaskActivityResponseDataItem] 592 has_more: bool
Successful response
595class TaskBlockingResponseDataItemCreatedByActorProfilePicture(BaseModel): 596 file: str | None = Field( 597 default=None, 598 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 599 ) 600 height: int | None = Field( 601 default=None, description="Height of the image in pixels. `null` if not known." 602 ) 603 media: str | None = Field( 604 default=None, 605 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 606 ) 607 mime_type: str | None = Field( 608 default=None, 609 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 610 ) 611 refresh_url: str | None = Field( 612 default=None, 613 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.", 614 ) 615 url: str | None = Field( 616 default=None, 617 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.", 618 ) 619 width: int | None = Field( 620 default=None, description="Width of the image in pixels. `null` if not known." 621 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
624class TaskBlockingResponseDataItemCreatedByActor(BaseModel): 625 alias: str | None = Field( 626 default=None, 627 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 628 ) 629 id: str | None = Field( 630 default=None, 631 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 632 ) 633 name: str | None = Field( 634 default=None, 635 description="Display name of the actor shown in the UI. `null` if no name is set.", 636 ) 637 profile_picture: TaskBlockingResponseDataItemCreatedByActorProfilePicture | None = Field( 638 default=None, 639 description="Profile picture for the actor. `null` if the actor has no profile picture.", 640 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
643class TaskBlockingResponseDataItemCurrentLease(BaseModel): 644 expires_at: datetime = Field( 645 ..., description="Server-calculated lease expiry in ISO 8601 format." 646 ) 647 harness: str = Field(..., description="Bounded harness identifier for the coding session.") 648 session_name: str = Field( 649 ..., description="Display name supplied by the coding session that holds the lease." 650 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
653class TaskBlockingResponseDataItemOwnerActorProfilePicture(BaseModel): 654 file: str | None = Field( 655 default=None, 656 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 657 ) 658 height: int | None = Field( 659 default=None, description="Height of the image in pixels. `null` if not known." 660 ) 661 media: str | None = Field( 662 default=None, 663 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 664 ) 665 mime_type: str | None = Field( 666 default=None, 667 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 668 ) 669 refresh_url: str | None = Field( 670 default=None, 671 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.", 672 ) 673 url: str | None = Field( 674 default=None, 675 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.", 676 ) 677 width: int | None = Field( 678 default=None, description="Width of the image in pixels. `null` if not known." 679 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
682class TaskBlockingResponseDataItemOwnerActor(BaseModel): 683 alias: str | None = Field( 684 default=None, 685 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 686 ) 687 id: str | None = Field( 688 default=None, 689 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 690 ) 691 name: str | None = Field( 692 default=None, 693 description="Display name of the actor shown in the UI. `null` if no name is set.", 694 ) 695 profile_picture: TaskBlockingResponseDataItemOwnerActorProfilePicture | None = Field( 696 default=None, 697 description="Profile picture for the actor. `null` if the actor has no profile picture.", 698 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
701class TaskBlockingResponseDataItem(BaseModel): 702 agent: str | None = Field( 703 default=None, 704 description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", 705 ) 706 aggregate_version: int | None = Field( 707 default=None, 708 description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", 709 ) 710 blocked_by_count: int | None = Field( 711 default=None, 712 description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", 713 ) 714 closed_at: datetime | None = Field( 715 default=None, 716 description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", 717 ) 718 comments_count: int | None = Field( 719 default=None, description="Total number of comments posted on this task." 720 ) 721 created_at: datetime | None = Field( 722 default=None, description="When the task was created (ISO 8601)." 723 ) 724 created_by_actor: TaskBlockingResponseDataItemCreatedByActor | None = Field( 725 default=None, 726 description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", 727 ) 728 created_by_agent: str | None = Field( 729 default=None, 730 description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", 731 ) 732 created_by_user: str | None = Field( 733 default=None, 734 description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", 735 ) 736 current_lease: TaskBlockingResponseDataItemCurrentLease | None = Field( 737 default=None, 738 description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", 739 ) 740 description: str | None = Field( 741 default=None, 742 description="Long-form description or notes for the task. `null` if no description has been provided.", 743 ) 744 due_date: datetime | None = Field( 745 default=None, 746 description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", 747 ) 748 epic: str | None = Field( 749 default=None, 750 description="Free-form grouping label. `null` when the task is not in an epic.", 751 ) 752 id: str = Field(..., description="Task ID (`tsk_...`).") 753 is_blocked: bool | None = Field( 754 default=None, 755 description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", 756 ) 757 is_stalled: bool | None = Field( 758 default=None, 759 description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", 760 ) 761 links: dict[str, Any] | None = Field( 762 default=None, 763 description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", 764 ) 765 metadata: dict[str, Any] | None = Field( 766 default=None, 767 description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", 768 ) 769 name: str = Field(..., description="Human-readable title of the task.") 770 org: str | None = Field( 771 default=None, 772 description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", 773 ) 774 owner_actor: TaskBlockingResponseDataItemOwnerActor | None = Field( 775 default=None, 776 description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", 777 ) 778 owner_agent: str | None = Field( 779 default=None, 780 description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", 781 ) 782 owner_user: str | None = Field( 783 default=None, 784 description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", 785 ) 786 parent: str | None = Field( 787 default=None, 788 description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", 789 ) 790 priority: int | None = Field( 791 default=None, 792 description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", 793 ) 794 project_id: str | None = Field( 795 default=None, 796 description="Optional project ID (`prj_...`). Membership does not change task visibility.", 797 ) 798 sandbox: str | None = Field( 799 default=None, 800 description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", 801 ) 802 source_id: str | None = Field( 803 default=None, 804 description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", 805 ) 806 source_scope: str | None = Field( 807 default=None, 808 description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", 809 ) 810 source_type: str | None = Field( 811 default=None, 812 description="Kind of source object (for example `repository`). `null` when the task has no source.", 813 ) 814 stalled_since: datetime | None = Field( 815 default=None, 816 description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", 817 ) 818 status: str = Field( 819 ..., 820 description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', 821 ) 822 subtasks_count: int | None = Field( 823 default=None, 824 description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", 825 ) 826 tags: list[str] | None = Field( 827 default=None, 828 description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", 829 ) 830 target_binary: str | None = Field( 831 default=None, 832 description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", 833 ) 834 target_version: str | None = Field( 835 default=None, 836 description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", 837 ) 838 team: str | None = Field( 839 default=None, 840 description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", 841 ) 842 thread: str | None = Field( 843 default=None, 844 description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", 845 ) 846 updated_at: datetime | None = Field( 847 default=None, description="When the task was last modified (ISO 8601)." 848 ) 849 user: str | None = Field( 850 default=None, 851 description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", 852 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the agent that owns this task (agi_...). null if the task is scoped to a team or user.
Event-stream version for optimistic update fencing. Pass this value as expected_version on an update to reject concurrent writes.
Number of readable tasks marked as blocking this task, whether or not they are done (see GET /tasks/{task}/blockers). Computed on list/show reads; create/update responses may lag one read behind.
When the task was marked as done or otherwise closed (ISO 8601). null if the task is still open.
ID of the agent that created this task (agi_...). null if the task was created by a human user, or if the creating agent was later deleted.
ID of the user who created this task (usr_...). null if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.
Viewer-safe live coding-session lease summary. null when the task is unleased or the projected lease has expired. Fencing identifiers are never included.
Long-form description or notes for the task. null if no description has been provided.
Date and time by which the task should be completed (ISO 8601). null if no due date is set.
true while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.
True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.
Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.
Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.
ID of the organization this task belongs to (org_...). null for tasks outside an org context.
ID of the agent assigned as owner (agi_...). null if the owner is a human user, the task is unassigned, or the assigned agent was deleted.
ID of the user assigned as owner (usr_...). null if the owner is an agent, the task is unassigned, or the assigned agent was deleted.
ID of the parent task when this task is a subtask (tsk_...). null for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.
Priority level of the task from 0 (highest) to 4 (lowest). Defaults to 2 (medium) when not explicitly set.
Optional project ID (prj_...). Membership does not change task visibility.
ID of the developer sandbox this task is scoped to (dsb_...). null for tasks outside a sandbox environment.
Source object identity (for example ArchAstro/firstlanding). null when the task has no source.
Container of the work this task is about (for example github.com). null when the task has no source. Set together with source_type and source_id.
Kind of source object (for example repository). null when the task has no source.
Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.
Current status of the task. One of "open", "in_progress", "in_review", "paused", "failed", "superseding", "done", or "cancelled".
Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.
Binary that must run this work (for example my-cli). A worker should take the task only when its own target_binary build is at least target_version. null when the task has no target. Set together with target_version.
Minimum semantic version of target_binary that can run this work (for example 0.48.9), in canonical MAJOR.MINOR.PATCH[-prerelease][+build] form. null when the task has no target.
ID of the team that owns this task (tem_...). null if the task is not scoped to a team.
855class TaskBlockingResponse(BaseModel): 856 """ 857 Successful response 858 """ 859 860 after_cursor: str | None = None 861 before_cursor: str | None = None 862 data: list[TaskBlockingResponseDataItem] 863 has_more: bool
Successful response
866class TaskSubtasksResponseDataItemCreatedByActorProfilePicture(BaseModel): 867 file: str | None = Field( 868 default=None, 869 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 870 ) 871 height: int | None = Field( 872 default=None, description="Height of the image in pixels. `null` if not known." 873 ) 874 media: str | None = Field( 875 default=None, 876 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 877 ) 878 mime_type: str | None = Field( 879 default=None, 880 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 881 ) 882 refresh_url: str | None = Field( 883 default=None, 884 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.", 885 ) 886 url: str | None = Field( 887 default=None, 888 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.", 889 ) 890 width: int | None = Field( 891 default=None, description="Width of the image in pixels. `null` if not known." 892 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
895class TaskSubtasksResponseDataItemCreatedByActor(BaseModel): 896 alias: str | None = Field( 897 default=None, 898 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 899 ) 900 id: str | None = Field( 901 default=None, 902 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 903 ) 904 name: str | None = Field( 905 default=None, 906 description="Display name of the actor shown in the UI. `null` if no name is set.", 907 ) 908 profile_picture: TaskSubtasksResponseDataItemCreatedByActorProfilePicture | None = Field( 909 default=None, 910 description="Profile picture for the actor. `null` if the actor has no profile picture.", 911 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
914class TaskSubtasksResponseDataItemCurrentLease(BaseModel): 915 expires_at: datetime = Field( 916 ..., description="Server-calculated lease expiry in ISO 8601 format." 917 ) 918 harness: str = Field(..., description="Bounded harness identifier for the coding session.") 919 session_name: str = Field( 920 ..., description="Display name supplied by the coding session that holds the lease." 921 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
924class TaskSubtasksResponseDataItemOwnerActorProfilePicture(BaseModel): 925 file: str | None = Field( 926 default=None, 927 description="ID of the underlying storage file (`fil_...`). `null` when the image is not backed by a platform storage file.", 928 ) 929 height: int | None = Field( 930 default=None, description="Height of the image in pixels. `null` if not known." 931 ) 932 media: str | None = Field( 933 default=None, 934 description="ID of the associated media record (`med_...`). `null` when the image is not linked to a media entity.", 935 ) 936 mime_type: str | None = Field( 937 default=None, 938 description='MIME type of the image, e.g. `"image/png"` or `"image/jpeg"`. `null` if not known.', 939 ) 940 refresh_url: str | None = Field( 941 default=None, 942 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.", 943 ) 944 url: str | None = Field( 945 default=None, 946 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.", 947 ) 948 width: int | None = Field( 949 default=None, description="Width of the image in pixels. `null` if not known." 950 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the underlying storage file (fil_...). null when the image is not backed by a platform storage file.
ID of the associated media record (med_...). null when the image is not linked to a media entity.
MIME type of the image, e.g. "image/png" or "image/jpeg". null if not known.
Endpoint URL you can call to obtain a fresh signed url when the current one has expired. null if the URL does not require refreshing.
Signed or public URL for downloading the image. May be time-limited; use refresh_url to obtain a new URL when this one expires.
953class TaskSubtasksResponseDataItemOwnerActor(BaseModel): 954 alias: str | None = Field( 955 default=None, 956 description="Short handle or alias for the actor, used as an alternate display identifier. `null` if not configured.", 957 ) 958 id: str | None = Field( 959 default=None, 960 description='Composite actor identifier. Format is `"user-<usr_...>"` for human users or `"agent-<agi_...>"` for agents.', 961 ) 962 name: str | None = Field( 963 default=None, 964 description="Display name of the actor shown in the UI. `null` if no name is set.", 965 ) 966 profile_picture: TaskSubtasksResponseDataItemOwnerActorProfilePicture | None = Field( 967 default=None, 968 description="Profile picture for the actor. `null` if the actor has no profile picture.", 969 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
Short handle or alias for the actor, used as an alternate display identifier. null if not configured.
Composite actor identifier. Format is "user-<usr_...>" for human users or "agent-<agi_...>" for agents.
972class TaskSubtasksResponseDataItem(BaseModel): 973 agent: str | None = Field( 974 default=None, 975 description="ID of the agent that owns this task (`agi_...`). `null` if the task is scoped to a team or user.", 976 ) 977 aggregate_version: int | None = Field( 978 default=None, 979 description="Event-stream version for optimistic update fencing. Pass this value as `expected_version` on an update to reject concurrent writes.", 980 ) 981 blocked_by_count: int | None = Field( 982 default=None, 983 description="Number of readable tasks marked as blocking this task, whether or not they are done (see `GET /tasks/{task}/blockers`). Computed on list/show reads; create/update responses may lag one read behind.", 984 ) 985 closed_at: datetime | None = Field( 986 default=None, 987 description="When the task was marked as done or otherwise closed (ISO 8601). `null` if the task is still open.", 988 ) 989 comments_count: int | None = Field( 990 default=None, description="Total number of comments posted on this task." 991 ) 992 created_at: datetime | None = Field( 993 default=None, description="When the task was created (ISO 8601)." 994 ) 995 created_by_actor: TaskSubtasksResponseDataItemCreatedByActor | None = Field( 996 default=None, 997 description="Resolved creator details including `id`, `name`, `alias`, and `profile_picture`. `null` if no creator is set or the creator cannot be resolved (e.g. creating agent was deleted).", 998 ) 999 created_by_agent: str | None = Field( 1000 default=None, 1001 description="ID of the agent that created this task (`agi_...`). `null` if the task was created by a human user, or if the creating agent was later deleted.", 1002 ) 1003 created_by_user: str | None = Field( 1004 default=None, 1005 description="ID of the user who created this task (`usr_...`). `null` if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.", 1006 ) 1007 current_lease: TaskSubtasksResponseDataItemCurrentLease | None = Field( 1008 default=None, 1009 description="Viewer-safe live coding-session lease summary. `null` when the task is unleased or the projected lease has expired. Fencing identifiers are never included.", 1010 ) 1011 description: str | None = Field( 1012 default=None, 1013 description="Long-form description or notes for the task. `null` if no description has been provided.", 1014 ) 1015 due_date: datetime | None = Field( 1016 default=None, 1017 description="Date and time by which the task should be completed (ISO 8601). `null` if no due date is set.", 1018 ) 1019 epic: str | None = Field( 1020 default=None, 1021 description="Free-form grouping label. `null` when the task is not in an epic.", 1022 ) 1023 id: str = Field(..., description="Task ID (`tsk_...`).") 1024 is_blocked: bool | None = Field( 1025 default=None, 1026 description="`true` while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.", 1027 ) 1028 is_stalled: bool | None = Field( 1029 default=None, 1030 description="True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.", 1031 ) 1032 links: dict[str, Any] | None = Field( 1033 default=None, 1034 description="Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.", 1035 ) 1036 metadata: dict[str, Any] | None = Field( 1037 default=None, 1038 description="Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.", 1039 ) 1040 name: str = Field(..., description="Human-readable title of the task.") 1041 org: str | None = Field( 1042 default=None, 1043 description="ID of the organization this task belongs to (`org_...`). `null` for tasks outside an org context.", 1044 ) 1045 owner_actor: TaskSubtasksResponseDataItemOwnerActor | None = Field( 1046 default=None, 1047 description="Resolved owner details including `id`, `name`, `alias`, and `profile_picture`. `null` if the task is unassigned or the owner cannot be resolved (e.g. assigned agent was deleted).", 1048 ) 1049 owner_agent: str | None = Field( 1050 default=None, 1051 description="ID of the agent assigned as owner (`agi_...`). `null` if the owner is a human user, the task is unassigned, or the assigned agent was deleted.", 1052 ) 1053 owner_user: str | None = Field( 1054 default=None, 1055 description="ID of the user assigned as owner (`usr_...`). `null` if the owner is an agent, the task is unassigned, or the assigned agent was deleted.", 1056 ) 1057 parent: str | None = Field( 1058 default=None, 1059 description="ID of the parent task when this task is a subtask (`tsk_...`). `null` for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.", 1060 ) 1061 priority: int | None = Field( 1062 default=None, 1063 description="Priority level of the task from `0` (highest) to `4` (lowest). Defaults to `2` (medium) when not explicitly set.", 1064 ) 1065 project_id: str | None = Field( 1066 default=None, 1067 description="Optional project ID (`prj_...`). Membership does not change task visibility.", 1068 ) 1069 sandbox: str | None = Field( 1070 default=None, 1071 description="ID of the developer sandbox this task is scoped to (`dsb_...`). `null` for tasks outside a sandbox environment.", 1072 ) 1073 source_id: str | None = Field( 1074 default=None, 1075 description="Source object identity (for example `ArchAstro/firstlanding`). `null` when the task has no source.", 1076 ) 1077 source_scope: str | None = Field( 1078 default=None, 1079 description="Container of the work this task is about (for example `github.com`). `null` when the task has no source. Set together with `source_type` and `source_id`.", 1080 ) 1081 source_type: str | None = Field( 1082 default=None, 1083 description="Kind of source object (for example `repository`). `null` when the task has no source.", 1084 ) 1085 stalled_since: datetime | None = Field( 1086 default=None, 1087 description="Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.", 1088 ) 1089 status: str = Field( 1090 ..., 1091 description='Current status of the task. One of `"open"`, `"in_progress"`, `"in_review"`, `"paused"`, `"failed"`, `"superseding"`, `"done"`, or `"cancelled"`.', 1092 ) 1093 subtasks_count: int | None = Field( 1094 default=None, 1095 description="Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.", 1096 ) 1097 tags: list[str] | None = Field( 1098 default=None, 1099 description="Labels for grouping and filtering, stored lowercase and de-duplicated. Empty array when untagged.", 1100 ) 1101 target_binary: str | None = Field( 1102 default=None, 1103 description="Binary that must run this work (for example `my-cli`). A worker should take the task only when its own `target_binary` build is at least `target_version`. `null` when the task has no target. Set together with `target_version`.", 1104 ) 1105 target_version: str | None = Field( 1106 default=None, 1107 description="Minimum semantic version of `target_binary` that can run this work (for example `0.48.9`), in canonical `MAJOR.MINOR.PATCH[-prerelease][+build]` form. `null` when the task has no target.", 1108 ) 1109 team: str | None = Field( 1110 default=None, 1111 description="ID of the team that owns this task (`tem_...`). `null` if the task is not scoped to a team.", 1112 ) 1113 thread: str | None = Field( 1114 default=None, 1115 description="ID of the thread this task is bound to (`thr_...`) - the conversation it was filed from, or the thread passed at creation. `null` for tasks not tied to a thread.", 1116 ) 1117 updated_at: datetime | None = Field( 1118 default=None, description="When the task was last modified (ISO 8601)." 1119 ) 1120 user: str | None = Field( 1121 default=None, 1122 description="ID of the user that owns this task (`usr_...`). `null` if the task is scoped to a team.", 1123 )
!!! abstract "Usage Documentation" Models
A base class for creating Pydantic models.
Attributes:
- __class_vars__: The names of the class variables defined on the model.
- __private_attributes__: Metadata about the private attributes of the model.
- __signature__: The synthesized
__init__[Signature][inspect.Signature] of the model. - __pydantic_complete__: Whether model building is completed, or if there are still undefined fields.
- __pydantic_core_schema__: The core schema of the model.
- __pydantic_custom_init__: Whether the model has a custom
__init__function. - __pydantic_decorators__: Metadata containing the decorators defined on the model.
This replaces
Model.__validators__andModel.__root_validators__from Pydantic V1. - __pydantic_generic_metadata__: A dictionary containing metadata about generic Pydantic models.
The
originandargsitems map to the [__origin__][genericalias.__origin__] and [__args__][genericalias.__args__] attributes of [generic aliases][types-genericalias], and theparameteritem maps to the__parameter__attribute of generic classes. - __pydantic_parent_namespace__: Parent namespace of the model, used for automatic rebuilding of models.
- __pydantic_post_init__: The name of the post-init method for the model, if defined.
- __pydantic_root_model__: Whether the model is a [
RootModel][pydantic.root_model.RootModel]. - __pydantic_serializer__: The
pydantic-coreSchemaSerializerused to dump instances of the model. - __pydantic_validator__: The
pydantic-coreSchemaValidatorused to validate instances of the model. - __pydantic_fields__: A dictionary of field names and their corresponding [
FieldInfo][pydantic.fields.FieldInfo] objects. - __pydantic_computed_fields__: A dictionary of computed field names and their corresponding [
ComputedFieldInfo][pydantic.fields.ComputedFieldInfo] objects. - __pydantic_extra__: A dictionary containing extra values, if [
extra][pydantic.config.ConfigDict.extra] is set to'allow'. - __pydantic_fields_set__: The names of fields explicitly set during instantiation.
- __pydantic_private__: Values of private attributes set on the model instance.
ID of the agent that owns this task (agi_...). null if the task is scoped to a team or user.
Event-stream version for optimistic update fencing. Pass this value as expected_version on an update to reject concurrent writes.
Number of readable tasks marked as blocking this task, whether or not they are done (see GET /tasks/{task}/blockers). Computed on list/show reads; create/update responses may lag one read behind.
When the task was marked as done or otherwise closed (ISO 8601). null if the task is still open.
ID of the agent that created this task (agi_...). null if the task was created by a human user, or if the creating agent was later deleted.
ID of the user who created this task (usr_...). null if the task was created by an agent, or if creator provenance was cleared after the creator was deleted.
Viewer-safe live coding-session lease summary. null when the task is unleased or the projected lease has expired. Fencing identifiers are never included.
Long-form description or notes for the task. null if no description has been provided.
Date and time by which the task should be completed (ISO 8601). null if no due date is set.
true while at least one blocking task is not yet done. Informational only - a blocked task can still change status - and derived at read time, so the task un-blocks automatically when its last open blocker completes. Computed on reads, including mutation responses.
True exactly when status is in_progress and the task has no lease or its lease expiry is in the past. Derived at read time from status and lease expiry, including on unannotated reads.
Key-value map of named URLs or references associated with the task. Returns an empty object when no links have been set.
Arbitrary key-value map of application-specific data stored alongside the task. Returns an empty object when no metadata has been set.
ID of the organization this task belongs to (org_...). null for tasks outside an org context.
ID of the agent assigned as owner (agi_...). null if the owner is a human user, the task is unassigned, or the assigned agent was deleted.
ID of the user assigned as owner (usr_...). null if the owner is an agent, the task is unassigned, or the assigned agent was deleted.
ID of the parent task when this task is a subtask (tsk_...). null for top-level tasks or when the parent is not readable. Subtasks nest exactly one level.
Priority level of the task from 0 (highest) to 4 (lowest). Defaults to 2 (medium) when not explicitly set.
Optional project ID (prj_...). Membership does not change task visibility.
ID of the developer sandbox this task is scoped to (dsb_...). null for tasks outside a sandbox environment.
Source object identity (for example ArchAstro/firstlanding). null when the task has no source.
Container of the work this task is about (for example github.com). null when the task has no source. Set together with source_type and source_id.
Kind of source object (for example repository). null when the task has no source.
Lease expiry for a stalled task, or its last update when no lease expiry exists. Null when not stalled.
Current status of the task. One of "open", "in_progress", "in_review", "paused", "failed", "superseding", "done", or "cancelled".
Number of readable subtasks under this task. Computed on list/show reads; create/update responses may report 0 until the next read. Always 0 for subtasks.
Binary that must run this work (for example my-cli). A worker should take the task only when its own target_binary build is at least target_version. null when the task has no target. Set together with target_version.
Minimum semantic version of target_binary that can run this work (for example 0.48.9), in canonical MAJOR.MINOR.PATCH[-prerelease][+build] form. null when the task has no target.
ID of the team that owns this task (tem_...). null if the task is not scoped to a team.
1126class TaskSubtasksResponse(BaseModel): 1127 """ 1128 Successful response 1129 """ 1130 1131 after_cursor: str | None = None 1132 before_cursor: str | None = None 1133 data: list[TaskSubtasksResponseDataItem] 1134 has_more: bool
Successful response
1137class AsyncBlockerResource: 1138 def __init__(self, http: HttpClient): 1139 self._http = http 1140 1141 async def list( 1142 self, 1143 task: str, 1144 *, 1145 team: str | None = None, 1146 user: str | None = None, 1147 agent: str | None = None, 1148 org: str | None = None, 1149 limit: int | None = None, 1150 after_cursor: str | None = None, 1151 ) -> BlockerListResponse: 1152 """ 1153 List a task's blockers 1154 Returns a bounded page of the tasks currently marked as blocking the 1155 specified task, newest first. Blocking is informational: a blocked task 1156 can still change status, and it stops counting as blocked as soon as 1157 every blocker is done. The task's owner is resolved from the task itself. 1158 1159 Args: 1160 task: Blocked task ID (`tsk_...`). 1161 team: Explicit owning team (`tem_...`) for privileged calls. 1162 user: Explicit owning user (`usr_...`) for privileged calls. 1163 agent: Explicit owning agent (`agi_...`) for privileged calls. 1164 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1165 limit: Maximum blockers to return. Capped at 100. 1166 after_cursor: Opaque cursor returned by the previous page. 1167 1168 Returns: 1169 Successful response 1170 """ 1171 query: dict[str, object] = {} 1172 if team is not None: 1173 query["team"] = team 1174 if user is not None: 1175 query["user"] = user 1176 if agent is not None: 1177 query["agent"] = agent 1178 if org is not None: 1179 query["org"] = org 1180 if limit is not None: 1181 query["limit"] = limit 1182 if after_cursor is not None: 1183 query["after_cursor"] = after_cursor 1184 return await self._http.request( 1185 f"/api/v1/tasks/{task}/blockers", 1186 query=query, 1187 response_type=BlockerListResponse, 1188 ) 1189 1190 async def create(self, task: str, input: BlockerCreateInput) -> Task: 1191 """ 1192 Mark a task as blocked by another task 1193 Records that the task in `blocker` blocks the specified task and returns 1194 the updated task. Blocking is informational the blocked task can still 1195 change status and derived at read time, so the task stops reporting 1196 `is_blocked` as soon as every blocker is done. The blocker must belong to 1197 the same owner (team or user) as the task; self-blocking and blocking a 1198 task that already blocks the blocker (a direct cycle) are rejected. 1199 1200 Args: 1201 task: Blocked task ID (`tsk_...`). 1202 input: Request body. 1203 input.agent: Explicit owning agent (`agi_...`) for privileged calls. 1204 input.blocker: ID of the task that blocks this task (`tsk_...`). 1205 input.org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1206 input.team: Explicit owning team (`tem_...`) for privileged calls. 1207 input.user: Explicit owning user (`usr_...`) for privileged calls. 1208 1209 Returns: 1210 The updated (blocked) task. 1211 """ 1212 return await self._http.request( 1213 f"/api/v1/tasks/{task}/blockers", 1214 method="POST", 1215 body=input, 1216 response_type=Task, 1217 ) 1218 1219 async def delete(self, task: str, blocker: str) -> None: 1220 """ 1221 Remove a blocker from a task 1222 Removes the blocking relationship between the task in `blocker` and the 1223 specified task. Returns 204 No Content on success, or 404 if the given 1224 task is not currently marked as blocking this task. 1225 1226 Args: 1227 task: Blocked task ID (`tsk_...`). 1228 blocker: ID of the blocking task to remove (`tsk_...`). 1229 1230 Returns: 1231 Empty response body. HTTP 204 No Content on success. 1232 """ 1233 await self._http.request(f"/api/v1/tasks/{task}/blockers/{blocker}", method="DELETE")
1141 async def list( 1142 self, 1143 task: str, 1144 *, 1145 team: str | None = None, 1146 user: str | None = None, 1147 agent: str | None = None, 1148 org: str | None = None, 1149 limit: int | None = None, 1150 after_cursor: str | None = None, 1151 ) -> BlockerListResponse: 1152 """ 1153 List a task's blockers 1154 Returns a bounded page of the tasks currently marked as blocking the 1155 specified task, newest first. Blocking is informational: a blocked task 1156 can still change status, and it stops counting as blocked as soon as 1157 every blocker is done. The task's owner is resolved from the task itself. 1158 1159 Args: 1160 task: Blocked task ID (`tsk_...`). 1161 team: Explicit owning team (`tem_...`) for privileged calls. 1162 user: Explicit owning user (`usr_...`) for privileged calls. 1163 agent: Explicit owning agent (`agi_...`) for privileged calls. 1164 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1165 limit: Maximum blockers to return. Capped at 100. 1166 after_cursor: Opaque cursor returned by the previous page. 1167 1168 Returns: 1169 Successful response 1170 """ 1171 query: dict[str, object] = {} 1172 if team is not None: 1173 query["team"] = team 1174 if user is not None: 1175 query["user"] = user 1176 if agent is not None: 1177 query["agent"] = agent 1178 if org is not None: 1179 query["org"] = org 1180 if limit is not None: 1181 query["limit"] = limit 1182 if after_cursor is not None: 1183 query["after_cursor"] = after_cursor 1184 return await self._http.request( 1185 f"/api/v1/tasks/{task}/blockers", 1186 query=query, 1187 response_type=BlockerListResponse, 1188 )
List a task's blockers Returns a bounded page of the tasks currently marked as blocking the specified task, newest first. Blocking is informational: a blocked task can still change status, and it stops counting as blocked as soon as every blocker is done. The task's owner is resolved from the task itself.
Arguments:
- task: Blocked task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum blockers to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1190 async def create(self, task: str, input: BlockerCreateInput) -> Task: 1191 """ 1192 Mark a task as blocked by another task 1193 Records that the task in `blocker` blocks the specified task and returns 1194 the updated task. Blocking is informational the blocked task can still 1195 change status and derived at read time, so the task stops reporting 1196 `is_blocked` as soon as every blocker is done. The blocker must belong to 1197 the same owner (team or user) as the task; self-blocking and blocking a 1198 task that already blocks the blocker (a direct cycle) are rejected. 1199 1200 Args: 1201 task: Blocked task ID (`tsk_...`). 1202 input: Request body. 1203 input.agent: Explicit owning agent (`agi_...`) for privileged calls. 1204 input.blocker: ID of the task that blocks this task (`tsk_...`). 1205 input.org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1206 input.team: Explicit owning team (`tem_...`) for privileged calls. 1207 input.user: Explicit owning user (`usr_...`) for privileged calls. 1208 1209 Returns: 1210 The updated (blocked) task. 1211 """ 1212 return await self._http.request( 1213 f"/api/v1/tasks/{task}/blockers", 1214 method="POST", 1215 body=input, 1216 response_type=Task, 1217 )
Mark a task as blocked by another task
Records that the task in blocker blocks the specified task and returns
the updated task. Blocking is informational the blocked task can still
change status and derived at read time, so the task stops reporting
is_blocked as soon as every blocker is done. The blocker must belong to
the same owner (team or user) as the task; self-blocking and blocking a
task that already blocks the blocker (a direct cycle) are rejected.
Arguments:
- task: Blocked task ID (
tsk_...). - input: Request body.
- input.agent: Explicit owning agent (
agi_...) for privileged calls. - input.blocker: ID of the task that blocks this task (
tsk_...). - input.org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - input.team: Explicit owning team (
tem_...) for privileged calls. - input.user: Explicit owning user (
usr_...) for privileged calls.
Returns:
The updated (blocked) task.
1219 async def delete(self, task: str, blocker: str) -> None: 1220 """ 1221 Remove a blocker from a task 1222 Removes the blocking relationship between the task in `blocker` and the 1223 specified task. Returns 204 No Content on success, or 404 if the given 1224 task is not currently marked as blocking this task. 1225 1226 Args: 1227 task: Blocked task ID (`tsk_...`). 1228 blocker: ID of the blocking task to remove (`tsk_...`). 1229 1230 Returns: 1231 Empty response body. HTTP 204 No Content on success. 1232 """ 1233 await self._http.request(f"/api/v1/tasks/{task}/blockers/{blocker}", method="DELETE")
Remove a blocker from a task
Removes the blocking relationship between the task in blocker and the
specified task. Returns 204 No Content on success, or 404 if the given
task is not currently marked as blocking this task.
Arguments:
- task: Blocked task ID (
tsk_...). - blocker: ID of the blocking task to remove (
tsk_...).
Returns:
Empty response body. HTTP 204 No Content on success.
1236class AsyncCommentResource: 1237 def __init__(self, http: HttpClient): 1238 self._http = http 1239 1240 async def list( 1241 self, 1242 task: str, 1243 *, 1244 team: str | None = None, 1245 user: str | None = None, 1246 agent: str | None = None, 1247 org: str | None = None, 1248 limit: int | None = None, 1249 after_cursor: str | None = None, 1250 ) -> CommentListResponse: 1251 """ 1252 List comments on a task 1253 Returns a bounded page of comments on the specified task, ordered by creation 1254 time ascending. App-scoped developer and server-to-server callers explicitly 1255 provide the owning `team`, `user`, or `agent` and `org`. 1256 1257 Args: 1258 task: Task ID (`tsk_...`). 1259 team: Explicit owning team (`tem_...`) for privileged calls. 1260 user: Explicit owning user (`usr_...`) for privileged calls. 1261 agent: Explicit owning agent (`agi_...`) for privileged calls. 1262 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1263 limit: Maximum comments to return. Capped at 100. 1264 after_cursor: Opaque cursor returned by the previous page. 1265 1266 Returns: 1267 Successful response 1268 """ 1269 query: dict[str, object] = {} 1270 if team is not None: 1271 query["team"] = team 1272 if user is not None: 1273 query["user"] = user 1274 if agent is not None: 1275 query["agent"] = agent 1276 if org is not None: 1277 query["org"] = org 1278 if limit is not None: 1279 query["limit"] = limit 1280 if after_cursor is not None: 1281 query["after_cursor"] = after_cursor 1282 return await self._http.request( 1283 f"/api/v1/tasks/{task}/comments", 1284 query=query, 1285 response_type=CommentListResponse, 1286 ) 1287 1288 async def create(self, task: str, input: CommentCreateInput) -> TaskComment: 1289 """ 1290 Create a comment on a task 1291 Posts a new comment on the specified task and returns the created comment. 1292 The task's owner is resolved from the task itself. 1293 1294 Args: 1295 task: Task ID (`tsk_...`). 1296 input: Request body. 1297 input.comment: Parameters for the comment to create, including its body. 1298 input.expected_version: Reject the comment if the task changed since this version. 1299 1300 Returns: 1301 The newly created comment. 1302 """ 1303 return await self._http.request( 1304 f"/api/v1/tasks/{task}/comments", 1305 method="POST", 1306 body=input, 1307 response_type=TaskComment, 1308 ) 1309 1310 async def delete(self, task: str, comment: str) -> None: 1311 """ 1312 Delete a task comment 1313 Permanently removes a comment from its task. This action cannot be undone. 1314 The task's owner is resolved from the task itself. 1315 Only the comment's author, an admin of the comment's organization, or an 1316 admin of the owning team may delete a comment. Returns `403 Forbidden` 1317 otherwise. 1318 1319 Args: 1320 task: Task ID (`tsk_...`). 1321 comment: Comment ID (`tcm_...`). 1322 1323 Returns: 1324 Empty body. The server responds with HTTP 204 No Content on success. 1325 """ 1326 await self._http.request(f"/api/v1/tasks/{task}/comments/{comment}", method="DELETE") 1327 1328 async def replace(self, task: str, comment: str, input: CommentReplaceInput) -> TaskComment: 1329 """ 1330 Update a task comment 1331 Replaces the body of an existing comment and returns the updated comment. 1332 The task's owner is resolved from the task itself. 1333 Only the comment's author, an admin of the comment's organization, or an 1334 admin of the owning team may edit a comment. Returns `403 Forbidden` 1335 otherwise. 1336 1337 Args: 1338 task: Task ID (`tsk_...`). 1339 comment: Comment ID (`tcm_...`). 1340 input: Request body. 1341 input.body: Replacement body for the comment. Must be non-empty. 1342 1343 Returns: 1344 The updated comment. 1345 """ 1346 return await self._http.request( 1347 f"/api/v1/tasks/{task}/comments/{comment}", 1348 method="PUT", 1349 body=input, 1350 response_type=TaskComment, 1351 )
1240 async def list( 1241 self, 1242 task: str, 1243 *, 1244 team: str | None = None, 1245 user: str | None = None, 1246 agent: str | None = None, 1247 org: str | None = None, 1248 limit: int | None = None, 1249 after_cursor: str | None = None, 1250 ) -> CommentListResponse: 1251 """ 1252 List comments on a task 1253 Returns a bounded page of comments on the specified task, ordered by creation 1254 time ascending. App-scoped developer and server-to-server callers explicitly 1255 provide the owning `team`, `user`, or `agent` and `org`. 1256 1257 Args: 1258 task: Task ID (`tsk_...`). 1259 team: Explicit owning team (`tem_...`) for privileged calls. 1260 user: Explicit owning user (`usr_...`) for privileged calls. 1261 agent: Explicit owning agent (`agi_...`) for privileged calls. 1262 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1263 limit: Maximum comments to return. Capped at 100. 1264 after_cursor: Opaque cursor returned by the previous page. 1265 1266 Returns: 1267 Successful response 1268 """ 1269 query: dict[str, object] = {} 1270 if team is not None: 1271 query["team"] = team 1272 if user is not None: 1273 query["user"] = user 1274 if agent is not None: 1275 query["agent"] = agent 1276 if org is not None: 1277 query["org"] = org 1278 if limit is not None: 1279 query["limit"] = limit 1280 if after_cursor is not None: 1281 query["after_cursor"] = after_cursor 1282 return await self._http.request( 1283 f"/api/v1/tasks/{task}/comments", 1284 query=query, 1285 response_type=CommentListResponse, 1286 )
List comments on a task
Returns a bounded page of comments on the specified task, ordered by creation
time ascending. App-scoped developer and server-to-server callers explicitly
provide the owning team, user, or agent and org.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum comments to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1288 async def create(self, task: str, input: CommentCreateInput) -> TaskComment: 1289 """ 1290 Create a comment on a task 1291 Posts a new comment on the specified task and returns the created comment. 1292 The task's owner is resolved from the task itself. 1293 1294 Args: 1295 task: Task ID (`tsk_...`). 1296 input: Request body. 1297 input.comment: Parameters for the comment to create, including its body. 1298 input.expected_version: Reject the comment if the task changed since this version. 1299 1300 Returns: 1301 The newly created comment. 1302 """ 1303 return await self._http.request( 1304 f"/api/v1/tasks/{task}/comments", 1305 method="POST", 1306 body=input, 1307 response_type=TaskComment, 1308 )
Create a comment on a task Posts a new comment on the specified task and returns the created comment. The task's owner is resolved from the task itself.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.comment: Parameters for the comment to create, including its body.
- input.expected_version: Reject the comment if the task changed since this version.
Returns:
The newly created comment.
1310 async def delete(self, task: str, comment: str) -> None: 1311 """ 1312 Delete a task comment 1313 Permanently removes a comment from its task. This action cannot be undone. 1314 The task's owner is resolved from the task itself. 1315 Only the comment's author, an admin of the comment's organization, or an 1316 admin of the owning team may delete a comment. Returns `403 Forbidden` 1317 otherwise. 1318 1319 Args: 1320 task: Task ID (`tsk_...`). 1321 comment: Comment ID (`tcm_...`). 1322 1323 Returns: 1324 Empty body. The server responds with HTTP 204 No Content on success. 1325 """ 1326 await self._http.request(f"/api/v1/tasks/{task}/comments/{comment}", method="DELETE")
Delete a task comment
Permanently removes a comment from its task. This action cannot be undone.
The task's owner is resolved from the task itself.
Only the comment's author, an admin of the comment's organization, or an
admin of the owning team may delete a comment. Returns 403 Forbidden
otherwise.
Arguments:
- task: Task ID (
tsk_...). - comment: Comment ID (
tcm_...).
Returns:
Empty body. The server responds with HTTP 204 No Content on success.
1328 async def replace(self, task: str, comment: str, input: CommentReplaceInput) -> TaskComment: 1329 """ 1330 Update a task comment 1331 Replaces the body of an existing comment and returns the updated comment. 1332 The task's owner is resolved from the task itself. 1333 Only the comment's author, an admin of the comment's organization, or an 1334 admin of the owning team may edit a comment. Returns `403 Forbidden` 1335 otherwise. 1336 1337 Args: 1338 task: Task ID (`tsk_...`). 1339 comment: Comment ID (`tcm_...`). 1340 input: Request body. 1341 input.body: Replacement body for the comment. Must be non-empty. 1342 1343 Returns: 1344 The updated comment. 1345 """ 1346 return await self._http.request( 1347 f"/api/v1/tasks/{task}/comments/{comment}", 1348 method="PUT", 1349 body=input, 1350 response_type=TaskComment, 1351 )
Update a task comment
Replaces the body of an existing comment and returns the updated comment.
The task's owner is resolved from the task itself.
Only the comment's author, an admin of the comment's organization, or an
admin of the owning team may edit a comment. Returns 403 Forbidden
otherwise.
Arguments:
- task: Task ID (
tsk_...). - comment: Comment ID (
tcm_...). - input: Request body.
- input.body: Replacement body for the comment. Must be non-empty.
Returns:
The updated comment.
1354class AsyncLeaseResource: 1355 def __init__(self, http: HttpClient): 1356 self._http = http 1357 1358 async def remove(self, task: str) -> None: 1359 """ 1360 Release a task session lease 1361 Releases the authenticated assignee's matching live task lease. Repeating a 1362 release after the lease is absent succeeds. A different live successor lease 1363 returns a mismatch. 1364 1365 Args: 1366 task: Task ID (`tsk_...`). 1367 1368 Returns: 1369 Empty response. HTTP 204 is returned after release is accepted. 1370 """ 1371 await self._http.request(f"/api/v1/tasks/{task}/lease", method="DELETE") 1372 1373 async def list(self, task: str) -> TaskSessionLeaseSummary | None: 1374 """ 1375 Retrieve a task's current session lease 1376 Returns the authenticated assignee's viewer-safe live lease summary, or null 1377 when no live lease exists. Fencing and opaque session identifiers are never 1378 included. 1379 1380 Args: 1381 task: Task ID (`tsk_...`). 1382 1383 Returns: 1384 Viewer-safe live lease summary, or null. 1385 """ 1386 return await self._http.request( 1387 f"/api/v1/tasks/{task}/lease", 1388 response_type=TaskSessionLeaseSummary | None, 1389 ) 1390 1391 async def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: 1392 """ 1393 Claim a task for a coding session 1394 Atomically claims a user-assigned task for the authenticated user's coding 1395 session. The caller generates and retains both UUIDs. An exact retry returns 1396 the existing lease without extending it; another live holder produces a 1397 conflict. Developer and server-to-server credentials cannot impersonate the 1398 assigned user. 1399 1400 Args: 1401 task: Task ID (`tsk_...`). 1402 input: Request body. 1403 input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. 1404 input.harness: Bounded harness identifier. 1405 input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. 1406 input.lease_id: Caller-generated lease UUID. 1407 input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers. 1408 input.session_id: Caller-generated coding-session UUID. 1409 input.session_name: Human-readable coding-session label. 1410 1411 Returns: 1412 The caller-held lease, including its fencing token. 1413 """ 1414 return await self._http.request( 1415 f"/api/v1/tasks/{task}/lease", 1416 method="POST", 1417 body=input, 1418 response_type=TaskSessionLease, 1419 ) 1420 1421 async def renew(self, task: str, input: LeaseRenewInput) -> TaskSessionLease: 1422 """ 1423 Renew a task session lease 1424 Renews the authenticated assignee's matching live task lease. Both 1425 caller-generated UUIDs must match the aggregate's current lease. 1426 1427 Args: 1428 task: Task ID (`tsk_...`). 1429 input: Request body. 1430 input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds. 1431 input.lease_id: Current caller-held lease UUID. 1432 input.session_id: Current coding-session UUID. 1433 1434 Returns: 1435 The renewed caller-held lease. 1436 """ 1437 return await self._http.request( 1438 f"/api/v1/tasks/{task}/lease/renew", 1439 method="POST", 1440 body=input, 1441 response_type=TaskSessionLease, 1442 )
1358 async def remove(self, task: str) -> None: 1359 """ 1360 Release a task session lease 1361 Releases the authenticated assignee's matching live task lease. Repeating a 1362 release after the lease is absent succeeds. A different live successor lease 1363 returns a mismatch. 1364 1365 Args: 1366 task: Task ID (`tsk_...`). 1367 1368 Returns: 1369 Empty response. HTTP 204 is returned after release is accepted. 1370 """ 1371 await self._http.request(f"/api/v1/tasks/{task}/lease", method="DELETE")
Release a task session lease Releases the authenticated assignee's matching live task lease. Repeating a release after the lease is absent succeeds. A different live successor lease returns a mismatch.
Arguments:
- task: Task ID (
tsk_...).
Returns:
Empty response. HTTP 204 is returned after release is accepted.
1373 async def list(self, task: str) -> TaskSessionLeaseSummary | None: 1374 """ 1375 Retrieve a task's current session lease 1376 Returns the authenticated assignee's viewer-safe live lease summary, or null 1377 when no live lease exists. Fencing and opaque session identifiers are never 1378 included. 1379 1380 Args: 1381 task: Task ID (`tsk_...`). 1382 1383 Returns: 1384 Viewer-safe live lease summary, or null. 1385 """ 1386 return await self._http.request( 1387 f"/api/v1/tasks/{task}/lease", 1388 response_type=TaskSessionLeaseSummary | None, 1389 )
Retrieve a task's current session lease Returns the authenticated assignee's viewer-safe live lease summary, or null when no live lease exists. Fencing and opaque session identifiers are never included.
Arguments:
- task: Task ID (
tsk_...).
Returns:
Viewer-safe live lease summary, or null.
1391 async def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: 1392 """ 1393 Claim a task for a coding session 1394 Atomically claims a user-assigned task for the authenticated user's coding 1395 session. The caller generates and retains both UUIDs. An exact retry returns 1396 the existing lease without extending it; another live holder produces a 1397 conflict. Developer and server-to-server credentials cannot impersonate the 1398 assigned user. 1399 1400 Args: 1401 task: Task ID (`tsk_...`). 1402 input: Request body. 1403 input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. 1404 input.harness: Bounded harness identifier. 1405 input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. 1406 input.lease_id: Caller-generated lease UUID. 1407 input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers. 1408 input.session_id: Caller-generated coding-session UUID. 1409 input.session_name: Human-readable coding-session label. 1410 1411 Returns: 1412 The caller-held lease, including its fencing token. 1413 """ 1414 return await self._http.request( 1415 f"/api/v1/tasks/{task}/lease", 1416 method="POST", 1417 body=input, 1418 response_type=TaskSessionLease, 1419 )
Claim a task for a coding session Atomically claims a user-assigned task for the authenticated user's coding session. The caller generates and retains both UUIDs. An exact retry returns the existing lease without extending it; another live holder produces a conflict. Developer and server-to-server credentials cannot impersonate the assigned user.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim.
- input.harness: Bounded harness identifier.
- input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds.
- input.lease_id: Caller-generated lease UUID.
- input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers.
- input.session_id: Caller-generated coding-session UUID.
- input.session_name: Human-readable coding-session label.
Returns:
The caller-held lease, including its fencing token.
1421 async def renew(self, task: str, input: LeaseRenewInput) -> TaskSessionLease: 1422 """ 1423 Renew a task session lease 1424 Renews the authenticated assignee's matching live task lease. Both 1425 caller-generated UUIDs must match the aggregate's current lease. 1426 1427 Args: 1428 task: Task ID (`tsk_...`). 1429 input: Request body. 1430 input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds. 1431 input.lease_id: Current caller-held lease UUID. 1432 input.session_id: Current coding-session UUID. 1433 1434 Returns: 1435 The renewed caller-held lease. 1436 """ 1437 return await self._http.request( 1438 f"/api/v1/tasks/{task}/lease/renew", 1439 method="POST", 1440 body=input, 1441 response_type=TaskSessionLease, 1442 )
Renew a task session lease Renews the authenticated assignee's matching live task lease. Both caller-generated UUIDs must match the aggregate's current lease.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds.
- input.lease_id: Current caller-held lease UUID.
- input.session_id: Current coding-session UUID.
Returns:
The renewed caller-held lease.
1445class AsyncLinkResource: 1446 def __init__(self, http: HttpClient): 1447 self._http = http 1448 1449 async def remove(self, task: str) -> None: 1450 """ 1451 Remove an external link from a task 1452 1453 Args: 1454 task: Task ID (`tsk_...`). 1455 1456 Returns: 1457 HTTP 204 on success. 1458 """ 1459 await self._http.request(f"/api/v1/tasks/{task}/links", method="DELETE") 1460 1461 async def list( 1462 self, 1463 task: str, 1464 *, 1465 team: str | None = None, 1466 user: str | None = None, 1467 agent: str | None = None, 1468 org: str | None = None, 1469 limit: int | None = None, 1470 after_cursor: str | None = None, 1471 ) -> LinkListResponse: 1472 """ 1473 List a task's external links 1474 Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map. 1475 1476 Args: 1477 task: Task ID (`tsk_...`). 1478 team: Explicit owning team for privileged calls. 1479 user: Explicit owning user for privileged calls. 1480 agent: Explicit owning agent for privileged calls. 1481 org: Explicit organization for privileged calls; must agree with owner. 1482 limit: Maximum links to return. Capped at 100. 1483 after_cursor: Opaque cursor returned by the previous page. 1484 1485 Returns: 1486 Successful response 1487 """ 1488 query: dict[str, object] = {} 1489 if team is not None: 1490 query["team"] = team 1491 if user is not None: 1492 query["user"] = user 1493 if agent is not None: 1494 query["agent"] = agent 1495 if org is not None: 1496 query["org"] = org 1497 if limit is not None: 1498 query["limit"] = limit 1499 if after_cursor is not None: 1500 query["after_cursor"] = after_cursor 1501 return await self._http.request( 1502 f"/api/v1/tasks/{task}/links", 1503 query=query, 1504 response_type=LinkListResponse, 1505 ) 1506 1507 async def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: 1508 """ 1509 Add an external link to a task 1510 Adds an indexed identity without changing the referenced object's ownership or ACL. 1511 For private files, upload with POST /api/v1/files, then pass external_scope=platform, 1512 object_type=file and object_id=fil_.... The reserved platform namespace means the 1513 authenticated current backend/app/sandbox, not a hostname or stored URL. 1514 File attachment requires both task mutation permission and current file read access. 1515 List and reverse lookup omit files that are missing or no longer readable, including 1516 thread-restricted files. Generic identities are not resolved as local files. 1517 GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; 1518 never persist that URL as the link identity. Existing signed URLs remain usable until 1519 their expiry. Task activity and replay may retain opaque file IDs, not file metadata, 1520 and confer no file access. 1521 Retain the upload response's file ID if attachment fails and retry the link request. 1522 Detaching or deleting a task does not delete the file. Deleting a file leaves historical 1523 link events intact; replay does not restore bytes or access. No ACL grant is implicit. 1524 Agent-owned uploads use an authorized human session; agent-only file credentials 1525 remain unsupported. 1526 Download URLs depend on the configured storage provider. The development local 1527 provider returns a local URL prefix plus a storage path, but Platform does not 1528 serve that path over HTTP. Local-provider verification reads bytes from the 1529 running Platform's configured storage directory after authorized metadata reads; 1530 it does not prove HTTP download authorization. Serving local downloads through 1531 an authorization-preserving route is a separate follow-up, not a public /storage 1532 mount. Served providers are verified through their HTTP download URLs. 1533 1534 Args: 1535 task: Task ID (`tsk_...`). 1536 input: Request body. 1537 input.external_scope: External container ID. 1538 input.object_id: External object ID. 1539 input.object_type: External object type. 1540 1541 Returns: 1542 The created external link, with its identity normalized. 1543 """ 1544 return await self._http.request( 1545 f"/api/v1/tasks/{task}/links", 1546 method="POST", 1547 body=input, 1548 response_type=TaskExternalLink, 1549 )
1449 async def remove(self, task: str) -> None: 1450 """ 1451 Remove an external link from a task 1452 1453 Args: 1454 task: Task ID (`tsk_...`). 1455 1456 Returns: 1457 HTTP 204 on success. 1458 """ 1459 await self._http.request(f"/api/v1/tasks/{task}/links", method="DELETE")
Remove an external link from a task
Arguments:
- task: Task ID (
tsk_...).
Returns:
HTTP 204 on success.
1461 async def list( 1462 self, 1463 task: str, 1464 *, 1465 team: str | None = None, 1466 user: str | None = None, 1467 agent: str | None = None, 1468 org: str | None = None, 1469 limit: int | None = None, 1470 after_cursor: str | None = None, 1471 ) -> LinkListResponse: 1472 """ 1473 List a task's external links 1474 Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map. 1475 1476 Args: 1477 task: Task ID (`tsk_...`). 1478 team: Explicit owning team for privileged calls. 1479 user: Explicit owning user for privileged calls. 1480 agent: Explicit owning agent for privileged calls. 1481 org: Explicit organization for privileged calls; must agree with owner. 1482 limit: Maximum links to return. Capped at 100. 1483 after_cursor: Opaque cursor returned by the previous page. 1484 1485 Returns: 1486 Successful response 1487 """ 1488 query: dict[str, object] = {} 1489 if team is not None: 1490 query["team"] = team 1491 if user is not None: 1492 query["user"] = user 1493 if agent is not None: 1494 query["agent"] = agent 1495 if org is not None: 1496 query["org"] = org 1497 if limit is not None: 1498 query["limit"] = limit 1499 if after_cursor is not None: 1500 query["after_cursor"] = after_cursor 1501 return await self._http.request( 1502 f"/api/v1/tasks/{task}/links", 1503 query=query, 1504 response_type=LinkListResponse, 1505 )
List a task's external links Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team for privileged calls.
- user: Explicit owning user for privileged calls.
- agent: Explicit owning agent for privileged calls.
- org: Explicit organization for privileged calls; must agree with owner.
- limit: Maximum links to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1507 async def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: 1508 """ 1509 Add an external link to a task 1510 Adds an indexed identity without changing the referenced object's ownership or ACL. 1511 For private files, upload with POST /api/v1/files, then pass external_scope=platform, 1512 object_type=file and object_id=fil_.... The reserved platform namespace means the 1513 authenticated current backend/app/sandbox, not a hostname or stored URL. 1514 File attachment requires both task mutation permission and current file read access. 1515 List and reverse lookup omit files that are missing or no longer readable, including 1516 thread-restricted files. Generic identities are not resolved as local files. 1517 GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; 1518 never persist that URL as the link identity. Existing signed URLs remain usable until 1519 their expiry. Task activity and replay may retain opaque file IDs, not file metadata, 1520 and confer no file access. 1521 Retain the upload response's file ID if attachment fails and retry the link request. 1522 Detaching or deleting a task does not delete the file. Deleting a file leaves historical 1523 link events intact; replay does not restore bytes or access. No ACL grant is implicit. 1524 Agent-owned uploads use an authorized human session; agent-only file credentials 1525 remain unsupported. 1526 Download URLs depend on the configured storage provider. The development local 1527 provider returns a local URL prefix plus a storage path, but Platform does not 1528 serve that path over HTTP. Local-provider verification reads bytes from the 1529 running Platform's configured storage directory after authorized metadata reads; 1530 it does not prove HTTP download authorization. Serving local downloads through 1531 an authorization-preserving route is a separate follow-up, not a public /storage 1532 mount. Served providers are verified through their HTTP download URLs. 1533 1534 Args: 1535 task: Task ID (`tsk_...`). 1536 input: Request body. 1537 input.external_scope: External container ID. 1538 input.object_id: External object ID. 1539 input.object_type: External object type. 1540 1541 Returns: 1542 The created external link, with its identity normalized. 1543 """ 1544 return await self._http.request( 1545 f"/api/v1/tasks/{task}/links", 1546 method="POST", 1547 body=input, 1548 response_type=TaskExternalLink, 1549 )
Add an external link to a task Adds an indexed identity without changing the referenced object's ownership or ACL. For private files, upload with POST /api/v1/files, then pass external_scope=platform, object_type=file and object_id=fil_.... The reserved platform namespace means the authenticated current backend/app/sandbox, not a hostname or stored URL. File attachment requires both task mutation permission and current file read access. List and reverse lookup omit files that are missing or no longer readable, including thread-restricted files. Generic identities are not resolved as local files. GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; never persist that URL as the link identity. Existing signed URLs remain usable until their expiry. Task activity and replay may retain opaque file IDs, not file metadata, and confer no file access. Retain the upload response's file ID if attachment fails and retry the link request. Detaching or deleting a task does not delete the file. Deleting a file leaves historical link events intact; replay does not restore bytes or access. No ACL grant is implicit. Agent-owned uploads use an authorized human session; agent-only file credentials remain unsupported. Download URLs depend on the configured storage provider. The development local provider returns a local URL prefix plus a storage path, but Platform does not serve that path over HTTP. Local-provider verification reads bytes from the running Platform's configured storage directory after authorized metadata reads; it does not prove HTTP download authorization. Serving local downloads through an authorization-preserving route is a separate follow-up, not a public /storage mount. Served providers are verified through their HTTP download URLs.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.external_scope: External container ID.
- input.object_id: External object ID.
- input.object_type: External object type.
Returns:
The created external link, with its identity normalized.
1552class AsyncTaskResource: 1553 def __init__(self, http: HttpClient): 1554 self._http = http 1555 self.blockers = AsyncBlockerResource(http) 1556 self.comments = AsyncCommentResource(http) 1557 self.lease = AsyncLeaseResource(http) 1558 self.links = AsyncLinkResource(http) 1559 1560 async def delete(self, task: str) -> None: 1561 """ 1562 Delete a task 1563 Deletes a task from task lists and detail views. The task event stream is 1564 retained for auditability, while comments are removed and direct subtasks 1565 are promoted to top-level tasks. 1566 The delete event is accepted before the read model is updated. Clients 1567 should remove the task from local collections immediately; subsequent reads 1568 converge once the projection processes the event. 1569 Authenticated users may delete tasks they can access using their session 1570 identity. App-scoped developer and server-to-server callers must explicitly 1571 supply the task's `org` and owner. `team` or `user` identifies that owner; 1572 when neither is present, `agent` identifies an agent-owned task. With a team 1573 or user owner, `agent` identifies the acting principal. Each reference is 1574 validated before deletion. 1575 1576 Args: 1577 task: Task ID (`tsk_...`). 1578 1579 Returns: 1580 Empty response. HTTP 204 is returned after the delete event is accepted. 1581 """ 1582 await self._http.request(f"/api/v1/tasks/{task}", method="DELETE") 1583 1584 async def get( 1585 self, 1586 task: str, 1587 *, 1588 team: str | None = None, 1589 user: str | None = None, 1590 agent: str | None = None, 1591 org: str | None = None, 1592 ) -> Task: 1593 """ 1594 Retrieve a task 1595 Returns the full task object for the specified task ID. Authenticated users 1596 and agents resolve access through their session. App-scoped developer and 1597 server-to-server callers explicitly provide the owning `team`, `user`, or `agent` and 1598 `org`. Callers without access receive a 404. 1599 1600 Args: 1601 task: Task ID (`tsk_...`). 1602 team: Explicit owning team (`tem_...`) for privileged calls. 1603 user: Explicit owning user (`usr_...`) for privileged calls. 1604 agent: Explicit owning agent (`agi_...`) for privileged calls. 1605 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1606 1607 Returns: 1608 The requested task. 1609 """ 1610 query: dict[str, object] = {} 1611 if team is not None: 1612 query["team"] = team 1613 if user is not None: 1614 query["user"] = user 1615 if agent is not None: 1616 query["agent"] = agent 1617 if org is not None: 1618 query["org"] = org 1619 return await self._http.request(f"/api/v1/tasks/{task}", query=query, response_type=Task) 1620 1621 async def replace(self, task: str, input: TaskReplaceInput) -> Task: 1622 """ 1623 Update a task 1624 Updates the supplied fields on a task and returns the complete updated task. 1625 Authenticated users use their session identity. App-scoped developer and 1626 server-to-server callers must explicitly supply the task's `org` and owner. 1627 `team` or `user` identifies that owner; when neither is present, `agent` 1628 identifies an agent-owned task. With a team or user owner, `agent` identifies 1629 the acting principal. Every reference is validated before the update. 1630 A cooperating coding-session client may supply both `lease_id` and 1631 `lease_session_id`. The task aggregate fences that update against the live 1632 lease and records server-sourced session provenance. Omitting both remains a 1633 normal authorized human/API update. 1634 Supply `expected_version` from the latest task representation to make the 1635 update conditional. A concurrent write returns `task_version_conflict`. 1636 1637 Args: 1638 task: Task ID (`tsk_...`). 1639 input: Request body. 1640 input.agent: Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal. 1641 input.description: Updated long-form description. 1642 input.due_date: Updated due date in ISO 8601 format, or null to clear it. 1643 input.epic: Replacement grouping label. Pass null to clear it. 1644 input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. 1645 input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. 1646 input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. 1647 input.links: Replacement related-links object. 1648 input.metadata: Replacement task metadata object. 1649 input.name: Updated display name for the task. 1650 input.org: Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization. 1651 input.owner_agent: Assign to an agent by public ID (`agi_...`). 1652 input.owner_user: Assign to a user by public ID (`usr_...`). 1653 input.parent: Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. 1654 input.priority: Updated priority from 0 (highest) to 4 (lowest). 1655 input.project_id: Project ID (`prj_...`). Omit to preserve; pass null to clear. 1656 input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. 1657 input.source_id: Replacement source object identity. Must be supplied with the other source fields. 1658 input.source_scope: Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. 1659 input.source_type: Replacement source object kind. Must be supplied with the other source fields. 1660 input.status: Updated status: `open`, `in_progress`, `in_review`, or `done`. 1661 input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. 1662 input.target_binary: Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. 1663 input.target_version: Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. 1664 input.team: Explicit owning team (`tem_...`) for a developer or server-to-server call. 1665 input.user: Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. 1666 1667 Returns: 1668 The updated task. 1669 """ 1670 return await self._http.request( 1671 f"/api/v1/tasks/{task}", 1672 method="PUT", 1673 body=input, 1674 response_type=Task, 1675 ) 1676 1677 async def activity( 1678 self, 1679 task: str, 1680 *, 1681 team: str | None = None, 1682 user: str | None = None, 1683 agent: str | None = None, 1684 org: str | None = None, 1685 limit: int | None = None, 1686 after_cursor: str | None = None, 1687 ) -> TaskActivityResponse: 1688 """ 1689 List a task's activity 1690 Returns a bounded chronological page of activity for the specified task. 1691 App-scoped developer and server-to-server callers explicitly provide the 1692 owning `team`, `user`, or `agent` and `org`. 1693 1694 Args: 1695 task: Task ID (`tsk_...`). 1696 team: Explicit owning team (`tem_...`) for privileged calls. 1697 user: Explicit owning user (`usr_...`) for privileged calls. 1698 agent: Explicit owning agent (`agi_...`) for privileged calls. 1699 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1700 limit: Maximum entries to return. Capped at 100. 1701 after_cursor: Opaque cursor returned by the previous page. 1702 1703 Returns: 1704 Successful response 1705 """ 1706 query: dict[str, object] = {} 1707 if team is not None: 1708 query["team"] = team 1709 if user is not None: 1710 query["user"] = user 1711 if agent is not None: 1712 query["agent"] = agent 1713 if org is not None: 1714 query["org"] = org 1715 if limit is not None: 1716 query["limit"] = limit 1717 if after_cursor is not None: 1718 query["after_cursor"] = after_cursor 1719 return await self._http.request( 1720 f"/api/v1/tasks/{task}/activity", 1721 query=query, 1722 response_type=TaskActivityResponse, 1723 ) 1724 1725 async def blocking( 1726 self, 1727 task: str, 1728 *, 1729 team: str | None = None, 1730 user: str | None = None, 1731 agent: str | None = None, 1732 org: str | None = None, 1733 limit: int | None = None, 1734 after_cursor: str | None = None, 1735 ) -> TaskBlockingResponse: 1736 """ 1737 List the tasks a task blocks 1738 Returns a bounded page of the tasks that the specified task is marked as 1739 blocking (the inverse of `GET /tasks/{task}/blockers`), newest first. 1740 The task's owner is resolved from the task itself. 1741 1742 Args: 1743 task: Blocking task ID (`tsk_...`). 1744 team: Explicit owning team (`tem_...`) for privileged calls. 1745 user: Explicit owning user (`usr_...`) for privileged calls. 1746 agent: Explicit owning agent (`agi_...`) for privileged calls. 1747 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1748 limit: Maximum tasks to return. Capped at 100. 1749 after_cursor: Opaque cursor returned by the previous page. 1750 1751 Returns: 1752 Successful response 1753 """ 1754 query: dict[str, object] = {} 1755 if team is not None: 1756 query["team"] = team 1757 if user is not None: 1758 query["user"] = user 1759 if agent is not None: 1760 query["agent"] = agent 1761 if org is not None: 1762 query["org"] = org 1763 if limit is not None: 1764 query["limit"] = limit 1765 if after_cursor is not None: 1766 query["after_cursor"] = after_cursor 1767 return await self._http.request( 1768 f"/api/v1/tasks/{task}/blocking", 1769 query=query, 1770 response_type=TaskBlockingResponse, 1771 ) 1772 1773 async def ownership_conversions( 1774 self, task: str, input: TaskOwnershipConversionsInput 1775 ) -> TaskOwnershipJob: 1776 """ 1777 Convert ownership of a connected task graph 1778 Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. 1779 1780 Args: 1781 task: Root task (`tsk_...`). 1782 input: Request body. 1783 input.dest_agent: Destination agent (`agi_...`). 1784 input.dest_org: Destination organization (`org_...`). 1785 input.dest_team: Destination team (`tem_...`). 1786 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 1787 1788 Returns: 1789 The queued background job. 1790 """ 1791 return await self._http.request( 1792 f"/api/v1/tasks/{task}/ownership_conversions", 1793 method="POST", 1794 body=input, 1795 response_type=TaskOwnershipJob, 1796 ) 1797 1798 async def subtasks( 1799 self, 1800 task: str, 1801 *, 1802 team: str | None = None, 1803 user: str | None = None, 1804 agent: str | None = None, 1805 org: str | None = None, 1806 limit: int | None = None, 1807 after_cursor: str | None = None, 1808 ) -> TaskSubtasksResponse: 1809 """ 1810 List a task's subtasks 1811 Returns a bounded page of the specified task's subtasks (tasks whose 1812 `parent` is this task), newest first. Subtasks nest exactly one level, so 1813 entries never have subtasks of their own. Privileged callers explicitly 1814 provide the owning `team`, `user`, or `agent` and `org`. 1815 1816 Args: 1817 task: Parent task ID (`tsk_...`). 1818 team: Explicit owning team (`tem_...`) for privileged calls. 1819 user: Explicit owning user (`usr_...`) for privileged calls. 1820 agent: Explicit owning agent (`agi_...`) for privileged calls. 1821 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1822 limit: Maximum subtasks to return. Capped at 100. 1823 after_cursor: Opaque cursor returned by the previous page. 1824 1825 Returns: 1826 Successful response 1827 """ 1828 query: dict[str, object] = {} 1829 if team is not None: 1830 query["team"] = team 1831 if user is not None: 1832 query["user"] = user 1833 if agent is not None: 1834 query["agent"] = agent 1835 if org is not None: 1836 query["org"] = org 1837 if limit is not None: 1838 query["limit"] = limit 1839 if after_cursor is not None: 1840 query["after_cursor"] = after_cursor 1841 return await self._http.request( 1842 f"/api/v1/tasks/{task}/subtasks", 1843 query=query, 1844 response_type=TaskSubtasksResponse, 1845 ) 1846 1847 async def transfer_ownership(self, task: str, input: TaskTransferOwnershipInput) -> Task: 1848 """ 1849 Transfer one task to a different owner 1850 Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. 1851 1852 Args: 1853 task: Task (`tsk_...`). 1854 input: Request body. 1855 input.dest_agent: Destination agent (`agi_...`). 1856 input.dest_org: Destination organization (`org_...`). 1857 input.dest_team: Destination team (`tem_...`). 1858 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 1859 input.expected_version: The task version reviewed by the caller. 1860 1861 Returns: 1862 The task with its new owner. 1863 """ 1864 return await self._http.request( 1865 f"/api/v1/tasks/{task}/transfer_ownership", 1866 method="POST", 1867 body=input, 1868 response_type=Task, 1869 )
1560 async def delete(self, task: str) -> None: 1561 """ 1562 Delete a task 1563 Deletes a task from task lists and detail views. The task event stream is 1564 retained for auditability, while comments are removed and direct subtasks 1565 are promoted to top-level tasks. 1566 The delete event is accepted before the read model is updated. Clients 1567 should remove the task from local collections immediately; subsequent reads 1568 converge once the projection processes the event. 1569 Authenticated users may delete tasks they can access using their session 1570 identity. App-scoped developer and server-to-server callers must explicitly 1571 supply the task's `org` and owner. `team` or `user` identifies that owner; 1572 when neither is present, `agent` identifies an agent-owned task. With a team 1573 or user owner, `agent` identifies the acting principal. Each reference is 1574 validated before deletion. 1575 1576 Args: 1577 task: Task ID (`tsk_...`). 1578 1579 Returns: 1580 Empty response. HTTP 204 is returned after the delete event is accepted. 1581 """ 1582 await self._http.request(f"/api/v1/tasks/{task}", method="DELETE")
Delete a task
Deletes a task from task lists and detail views. The task event stream is
retained for auditability, while comments are removed and direct subtasks
are promoted to top-level tasks.
The delete event is accepted before the read model is updated. Clients
should remove the task from local collections immediately; subsequent reads
converge once the projection processes the event.
Authenticated users may delete tasks they can access using their session
identity. App-scoped developer and server-to-server callers must explicitly
supply the task's org and owner. team or user identifies that owner;
when neither is present, agent identifies an agent-owned task. With a team
or user owner, agent identifies the acting principal. Each reference is
validated before deletion.
Arguments:
- task: Task ID (
tsk_...).
Returns:
Empty response. HTTP 204 is returned after the delete event is accepted.
1584 async def get( 1585 self, 1586 task: str, 1587 *, 1588 team: str | None = None, 1589 user: str | None = None, 1590 agent: str | None = None, 1591 org: str | None = None, 1592 ) -> Task: 1593 """ 1594 Retrieve a task 1595 Returns the full task object for the specified task ID. Authenticated users 1596 and agents resolve access through their session. App-scoped developer and 1597 server-to-server callers explicitly provide the owning `team`, `user`, or `agent` and 1598 `org`. Callers without access receive a 404. 1599 1600 Args: 1601 task: Task ID (`tsk_...`). 1602 team: Explicit owning team (`tem_...`) for privileged calls. 1603 user: Explicit owning user (`usr_...`) for privileged calls. 1604 agent: Explicit owning agent (`agi_...`) for privileged calls. 1605 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1606 1607 Returns: 1608 The requested task. 1609 """ 1610 query: dict[str, object] = {} 1611 if team is not None: 1612 query["team"] = team 1613 if user is not None: 1614 query["user"] = user 1615 if agent is not None: 1616 query["agent"] = agent 1617 if org is not None: 1618 query["org"] = org 1619 return await self._http.request(f"/api/v1/tasks/{task}", query=query, response_type=Task)
Retrieve a task
Returns the full task object for the specified task ID. Authenticated users
and agents resolve access through their session. App-scoped developer and
server-to-server callers explicitly provide the owning team, user, or agent and
org. Callers without access receive a 404.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped.
Returns:
The requested task.
1621 async def replace(self, task: str, input: TaskReplaceInput) -> Task: 1622 """ 1623 Update a task 1624 Updates the supplied fields on a task and returns the complete updated task. 1625 Authenticated users use their session identity. App-scoped developer and 1626 server-to-server callers must explicitly supply the task's `org` and owner. 1627 `team` or `user` identifies that owner; when neither is present, `agent` 1628 identifies an agent-owned task. With a team or user owner, `agent` identifies 1629 the acting principal. Every reference is validated before the update. 1630 A cooperating coding-session client may supply both `lease_id` and 1631 `lease_session_id`. The task aggregate fences that update against the live 1632 lease and records server-sourced session provenance. Omitting both remains a 1633 normal authorized human/API update. 1634 Supply `expected_version` from the latest task representation to make the 1635 update conditional. A concurrent write returns `task_version_conflict`. 1636 1637 Args: 1638 task: Task ID (`tsk_...`). 1639 input: Request body. 1640 input.agent: Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal. 1641 input.description: Updated long-form description. 1642 input.due_date: Updated due date in ISO 8601 format, or null to clear it. 1643 input.epic: Replacement grouping label. Pass null to clear it. 1644 input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. 1645 input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. 1646 input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. 1647 input.links: Replacement related-links object. 1648 input.metadata: Replacement task metadata object. 1649 input.name: Updated display name for the task. 1650 input.org: Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization. 1651 input.owner_agent: Assign to an agent by public ID (`agi_...`). 1652 input.owner_user: Assign to a user by public ID (`usr_...`). 1653 input.parent: Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. 1654 input.priority: Updated priority from 0 (highest) to 4 (lowest). 1655 input.project_id: Project ID (`prj_...`). Omit to preserve; pass null to clear. 1656 input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. 1657 input.source_id: Replacement source object identity. Must be supplied with the other source fields. 1658 input.source_scope: Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. 1659 input.source_type: Replacement source object kind. Must be supplied with the other source fields. 1660 input.status: Updated status: `open`, `in_progress`, `in_review`, or `done`. 1661 input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. 1662 input.target_binary: Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. 1663 input.target_version: Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. 1664 input.team: Explicit owning team (`tem_...`) for a developer or server-to-server call. 1665 input.user: Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. 1666 1667 Returns: 1668 The updated task. 1669 """ 1670 return await self._http.request( 1671 f"/api/v1/tasks/{task}", 1672 method="PUT", 1673 body=input, 1674 response_type=Task, 1675 )
Update a task
Updates the supplied fields on a task and returns the complete updated task.
Authenticated users use their session identity. App-scoped developer and
server-to-server callers must explicitly supply the task's org and owner.
team or user identifies that owner; when neither is present, agent
identifies an agent-owned task. With a team or user owner, agent identifies
the acting principal. Every reference is validated before the update.
A cooperating coding-session client may supply both lease_id and
lease_session_id. The task aggregate fences that update against the live
lease and records server-sourced session provenance. Omitting both remains a
normal authorized human/API update.
Supply expected_version from the latest task representation to make the
update conditional. A concurrent write returns task_version_conflict.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.agent: Explicit agent (
agi_...). It is the owner whenteamanduserare absent; otherwise it is the acting principal. - input.description: Updated long-form description.
- input.due_date: Updated due date in ISO 8601 format, or null to clear it.
- input.epic: Replacement grouping label. Pass null to clear it.
- input.expected_version: Aggregate version returned by the latest task read. The update fails with
task_version_conflictif the task changed first. - input.lease_id: Current caller-held lease UUID. Must be paired with
lease_session_id. - input.lease_session_id: Current coding-session UUID. Must be paired with
lease_id. - input.links: Replacement related-links object.
- input.metadata: Replacement task metadata object.
- input.name: Updated display name for the task.
- input.org: Explicit organization (
org_...) for a developer or server-to-server call. Pass null for an owner outside an organization. - input.owner_agent: Assign to an agent by public ID (
agi_...). - input.owner_user: Assign to a user by public ID (
usr_...). - input.parent: Move this task under a top-level parent (
tsk_...), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. - input.priority: Updated priority from 0 (highest) to 4 (lowest).
- input.project_id: Project ID (
prj_...). Omit to preserve; pass null to clear. - input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available.
- input.source_id: Replacement source object identity. Must be supplied with the other source fields.
- input.source_scope: Replacement source container. Pass together with
source_typeandsource_id, or pass all three as null to clear the source. - input.source_type: Replacement source object kind. Must be supplied with the other source fields.
- input.status: Updated status:
open,in_progress,in_review, ordone. - input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags.
- input.target_binary: Replacement target binary (for example
my-cli): a lowercase identifier of 1-64 characters. Pass together withtarget_version, or pass both as null to clear the target. - input.target_version: Replacement minimum semantic version of
target_binary(for example0.48.9). Must be supplied withtarget_binary. - input.team: Explicit owning team (
tem_...) for a developer or server-to-server call. - input.user: Explicit user (
usr_...) for a developer or server-to-server call. Withteam, this identifies the acting team member.
Returns:
The updated task.
1677 async def activity( 1678 self, 1679 task: str, 1680 *, 1681 team: str | None = None, 1682 user: str | None = None, 1683 agent: str | None = None, 1684 org: str | None = None, 1685 limit: int | None = None, 1686 after_cursor: str | None = None, 1687 ) -> TaskActivityResponse: 1688 """ 1689 List a task's activity 1690 Returns a bounded chronological page of activity for the specified task. 1691 App-scoped developer and server-to-server callers explicitly provide the 1692 owning `team`, `user`, or `agent` and `org`. 1693 1694 Args: 1695 task: Task ID (`tsk_...`). 1696 team: Explicit owning team (`tem_...`) for privileged calls. 1697 user: Explicit owning user (`usr_...`) for privileged calls. 1698 agent: Explicit owning agent (`agi_...`) for privileged calls. 1699 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1700 limit: Maximum entries to return. Capped at 100. 1701 after_cursor: Opaque cursor returned by the previous page. 1702 1703 Returns: 1704 Successful response 1705 """ 1706 query: dict[str, object] = {} 1707 if team is not None: 1708 query["team"] = team 1709 if user is not None: 1710 query["user"] = user 1711 if agent is not None: 1712 query["agent"] = agent 1713 if org is not None: 1714 query["org"] = org 1715 if limit is not None: 1716 query["limit"] = limit 1717 if after_cursor is not None: 1718 query["after_cursor"] = after_cursor 1719 return await self._http.request( 1720 f"/api/v1/tasks/{task}/activity", 1721 query=query, 1722 response_type=TaskActivityResponse, 1723 )
List a task's activity
Returns a bounded chronological page of activity for the specified task.
App-scoped developer and server-to-server callers explicitly provide the
owning team, user, or agent and org.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum entries to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1725 async def blocking( 1726 self, 1727 task: str, 1728 *, 1729 team: str | None = None, 1730 user: str | None = None, 1731 agent: str | None = None, 1732 org: str | None = None, 1733 limit: int | None = None, 1734 after_cursor: str | None = None, 1735 ) -> TaskBlockingResponse: 1736 """ 1737 List the tasks a task blocks 1738 Returns a bounded page of the tasks that the specified task is marked as 1739 blocking (the inverse of `GET /tasks/{task}/blockers`), newest first. 1740 The task's owner is resolved from the task itself. 1741 1742 Args: 1743 task: Blocking task ID (`tsk_...`). 1744 team: Explicit owning team (`tem_...`) for privileged calls. 1745 user: Explicit owning user (`usr_...`) for privileged calls. 1746 agent: Explicit owning agent (`agi_...`) for privileged calls. 1747 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1748 limit: Maximum tasks to return. Capped at 100. 1749 after_cursor: Opaque cursor returned by the previous page. 1750 1751 Returns: 1752 Successful response 1753 """ 1754 query: dict[str, object] = {} 1755 if team is not None: 1756 query["team"] = team 1757 if user is not None: 1758 query["user"] = user 1759 if agent is not None: 1760 query["agent"] = agent 1761 if org is not None: 1762 query["org"] = org 1763 if limit is not None: 1764 query["limit"] = limit 1765 if after_cursor is not None: 1766 query["after_cursor"] = after_cursor 1767 return await self._http.request( 1768 f"/api/v1/tasks/{task}/blocking", 1769 query=query, 1770 response_type=TaskBlockingResponse, 1771 )
List the tasks a task blocks
Returns a bounded page of the tasks that the specified task is marked as
blocking (the inverse of GET /tasks/{task}/blockers), newest first.
The task's owner is resolved from the task itself.
Arguments:
- task: Blocking task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum tasks to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1773 async def ownership_conversions( 1774 self, task: str, input: TaskOwnershipConversionsInput 1775 ) -> TaskOwnershipJob: 1776 """ 1777 Convert ownership of a connected task graph 1778 Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. 1779 1780 Args: 1781 task: Root task (`tsk_...`). 1782 input: Request body. 1783 input.dest_agent: Destination agent (`agi_...`). 1784 input.dest_org: Destination organization (`org_...`). 1785 input.dest_team: Destination team (`tem_...`). 1786 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 1787 1788 Returns: 1789 The queued background job. 1790 """ 1791 return await self._http.request( 1792 f"/api/v1/tasks/{task}/ownership_conversions", 1793 method="POST", 1794 body=input, 1795 response_type=TaskOwnershipJob, 1796 )
Convert ownership of a connected task graph Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers.
Arguments:
- task: Root task (
tsk_...). - input: Request body.
- input.dest_agent: Destination agent (
agi_...). - input.dest_org: Destination organization (
org_...). - input.dest_team: Destination team (
tem_...). - input.dest_user: Destination user (
usr_...). Supply exactly one destination.
Returns:
The queued background job.
1798 async def subtasks( 1799 self, 1800 task: str, 1801 *, 1802 team: str | None = None, 1803 user: str | None = None, 1804 agent: str | None = None, 1805 org: str | None = None, 1806 limit: int | None = None, 1807 after_cursor: str | None = None, 1808 ) -> TaskSubtasksResponse: 1809 """ 1810 List a task's subtasks 1811 Returns a bounded page of the specified task's subtasks (tasks whose 1812 `parent` is this task), newest first. Subtasks nest exactly one level, so 1813 entries never have subtasks of their own. Privileged callers explicitly 1814 provide the owning `team`, `user`, or `agent` and `org`. 1815 1816 Args: 1817 task: Parent task ID (`tsk_...`). 1818 team: Explicit owning team (`tem_...`) for privileged calls. 1819 user: Explicit owning user (`usr_...`) for privileged calls. 1820 agent: Explicit owning agent (`agi_...`) for privileged calls. 1821 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1822 limit: Maximum subtasks to return. Capped at 100. 1823 after_cursor: Opaque cursor returned by the previous page. 1824 1825 Returns: 1826 Successful response 1827 """ 1828 query: dict[str, object] = {} 1829 if team is not None: 1830 query["team"] = team 1831 if user is not None: 1832 query["user"] = user 1833 if agent is not None: 1834 query["agent"] = agent 1835 if org is not None: 1836 query["org"] = org 1837 if limit is not None: 1838 query["limit"] = limit 1839 if after_cursor is not None: 1840 query["after_cursor"] = after_cursor 1841 return await self._http.request( 1842 f"/api/v1/tasks/{task}/subtasks", 1843 query=query, 1844 response_type=TaskSubtasksResponse, 1845 )
List a task's subtasks
Returns a bounded page of the specified task's subtasks (tasks whose
parent is this task), newest first. Subtasks nest exactly one level, so
entries never have subtasks of their own. Privileged callers explicitly
provide the owning team, user, or agent and org.
Arguments:
- task: Parent task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum subtasks to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1847 async def transfer_ownership(self, task: str, input: TaskTransferOwnershipInput) -> Task: 1848 """ 1849 Transfer one task to a different owner 1850 Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. 1851 1852 Args: 1853 task: Task (`tsk_...`). 1854 input: Request body. 1855 input.dest_agent: Destination agent (`agi_...`). 1856 input.dest_org: Destination organization (`org_...`). 1857 input.dest_team: Destination team (`tem_...`). 1858 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 1859 input.expected_version: The task version reviewed by the caller. 1860 1861 Returns: 1862 The task with its new owner. 1863 """ 1864 return await self._http.request( 1865 f"/api/v1/tasks/{task}/transfer_ownership", 1866 method="POST", 1867 body=input, 1868 response_type=Task, 1869 )
Transfer one task to a different owner Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes.
Arguments:
- task: Task (
tsk_...). - input: Request body.
- input.dest_agent: Destination agent (
agi_...). - input.dest_org: Destination organization (
org_...). - input.dest_team: Destination team (
tem_...). - input.dest_user: Destination user (
usr_...). Supply exactly one destination. - input.expected_version: The task version reviewed by the caller.
Returns:
The task with its new owner.
1872class BlockerResource: 1873 def __init__(self, http: SyncHttpClient): 1874 self._http = http 1875 1876 def list( 1877 self, 1878 task: str, 1879 *, 1880 team: str | None = None, 1881 user: str | None = None, 1882 agent: str | None = None, 1883 org: str | None = None, 1884 limit: int | None = None, 1885 after_cursor: str | None = None, 1886 ) -> BlockerListResponse: 1887 """ 1888 List a task's blockers 1889 Returns a bounded page of the tasks currently marked as blocking the 1890 specified task, newest first. Blocking is informational: a blocked task 1891 can still change status, and it stops counting as blocked as soon as 1892 every blocker is done. The task's owner is resolved from the task itself. 1893 1894 Args: 1895 task: Blocked task ID (`tsk_...`). 1896 team: Explicit owning team (`tem_...`) for privileged calls. 1897 user: Explicit owning user (`usr_...`) for privileged calls. 1898 agent: Explicit owning agent (`agi_...`) for privileged calls. 1899 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1900 limit: Maximum blockers to return. Capped at 100. 1901 after_cursor: Opaque cursor returned by the previous page. 1902 1903 Returns: 1904 Successful response 1905 """ 1906 query: dict[str, object] = {} 1907 if team is not None: 1908 query["team"] = team 1909 if user is not None: 1910 query["user"] = user 1911 if agent is not None: 1912 query["agent"] = agent 1913 if org is not None: 1914 query["org"] = org 1915 if limit is not None: 1916 query["limit"] = limit 1917 if after_cursor is not None: 1918 query["after_cursor"] = after_cursor 1919 return self._http.request( 1920 f"/api/v1/tasks/{task}/blockers", 1921 query=query, 1922 response_type=BlockerListResponse, 1923 ) 1924 1925 def create(self, task: str, input: BlockerCreateInput) -> Task: 1926 """ 1927 Mark a task as blocked by another task 1928 Records that the task in `blocker` blocks the specified task and returns 1929 the updated task. Blocking is informational the blocked task can still 1930 change status and derived at read time, so the task stops reporting 1931 `is_blocked` as soon as every blocker is done. The blocker must belong to 1932 the same owner (team or user) as the task; self-blocking and blocking a 1933 task that already blocks the blocker (a direct cycle) are rejected. 1934 1935 Args: 1936 task: Blocked task ID (`tsk_...`). 1937 input: Request body. 1938 input.agent: Explicit owning agent (`agi_...`) for privileged calls. 1939 input.blocker: ID of the task that blocks this task (`tsk_...`). 1940 input.org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1941 input.team: Explicit owning team (`tem_...`) for privileged calls. 1942 input.user: Explicit owning user (`usr_...`) for privileged calls. 1943 1944 Returns: 1945 The updated (blocked) task. 1946 """ 1947 return self._http.request( 1948 f"/api/v1/tasks/{task}/blockers", 1949 method="POST", 1950 body=input, 1951 response_type=Task, 1952 ) 1953 1954 def delete(self, task: str, blocker: str) -> None: 1955 """ 1956 Remove a blocker from a task 1957 Removes the blocking relationship between the task in `blocker` and the 1958 specified task. Returns 204 No Content on success, or 404 if the given 1959 task is not currently marked as blocking this task. 1960 1961 Args: 1962 task: Blocked task ID (`tsk_...`). 1963 blocker: ID of the blocking task to remove (`tsk_...`). 1964 1965 Returns: 1966 Empty response body. HTTP 204 No Content on success. 1967 """ 1968 self._http.request(f"/api/v1/tasks/{task}/blockers/{blocker}", method="DELETE")
1876 def list( 1877 self, 1878 task: str, 1879 *, 1880 team: str | None = None, 1881 user: str | None = None, 1882 agent: str | None = None, 1883 org: str | None = None, 1884 limit: int | None = None, 1885 after_cursor: str | None = None, 1886 ) -> BlockerListResponse: 1887 """ 1888 List a task's blockers 1889 Returns a bounded page of the tasks currently marked as blocking the 1890 specified task, newest first. Blocking is informational: a blocked task 1891 can still change status, and it stops counting as blocked as soon as 1892 every blocker is done. The task's owner is resolved from the task itself. 1893 1894 Args: 1895 task: Blocked task ID (`tsk_...`). 1896 team: Explicit owning team (`tem_...`) for privileged calls. 1897 user: Explicit owning user (`usr_...`) for privileged calls. 1898 agent: Explicit owning agent (`agi_...`) for privileged calls. 1899 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1900 limit: Maximum blockers to return. Capped at 100. 1901 after_cursor: Opaque cursor returned by the previous page. 1902 1903 Returns: 1904 Successful response 1905 """ 1906 query: dict[str, object] = {} 1907 if team is not None: 1908 query["team"] = team 1909 if user is not None: 1910 query["user"] = user 1911 if agent is not None: 1912 query["agent"] = agent 1913 if org is not None: 1914 query["org"] = org 1915 if limit is not None: 1916 query["limit"] = limit 1917 if after_cursor is not None: 1918 query["after_cursor"] = after_cursor 1919 return self._http.request( 1920 f"/api/v1/tasks/{task}/blockers", 1921 query=query, 1922 response_type=BlockerListResponse, 1923 )
List a task's blockers Returns a bounded page of the tasks currently marked as blocking the specified task, newest first. Blocking is informational: a blocked task can still change status, and it stops counting as blocked as soon as every blocker is done. The task's owner is resolved from the task itself.
Arguments:
- task: Blocked task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum blockers to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
1925 def create(self, task: str, input: BlockerCreateInput) -> Task: 1926 """ 1927 Mark a task as blocked by another task 1928 Records that the task in `blocker` blocks the specified task and returns 1929 the updated task. Blocking is informational the blocked task can still 1930 change status and derived at read time, so the task stops reporting 1931 `is_blocked` as soon as every blocker is done. The blocker must belong to 1932 the same owner (team or user) as the task; self-blocking and blocking a 1933 task that already blocks the blocker (a direct cycle) are rejected. 1934 1935 Args: 1936 task: Blocked task ID (`tsk_...`). 1937 input: Request body. 1938 input.agent: Explicit owning agent (`agi_...`) for privileged calls. 1939 input.blocker: ID of the task that blocks this task (`tsk_...`). 1940 input.org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1941 input.team: Explicit owning team (`tem_...`) for privileged calls. 1942 input.user: Explicit owning user (`usr_...`) for privileged calls. 1943 1944 Returns: 1945 The updated (blocked) task. 1946 """ 1947 return self._http.request( 1948 f"/api/v1/tasks/{task}/blockers", 1949 method="POST", 1950 body=input, 1951 response_type=Task, 1952 )
Mark a task as blocked by another task
Records that the task in blocker blocks the specified task and returns
the updated task. Blocking is informational the blocked task can still
change status and derived at read time, so the task stops reporting
is_blocked as soon as every blocker is done. The blocker must belong to
the same owner (team or user) as the task; self-blocking and blocking a
task that already blocks the blocker (a direct cycle) are rejected.
Arguments:
- task: Blocked task ID (
tsk_...). - input: Request body.
- input.agent: Explicit owning agent (
agi_...) for privileged calls. - input.blocker: ID of the task that blocks this task (
tsk_...). - input.org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - input.team: Explicit owning team (
tem_...) for privileged calls. - input.user: Explicit owning user (
usr_...) for privileged calls.
Returns:
The updated (blocked) task.
1954 def delete(self, task: str, blocker: str) -> None: 1955 """ 1956 Remove a blocker from a task 1957 Removes the blocking relationship between the task in `blocker` and the 1958 specified task. Returns 204 No Content on success, or 404 if the given 1959 task is not currently marked as blocking this task. 1960 1961 Args: 1962 task: Blocked task ID (`tsk_...`). 1963 blocker: ID of the blocking task to remove (`tsk_...`). 1964 1965 Returns: 1966 Empty response body. HTTP 204 No Content on success. 1967 """ 1968 self._http.request(f"/api/v1/tasks/{task}/blockers/{blocker}", method="DELETE")
Remove a blocker from a task
Removes the blocking relationship between the task in blocker and the
specified task. Returns 204 No Content on success, or 404 if the given
task is not currently marked as blocking this task.
Arguments:
- task: Blocked task ID (
tsk_...). - blocker: ID of the blocking task to remove (
tsk_...).
Returns:
Empty response body. HTTP 204 No Content on success.
1971class CommentResource: 1972 def __init__(self, http: SyncHttpClient): 1973 self._http = http 1974 1975 def list( 1976 self, 1977 task: str, 1978 *, 1979 team: str | None = None, 1980 user: str | None = None, 1981 agent: str | None = None, 1982 org: str | None = None, 1983 limit: int | None = None, 1984 after_cursor: str | None = None, 1985 ) -> CommentListResponse: 1986 """ 1987 List comments on a task 1988 Returns a bounded page of comments on the specified task, ordered by creation 1989 time ascending. App-scoped developer and server-to-server callers explicitly 1990 provide the owning `team`, `user`, or `agent` and `org`. 1991 1992 Args: 1993 task: Task ID (`tsk_...`). 1994 team: Explicit owning team (`tem_...`) for privileged calls. 1995 user: Explicit owning user (`usr_...`) for privileged calls. 1996 agent: Explicit owning agent (`agi_...`) for privileged calls. 1997 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1998 limit: Maximum comments to return. Capped at 100. 1999 after_cursor: Opaque cursor returned by the previous page. 2000 2001 Returns: 2002 Successful response 2003 """ 2004 query: dict[str, object] = {} 2005 if team is not None: 2006 query["team"] = team 2007 if user is not None: 2008 query["user"] = user 2009 if agent is not None: 2010 query["agent"] = agent 2011 if org is not None: 2012 query["org"] = org 2013 if limit is not None: 2014 query["limit"] = limit 2015 if after_cursor is not None: 2016 query["after_cursor"] = after_cursor 2017 return self._http.request( 2018 f"/api/v1/tasks/{task}/comments", 2019 query=query, 2020 response_type=CommentListResponse, 2021 ) 2022 2023 def create(self, task: str, input: CommentCreateInput) -> TaskComment: 2024 """ 2025 Create a comment on a task 2026 Posts a new comment on the specified task and returns the created comment. 2027 The task's owner is resolved from the task itself. 2028 2029 Args: 2030 task: Task ID (`tsk_...`). 2031 input: Request body. 2032 input.comment: Parameters for the comment to create, including its body. 2033 input.expected_version: Reject the comment if the task changed since this version. 2034 2035 Returns: 2036 The newly created comment. 2037 """ 2038 return self._http.request( 2039 f"/api/v1/tasks/{task}/comments", 2040 method="POST", 2041 body=input, 2042 response_type=TaskComment, 2043 ) 2044 2045 def delete(self, task: str, comment: str) -> None: 2046 """ 2047 Delete a task comment 2048 Permanently removes a comment from its task. This action cannot be undone. 2049 The task's owner is resolved from the task itself. 2050 Only the comment's author, an admin of the comment's organization, or an 2051 admin of the owning team may delete a comment. Returns `403 Forbidden` 2052 otherwise. 2053 2054 Args: 2055 task: Task ID (`tsk_...`). 2056 comment: Comment ID (`tcm_...`). 2057 2058 Returns: 2059 Empty body. The server responds with HTTP 204 No Content on success. 2060 """ 2061 self._http.request(f"/api/v1/tasks/{task}/comments/{comment}", method="DELETE") 2062 2063 def replace(self, task: str, comment: str, input: CommentReplaceInput) -> TaskComment: 2064 """ 2065 Update a task comment 2066 Replaces the body of an existing comment and returns the updated comment. 2067 The task's owner is resolved from the task itself. 2068 Only the comment's author, an admin of the comment's organization, or an 2069 admin of the owning team may edit a comment. Returns `403 Forbidden` 2070 otherwise. 2071 2072 Args: 2073 task: Task ID (`tsk_...`). 2074 comment: Comment ID (`tcm_...`). 2075 input: Request body. 2076 input.body: Replacement body for the comment. Must be non-empty. 2077 2078 Returns: 2079 The updated comment. 2080 """ 2081 return self._http.request( 2082 f"/api/v1/tasks/{task}/comments/{comment}", 2083 method="PUT", 2084 body=input, 2085 response_type=TaskComment, 2086 )
1975 def list( 1976 self, 1977 task: str, 1978 *, 1979 team: str | None = None, 1980 user: str | None = None, 1981 agent: str | None = None, 1982 org: str | None = None, 1983 limit: int | None = None, 1984 after_cursor: str | None = None, 1985 ) -> CommentListResponse: 1986 """ 1987 List comments on a task 1988 Returns a bounded page of comments on the specified task, ordered by creation 1989 time ascending. App-scoped developer and server-to-server callers explicitly 1990 provide the owning `team`, `user`, or `agent` and `org`. 1991 1992 Args: 1993 task: Task ID (`tsk_...`). 1994 team: Explicit owning team (`tem_...`) for privileged calls. 1995 user: Explicit owning user (`usr_...`) for privileged calls. 1996 agent: Explicit owning agent (`agi_...`) for privileged calls. 1997 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 1998 limit: Maximum comments to return. Capped at 100. 1999 after_cursor: Opaque cursor returned by the previous page. 2000 2001 Returns: 2002 Successful response 2003 """ 2004 query: dict[str, object] = {} 2005 if team is not None: 2006 query["team"] = team 2007 if user is not None: 2008 query["user"] = user 2009 if agent is not None: 2010 query["agent"] = agent 2011 if org is not None: 2012 query["org"] = org 2013 if limit is not None: 2014 query["limit"] = limit 2015 if after_cursor is not None: 2016 query["after_cursor"] = after_cursor 2017 return self._http.request( 2018 f"/api/v1/tasks/{task}/comments", 2019 query=query, 2020 response_type=CommentListResponse, 2021 )
List comments on a task
Returns a bounded page of comments on the specified task, ordered by creation
time ascending. App-scoped developer and server-to-server callers explicitly
provide the owning team, user, or agent and org.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum comments to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
2023 def create(self, task: str, input: CommentCreateInput) -> TaskComment: 2024 """ 2025 Create a comment on a task 2026 Posts a new comment on the specified task and returns the created comment. 2027 The task's owner is resolved from the task itself. 2028 2029 Args: 2030 task: Task ID (`tsk_...`). 2031 input: Request body. 2032 input.comment: Parameters for the comment to create, including its body. 2033 input.expected_version: Reject the comment if the task changed since this version. 2034 2035 Returns: 2036 The newly created comment. 2037 """ 2038 return self._http.request( 2039 f"/api/v1/tasks/{task}/comments", 2040 method="POST", 2041 body=input, 2042 response_type=TaskComment, 2043 )
Create a comment on a task Posts a new comment on the specified task and returns the created comment. The task's owner is resolved from the task itself.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.comment: Parameters for the comment to create, including its body.
- input.expected_version: Reject the comment if the task changed since this version.
Returns:
The newly created comment.
2045 def delete(self, task: str, comment: str) -> None: 2046 """ 2047 Delete a task comment 2048 Permanently removes a comment from its task. This action cannot be undone. 2049 The task's owner is resolved from the task itself. 2050 Only the comment's author, an admin of the comment's organization, or an 2051 admin of the owning team may delete a comment. Returns `403 Forbidden` 2052 otherwise. 2053 2054 Args: 2055 task: Task ID (`tsk_...`). 2056 comment: Comment ID (`tcm_...`). 2057 2058 Returns: 2059 Empty body. The server responds with HTTP 204 No Content on success. 2060 """ 2061 self._http.request(f"/api/v1/tasks/{task}/comments/{comment}", method="DELETE")
Delete a task comment
Permanently removes a comment from its task. This action cannot be undone.
The task's owner is resolved from the task itself.
Only the comment's author, an admin of the comment's organization, or an
admin of the owning team may delete a comment. Returns 403 Forbidden
otherwise.
Arguments:
- task: Task ID (
tsk_...). - comment: Comment ID (
tcm_...).
Returns:
Empty body. The server responds with HTTP 204 No Content on success.
2063 def replace(self, task: str, comment: str, input: CommentReplaceInput) -> TaskComment: 2064 """ 2065 Update a task comment 2066 Replaces the body of an existing comment and returns the updated comment. 2067 The task's owner is resolved from the task itself. 2068 Only the comment's author, an admin of the comment's organization, or an 2069 admin of the owning team may edit a comment. Returns `403 Forbidden` 2070 otherwise. 2071 2072 Args: 2073 task: Task ID (`tsk_...`). 2074 comment: Comment ID (`tcm_...`). 2075 input: Request body. 2076 input.body: Replacement body for the comment. Must be non-empty. 2077 2078 Returns: 2079 The updated comment. 2080 """ 2081 return self._http.request( 2082 f"/api/v1/tasks/{task}/comments/{comment}", 2083 method="PUT", 2084 body=input, 2085 response_type=TaskComment, 2086 )
Update a task comment
Replaces the body of an existing comment and returns the updated comment.
The task's owner is resolved from the task itself.
Only the comment's author, an admin of the comment's organization, or an
admin of the owning team may edit a comment. Returns 403 Forbidden
otherwise.
Arguments:
- task: Task ID (
tsk_...). - comment: Comment ID (
tcm_...). - input: Request body.
- input.body: Replacement body for the comment. Must be non-empty.
Returns:
The updated comment.
2089class LeaseResource: 2090 def __init__(self, http: SyncHttpClient): 2091 self._http = http 2092 2093 def remove(self, task: str) -> None: 2094 """ 2095 Release a task session lease 2096 Releases the authenticated assignee's matching live task lease. Repeating a 2097 release after the lease is absent succeeds. A different live successor lease 2098 returns a mismatch. 2099 2100 Args: 2101 task: Task ID (`tsk_...`). 2102 2103 Returns: 2104 Empty response. HTTP 204 is returned after release is accepted. 2105 """ 2106 self._http.request(f"/api/v1/tasks/{task}/lease", method="DELETE") 2107 2108 def list(self, task: str) -> TaskSessionLeaseSummary | None: 2109 """ 2110 Retrieve a task's current session lease 2111 Returns the authenticated assignee's viewer-safe live lease summary, or null 2112 when no live lease exists. Fencing and opaque session identifiers are never 2113 included. 2114 2115 Args: 2116 task: Task ID (`tsk_...`). 2117 2118 Returns: 2119 Viewer-safe live lease summary, or null. 2120 """ 2121 return self._http.request( 2122 f"/api/v1/tasks/{task}/lease", 2123 response_type=TaskSessionLeaseSummary | None, 2124 ) 2125 2126 def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: 2127 """ 2128 Claim a task for a coding session 2129 Atomically claims a user-assigned task for the authenticated user's coding 2130 session. The caller generates and retains both UUIDs. An exact retry returns 2131 the existing lease without extending it; another live holder produces a 2132 conflict. Developer and server-to-server credentials cannot impersonate the 2133 assigned user. 2134 2135 Args: 2136 task: Task ID (`tsk_...`). 2137 input: Request body. 2138 input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. 2139 input.harness: Bounded harness identifier. 2140 input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. 2141 input.lease_id: Caller-generated lease UUID. 2142 input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers. 2143 input.session_id: Caller-generated coding-session UUID. 2144 input.session_name: Human-readable coding-session label. 2145 2146 Returns: 2147 The caller-held lease, including its fencing token. 2148 """ 2149 return self._http.request( 2150 f"/api/v1/tasks/{task}/lease", 2151 method="POST", 2152 body=input, 2153 response_type=TaskSessionLease, 2154 ) 2155 2156 def renew(self, task: str, input: LeaseRenewInput) -> TaskSessionLease: 2157 """ 2158 Renew a task session lease 2159 Renews the authenticated assignee's matching live task lease. Both 2160 caller-generated UUIDs must match the aggregate's current lease. 2161 2162 Args: 2163 task: Task ID (`tsk_...`). 2164 input: Request body. 2165 input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds. 2166 input.lease_id: Current caller-held lease UUID. 2167 input.session_id: Current coding-session UUID. 2168 2169 Returns: 2170 The renewed caller-held lease. 2171 """ 2172 return self._http.request( 2173 f"/api/v1/tasks/{task}/lease/renew", 2174 method="POST", 2175 body=input, 2176 response_type=TaskSessionLease, 2177 )
2093 def remove(self, task: str) -> None: 2094 """ 2095 Release a task session lease 2096 Releases the authenticated assignee's matching live task lease. Repeating a 2097 release after the lease is absent succeeds. A different live successor lease 2098 returns a mismatch. 2099 2100 Args: 2101 task: Task ID (`tsk_...`). 2102 2103 Returns: 2104 Empty response. HTTP 204 is returned after release is accepted. 2105 """ 2106 self._http.request(f"/api/v1/tasks/{task}/lease", method="DELETE")
Release a task session lease Releases the authenticated assignee's matching live task lease. Repeating a release after the lease is absent succeeds. A different live successor lease returns a mismatch.
Arguments:
- task: Task ID (
tsk_...).
Returns:
Empty response. HTTP 204 is returned after release is accepted.
2108 def list(self, task: str) -> TaskSessionLeaseSummary | None: 2109 """ 2110 Retrieve a task's current session lease 2111 Returns the authenticated assignee's viewer-safe live lease summary, or null 2112 when no live lease exists. Fencing and opaque session identifiers are never 2113 included. 2114 2115 Args: 2116 task: Task ID (`tsk_...`). 2117 2118 Returns: 2119 Viewer-safe live lease summary, or null. 2120 """ 2121 return self._http.request( 2122 f"/api/v1/tasks/{task}/lease", 2123 response_type=TaskSessionLeaseSummary | None, 2124 )
Retrieve a task's current session lease Returns the authenticated assignee's viewer-safe live lease summary, or null when no live lease exists. Fencing and opaque session identifiers are never included.
Arguments:
- task: Task ID (
tsk_...).
Returns:
Viewer-safe live lease summary, or null.
2126 def create(self, task: str, input: LeaseCreateInput) -> TaskSessionLease: 2127 """ 2128 Claim a task for a coding session 2129 Atomically claims a user-assigned task for the authenticated user's coding 2130 session. The caller generates and retains both UUIDs. An exact retry returns 2131 the existing lease without extending it; another live holder produces a 2132 conflict. Developer and server-to-server credentials cannot impersonate the 2133 assigned user. 2134 2135 Args: 2136 task: Task ID (`tsk_...`). 2137 input: Request body. 2138 input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim. 2139 input.harness: Bounded harness identifier. 2140 input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds. 2141 input.lease_id: Caller-generated lease UUID. 2142 input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers. 2143 input.session_id: Caller-generated coding-session UUID. 2144 input.session_name: Human-readable coding-session label. 2145 2146 Returns: 2147 The caller-held lease, including its fencing token. 2148 """ 2149 return self._http.request( 2150 f"/api/v1/tasks/{task}/lease", 2151 method="POST", 2152 body=input, 2153 response_type=TaskSessionLease, 2154 )
Claim a task for a coding session Atomically claims a user-assigned task for the authenticated user's coding session. The caller generates and retains both UUIDs. An exact retry returns the existing lease without extending it; another live holder produces a conflict. Developer and server-to-server credentials cannot impersonate the assigned user.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.force: Take the lease from a live but dead holder instead of returning a conflict. Releases the prior session's lease and claims the new one atomically. Always scoped to the task's assigned owner, same as an ordinary claim.
- input.harness: Bounded harness identifier.
- input.lease_duration_seconds: Requested lease lifetime in seconds; the task aggregate enforces its bounds.
- input.lease_id: Caller-generated lease UUID.
- input.require_ready: Conservatively reject the claim when the current task projection has unfinished blockers.
- input.session_id: Caller-generated coding-session UUID.
- input.session_name: Human-readable coding-session label.
Returns:
The caller-held lease, including its fencing token.
2156 def renew(self, task: str, input: LeaseRenewInput) -> TaskSessionLease: 2157 """ 2158 Renew a task session lease 2159 Renews the authenticated assignee's matching live task lease. Both 2160 caller-generated UUIDs must match the aggregate's current lease. 2161 2162 Args: 2163 task: Task ID (`tsk_...`). 2164 input: Request body. 2165 input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds. 2166 input.lease_id: Current caller-held lease UUID. 2167 input.session_id: Current coding-session UUID. 2168 2169 Returns: 2170 The renewed caller-held lease. 2171 """ 2172 return self._http.request( 2173 f"/api/v1/tasks/{task}/lease/renew", 2174 method="POST", 2175 body=input, 2176 response_type=TaskSessionLease, 2177 )
Renew a task session lease Renews the authenticated assignee's matching live task lease. Both caller-generated UUIDs must match the aggregate's current lease.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.lease_duration_seconds: Requested renewed lifetime in seconds; the task aggregate enforces its bounds.
- input.lease_id: Current caller-held lease UUID.
- input.session_id: Current coding-session UUID.
Returns:
The renewed caller-held lease.
2180class LinkResource: 2181 def __init__(self, http: SyncHttpClient): 2182 self._http = http 2183 2184 def remove(self, task: str) -> None: 2185 """ 2186 Remove an external link from a task 2187 2188 Args: 2189 task: Task ID (`tsk_...`). 2190 2191 Returns: 2192 HTTP 204 on success. 2193 """ 2194 self._http.request(f"/api/v1/tasks/{task}/links", method="DELETE") 2195 2196 def list( 2197 self, 2198 task: str, 2199 *, 2200 team: str | None = None, 2201 user: str | None = None, 2202 agent: str | None = None, 2203 org: str | None = None, 2204 limit: int | None = None, 2205 after_cursor: str | None = None, 2206 ) -> LinkListResponse: 2207 """ 2208 List a task's external links 2209 Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map. 2210 2211 Args: 2212 task: Task ID (`tsk_...`). 2213 team: Explicit owning team for privileged calls. 2214 user: Explicit owning user for privileged calls. 2215 agent: Explicit owning agent for privileged calls. 2216 org: Explicit organization for privileged calls; must agree with owner. 2217 limit: Maximum links to return. Capped at 100. 2218 after_cursor: Opaque cursor returned by the previous page. 2219 2220 Returns: 2221 Successful response 2222 """ 2223 query: dict[str, object] = {} 2224 if team is not None: 2225 query["team"] = team 2226 if user is not None: 2227 query["user"] = user 2228 if agent is not None: 2229 query["agent"] = agent 2230 if org is not None: 2231 query["org"] = org 2232 if limit is not None: 2233 query["limit"] = limit 2234 if after_cursor is not None: 2235 query["after_cursor"] = after_cursor 2236 return self._http.request( 2237 f"/api/v1/tasks/{task}/links", 2238 query=query, 2239 response_type=LinkListResponse, 2240 ) 2241 2242 def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: 2243 """ 2244 Add an external link to a task 2245 Adds an indexed identity without changing the referenced object's ownership or ACL. 2246 For private files, upload with POST /api/v1/files, then pass external_scope=platform, 2247 object_type=file and object_id=fil_.... The reserved platform namespace means the 2248 authenticated current backend/app/sandbox, not a hostname or stored URL. 2249 File attachment requires both task mutation permission and current file read access. 2250 List and reverse lookup omit files that are missing or no longer readable, including 2251 thread-restricted files. Generic identities are not resolved as local files. 2252 GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; 2253 never persist that URL as the link identity. Existing signed URLs remain usable until 2254 their expiry. Task activity and replay may retain opaque file IDs, not file metadata, 2255 and confer no file access. 2256 Retain the upload response's file ID if attachment fails and retry the link request. 2257 Detaching or deleting a task does not delete the file. Deleting a file leaves historical 2258 link events intact; replay does not restore bytes or access. No ACL grant is implicit. 2259 Agent-owned uploads use an authorized human session; agent-only file credentials 2260 remain unsupported. 2261 Download URLs depend on the configured storage provider. The development local 2262 provider returns a local URL prefix plus a storage path, but Platform does not 2263 serve that path over HTTP. Local-provider verification reads bytes from the 2264 running Platform's configured storage directory after authorized metadata reads; 2265 it does not prove HTTP download authorization. Serving local downloads through 2266 an authorization-preserving route is a separate follow-up, not a public /storage 2267 mount. Served providers are verified through their HTTP download URLs. 2268 2269 Args: 2270 task: Task ID (`tsk_...`). 2271 input: Request body. 2272 input.external_scope: External container ID. 2273 input.object_id: External object ID. 2274 input.object_type: External object type. 2275 2276 Returns: 2277 The created external link, with its identity normalized. 2278 """ 2279 return self._http.request( 2280 f"/api/v1/tasks/{task}/links", 2281 method="POST", 2282 body=input, 2283 response_type=TaskExternalLink, 2284 )
2184 def remove(self, task: str) -> None: 2185 """ 2186 Remove an external link from a task 2187 2188 Args: 2189 task: Task ID (`tsk_...`). 2190 2191 Returns: 2192 HTTP 204 on success. 2193 """ 2194 self._http.request(f"/api/v1/tasks/{task}/links", method="DELETE")
Remove an external link from a task
Arguments:
- task: Task ID (
tsk_...).
Returns:
HTTP 204 on success.
2196 def list( 2197 self, 2198 task: str, 2199 *, 2200 team: str | None = None, 2201 user: str | None = None, 2202 agent: str | None = None, 2203 org: str | None = None, 2204 limit: int | None = None, 2205 after_cursor: str | None = None, 2206 ) -> LinkListResponse: 2207 """ 2208 List a task's external links 2209 Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map. 2210 2211 Args: 2212 task: Task ID (`tsk_...`). 2213 team: Explicit owning team for privileged calls. 2214 user: Explicit owning user for privileged calls. 2215 agent: Explicit owning agent for privileged calls. 2216 org: Explicit organization for privileged calls; must agree with owner. 2217 limit: Maximum links to return. Capped at 100. 2218 after_cursor: Opaque cursor returned by the previous page. 2219 2220 Returns: 2221 Successful response 2222 """ 2223 query: dict[str, object] = {} 2224 if team is not None: 2225 query["team"] = team 2226 if user is not None: 2227 query["user"] = user 2228 if agent is not None: 2229 query["agent"] = agent 2230 if org is not None: 2231 query["org"] = org 2232 if limit is not None: 2233 query["limit"] = limit 2234 if after_cursor is not None: 2235 query["after_cursor"] = after_cursor 2236 return self._http.request( 2237 f"/api/v1/tasks/{task}/links", 2238 query=query, 2239 response_type=LinkListResponse, 2240 )
List a task's external links Returns indexed link identities ordered by external_scope, object_type, then object_id ascending. This does not read the legacy Task links map.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team for privileged calls.
- user: Explicit owning user for privileged calls.
- agent: Explicit owning agent for privileged calls.
- org: Explicit organization for privileged calls; must agree with owner.
- limit: Maximum links to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
2242 def create(self, task: str, input: LinkCreateInput) -> TaskExternalLink: 2243 """ 2244 Add an external link to a task 2245 Adds an indexed identity without changing the referenced object's ownership or ACL. 2246 For private files, upload with POST /api/v1/files, then pass external_scope=platform, 2247 object_type=file and object_id=fil_.... The reserved platform namespace means the 2248 authenticated current backend/app/sandbox, not a hostname or stored URL. 2249 File attachment requires both task mutation permission and current file read access. 2250 List and reverse lookup omit files that are missing or no longer readable, including 2251 thread-restricted files. Generic identities are not resolved as local files. 2252 GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; 2253 never persist that URL as the link identity. Existing signed URLs remain usable until 2254 their expiry. Task activity and replay may retain opaque file IDs, not file metadata, 2255 and confer no file access. 2256 Retain the upload response's file ID if attachment fails and retry the link request. 2257 Detaching or deleting a task does not delete the file. Deleting a file leaves historical 2258 link events intact; replay does not restore bytes or access. No ACL grant is implicit. 2259 Agent-owned uploads use an authorized human session; agent-only file credentials 2260 remain unsupported. 2261 Download URLs depend on the configured storage provider. The development local 2262 provider returns a local URL prefix plus a storage path, but Platform does not 2263 serve that path over HTTP. Local-provider verification reads bytes from the 2264 running Platform's configured storage directory after authorized metadata reads; 2265 it does not prove HTTP download authorization. Serving local downloads through 2266 an authorization-preserving route is a separate follow-up, not a public /storage 2267 mount. Served providers are verified through their HTTP download URLs. 2268 2269 Args: 2270 task: Task ID (`tsk_...`). 2271 input: Request body. 2272 input.external_scope: External container ID. 2273 input.object_id: External object ID. 2274 input.object_type: External object type. 2275 2276 Returns: 2277 The created external link, with its identity normalized. 2278 """ 2279 return self._http.request( 2280 f"/api/v1/tasks/{task}/links", 2281 method="POST", 2282 body=input, 2283 response_type=TaskExternalLink, 2284 )
Add an external link to a task Adds an indexed identity without changing the referenced object's ownership or ACL. For private files, upload with POST /api/v1/files, then pass external_scope=platform, object_type=file and object_id=fil_.... The reserved platform namespace means the authenticated current backend/app/sandbox, not a hostname or stored URL. File attachment requires both task mutation permission and current file read access. List and reverse lookup omit files that are missing or no longer readable, including thread-restricted files. Generic identities are not resolved as local files. GET /api/v1/files/:file rechecks permission and returns a fresh expiring download URL; never persist that URL as the link identity. Existing signed URLs remain usable until their expiry. Task activity and replay may retain opaque file IDs, not file metadata, and confer no file access. Retain the upload response's file ID if attachment fails and retry the link request. Detaching or deleting a task does not delete the file. Deleting a file leaves historical link events intact; replay does not restore bytes or access. No ACL grant is implicit. Agent-owned uploads use an authorized human session; agent-only file credentials remain unsupported. Download URLs depend on the configured storage provider. The development local provider returns a local URL prefix plus a storage path, but Platform does not serve that path over HTTP. Local-provider verification reads bytes from the running Platform's configured storage directory after authorized metadata reads; it does not prove HTTP download authorization. Serving local downloads through an authorization-preserving route is a separate follow-up, not a public /storage mount. Served providers are verified through their HTTP download URLs.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.external_scope: External container ID.
- input.object_id: External object ID.
- input.object_type: External object type.
Returns:
The created external link, with its identity normalized.
2287class TaskResource: 2288 def __init__(self, http: SyncHttpClient): 2289 self._http = http 2290 self.blockers = BlockerResource(http) 2291 self.comments = CommentResource(http) 2292 self.lease = LeaseResource(http) 2293 self.links = LinkResource(http) 2294 2295 def delete(self, task: str) -> None: 2296 """ 2297 Delete a task 2298 Deletes a task from task lists and detail views. The task event stream is 2299 retained for auditability, while comments are removed and direct subtasks 2300 are promoted to top-level tasks. 2301 The delete event is accepted before the read model is updated. Clients 2302 should remove the task from local collections immediately; subsequent reads 2303 converge once the projection processes the event. 2304 Authenticated users may delete tasks they can access using their session 2305 identity. App-scoped developer and server-to-server callers must explicitly 2306 supply the task's `org` and owner. `team` or `user` identifies that owner; 2307 when neither is present, `agent` identifies an agent-owned task. With a team 2308 or user owner, `agent` identifies the acting principal. Each reference is 2309 validated before deletion. 2310 2311 Args: 2312 task: Task ID (`tsk_...`). 2313 2314 Returns: 2315 Empty response. HTTP 204 is returned after the delete event is accepted. 2316 """ 2317 self._http.request(f"/api/v1/tasks/{task}", method="DELETE") 2318 2319 def get( 2320 self, 2321 task: str, 2322 *, 2323 team: str | None = None, 2324 user: str | None = None, 2325 agent: str | None = None, 2326 org: str | None = None, 2327 ) -> Task: 2328 """ 2329 Retrieve a task 2330 Returns the full task object for the specified task ID. Authenticated users 2331 and agents resolve access through their session. App-scoped developer and 2332 server-to-server callers explicitly provide the owning `team`, `user`, or `agent` and 2333 `org`. Callers without access receive a 404. 2334 2335 Args: 2336 task: Task ID (`tsk_...`). 2337 team: Explicit owning team (`tem_...`) for privileged calls. 2338 user: Explicit owning user (`usr_...`) for privileged calls. 2339 agent: Explicit owning agent (`agi_...`) for privileged calls. 2340 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2341 2342 Returns: 2343 The requested task. 2344 """ 2345 query: dict[str, object] = {} 2346 if team is not None: 2347 query["team"] = team 2348 if user is not None: 2349 query["user"] = user 2350 if agent is not None: 2351 query["agent"] = agent 2352 if org is not None: 2353 query["org"] = org 2354 return self._http.request(f"/api/v1/tasks/{task}", query=query, response_type=Task) 2355 2356 def replace(self, task: str, input: TaskReplaceInput) -> Task: 2357 """ 2358 Update a task 2359 Updates the supplied fields on a task and returns the complete updated task. 2360 Authenticated users use their session identity. App-scoped developer and 2361 server-to-server callers must explicitly supply the task's `org` and owner. 2362 `team` or `user` identifies that owner; when neither is present, `agent` 2363 identifies an agent-owned task. With a team or user owner, `agent` identifies 2364 the acting principal. Every reference is validated before the update. 2365 A cooperating coding-session client may supply both `lease_id` and 2366 `lease_session_id`. The task aggregate fences that update against the live 2367 lease and records server-sourced session provenance. Omitting both remains a 2368 normal authorized human/API update. 2369 Supply `expected_version` from the latest task representation to make the 2370 update conditional. A concurrent write returns `task_version_conflict`. 2371 2372 Args: 2373 task: Task ID (`tsk_...`). 2374 input: Request body. 2375 input.agent: Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal. 2376 input.description: Updated long-form description. 2377 input.due_date: Updated due date in ISO 8601 format, or null to clear it. 2378 input.epic: Replacement grouping label. Pass null to clear it. 2379 input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. 2380 input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. 2381 input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. 2382 input.links: Replacement related-links object. 2383 input.metadata: Replacement task metadata object. 2384 input.name: Updated display name for the task. 2385 input.org: Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization. 2386 input.owner_agent: Assign to an agent by public ID (`agi_...`). 2387 input.owner_user: Assign to a user by public ID (`usr_...`). 2388 input.parent: Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. 2389 input.priority: Updated priority from 0 (highest) to 4 (lowest). 2390 input.project_id: Project ID (`prj_...`). Omit to preserve; pass null to clear. 2391 input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. 2392 input.source_id: Replacement source object identity. Must be supplied with the other source fields. 2393 input.source_scope: Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. 2394 input.source_type: Replacement source object kind. Must be supplied with the other source fields. 2395 input.status: Updated status: `open`, `in_progress`, `in_review`, or `done`. 2396 input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. 2397 input.target_binary: Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. 2398 input.target_version: Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. 2399 input.team: Explicit owning team (`tem_...`) for a developer or server-to-server call. 2400 input.user: Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. 2401 2402 Returns: 2403 The updated task. 2404 """ 2405 return self._http.request( 2406 f"/api/v1/tasks/{task}", 2407 method="PUT", 2408 body=input, 2409 response_type=Task, 2410 ) 2411 2412 def activity( 2413 self, 2414 task: str, 2415 *, 2416 team: str | None = None, 2417 user: str | None = None, 2418 agent: str | None = None, 2419 org: str | None = None, 2420 limit: int | None = None, 2421 after_cursor: str | None = None, 2422 ) -> TaskActivityResponse: 2423 """ 2424 List a task's activity 2425 Returns a bounded chronological page of activity for the specified task. 2426 App-scoped developer and server-to-server callers explicitly provide the 2427 owning `team`, `user`, or `agent` and `org`. 2428 2429 Args: 2430 task: Task ID (`tsk_...`). 2431 team: Explicit owning team (`tem_...`) for privileged calls. 2432 user: Explicit owning user (`usr_...`) for privileged calls. 2433 agent: Explicit owning agent (`agi_...`) for privileged calls. 2434 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2435 limit: Maximum entries to return. Capped at 100. 2436 after_cursor: Opaque cursor returned by the previous page. 2437 2438 Returns: 2439 Successful response 2440 """ 2441 query: dict[str, object] = {} 2442 if team is not None: 2443 query["team"] = team 2444 if user is not None: 2445 query["user"] = user 2446 if agent is not None: 2447 query["agent"] = agent 2448 if org is not None: 2449 query["org"] = org 2450 if limit is not None: 2451 query["limit"] = limit 2452 if after_cursor is not None: 2453 query["after_cursor"] = after_cursor 2454 return self._http.request( 2455 f"/api/v1/tasks/{task}/activity", 2456 query=query, 2457 response_type=TaskActivityResponse, 2458 ) 2459 2460 def blocking( 2461 self, 2462 task: str, 2463 *, 2464 team: str | None = None, 2465 user: str | None = None, 2466 agent: str | None = None, 2467 org: str | None = None, 2468 limit: int | None = None, 2469 after_cursor: str | None = None, 2470 ) -> TaskBlockingResponse: 2471 """ 2472 List the tasks a task blocks 2473 Returns a bounded page of the tasks that the specified task is marked as 2474 blocking (the inverse of `GET /tasks/{task}/blockers`), newest first. 2475 The task's owner is resolved from the task itself. 2476 2477 Args: 2478 task: Blocking task ID (`tsk_...`). 2479 team: Explicit owning team (`tem_...`) for privileged calls. 2480 user: Explicit owning user (`usr_...`) for privileged calls. 2481 agent: Explicit owning agent (`agi_...`) for privileged calls. 2482 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2483 limit: Maximum tasks to return. Capped at 100. 2484 after_cursor: Opaque cursor returned by the previous page. 2485 2486 Returns: 2487 Successful response 2488 """ 2489 query: dict[str, object] = {} 2490 if team is not None: 2491 query["team"] = team 2492 if user is not None: 2493 query["user"] = user 2494 if agent is not None: 2495 query["agent"] = agent 2496 if org is not None: 2497 query["org"] = org 2498 if limit is not None: 2499 query["limit"] = limit 2500 if after_cursor is not None: 2501 query["after_cursor"] = after_cursor 2502 return self._http.request( 2503 f"/api/v1/tasks/{task}/blocking", 2504 query=query, 2505 response_type=TaskBlockingResponse, 2506 ) 2507 2508 def ownership_conversions( 2509 self, task: str, input: TaskOwnershipConversionsInput 2510 ) -> TaskOwnershipJob: 2511 """ 2512 Convert ownership of a connected task graph 2513 Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. 2514 2515 Args: 2516 task: Root task (`tsk_...`). 2517 input: Request body. 2518 input.dest_agent: Destination agent (`agi_...`). 2519 input.dest_org: Destination organization (`org_...`). 2520 input.dest_team: Destination team (`tem_...`). 2521 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 2522 2523 Returns: 2524 The queued background job. 2525 """ 2526 return self._http.request( 2527 f"/api/v1/tasks/{task}/ownership_conversions", 2528 method="POST", 2529 body=input, 2530 response_type=TaskOwnershipJob, 2531 ) 2532 2533 def subtasks( 2534 self, 2535 task: str, 2536 *, 2537 team: str | None = None, 2538 user: str | None = None, 2539 agent: str | None = None, 2540 org: str | None = None, 2541 limit: int | None = None, 2542 after_cursor: str | None = None, 2543 ) -> TaskSubtasksResponse: 2544 """ 2545 List a task's subtasks 2546 Returns a bounded page of the specified task's subtasks (tasks whose 2547 `parent` is this task), newest first. Subtasks nest exactly one level, so 2548 entries never have subtasks of their own. Privileged callers explicitly 2549 provide the owning `team`, `user`, or `agent` and `org`. 2550 2551 Args: 2552 task: Parent task ID (`tsk_...`). 2553 team: Explicit owning team (`tem_...`) for privileged calls. 2554 user: Explicit owning user (`usr_...`) for privileged calls. 2555 agent: Explicit owning agent (`agi_...`) for privileged calls. 2556 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2557 limit: Maximum subtasks to return. Capped at 100. 2558 after_cursor: Opaque cursor returned by the previous page. 2559 2560 Returns: 2561 Successful response 2562 """ 2563 query: dict[str, object] = {} 2564 if team is not None: 2565 query["team"] = team 2566 if user is not None: 2567 query["user"] = user 2568 if agent is not None: 2569 query["agent"] = agent 2570 if org is not None: 2571 query["org"] = org 2572 if limit is not None: 2573 query["limit"] = limit 2574 if after_cursor is not None: 2575 query["after_cursor"] = after_cursor 2576 return self._http.request( 2577 f"/api/v1/tasks/{task}/subtasks", 2578 query=query, 2579 response_type=TaskSubtasksResponse, 2580 ) 2581 2582 def transfer_ownership(self, task: str, input: TaskTransferOwnershipInput) -> Task: 2583 """ 2584 Transfer one task to a different owner 2585 Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. 2586 2587 Args: 2588 task: Task (`tsk_...`). 2589 input: Request body. 2590 input.dest_agent: Destination agent (`agi_...`). 2591 input.dest_org: Destination organization (`org_...`). 2592 input.dest_team: Destination team (`tem_...`). 2593 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 2594 input.expected_version: The task version reviewed by the caller. 2595 2596 Returns: 2597 The task with its new owner. 2598 """ 2599 return self._http.request( 2600 f"/api/v1/tasks/{task}/transfer_ownership", 2601 method="POST", 2602 body=input, 2603 response_type=Task, 2604 )
2295 def delete(self, task: str) -> None: 2296 """ 2297 Delete a task 2298 Deletes a task from task lists and detail views. The task event stream is 2299 retained for auditability, while comments are removed and direct subtasks 2300 are promoted to top-level tasks. 2301 The delete event is accepted before the read model is updated. Clients 2302 should remove the task from local collections immediately; subsequent reads 2303 converge once the projection processes the event. 2304 Authenticated users may delete tasks they can access using their session 2305 identity. App-scoped developer and server-to-server callers must explicitly 2306 supply the task's `org` and owner. `team` or `user` identifies that owner; 2307 when neither is present, `agent` identifies an agent-owned task. With a team 2308 or user owner, `agent` identifies the acting principal. Each reference is 2309 validated before deletion. 2310 2311 Args: 2312 task: Task ID (`tsk_...`). 2313 2314 Returns: 2315 Empty response. HTTP 204 is returned after the delete event is accepted. 2316 """ 2317 self._http.request(f"/api/v1/tasks/{task}", method="DELETE")
Delete a task
Deletes a task from task lists and detail views. The task event stream is
retained for auditability, while comments are removed and direct subtasks
are promoted to top-level tasks.
The delete event is accepted before the read model is updated. Clients
should remove the task from local collections immediately; subsequent reads
converge once the projection processes the event.
Authenticated users may delete tasks they can access using their session
identity. App-scoped developer and server-to-server callers must explicitly
supply the task's org and owner. team or user identifies that owner;
when neither is present, agent identifies an agent-owned task. With a team
or user owner, agent identifies the acting principal. Each reference is
validated before deletion.
Arguments:
- task: Task ID (
tsk_...).
Returns:
Empty response. HTTP 204 is returned after the delete event is accepted.
2319 def get( 2320 self, 2321 task: str, 2322 *, 2323 team: str | None = None, 2324 user: str | None = None, 2325 agent: str | None = None, 2326 org: str | None = None, 2327 ) -> Task: 2328 """ 2329 Retrieve a task 2330 Returns the full task object for the specified task ID. Authenticated users 2331 and agents resolve access through their session. App-scoped developer and 2332 server-to-server callers explicitly provide the owning `team`, `user`, or `agent` and 2333 `org`. Callers without access receive a 404. 2334 2335 Args: 2336 task: Task ID (`tsk_...`). 2337 team: Explicit owning team (`tem_...`) for privileged calls. 2338 user: Explicit owning user (`usr_...`) for privileged calls. 2339 agent: Explicit owning agent (`agi_...`) for privileged calls. 2340 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2341 2342 Returns: 2343 The requested task. 2344 """ 2345 query: dict[str, object] = {} 2346 if team is not None: 2347 query["team"] = team 2348 if user is not None: 2349 query["user"] = user 2350 if agent is not None: 2351 query["agent"] = agent 2352 if org is not None: 2353 query["org"] = org 2354 return self._http.request(f"/api/v1/tasks/{task}", query=query, response_type=Task)
Retrieve a task
Returns the full task object for the specified task ID. Authenticated users
and agents resolve access through their session. App-scoped developer and
server-to-server callers explicitly provide the owning team, user, or agent and
org. Callers without access receive a 404.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped.
Returns:
The requested task.
2356 def replace(self, task: str, input: TaskReplaceInput) -> Task: 2357 """ 2358 Update a task 2359 Updates the supplied fields on a task and returns the complete updated task. 2360 Authenticated users use their session identity. App-scoped developer and 2361 server-to-server callers must explicitly supply the task's `org` and owner. 2362 `team` or `user` identifies that owner; when neither is present, `agent` 2363 identifies an agent-owned task. With a team or user owner, `agent` identifies 2364 the acting principal. Every reference is validated before the update. 2365 A cooperating coding-session client may supply both `lease_id` and 2366 `lease_session_id`. The task aggregate fences that update against the live 2367 lease and records server-sourced session provenance. Omitting both remains a 2368 normal authorized human/API update. 2369 Supply `expected_version` from the latest task representation to make the 2370 update conditional. A concurrent write returns `task_version_conflict`. 2371 2372 Args: 2373 task: Task ID (`tsk_...`). 2374 input: Request body. 2375 input.agent: Explicit agent (`agi_...`). It is the owner when `team` and `user` are absent; otherwise it is the acting principal. 2376 input.description: Updated long-form description. 2377 input.due_date: Updated due date in ISO 8601 format, or null to clear it. 2378 input.epic: Replacement grouping label. Pass null to clear it. 2379 input.expected_version: Aggregate version returned by the latest task read. The update fails with `task_version_conflict` if the task changed first. 2380 input.lease_id: Current caller-held lease UUID. Must be paired with `lease_session_id`. 2381 input.lease_session_id: Current coding-session UUID. Must be paired with `lease_id`. 2382 input.links: Replacement related-links object. 2383 input.metadata: Replacement task metadata object. 2384 input.name: Updated display name for the task. 2385 input.org: Explicit organization (`org_...`) for a developer or server-to-server call. Pass null for an owner outside an organization. 2386 input.owner_agent: Assign to an agent by public ID (`agi_...`). 2387 input.owner_user: Assign to a user by public ID (`usr_...`). 2388 input.parent: Move this task under a top-level parent (`tsk_...`), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. 2389 input.priority: Updated priority from 0 (highest) to 4 (lowest). 2390 input.project_id: Project ID (`prj_...`). Omit to preserve; pass null to clear. 2391 input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available. 2392 input.source_id: Replacement source object identity. Must be supplied with the other source fields. 2393 input.source_scope: Replacement source container. Pass together with `source_type` and `source_id`, or pass all three as null to clear the source. 2394 input.source_type: Replacement source object kind. Must be supplied with the other source fields. 2395 input.status: Updated status: `open`, `in_progress`, `in_review`, or `done`. 2396 input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags. 2397 input.target_binary: Replacement target binary (for example `my-cli`): a lowercase identifier of 1-64 characters. Pass together with `target_version`, or pass both as null to clear the target. 2398 input.target_version: Replacement minimum semantic version of `target_binary` (for example `0.48.9`). Must be supplied with `target_binary`. 2399 input.team: Explicit owning team (`tem_...`) for a developer or server-to-server call. 2400 input.user: Explicit user (`usr_...`) for a developer or server-to-server call. With `team`, this identifies the acting team member. 2401 2402 Returns: 2403 The updated task. 2404 """ 2405 return self._http.request( 2406 f"/api/v1/tasks/{task}", 2407 method="PUT", 2408 body=input, 2409 response_type=Task, 2410 )
Update a task
Updates the supplied fields on a task and returns the complete updated task.
Authenticated users use their session identity. App-scoped developer and
server-to-server callers must explicitly supply the task's org and owner.
team or user identifies that owner; when neither is present, agent
identifies an agent-owned task. With a team or user owner, agent identifies
the acting principal. Every reference is validated before the update.
A cooperating coding-session client may supply both lease_id and
lease_session_id. The task aggregate fences that update against the live
lease and records server-sourced session provenance. Omitting both remains a
normal authorized human/API update.
Supply expected_version from the latest task representation to make the
update conditional. A concurrent write returns task_version_conflict.
Arguments:
- task: Task ID (
tsk_...). - input: Request body.
- input.agent: Explicit agent (
agi_...). It is the owner whenteamanduserare absent; otherwise it is the acting principal. - input.description: Updated long-form description.
- input.due_date: Updated due date in ISO 8601 format, or null to clear it.
- input.epic: Replacement grouping label. Pass null to clear it.
- input.expected_version: Aggregate version returned by the latest task read. The update fails with
task_version_conflictif the task changed first. - input.lease_id: Current caller-held lease UUID. Must be paired with
lease_session_id. - input.lease_session_id: Current coding-session UUID. Must be paired with
lease_id. - input.links: Replacement related-links object.
- input.metadata: Replacement task metadata object.
- input.name: Updated display name for the task.
- input.org: Explicit organization (
org_...) for a developer or server-to-server call. Pass null for an owner outside an organization. - input.owner_agent: Assign to an agent by public ID (
agi_...). - input.owner_user: Assign to a user by public ID (
usr_...). - input.parent: Move this task under a top-level parent (
tsk_...), or pass null to promote it to a top-level task. A task that has subtasks cannot become one. - input.priority: Updated priority from 0 (highest) to 4 (lowest).
- input.project_id: Project ID (
prj_...). Omit to preserve; pass null to clear. - input.require_status_lease: Session clients must set true for status changes. A live lease then requires the holder's lease_id and lease_session_id; human and host overrides remain available.
- input.source_id: Replacement source object identity. Must be supplied with the other source fields.
- input.source_scope: Replacement source container. Pass together with
source_typeandsource_id, or pass all three as null to clear the source. - input.source_type: Replacement source object kind. Must be supplied with the other source fields.
- input.status: Updated status:
open,in_progress,in_review, ordone. - input.tags: Replacement tag list (max 20, each up to 40 characters; normalized to lowercase). Pass an empty array to clear all tags.
- input.target_binary: Replacement target binary (for example
my-cli): a lowercase identifier of 1-64 characters. Pass together withtarget_version, or pass both as null to clear the target. - input.target_version: Replacement minimum semantic version of
target_binary(for example0.48.9). Must be supplied withtarget_binary. - input.team: Explicit owning team (
tem_...) for a developer or server-to-server call. - input.user: Explicit user (
usr_...) for a developer or server-to-server call. Withteam, this identifies the acting team member.
Returns:
The updated task.
2412 def activity( 2413 self, 2414 task: str, 2415 *, 2416 team: str | None = None, 2417 user: str | None = None, 2418 agent: str | None = None, 2419 org: str | None = None, 2420 limit: int | None = None, 2421 after_cursor: str | None = None, 2422 ) -> TaskActivityResponse: 2423 """ 2424 List a task's activity 2425 Returns a bounded chronological page of activity for the specified task. 2426 App-scoped developer and server-to-server callers explicitly provide the 2427 owning `team`, `user`, or `agent` and `org`. 2428 2429 Args: 2430 task: Task ID (`tsk_...`). 2431 team: Explicit owning team (`tem_...`) for privileged calls. 2432 user: Explicit owning user (`usr_...`) for privileged calls. 2433 agent: Explicit owning agent (`agi_...`) for privileged calls. 2434 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2435 limit: Maximum entries to return. Capped at 100. 2436 after_cursor: Opaque cursor returned by the previous page. 2437 2438 Returns: 2439 Successful response 2440 """ 2441 query: dict[str, object] = {} 2442 if team is not None: 2443 query["team"] = team 2444 if user is not None: 2445 query["user"] = user 2446 if agent is not None: 2447 query["agent"] = agent 2448 if org is not None: 2449 query["org"] = org 2450 if limit is not None: 2451 query["limit"] = limit 2452 if after_cursor is not None: 2453 query["after_cursor"] = after_cursor 2454 return self._http.request( 2455 f"/api/v1/tasks/{task}/activity", 2456 query=query, 2457 response_type=TaskActivityResponse, 2458 )
List a task's activity
Returns a bounded chronological page of activity for the specified task.
App-scoped developer and server-to-server callers explicitly provide the
owning team, user, or agent and org.
Arguments:
- task: Task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum entries to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
2460 def blocking( 2461 self, 2462 task: str, 2463 *, 2464 team: str | None = None, 2465 user: str | None = None, 2466 agent: str | None = None, 2467 org: str | None = None, 2468 limit: int | None = None, 2469 after_cursor: str | None = None, 2470 ) -> TaskBlockingResponse: 2471 """ 2472 List the tasks a task blocks 2473 Returns a bounded page of the tasks that the specified task is marked as 2474 blocking (the inverse of `GET /tasks/{task}/blockers`), newest first. 2475 The task's owner is resolved from the task itself. 2476 2477 Args: 2478 task: Blocking task ID (`tsk_...`). 2479 team: Explicit owning team (`tem_...`) for privileged calls. 2480 user: Explicit owning user (`usr_...`) for privileged calls. 2481 agent: Explicit owning agent (`agi_...`) for privileged calls. 2482 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2483 limit: Maximum tasks to return. Capped at 100. 2484 after_cursor: Opaque cursor returned by the previous page. 2485 2486 Returns: 2487 Successful response 2488 """ 2489 query: dict[str, object] = {} 2490 if team is not None: 2491 query["team"] = team 2492 if user is not None: 2493 query["user"] = user 2494 if agent is not None: 2495 query["agent"] = agent 2496 if org is not None: 2497 query["org"] = org 2498 if limit is not None: 2499 query["limit"] = limit 2500 if after_cursor is not None: 2501 query["after_cursor"] = after_cursor 2502 return self._http.request( 2503 f"/api/v1/tasks/{task}/blocking", 2504 query=query, 2505 response_type=TaskBlockingResponse, 2506 )
List the tasks a task blocks
Returns a bounded page of the tasks that the specified task is marked as
blocking (the inverse of GET /tasks/{task}/blockers), newest first.
The task's owner is resolved from the task itself.
Arguments:
- task: Blocking task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum tasks to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
2508 def ownership_conversions( 2509 self, task: str, input: TaskOwnershipConversionsInput 2510 ) -> TaskOwnershipJob: 2511 """ 2512 Convert ownership of a connected task graph 2513 Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers. 2514 2515 Args: 2516 task: Root task (`tsk_...`). 2517 input: Request body. 2518 input.dest_agent: Destination agent (`agi_...`). 2519 input.dest_org: Destination organization (`org_...`). 2520 input.dest_team: Destination team (`tem_...`). 2521 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 2522 2523 Returns: 2524 The queued background job. 2525 """ 2526 return self._http.request( 2527 f"/api/v1/tasks/{task}/ownership_conversions", 2528 method="POST", 2529 body=input, 2530 response_type=TaskOwnershipJob, 2531 )
Convert ownership of a connected task graph Queues ownership changes for the connected task graph across parent, child, blocker, and blocking relationships. The selected tasks and their versions are frozen when queued. Each transfer checks the requesting user s current authority; conflicts fail the job without undoing completed transfers.
Arguments:
- task: Root task (
tsk_...). - input: Request body.
- input.dest_agent: Destination agent (
agi_...). - input.dest_org: Destination organization (
org_...). - input.dest_team: Destination team (
tem_...). - input.dest_user: Destination user (
usr_...). Supply exactly one destination.
Returns:
The queued background job.
2533 def subtasks( 2534 self, 2535 task: str, 2536 *, 2537 team: str | None = None, 2538 user: str | None = None, 2539 agent: str | None = None, 2540 org: str | None = None, 2541 limit: int | None = None, 2542 after_cursor: str | None = None, 2543 ) -> TaskSubtasksResponse: 2544 """ 2545 List a task's subtasks 2546 Returns a bounded page of the specified task's subtasks (tasks whose 2547 `parent` is this task), newest first. Subtasks nest exactly one level, so 2548 entries never have subtasks of their own. Privileged callers explicitly 2549 provide the owning `team`, `user`, or `agent` and `org`. 2550 2551 Args: 2552 task: Parent task ID (`tsk_...`). 2553 team: Explicit owning team (`tem_...`) for privileged calls. 2554 user: Explicit owning user (`usr_...`) for privileged calls. 2555 agent: Explicit owning agent (`agi_...`) for privileged calls. 2556 org: Explicit organization (`org_...`) for privileged calls; pass null when unscoped. 2557 limit: Maximum subtasks to return. Capped at 100. 2558 after_cursor: Opaque cursor returned by the previous page. 2559 2560 Returns: 2561 Successful response 2562 """ 2563 query: dict[str, object] = {} 2564 if team is not None: 2565 query["team"] = team 2566 if user is not None: 2567 query["user"] = user 2568 if agent is not None: 2569 query["agent"] = agent 2570 if org is not None: 2571 query["org"] = org 2572 if limit is not None: 2573 query["limit"] = limit 2574 if after_cursor is not None: 2575 query["after_cursor"] = after_cursor 2576 return self._http.request( 2577 f"/api/v1/tasks/{task}/subtasks", 2578 query=query, 2579 response_type=TaskSubtasksResponse, 2580 )
List a task's subtasks
Returns a bounded page of the specified task's subtasks (tasks whose
parent is this task), newest first. Subtasks nest exactly one level, so
entries never have subtasks of their own. Privileged callers explicitly
provide the owning team, user, or agent and org.
Arguments:
- task: Parent task ID (
tsk_...). - team: Explicit owning team (
tem_...) for privileged calls. - user: Explicit owning user (
usr_...) for privileged calls. - agent: Explicit owning agent (
agi_...) for privileged calls. - org: Explicit organization (
org_...) for privileged calls; pass null when unscoped. - limit: Maximum subtasks to return. Capped at 100.
- after_cursor: Opaque cursor returned by the previous page.
Returns:
Successful response
2582 def transfer_ownership(self, task: str, input: TaskTransferOwnershipInput) -> Task: 2583 """ 2584 Transfer one task to a different owner 2585 Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes. 2586 2587 Args: 2588 task: Task (`tsk_...`). 2589 input: Request body. 2590 input.dest_agent: Destination agent (`agi_...`). 2591 input.dest_org: Destination organization (`org_...`). 2592 input.dest_team: Destination team (`tem_...`). 2593 input.dest_user: Destination user (`usr_...`). Supply exactly one destination. 2594 input.expected_version: The task version reviewed by the caller. 2595 2596 Returns: 2597 The task with its new owner. 2598 """ 2599 return self._http.request( 2600 f"/api/v1/tasks/{task}/transfer_ownership", 2601 method="POST", 2602 body=input, 2603 response_type=Task, 2604 )
Transfer one task to a different owner Changes one task s privacy owner at the supplied aggregate version. Assignment, creator, source identity, comments, and relationship IDs remain unchanged. Source and destination must have the same app and sandbox; the authenticated user must have authority over both scopes.
Arguments:
- task: Task (
tsk_...). - input: Request body.
- input.dest_agent: Destination agent (
agi_...). - input.dest_org: Destination organization (
org_...). - input.dest_team: Destination team (
tem_...). - input.dest_user: Destination user (
usr_...). Supply exactly one destination. - input.expected_version: The task version reviewed by the caller.
Returns:
The task with its new owner.