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

# Հոսքային պատասխան

> Ստացեք պատասխանը թոքեն առ թոքեն՝ server-sent events-ի միջոցով:

`POST /v1/agents/{agent_id}/chat/stream`-ն ընդունում է ճիշտ նույն հարցումը, ինչ համաժամանակյա չատ-էնդփոինթը. նույն մարմին, նույն `Authorization` և `Idempotency-Key` վերնագրեր, նույն `full` թույլտվություն, խոսակցությունների նույն կանոններ, նույն վճարում և սխալի կոդեր: Տարբերվում է միայն փոխադրումը. պատասխանը `text/event-stream` է:

## Իրադարձություններ

Յուրաքանչյուր իրադարձություն ունի անուն և կրում է մեկ JSON `data` տող:

| Իրադարձություն               | Տվյալներ                                                                        | Երբ                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `response.created`           | `{"request_id", "conversation_id"}`                                             | Հենց որ խոսակցությունը որոշված է                                                    |
| `response.output_text.delta` | `{"delta": "..."}`                                                              | Պատասխանի տեքստի յուրաքանչյուր հատվածի համար, երբ մոդելը ստեղծում է այն; կրկնվում է |
| `response.completed`         | Չատի ամբողջական պատասխանը (`request_id`, `conversation_id`, `message`, `usage`) | Միշտ հաջողված հոսքի վերջին իրադարձությունը                                          |
| `error`                      | `{"code", "message", "request_id"}`                                             | Միշտ ձախողված հոսքի վերջին իրադարձությունը                                          |

```text theme={null}
event: response.created
data: {"request_id":"7f20a5f0-...","conversation_id":"1c2e..."}

event: response.output_text.delta
data: {"delta":"The basic"}

event: response.output_text.delta
data: {"delta":" plan is $19 per month."}

event: response.completed
data: {"request_id":"7f20a5f0-...","conversation_id":"1c2e...","message":{"id":"66e0...","role":"assistant","content":"The basic plan is $19 per month.","created_at":"2026-09-13T12:00:00Z"},"usage":{"prompt_tokens":120,"completion_tokens":45,"total_tokens":165,"charged_usd":"0.00123400"}}
```

<Note>
  Դատողությունների տեքստը և գործիքների գործունեությունը երբեք հոսքի մաս չեն: `response.completed`-ը միշտ կրում է ամբողջական վերջնական տեքստը, ուստի հաճախորդը, որը բաց է թողել որոշ դելտաներ, կարող է վերականգնվել դրանից, այլ ոչ թե միացված դելտաներից:
</Note>

## Սխալները հոսքում

Հոսքի հաստատումից **առաջ** տեղի ունեցող ձախողումները (անվավեր բանալի, վավերացում, `idempotency_conflict`, `conversation_busy`, անջատված գործակալ, հարցումների սահմանաչափ) սովորական JSON [սխալի ծրարներ](/am/guides/errors) են՝ իրենց HTTP կարգավիճակով; ստուգեք `response.ok`-ը նախքան իրադարձությունները կարդալը:

Երբ վերնագրերն ուղարկված են, կարգավիճակն արդեն `200` է: Այդ պահից հետո ձախողումը (օրինակ՝ `insufficient_balance` կամ `internal_error`) գալիս է որպես `error` իրադարձություն՝ ծրարի նույն դաշտերով, և փակում է հոսքը:

## Անջատումներ և կրկնություններ

Կապն ընդհատած հաճախորդը պատասխանը չի կանգնեցնում. այն դեռ ստեղծվում և պահվում է, և իդեմպոտենտության գրառումն ավարտվում է: Նույն `Idempotency-Key`-ով կրկնությունը հոսքով ուղարկում է `response.created`, որին անմիջապես հաջորդում է `response.completed`՝ պահված արդյունքով; դելտաները չեն վերարտադրվում: Տե՛ս [Իդեմպոտենտություն](/am/guides/idempotency):

