{
  "schemaVersion": "1.0",
  "title": "Hermes chat and Responses capabilities",
  "description": "Use these six endpoint-qualified capabilities to run a Hermes model turn, stream it, continue a Responses chain, read a stored response, or delete that stored response. They are for applications using a Hermes endpoint already admitted to t",
  "canonical": "https://getaip.org/docs/connectors/hermes-agent/capabilities/chat-and-responses",
  "route": "/docs/connectors/hermes-agent/capabilities/chat-and-responses",
  "source": "docs/connectors/hermes-agent/capabilities/chat-and-responses.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/hermes-agent/capabilities/chat-and-responses.md",
    "txt": "/docs/download/connectors/hermes-agent/capabilities/chat-and-responses.txt",
    "json": "/docs/download/connectors/hermes-agent/capabilities/chat-and-responses.json",
    "pdf": "/docs/download/connectors/hermes-agent/capabilities/chat-and-responses.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Hermes chat and Responses capabilities\ndescription: >-\n  Run conversational model work, preserve the intended continuity boundary,\n  and manage stored Responses objects without unsafe replay\nkind: capability-reference\naudience: application-developer\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: hermes-agent\ncapabilityIds:\n  - cap:hermes_agent:<endpoint_id>:chat\n  - cap:hermes_agent:<endpoint_id>:chat_stream\n  - cap:hermes_agent:<endpoint_id>:responses\n  - cap:hermes_agent:<endpoint_id>:responses_stream\n  - cap:hermes_agent:<endpoint_id>:response_get\n  - cap:hermes_agent:<endpoint_id>:response_delete\n---\n\n# Hermes chat and Responses capabilities\n\nUse these six endpoint-qualified capabilities to run a Hermes model turn,\nstream it, continue a Responses chain, read a stored response, or delete that\nstored response. They are for applications using a Hermes endpoint already\nadmitted to the tenant's AIP catalogue.\n\nChat and Responses calls can run tools and create external effects. They are\nnot read-only text generation, and an interrupted call is not safe to replay\nblindly. This page covers non-streaming request, result, continuity, storage, and\nretry behavior. The later streaming guide and cursor reference cover individual\nSSE events, truncation, publication, and cancellation.\n\n## Operations\n\nReplace `<endpoint_id>` with the normalized endpoint ID present in AIP\ndiscovery.\n\n| Operation | Provider request | Risk | Approval | Key | Retry | Stability |\n|---|---|---|---|---|---|---|\n| `chat` | `POST /v1/chat/completions` | Medium | No | Optional | Unsafe | Stable |\n| `chat_stream` | `POST /v1/chat/completions` | Medium | No | Optional | Unsafe | Stable |\n| `responses` | `POST /v1/responses` | Medium | No | Optional | Unsafe | Stable |\n| `responses_stream` | `POST /v1/responses` | Medium | No | Optional | Unsafe | Stable |\n| `response_get` | `GET /v1/responses/{response_id}` | Low | No | Optional | Safe | Experimental |\n| `response_delete` | `DELETE /v1/responses/{response_id}` | High | Yes | Required | Unsafe | Experimental |\n\nAll six are AIP Agent capabilities and require the selected endpoint's Bearer\ntoken. The endpoint comes from the capability ID. Input cannot select a\ndifferent endpoint or provider URL.\n\n## Choose chat or Responses\n\n| Need | Use | Continuity owner | Result |\n|---|---|---|---|\n| Submit OpenAI-compatible messages for one turn | `chat` or `chat_stream` | Explicit Hermes `session_id`, optional long-term-memory `session_key`, or supplied message history | Chat completion object or stream aggregate |\n| Continue work by a stored response ID | `responses` or `responses_stream` | `previous_response_id` in the Hermes response store | Responses object or stream aggregate |\n| Continue work by an application name | `responses` or `responses_stream` | `conversation` mapped to the latest stored response | Responses object or stream aggregate |\n| Supply all prior history yourself | `responses` or `responses_stream` | `conversation_history` in the current request | Responses object or stream aggregate |\n| Inspect or remove one stored Responses object | `response_get` or `response_delete` | `response_id` returned by a stored Responses call | Stored public object or deletion receipt |\n\nUse the durable-runs capabilities when an application needs a pollable run,\nstructured lifecycle events, or an approval continuation. Use the session\ncapabilities when the application needs an addressable persistent session\nresource. Neither lifecycle is created merely by calling `chat`.\n\n## Shared AIP contract\n\nThe four model-executing operations publish these values:\n\n| Contract field | Published value |\n|---|---|\n| Side effects | `read`, `write`, `send_message`, `external_network` |\n| Data | Confidential; contains PII; redaction required |\n| Transaction | None |\n| Compensation | Rollback not supported |\n| Expected latency | 5000 ms (5 s) for non-streaming; 30000 ms (30 s) for streaming |\n| AIP contract timeout | 60000 ms (60 s) for non-streaming; 300000 ms (300 s) for streaming |\n| Maximum queue-delay hint | 10000 ms (10 s) |\n| Availability target | `99.9%`, declared but not observed by this page |\n\nEvery operation supports synchronous execution. The two stream operations also\nadvertise async, streaming, and cancellation support, with streaming expected\ncompletion. `async_expected` remains false for both. The non-streaming\noperations do not advertise async, streaming, cancellation, or connector\nretry.\n\n`response_get` publishes `read` and `external_network` side effects. It is the\nonly retry-supported operation in this family. `response_delete` publishes\n`read`, `delete`, and `external_network`, requires tenant-policy approval, and\nhas no rollback.\n\n## Submit a chat request\n\nThe published AIP schema selects exactly one input branch:\n\n- `prompt`: one non-empty user prompt;\n- `query`: an alias for `prompt`; or\n- `messages`: one non-empty OpenAI-compatible message array.\n\nUse only one branch. The connector's defensive runtime parser gives a non-empty\n`messages` array precedence, then `prompt`, then `query`, but normal AIP schema\nvalidation rejects an input that satisfies more than one `oneOf` branch.\n\nThe connector builds a `messages` array from `prompt` or `query`, defaults\n`model` to `hermes-agent`, and forces `stream` to match the selected capability.\nIt accepts these additional typed fields:\n\n| Field | Purpose or constraint |\n|---|---|\n| `model` | Hermes model alias; defaults to `hermes-agent` |\n| `session_id` | Hermes transcript continuity; at most 256 characters; sent as `X-Hermes-Session-Id` |\n| `session_key` | Long-term-memory scope; at most 256 characters; sent as `X-Hermes-Session-Key` |\n| `temperature`, `top_p` | Numeric sampling controls; the AIP schema adds no range |\n| `max_tokens` | Non-negative integer in the typed connector request |\n| `stop` | OpenAI-compatible stop value |\n| `tools`, `tool_choice` | OpenAI-compatible tool declarations and selection |\n| `response_format` | OpenAI-compatible response-format value |\n| `user` | Application-supplied user identifier |\n| `metadata` | Application metadata object |\n\nUnknown fields are accepted and forwarded for provider compatibility. Do not\nput credentials or trusted AIP identity claims in those fields. The connector\nremoves `session_id`, `session_key`, and `idempotency_key` from the provider\nJSON body because they belong to headers. Trusted AIP execution overwrites the\nheader idempotency value with `Action.idempotency_key`.\n\nA bounded non-streaming input can look like this:\n\n```json\n{\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Answer with a short operational summary.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"Summarize the current incident notes.\"\n    }\n  ],\n  \"model\": \"hermes-agent\",\n  \"temperature\": 0.2,\n  \"session_id\": \"incident-review-2030-01\",\n  \"session_key\": \"support:incident-review\"\n}\n```\n\nHermes concatenates `system` messages into an ephemeral system prompt. The\npinned handler takes the final supported `user` or `assistant` message as the\ncurrent agent input without checking that its role is `user`. End every request\nwith a visible `user` message. Earlier supported messages become history, and\nother roles do not enter this chat history path.\n\nWhen `session_id` is present, Hermes attempts to load that transcript's history\nfrom its session database instead of using the earlier messages in the request.\nSupply a stable explicit ID from the first turn when the application owns\ncontinuity.\n\nIf `session_id` is absent, Hermes derives an ID and returns it only in an HTTP\nheader. The current connector returns the JSON body, not provider response\nheaders.\n\nIf the session database is unavailable, the handler can continue with the\nrequest history. If history loading raises an error, it logs the failure and\ncontinues with empty history. A successful chat result therefore does not by\nitself prove that an earlier transcript was loaded.\n\n## Read a chat result\n\nA successful non-streaming result follows the chat-completion shape:\n\n```json\n{\n  \"id\": \"chatcmpl-0123456789abcdef0123456789abc\",\n  \"object\": \"chat.completion\",\n  \"created\": 1893456000,\n  \"model\": \"hermes-agent\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"The incident is contained and verification is pending.\"\n      },\n      \"finish_reason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompt_tokens\": 120,\n    \"completion_tokens\": 11,\n    \"total_tokens\": 131\n  }\n}\n```\n\nRead `choices[0].message.content`, but also inspect `finish_reason`. When Hermes\nhas usable partial text, it can return HTTP 200 with `finish_reason` set to\n`length` or `error` and an additional `hermes` object describing completion,\npartial, failed, and redacted error state. A failed or partial run with no\nusable text returns an OpenAI-style error with HTTP 502.\n\n## Submit a Responses request\n\nUse a top-level `body` object for the provider request. Keep connector control\nfields beside it so they become headers rather than provider JSON:\n\n```json\n{\n  \"body\": {\n    \"model\": \"hermes-agent\",\n    \"input\": \"Summarize the current incident notes.\",\n    \"instructions\": \"Return three concise findings.\",\n    \"store\": true,\n    \"truncation\": \"auto\"\n  },\n  \"session_key\": \"support:incident-review\"\n}\n```\n\nSet `Action.idempotency_key` as a sibling of `Action.input`. Do not create a\nsecond business key inside the provider body. During trusted execution, the\nconnector sends the action key as `Idempotency-Key` and forces `stream` to\n`false` or `true` for the selected capability.\n\nThe AIP schema is intentionally open for forward-compatible Responses fields,\nbut the pinned Hermes provider requires `input`. It accepts a string or an\narray of strings or message objects. These continuity rules then apply:\n\n| Field | Behavior |\n|---|---|\n| `previous_response_id` | Loads retained history, session ID, and prior instructions when new instructions are absent |\n| `conversation` | Resolves an application name to its latest stored response; a missing name starts a new chain |\n| `conversation_history` | A non-empty array supplies explicit history and takes precedence over `previous_response_id` |\n| `store` | Defaults to `true`; controls response storage and future lookup or chaining |\n| `truncation` | `auto` keeps the newest 100 history messages; omission keeps the full retained history |\n\n`conversation` and `previous_response_id` cannot appear together. An explicit\n`conversation_history` must be an array whose entries contain `role` and\n`content`. The last normalized item in `input` becomes the current agent input;\npreceding items join the history. End an input array with a visible `user` item\nbecause the handler does not require that role on the last item.\n\n## Read and delete stored responses\n\nA non-streaming Responses result contains the current turn's public output:\n\n```json\n{\n  \"id\": \"resp_0123456789abcdef0123456789ab\",\n  \"object\": \"response\",\n  \"status\": \"completed\",\n  \"created_at\": 1893456000,\n  \"model\": \"hermes-agent\",\n  \"output\": [\n    {\n      \"type\": \"message\",\n      \"role\": \"assistant\",\n      \"content\": [\n        {\n          \"type\": \"output_text\",\n          \"text\": \"Three findings are ready for review.\"\n        }\n      ]\n    }\n  ],\n  \"usage\": {\n    \"input_tokens\": 120,\n    \"output_tokens\": 11,\n    \"total_tokens\": 131\n  }\n}\n```\n\nWhen `store` is `true`, pass its ID to either focused capability:\n\n```json\n{\n  \"response_id\": \"resp_0123456789abcdef0123456789ab\"\n}\n```\n\n`response_get` returns the stored public response object. It does not return\nthe internal conversation history. `response_delete` removes the stored record\nand any conversation-name pointer that currently refers to it, then returns:\n\n```json\n{\n  \"id\": \"resp_0123456789abcdef0123456789ab\",\n  \"object\": \"response\",\n  \"deleted\": true\n}\n```\n\nDeletion does not undo model calls, tool effects, long-term memory, or session\nhistory. It has no compensation capability. Complete its tenant-policy AIP\napproval and use a required capability-scoped idempotency key before invocation.\nThe approval record has a 900000 ms (15-minute) policy TTL and requires a\nreason, an input snapshot, and the policy decision as evidence.\n\nThe provider DELETE handler does not implement its own idempotent replay. The\npublished 86400000 ms (24-hour) contract and original-result replay belong to\nthe AIP runtime boundary; their durability depends on the runtime idempotency\nbackend.\n\nThe connector rejects an empty response ID and percent-encodes the value as one\nprovider path segment. A response created with `store: false` still has an ID,\nbut later GET, deletion, `previous_response_id`, and conversation lookup cannot\nresolve it.\n\nThis family has no response-list operation. If an interrupted creation never\nreturned its `response_id`, do not invent a path or replay the model request.\nRead the original AIP action result and escalate an unresolved provider outcome.\n\n## Understand response retention\n\nHermes stores at most 100 Responses objects by default. The store uses\nleast-recently-used eviction, and a successful GET refreshes the access time.\nIt has no time-based expiry. Eviction and deletion also clear a conversation\npointer that names the removed response.\n\nThe normal store is a SQLite database under `HERMES_HOME` and can survive a\ngateway restart. Hermes attempts to set the database and existing SQLite\nsidecars to owner-only mode `0600`. Permission-change failure does not stop\nstartup, so verify the effective filesystem mode.\n\nIf Hermes cannot open the file, it falls back to in-memory SQLite; that fallback\nis lost at restart. AIP does not add cross-instance replication or guarantee\nthat a later request reaches the same response database.\n\nThe database contains full conversation history, including tool payloads and\nresults, even though `response_get` exposes only the public response object.\nProtect the Hermes home directory as confidential application state.\n\n## Keep continuity identifiers separate\n\n| Identifier | Owner | Purpose |\n|---|---|---|\n| AIP action ID | AIP application and runtime | Identifies one governed invocation and its durable result |\n| AIP session ID | AIP envelope and runtime | Groups native protocol messages and actions |\n| Hermes `session_id` | Chat input and Hermes session database | Continues a chat transcript |\n| Hermes `session_key` | Application and Hermes memory layer | Scopes long-term memory across transcripts |\n| `response_id` | Hermes Responses store | Retrieves or chains one stored Responses object |\n| `conversation` | Application and Hermes Responses store | Names the latest stored response in one chain |\n\nThe connector can send the AIP session ID as `X-AIP-Session-Id`, but it does\nnot silently copy that value into `X-Hermes-Session-Id`. Set Hermes continuity\nexplicitly when the application needs it.\n\nTrusted execution can also add principal, tenant, authentication issuer,\ntrace, correlation, delegation-chain, and deadline headers. The Hermes endpoint\ntoken authenticates the connector host; these context headers do not replace\nthat token or grant provider authority by themselves.\n\n## Apply idempotency and retry safely\n\nThe AIP contract uses capability-scoped keys and\n`return_original_result` collision behavior. For `response_delete`, the key is\nrequired and retained for 86400000 ms (24 hours) by the declared contract. The\nother five operations publish an optional key and no TTL.\n\n`return_original_result` does not revalidate a changed input. Reusing one key\nfor a different business request can return the first retained AIP result.\nAllocate one key per exact intent and keep it with the original action ID.\n\nHermes also has a narrower provider cache for non-streaming `chat` and\n`responses`: it is process memory, retains at most 1000 entries for 300 seconds,\nand reuses only the same key with the same route-specific fingerprint.\n\nThe cache reuses the agent execution result but still constructs a fresh HTTP\nresponse and response ID. A different fingerprint can execute again.\nStreaming, retrieval, and deletion do not use this cache. It cannot replace\nAIP's durable result and key record.\n\nThe safe recovery rule is:\n\n1. retain the original AIP action ID and idempotency key;\n2. after interruption, read the durable AIP action result first;\n3. retry `response_get` only when the typed error permits it;\n4. do not resubmit chat, Responses, a stream, or deletion automatically;\n5. reconcile provider state or escalate when the result remains unknown.\n\nAn optional key does not change the four model operations from retry-unsafe to\nretry-safe. Model execution can call tools or send messages before the\nconnector observes a transport, deadline, decode, or provider error.\n\n## Respect data and execution limits\n\n| Limit or classification | Reviewed behavior |\n|---|---|\n| Provider request body | At most 10000000 bytes (10 MB) |\n| Provider concurrency | 10 agent runs by default across chat, Responses, and runs; `0` disables the cap |\n| Saturation | Provider HTTP 429 with `Retry-After: 1`; the connector's typed failure does not retain that header |\n| Non-streaming chat/Responses HTTP timeout | 300 seconds inside the connector |\n| Response GET/delete HTTP timeout | 30 seconds inside the connector |\n| Trusted AIP deadline | Can end the operation earlier than the HTTP timeout |\n| Connector response body | No explicit byte limit in this connector path |\n\nThe capability contract classifies chat and Responses data as confidential,\nPII-bearing, and redaction-required. It classifies deletion as restricted.\n\nThe current generated contract classifies `response_get` as internal and\n`contains_pii: false` because it is a generic read operation. That declaration\nis too weak for a stored model or tool result, which can contain confidential\nor personal data.\n\nUntil the contract is corrected, handle `response_get` input, output, storage,\nlogs, and traces as confidential and potentially PII-bearing. The generated\ncontract still requires redaction for this read. It classifies\n`response_delete` as PII-bearing and redaction-required as well as restricted.\n\n## Streaming boundary\n\n`chat_stream` and `responses_stream` force provider streaming and aggregate SSE\nframes into an object containing endpoint, operation, HTTP status, ordered\nevents, best-effort text, terminal state, and optional truncation state. A\npositive `max_events` value can stop collection before a terminal event.\n\nAdvertised AIP async support does not create provider background delivery after\nthe HTTP turn. Hermes binds this API-server channel with asynchronous delivery\ndisabled; the stream must settle through the active request and AIP lifecycle.\n\nDo not infer completion from a closed client connection or accumulated text.\nUse the streaming guide for the application procedure and the cursor and\ncancellation reference for exact terminal, replay, publication, and stop\nbehavior.\n\n## Failures and recovery\n\n| Symptom | Meaning | Decision |\n|---|---|---|\n| Schema rejection or HTTP 400 | Branch, message, `input`, history, or continuity fields are invalid | Correct the request; do not retry unchanged |\n| `connector.hermes_agent.authentication` | Endpoint token was rejected | Correct the endpoint credential; do not broaden caller scopes |\n| `connector.hermes_agent.tenant_mismatch` | Trusted AIP tenant does not own the selected endpoint | Select the admitted tenant route |\n| HTTP 404 on a response ID | The record was never stored, was evicted or deleted, or is absent from the reached database | Check `store`, the ID, the target instance, and the original AIP result |\n| HTTP 413 | Provider request exceeded 10000000 bytes | Reduce bounded input and history |\n| HTTP 429 | Hermes concurrent-run gate is full | Preserve the action; follow its typed result instead of blindly replaying model work |\n| HTTP 502 with `agent_incomplete` | Hermes produced no usable text after a failed or partial run | Treat tool and model outcome as uncertain |\n| Transport, decode, deadline, or provider 5xx on a model call | Hermes may have begun model or tool work | Read durable AIP state and reconcile; do not auto-retry |\n| Repeated deletion returns 404 | The record is already absent or the request reached another store | Read the original approved action result; do not create a new delete attempt blindly |\n\nThe connector maps temporary and transport failures as retryable only for\n`response_get`. It conservatively marks uncertain outcomes on non-read\ninvocations. Use protocol error fields rather than matching provider message\ntext.\n\n## Verify an integration\n\nBefore accepting a chat or Responses path:\n\n1. discover the exact endpoint-qualified capability ID;\n2. confirm its risk, stability, execution, approval, key, and data contract;\n3. submit one bounded input and retain the AIP action ID and key;\n4. inspect finish, partial, failure, and usage fields instead of content alone;\n5. for a stored Responses call, read the returned ID through `response_get`;\n6. verify that logs and traces redact prompts, outputs, tool data, and IDs;\n7. if deletion is required, complete approval, delete once, and retain the\n   original result as the audit record.\n\nThis verifies request mapping and lifecycle handling. It does not establish\nmodel quality, tool safety, provider availability, or production qualification.\n\n## Related documentation\n\n- [Hermes Agent capabilities](README.md)\n- [Authenticate and bind Hermes\n  endpoints](../getting-started/authentication-and-endpoints.md)\n- [Actions and sessions](../../../concepts/actions-and-sessions.md)\n- [Approvals and policy](../../../concepts/approvals-and-policy.md)\n- [Errors and retry decisions](../../../reference/errors.md)\n",
    "text": "Hermes chat and Responses capabilities\n\nUse these six endpoint-qualified capabilities to run a Hermes model turn,\nstream it, continue a Responses chain, read a stored response, or delete that\nstored response. They are for applications using a Hermes endpoint already\nadmitted to the tenant's AIP catalogue.\n\nChat and Responses calls can run tools and create external effects. They are\nnot read-only text generation, and an interrupted call is not safe to replay\nblindly. This page covers non-streaming request, result, continuity, storage, and\nretry behavior. The later streaming guide and cursor reference cover individual\nSSE events, truncation, publication, and cancellation.\n\nOperations\n\nReplace  with the normalized endpoint ID present in AIP\ndiscovery.\n\n| Operation | Provider request | Risk | Approval | Key | Retry | Stability |\n\n| chat | POST /v1/chat/completions | Medium | No | Optional | Unsafe | Stable |\n| chatstream | POST /v1/chat/completions | Medium | No | Optional | Unsafe | Stable |\n| responses | POST /v1/responses | Medium | No | Optional | Unsafe | Stable |\n| responsesstream | POST /v1/responses | Medium | No | Optional | Unsafe | Stable |\n| responseget | GET /v1/responses/{responseid} | Low | No | Optional | Safe | Experimental |\n| responsedelete | DELETE /v1/responses/{responseid} | High | Yes | Required | Unsafe | Experimental |\n\nAll six are AIP Agent capabilities and require the selected endpoint's Bearer\ntoken. The endpoint comes from the capability ID. Input cannot select a\ndifferent endpoint or provider URL.\n\nChoose chat or Responses\n\n| Need | Use | Continuity owner | Result |\n\n| Submit OpenAI-compatible messages for one turn | chat or chatstream | Explicit Hermes sessionid, optional long-term-memory sessionkey, or supplied message history | Chat completion object or stream aggregate |\n| Continue work by a stored response ID | responses or responsesstream | previousresponseid in the Hermes response store | Responses object or stream aggregate |\n| Continue work by an application name | responses or responsesstream | conversation mapped to the latest stored response | Responses object or stream aggregate |\n| Supply all prior history yourself | responses or responsesstream | conversationhistory in the current request | Responses object or stream aggregate |\n| Inspect or remove one stored Responses object | responseget or responsedelete | responseid returned by a stored Responses call | Stored public object or deletion receipt |\n\nUse the durable-runs capabilities when an application needs a pollable run,\nstructured lifecycle events, or an approval continuation. Use the session\ncapabilities when the application needs an addressable persistent session\nresource. Neither lifecycle is created merely by calling chat.\n\nShared AIP contract\n\nThe four model-executing operations publish these values:\n\n| Contract field | Published value |\n\n| Side effects | read, write, sendmessage, externalnetwork |\n| Data | Confidential; contains PII; redaction required |\n| Transaction | None |\n| Compensation | Rollback not supported |\n| Expected latency | 5000 ms (5 s) for non-streaming; 30000 ms (30 s) for streaming |\n| AIP contract timeout | 60000 ms (60 s) for non-streaming; 300000 ms (300 s) for streaming |\n| Maximum queue-delay hint | 10000 ms (10 s) |\n| Availability target | 99.9%, declared but not observed by this page |\n\nEvery operation supports synchronous execution. The two stream operations also\nadvertise async, streaming, and cancellation support, with streaming expected\ncompletion. asyncexpected remains false for both. The non-streaming\noperations do not advertise async, streaming, cancellation, or connector\nretry.\n\nresponseget publishes read and externalnetwork side effects. It is the\nonly retry-supported operation in this family. responsedelete publishes\nread, delete, and externalnetwork, requires tenant-policy approval, and\nhas no rollback.\n\nSubmit a chat request\n\nThe published AIP schema selects exactly one input branch:\n• prompt: one non-empty user prompt;\n• query: an alias for prompt; or\n• messages: one non-empty OpenAI-compatible message array.\n\nUse only one branch. The connector's defensive runtime parser gives a non-empty\nmessages array precedence, then prompt, then query, but normal AIP schema\nvalidation rejects an input that satisfies more than one oneOf branch.\n\nThe connector builds a messages array from prompt or query, defaults\nmodel to hermes-agent, and forces stream to match the selected capability.\nIt accepts these additional typed fields:\n\n| Field | Purpose or constraint |\n\n| model | Hermes model alias; defaults to hermes-agent |\n| sessionid | Hermes transcript continuity; at most 256 characters; sent as X-Hermes-Session-Id |\n| sessionkey | Long-term-memory scope; at most 256 characters; sent as X-Hermes-Session-Key |\n| temperature, topp | Numeric sampling controls; the AIP schema adds no range |\n| maxtokens | Non-negative integer in the typed connector request |\n| stop | OpenAI-compatible stop value |\n| tools, toolchoice | OpenAI-compatible tool declarations and selection |\n| responseformat | OpenAI-compatible response-format value |\n| user | Application-supplied user identifier |\n| metadata | Application metadata object |\n\nUnknown fields are accepted and forwarded for provider compatibility. Do not\nput credentials or trusted AIP identity claims in those fields. The connector\nremoves sessionid, sessionkey, and idempotencykey from the provider\nJSON body because they belong to headers. Trusted AIP execution overwrites the\nheader idempotency value with Action.idempotencykey.\n\nA bounded non-streaming input can look like this:\n\n{\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Answer with a short operational summary.\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"Summarize the current incident notes.\"\n    }\n  ],\n  \"model\": \"hermes-agent\",\n  \"temperature\": 0.2,\n  \"sessionid\": \"incident-review-2030-01\",\n  \"sessionkey\": \"support:incident-review\"\n}\n\nHermes concatenates system messages into an ephemeral system prompt. The\npinned handler takes the final supported user or assistant message as the\ncurrent agent input without checking that its role is user. End every request\nwith a visible user message. Earlier supported messages become history, and\nother roles do not enter this chat history path.\n\nWhen sessionid is present, Hermes attempts to load that transcript's history\nfrom its session database instead of using the earlier messages in the request.\nSupply a stable explicit ID from the first turn when the application owns\ncontinuity.\n\nIf sessionid is absent, Hermes derives an ID and returns it only in an HTTP\nheader. The current connector returns the JSON body, not provider response\nheaders.\n\nIf the session database is unavailable, the handler can continue with the\nrequest history. If history loading raises an error, it logs the failure and\ncontinues with empty history. A successful chat result therefore does not by\nitself prove that an earlier transcript was loaded.\n\nRead a chat result\n\nA successful non-streaming result follows the chat-completion shape:\n\n{\n  \"id\": \"chatcmpl-0123456789abcdef0123456789abc\",\n  \"object\": \"chat.completion\",\n  \"created\": 1893456000,\n  \"model\": \"hermes-agent\",\n  \"choices\": [\n    {\n      \"index\": 0,\n      \"message\": {\n        \"role\": \"assistant\",\n        \"content\": \"The incident is contained and verification is pending.\"\n      },\n      \"finishreason\": \"stop\"\n    }\n  ],\n  \"usage\": {\n    \"prompttokens\": 120,\n    \"completiontokens\": 11,\n    \"totaltokens\": 131\n  }\n}\n\nRead choices[0].message.content, but also inspect finishreason. When Hermes\nhas usable partial text, it can return HTTP 200 with finishreason set to\nlength or error and an additional hermes object describing completion,\npartial, failed, and redacted error state. A failed or partial run with no\nusable text returns an OpenAI-style error with HTTP 502.\n\nSubmit a Responses request\n\nUse a top-level body object for the provider request. Keep connector control\nfields beside it so they become headers rather than provider JSON:\n\n{\n  \"body\": {\n    \"model\": \"hermes-agent\",\n    \"input\": \"Summarize the current incident notes.\",\n    \"instructions\": \"Return three concise findings.\",\n    \"store\": true,\n    \"truncation\": \"auto\"\n  },\n  \"sessionkey\": \"support:incident-review\"\n}\n\nSet Action.idempotencykey as a sibling of Action.input. Do not create a\nsecond business key inside the provider body. During trusted execution, the\nconnector sends the action key as Idempotency-Key and forces stream to\nfalse or true for the selected capability.\n\nThe AIP schema is intentionally open for forward-compatible Responses fields,\nbut the pinned Hermes provider requires input. It accepts a string or an\narray of strings or message objects. These continuity rules then apply:\n\n| Field | Behavior |\n\n| previousresponseid | Loads retained history, session ID, and prior instructions when new instructions are absent |\n| conversation | Resolves an application name to its latest stored response; a missing name starts a new chain |\n| conversationhistory | A non-empty array supplies explicit history and takes precedence over previousresponseid |\n| store | Defaults to true; controls response storage and future lookup or chaining |\n| truncation | auto keeps the newest 100 history messages; omission keeps the full retained history |\n\nconversation and previousresponseid cannot appear together. An explicit\nconversationhistory must be an array whose entries contain role and\ncontent. The last normalized item in input becomes the current agent input;\npreceding items join the history. End an input array with a visible user item\nbecause the handler does not require that role on the last item.\n\nRead and delete stored responses\n\nA non-streaming Responses result contains the current turn's public output:\n\n{\n  \"id\": \"resp0123456789abcdef0123456789ab\",\n  \"object\": \"response\",\n  \"status\": \"completed\",\n  \"createdat\": 1893456000,\n  \"model\": \"hermes-agent\",\n  \"output\": [\n    {\n      \"type\": \"message\",\n      \"role\": \"assistant\",\n      \"content\": [\n        {\n          \"type\": \"outputtext\",\n          \"text\": \"Three findings are ready for review.\"\n        }\n      ]\n    }\n  ],\n  \"usage\": {\n    \"inputtokens\": 120,\n    \"outputtokens\": 11,\n    \"totaltokens\": 131\n  }\n}\n\nWhen store is true, pass its ID to either focused capability:\n\n{\n  \"responseid\": \"resp0123456789abcdef0123456789ab\"\n}\n\nresponseget returns the stored public response object. It does not return\nthe internal conversation history. responsedelete removes the stored record\nand any conversation-name pointer that currently refers to it, then returns:\n\n{\n  \"id\": \"resp0123456789abcdef0123456789ab\",\n  \"object\": \"response\",\n  \"deleted\": true\n}\n\nDeletion does not undo model calls, tool effects, long-term memory, or session\nhistory. It has no compensation capability. Complete its tenant-policy AIP\napproval and use a required capability-scoped idempotency key before invocation.\nThe approval record has a 900000 ms (15-minute) policy TTL and requires a\nreason, an input snapshot, and the policy decision as evidence.\n\nThe provider DELETE handler does not implement its own idempotent replay. The\npublished 86400000 ms (24-hour) contract and original-result replay belong to\nthe AIP runtime boundary; their durability depends on the runtime idempotency\nbackend.\n\nThe connector rejects an empty response ID and percent-encodes the value as one\nprovider path segment. A response created with store: false still has an ID,\nbut later GET, deletion, previousresponseid, and conversation lookup cannot\nresolve it.\n\nThis family has no response-list operation. If an interrupted creation never\nreturned its responseid, do not invent a path or replay the model request.\nRead the original AIP action result and escalate an unresolved provider outcome.\n\nUnderstand response retention\n\nHermes stores at most 100 Responses objects by default. The store uses\nleast-recently-used eviction, and a successful GET refreshes the access time.\nIt has no time-based expiry. Eviction and deletion also clear a conversation\npointer that names the removed response.\n\nThe normal store is a SQLite database under HERMESHOME and can survive a\ngateway restart. Hermes attempts to set the database and existing SQLite\nsidecars to owner-only mode 0600. Permission-change failure does not stop\nstartup, so verify the effective filesystem mode.\n\nIf Hermes cannot open the file, it falls back to in-memory SQLite; that fallback\nis lost at restart. AIP does not add cross-instance replication or guarantee\nthat a later request reaches the same response database.\n\nThe database contains full conversation history, including tool payloads and\nresults, even though responseget exposes only the public response object.\nProtect the Hermes home directory as confidential application state.\n\nKeep continuity identifiers separate\n\n| Identifier | Owner | Purpose |\n\n| AIP action ID | AIP application and runtime | Identifies one governed invocation and its durable result |\n| AIP session ID | AIP envelope and runtime | Groups native protocol messages and actions |\n| Hermes sessionid | Chat input and Hermes session database | Continues a chat transcript |\n| Hermes sessionkey | Application and Hermes memory layer | Scopes long-term memory across transcripts |\n| responseid | Hermes Responses store | Retrieves or chains one stored Responses object |\n| conversation | Application and Hermes Responses store | Names the latest stored response in one chain |\n\nThe connector can send the AIP session ID as X-AIP-Session-Id, but it does\nnot silently copy that value into X-Hermes-Session-Id. Set Hermes continuity\nexplicitly when the application needs it.\n\nTrusted execution can also add principal, tenant, authentication issuer,\ntrace, correlation, delegation-chain, and deadline headers. The Hermes endpoint\ntoken authenticates the connector host; these context headers do not replace\nthat token or grant provider authority by themselves.\n\nApply idempotency and retry safely\n\nThe AIP contract uses capability-scoped keys and\nreturnoriginalresult collision behavior. For responsedelete, the key is\nrequired and retained for 86400000 ms (24 hours) by the declared contract. The\nother five operations publish an optional key and no TTL.\n\nreturnoriginalresult does not revalidate a changed input. Reusing one key\nfor a different business request can return the first retained AIP result.\nAllocate one key per exact intent and keep it with the original action ID.\n\nHermes also has a narrower provider cache for non-streaming chat and\nresponses: it is process memory, retains at most 1000 entries for 300 seconds,\nand reuses only the same key with the same route-specific fingerprint.\n\nThe cache reuses the agent execution result but still constructs a fresh HTTP\nresponse and response ID. A different fingerprint can execute again.\nStreaming, retrieval, and deletion do not use this cache. It cannot replace\nAIP's durable result and key record.\n\nThe safe recovery rule is:\n1. retain the original AIP action ID and idempotency key;\n2. after interruption, read the durable AIP action result first;\n3. retry responseget only when the typed error permits it;\n4. do not resubmit chat, Responses, a stream, or deletion automatically;\n5. reconcile provider state or escalate when the result remains unknown.\n\nAn optional key does not change the four model operations from retry-unsafe to\nretry-safe. Model execution can call tools or send messages before the\nconnector observes a transport, deadline, decode, or provider error.\n\nRespect data and execution limits\n\n| Limit or classification | Reviewed behavior |\n\n| Provider request body | At most 10000000 bytes (10 MB) |\n| Provider concurrency | 10 agent runs by default across chat, Responses, and runs; 0 disables the cap |\n| Saturation | Provider HTTP 429 with Retry-After: 1; the connector's typed failure does not retain that header |\n| Non-streaming chat/Responses HTTP timeout | 300 seconds inside the connector |\n| Response GET/delete HTTP timeout | 30 seconds inside the connector |\n| Trusted AIP deadline | Can end the operation earlier than the HTTP timeout |\n| Connector response body | No explicit byte limit in this connector path |\n\nThe capability contract classifies chat and Responses data as confidential,\nPII-bearing, and redaction-required. It classifies deletion as restricted.\n\nThe current generated contract classifies responseget as internal and\ncontainspii: false because it is a generic read operation. That declaration\nis too weak for a stored model or tool result, which can contain confidential\nor personal data.\n\nUntil the contract is corrected, handle responseget input, output, storage,\nlogs, and traces as confidential and potentially PII-bearing. The generated\ncontract still requires redaction for this read. It classifies\nresponsedelete as PII-bearing and redaction-required as well as restricted.\n\nStreaming boundary\n\nchatstream and responsesstream force provider streaming and aggregate SSE\nframes into an object containing endpoint, operation, HTTP status, ordered\nevents, best-effort text, terminal state, and optional truncation state. A\npositive maxevents value can stop collection before a terminal event.\n\nAdvertised AIP async support does not create provider background delivery after\nthe HTTP turn. Hermes binds this API-server channel with asynchronous delivery\ndisabled; the stream must settle through the active request and AIP lifecycle.\n\nDo not infer completion from a closed client connection or accumulated text.\nUse the streaming guide for the application procedure and the cursor and\ncancellation reference for exact terminal, replay, publication, and stop\nbehavior.\n\nFailures and recovery\n\n| Symptom | Meaning | Decision |\n\n| Schema rejection or HTTP 400 | Branch, message, input, history, or continuity fields are invalid | Correct the request; do not retry unchanged |\n| connector.hermesagent.authentication | Endpoint token was rejected | Correct the endpoint credential; do not broaden caller scopes |\n| connector.hermesagent.tenantmismatch | Trusted AIP tenant does not own the selected endpoint | Select the admitted tenant route |\n| HTTP 404 on a response ID | The record was never stored, was evicted or deleted, or is absent from the reached database | Check store, the ID, the target instance, and the original AIP result |\n| HTTP 413 | Provider request exceeded 10000000 bytes | Reduce bounded input and history |\n| HTTP 429 | Hermes concurrent-run gate is full | Preserve the action; follow its typed result instead of blindly replaying model work |\n| HTTP 502 with agentincomplete | Hermes produced no usable text after a failed or partial run | Treat tool and model outcome as uncertain |\n| Transport, decode, deadline, or provider 5xx on a model call | Hermes may have begun model or tool work | Read durable AIP state and reconcile; do not auto-retry |\n| Repeated deletion returns 404 | The record is already absent or the request reached another store | Read the original approved action result; do not create a new delete attempt blindly |\n\nThe connector maps temporary and transport failures as retryable only for\nresponseget. It conservatively marks uncertain outcomes on non-read\ninvocations. Use protocol error fields rather than matching provider message\ntext.\n\nVerify an integration\n\nBefore accepting a chat or Responses path:\n1. discover the exact endpoint-qualified capability ID;\n2. confirm its risk, stability, execution, approval, key, and data contract;\n3. submit one bounded input and retain the AIP action ID and key;\n4. inspect finish, partial, failure, and usage fields instead of content alone;\n5. for a stored Responses call, read the returned ID through responseget;\n6. verify that logs and traces redact prompts, outputs, tool data, and IDs;\n7. if deletion is required, complete approval, delete once, and retain the\n   original result as the audit record.\n\nThis verifies request mapping and lifecycle handling. It does not establish\nmodel quality, tool safety, provider availability, or production qualification.\n\nRelated documentation\n• Hermes Agent capabilities (README.md)\n• Authenticate and bind Hermes\n  endpoints (../getting-started/authentication-and-endpoints.md)\n• Actions and sessions (../../../concepts/actions-and-sessions.md)\n• Approvals and policy (../../../concepts/approvals-and-policy.md)\n• Errors and retry decisions (../../../reference/errors.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "c28ea81bc299343f584a4f7c6f113a504fd3c568a189511b075a83f03ad36916"
  }
}
