> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aion.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Thread

> Fluent thread surface for LangGraph messaging integrations.

This page describes the `Thread` type from `aion-authoring-langgraph`.

The `Thread` object is the main fluent surface for replying, posting, and
emitting streaming intents without forcing authors to build raw A2A messages by
hand.

## Properties

| Property               | Purpose                                                                |
| ---------------------- | ---------------------------------------------------------------------- |
| `context_id`           | Current messaging thread or context identifier                         |
| `parent_context_id`    | Parent thread or context identifier when one exists                    |
| `network`              | Originating network or distribution identifier                         |
| `default_reply_target` | Canonical reply target derived from the inbound event                  |
| `message`              | Normalized inbound `Message`, or `None` when no inbound message exists |

## Methods

| Method                                         | Purpose                                                      |
| ---------------------------------------------- | ------------------------------------------------------------ |
| `from_context(context)`                        | Class method. Create a `Thread` from an `AionRuntimeContext` |
| `reply(content, *, metadata=None)`             | Add a durable reply to the current thread                    |
| `post(content, *, target=None, metadata=None)` | Create an explicit outbound post action                      |
| `history(limit=20, offset=None)`               | Not implemented yet; currently returns an empty list         |
| `typing(content, *, metadata=None)`            | Emit a stream-only typing or progress intent                 |

`reply(...)` and `post(...)` accept the same content categories:

* plain text (`str`)
* `AIMessage` or `AIMessageChunk`
* async iterator of `str` or `AIMessageChunk` for streaming replies
* a [`Card`](/sdk/python/messaging/card) object — provider-neutral card document
* an `a2a.types.Artifact` built with [`url_artifact`, `file_artifact`, or `data_artifact`](/sdk/python/messaging/artifacts)

## `reply(...)`

`reply(...)` is intended for the most common case: answer in the same place
the inbound message arrived.

```python theme={null}
from langchain_core.messages import AIMessage, AIMessageChunk
from langgraph.runtime import Runtime

from aion.core.a2a import data_artifact, file_artifact, url_artifact
from aion.core.agent.invocation.card import Card, Text
from aion.core.runtime import AionRuntimeContext
from aion.langgraph.authoring import Thread


async def node(state: State, runtime: Runtime[AionRuntimeContext]) -> dict:
    thread = Thread.from_context(runtime.context)

    # Plain text
    await thread.reply("Thanks. I'm looking into that now.")

    # LangChain message types
    await thread.reply(AIMessage(content="Done."))
    await thread.reply(AIMessageChunk(content="Streaming chunk..."))

    # Async iterator — streamed live, accumulated as a durable reply
    async def generate():
        for word in ["Processing", " your", " request..."]:
            yield word

    await thread.reply(generate())

    # Card — see /sdk/python/messaging/card for all creation modes
    await thread.reply(Card("Report ready").add(Text("All checks passed.")))

    # Artifacts — see /sdk/python/messaging/artifacts for the full reference
    await thread.reply(url_artifact("https://example.com/report.pdf", mime_type="application/pdf", name="report"))
    await thread.reply(file_artifact(pdf_bytes, mime_type="application/pdf", name="report"))
    await thread.reply(data_artifact({"score": 0.95}, name="result"))

    return {}
```

## `post(...)`

`post(...)` is intended for explicit outbound actions that should remain
distinct from the default reply target.

```python theme={null}
async def node(state: State, runtime: Runtime[AionRuntimeContext]) -> dict:
    thread = Thread.from_context(runtime.context)
    await thread.post("Posting a follow-up note to a different channel.")
    return {}
```

Unlike `reply(...)`, `post(...)` should remain explicit in the response buffer
so cross-target delivery is never inferred from transcript order alone.

## `history(...)`

`history(...)` is reserved for asking the control plane for more context than
was included on the inbound turn.

```python theme={null}
async def node(state: State, runtime: Runtime[AionRuntimeContext]) -> dict:
    thread = Thread.from_context(runtime.context)
    recent = await thread.history(limit=5)
    return {}
```

<Note>
  `history()` is not implemented yet and currently returns an empty list.
</Note>

## `typing(...)`

`typing(content, *, metadata=None)` is intended for stream-only live intents.
`content` is a required string — the transient text shown to the user while the
agent is working.

```python theme={null}
async def node(state: State, runtime: Runtime[AionRuntimeContext]) -> dict:
    thread = Thread.from_context(runtime.context)
    await thread.typing("Thinking...")
    return {}
```

These intents should not replace the durable response precedence. They are
best-effort live hints for streaming views.

## Related Pages

* [Card](/sdk/python/messaging/card)
* [Artifact Builders](/sdk/python/messaging/artifacts)
* [AionRuntimeContext](/sdk/langgraph/api/runtime-context)
* [Message](/sdk/langgraph/api/message)
* [LangGraph Streaming API](/sdk/langgraph/streaming-api)
