Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

episodes.attach

Otevře epizodu provádění pro volajícího klienta, nebo obnoví tu, kterou už měl. 'external_id' je vlastní trvalé jméno klienta pro sezení — id jeho konverzace nebo vlákna — a musí přežít opětovné připojení: klient, který se vrátí pod stejnou identitou, dostane znovu svou vlastní epizodu, pod jakýmkoli peer id, které má nyní, místo druhé. Peer id tohoto serveru nestačí; přiděluje se na připojení. Poté vlastní provoz klienta udržuje epizodu naživu, ztráta spojení ji odpojí, ne uzavře, a uzavře ji majordomus_session_detach, zastavení serveru nebo reaper po uplynutí odkladu opětovného připojení. Epizodu repozitáře otevírá stejný příkaz, který spouští hook providera, a co ohlásil, je v odpovědi. Vyžaduje relaci MCP: přes prosté HTTP není připojení, ke kterému by se vázalo.

Otevře epizodu provádění pro volajícího klienta, nebo obnoví tu, kterou už měl. 'external_id' je vlastní trvalé jméno klienta pro sezení — id jeho konverzace nebo vlákna — a musí přežít opětovné připojení: klient, který se vrátí pod stejnou identitou, dostane znovu svou vlastní epizodu, pod jakýmkoli peer id, které má nyní, místo druhé. Peer id tohoto serveru nestačí; přiděluje se na připojení. Poté vlastní provoz klienta udržuje epizodu naživu, ztráta spojení ji odpojí, ne uzavře, a uzavře ji majordomus_session_detach, zastavení serveru nebo reaper po uplynutí odkladu opětovného připojení. Epizodu repozitáře otevírá stejný příkaz, který spouští hook providera, a co ohlásil, je v odpovědi. Vyžaduje relaci MCP: přes prosté HTTP není připojení, ke kterému by se vázalo.

  • command
  • behaviorally_verified
  • module episodes
  • #episodes
  • #session
  • #coordination

Zpřístupnění

Kde je tato jedna definice dosažitelná. Absence je explicitní: povrch, který není uveden, ji nenese.

povrchjako
MCPnástroj majordomus_session_attach
HTTPPOST /api/v1/episodes/attach operationId episodes.attach
příkazová řádka—

Schémata

Kanonický vstup a výstup z typů Rustu; schéma nástroje MCP a parametry a odpovědi OpenAPI se odvozují z nich.

input · AttachInput

Vstup episodes.attach: který kus práce toto připojení nese.

Identita je jediné pole a neznámé je odmítnuto místo ignorováno, takže klient, který pošle peer id pod jiným názvem, se to dozví hned:

use majordomus_cli::capability::builtin::episodes::AttachInput;
let input: AttachInput = serde_json::from_str(r#"{"external_id":"conv-42"}"#).unwrap();
assert_eq!(input.external_id, "conv-42");
assert!(serde_json::from_str::<AttachInput>(r#"{"external_id":"x","peer":"p1"}"#).is_err());
assert!(serde_json::from_str::<AttachInput>("{}").is_err(), "the identity is required");
vlastnosttyppovinnépopis
external_id string ano Vlastní trvalé jméno epizody od klienta — id jeho konverzace, id vlákna nebo jak jinak nazývá sezení, v němž je.

Musí přežít znovupřipojení, protože to je celá jeho úloha: klient, který se vrátí pod stejnou identitou, dostane znovu svou vlastní epizodu a ne druhou. Postačí cokoli, co klient dokáže reprodukovat; nepostačí peer id tohoto serveru, které se přiděluje pro každé spojení a je při každém znovupřipojení klienta jiným řetězcem.

JSON Schema
{
  "additionalProperties": false,
  "description": "The input of `episodes.attach`: which piece of work this connection is carrying.\n\nThe identity is the only field, and an unknown one is refused rather than ignored, so a\nclient that sends a peer id under another name learns it at once:\n\n```\nuse majordomus_cli::capability::builtin::episodes::AttachInput;\nlet input: AttachInput = serde_json::from_str(r#\"{\"external_id\":\"conv-42\"}\"#).unwrap();\nassert_eq!(input.external_id, \"conv-42\");\nassert!(serde_json::from_str::<AttachInput>(r#\"{\"external_id\":\"x\",\"peer\":\"p1\"}\"#).is_err());\nassert!(serde_json::from_str::<AttachInput>(\"{}\").is_err(), \"the identity is required\");\n```",
  "properties": {
    "external_id": {
      "description": "The client's own durable name for this episode — its conversation id, thread id, or\nwhatever it calls the sitting it is in.\n\n**It must survive a reconnect**, because that is the whole of its job: a client that\ncomes back under the same identity is given its own episode again rather than a\nsecond one. Anything the client can reproduce will do; what will not do is this\nserver's peer id, which is handed out per connection and is a different string every\ntime the client reconnects.",
      "type": "string"
    }
  },
  "required": [
    "external_id"
  ],
  "title": "AttachInput",
  "type": "object"
}

výstup · Attached

Odpověď episodes.attach: epizoda, kterou spojení nyní drží, zda byla obnovena místo otevřena a jak dlouho přežije ztrátu spojení.

use majordomus_cli::capability::builtin::episodes::Attached;
let schema = serde_json::to_value(schemars::schema_for!(Attached)).unwrap();
for field in ["episode", "resumed", "reattach_grace_seconds"] {
    assert!(schema["required"].as_array().unwrap().iter().any(|f| f == field), "{field}");
}
vlastnosttyppovinnépopis
epizoda reference ano Epizoda, kterou toto spojení nyní drží.
reattach_grace_seconds integer ano Jak dlouho tato epizoda přežije své spojení, než ji reaper uzavře, v sekundách. Uvedeno, ne ponecháno k objevení: klient, který zná odklad, může rozhodnout, zda se vyplatí znovu připojit.
obnoveno boolean ano Zda byla obnovena epizoda už existující pod touto identitou, místo aby se otevřela nová. Pravda po znovupřipojení, restartu klienta nebo pádu, a pole, které volající kontroluje, aby věděl, zda v něčem pokračuje.
JSON Schema
{
  "$defs": {
    "ConnectionEpisode": {
      "description": "One episode: what the client calls itself, which connection holds it now, and what the\nrepository did about it.\n\n```\nuse majordomus_cli::episodes::{ConnectionEpisode, EpisodeBoard};\nuse majordomus_cli::peers::{PeerBoard, Transport};\nlet peer = PeerBoard::new().attach(Transport::Http);\nlet (episode, _) = EpisodeBoard::new().attach(&peer, \"conv-42\", \"generic\");\nlet episode: ConnectionEpisode = episode;\nassert_eq!((episode.external_id.as_str(), episode.provider.as_str()), (\"conv-42\", \"generic\"));\nassert_eq!(episode.peer.as_ref(), Some(&peer));\n// never empty: a board with no repository behind it says so\nassert!(episode.repository.contains(\"without a driver\"));\n```",
      "properties": {
        "attachments": {
          "description": "How many times a connection has taken it over, the first attach included.",
          "format": "uint32",
          "minimum": 0,
          "type": "integer"
        },
        "external_id": {
          "description": "The client's own durable name for this piece of work, and the key everything here is\naddressed by. Never a peer id: see the module documentation.",
          "type": "string"
        },
        "last_activity_seconds_ago": {
          "description": "Seconds since the client last spoke on it, through any connection.",
          "format": "uint64",
          "minimum": 0,
          "type": "integer"
        },
        "opened_at": {
          "description": "When it was first opened, RFC 3339, UTC. Unchanged by a re-attach: the episode is\nthe work, and the work did not restart because a socket did.",
          "type": "string"
        },
        "peer": {
          "anyOf": [
            {
              "$ref": "#/$defs/PeerId"
            },
            {
              "type": "null"
            }
          ],
          "description": "The connection holding it, when one does. `None` while detached — which is a state\nan episode is *supposed* to reach and come back from, not a fault."
        },
        "provider": {
          "description": "The provider id this episode is recorded under, as `share/providers.yaml` names one.",
          "type": "string"
        },
        "repository": {
          "description": "What the repository's own episode command reported, verbatim — the record it opened,\nor the reason it could not. Never interpreted here, and never empty: a subsystem\nthat silently does nothing is the failure mode this field exists to make visible.",
          "type": "string"
        },
        "state": {
          "$ref": "#/$defs/ConnectionEpisodeState",
          "description": "Open, or detached and waiting for its client."
        }
      },
      "required": [
        "external_id",
        "provider",
        "opened_at",
        "last_activity_seconds_ago",
        "attachments",
        "state",
        "repository"
      ],
      "type": "object"
    },
    "ConnectionEpisodeState": {
      "description": "Where an episode stands: held by a live connection, or waiting for its client to come\nback. There is no closed state, because a closed episode leaves the board; what survives\nit is the repository's own record.\n\n```\nuse majordomus_cli::episodes::{ConnectionEpisodeState, EpisodeBoard};\nuse majordomus_cli::peers::{PeerBoard, Transport};\nlet peer = PeerBoard::new().attach(Transport::Stdio);\nlet board = EpisodeBoard::new();\nassert_eq!(board.attach(&peer, \"w\", \"generic\").0.state, ConnectionEpisodeState::Open);\nassert_eq!(board.detach(&peer)[0].state, ConnectionEpisodeState::Detached);\nassert_eq!(serde_json::to_string(&ConnectionEpisodeState::Detached).unwrap(), \"\\\"detached\\\"\");\n```",
      "oneOf": [
        {
          "const": "open",
          "description": "A connection holds it and the client is speaking.",
          "type": "string"
        },
        {
          "const": "detached",
          "description": "The connection has gone; the episode is kept for `REATTACH_GRACE` so the client\ncan come back to it. This is the state a crash lands in, and the one a reconnect\nrecovers from.",
          "type": "string"
        }
      ]
    },
    "PeerId": {
      "description": "A peer's identity for the life of the server: `p1`, `p2`, ... in attachment order.\n`p1` is the session that started the server.",
      "type": "string"
    }
  },
  "description": "The answer of `episodes.attach`: the episode the connection now holds, whether it was\nresumed rather than opened, and how long it outlives a lost connection.\n\n```\nuse majordomus_cli::capability::builtin::episodes::Attached;\nlet schema = serde_json::to_value(schemars::schema_for!(Attached)).unwrap();\nfor field in [\"episode\", \"resumed\", \"reattach_grace_seconds\"] {\n    assert!(schema[\"required\"].as_array().unwrap().iter().any(|f| f == field), \"{field}\");\n}\n```",
  "properties": {
    "episode": {
      "$ref": "#/$defs/ConnectionEpisode",
      "description": "The episode this connection now holds."
    },
    "reattach_grace_seconds": {
      "description": "How long this episode survives its connection before the reaper closes it, in\nseconds. Stated rather than left to be discovered: a client that knows the grace can\ndecide whether reconnecting is worth it.",
      "format": "uint64",
      "minimum": 0,
      "type": "integer"
    },
    "resumed": {
      "description": "Whether an episode already under this identity was resumed rather than a new one\nopened. True after a reconnect, a client restart or a crash, and the field a caller\nchecks to know whether it is continuing something.",
      "type": "boolean"
    }
  },
  "required": [
    "episode",
    "resumed",
    "reattach_grace_seconds"
  ],
  "title": "Attached",
  "type": "object"
}

Politiky

benchmark
povinné — cíl na každém transportu, který expozice deklaruje; případy jsou ty ze vstupního typu
cache
vypnuto — každé volání spustí handler

Cíle benchmarku

Odvozeno z registru pro tento repozitář: jeden požadavek na transport a případy, které poskytuje typ vstupu. Celá matice je na stránce měření výkonu.

transportstatepřípadytargets
directpokryto1výchozí
mcppokryto1výchozí
httppokryto1výchozí

Prohledává názvy a popisy všech stránek, které tento web publikuje.