## Օրինակներ

<CodeGroup>
  ```bash curl theme={null}
  curl -N -X POST "$CHATTLER_BASE_URL/v1/agents/$CHATTLER_AGENT_ID/chat/stream" \
    -H "Authorization: Bearer $CHATTLER_API_KEY" \
    -H "Idempotency-Key: $(uuidgen)" \
    -H "Content-Type: application/json" \
    -d '{"external_user_id": "customer-123", "message": "Tell me more"}'
  ```

  ```python Python theme={null}
  import json
  import os
  import uuid

  import httpx


  def stream_chat(external_user_id: str, message: str) -> dict:
      url = f"{os.environ['CHATTLER_BASE_URL']}/v1/agents/{os.environ['CHATTLER_AGENT_ID']}/chat/stream"
      headers = {
          "Authorization": f"Bearer {os.environ['CHATTLER_API_KEY']}",
          "Idempotency-Key": str(uuid.uuid4()),
      }
      with httpx.stream("POST", url, headers=headers, timeout=120,
                        json={"external_user_id": external_user_id, "message": message}) as response:
          if response.status_code >= 400:
              response.read()
              raise RuntimeError(response.json()["error"])
          event, completed = None, None
          for line in response.iter_lines():
              if line.startswith("event: "):
                  event = line[len("event: "):]
              elif line.startswith("data: "):
                  data = json.loads(line[len("data: "):])
                  if event == "response.output_text.delta":
                      print(data["delta"], end="", flush=True)
                  elif event == "response.completed":
                      completed = data
                  elif event == "error":
                      raise RuntimeError(f"{data['code']}: {data['message']}")
              elif line == "":
                  event = None
          return completed


  stream_chat("customer-123", "Tell me more")
  ```

  ```javascript Node theme={null}
  const baseUrl = process.env.CHATTLER_BASE_URL;
  const agentId = process.env.CHATTLER_AGENT_ID;
  const apiKey = process.env.CHATTLER_API_KEY;

  async function streamChat(externalUserId, message, onDelta) {
    const response = await fetch(`${baseUrl}/v1/agents/${agentId}/chat/stream`, {
      method: "POST",
      headers: {
        Authorization: `Bearer ${apiKey}`,
        "Idempotency-Key": crypto.randomUUID(),
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ external_user_id: externalUserId, message }),
    });
    if (!response.ok) {
      const body = await response.json();
      throw new Error(`${body.error.code}: ${body.error.message}`);
    }
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = "";
    let completed = null;
    for (;;) {
      const { value, done } = await reader.read();
      if (done) break;
      buffer += decoder.decode(value, { stream: true });
      let boundary;
      while ((boundary = buffer.indexOf("\n\n")) >= 0) {
        const frame = buffer.slice(0, boundary);
        buffer = buffer.slice(boundary + 2);
        const event = frame.match(/^event: (.+)$/m)?.[1];
        const data = JSON.parse(frame.match(/^data: (.+)$/m)?.[1] ?? "{}");
        if (event === "response.output_text.delta") onDelta(data.delta);
        else if (event === "response.completed") completed = data;
        else if (event === "error") throw new Error(`${data.code}: ${data.message}`);
      }
    }
    return completed;
  }

  const result = await streamChat("customer-123", "Tell me more", (t) => process.stdout.write(t));
  console.log("\n", result.usage);
  ```
</CodeGroup>

<Tip>
  Օգտագործեք `curl -N` (առանց բուֆերացման)՝ իրադարձությունները ժամանելուն պես տեսնելու համար: Բրաուզերներում `EventSource`-ը չի կարող ուղարկել `POST` մարմիններ կամ սովորական վերնագրեր, և բանալին ամեն դեպքում երբեք չպետք է հասնի բրաուզեր; հոսքն ստացեք ձեր սեփական սերվերից և տեքստը փոխանցեք հաճախորդին:
</Tip>
