Skip to content
ochat
Search documentation

Use quotes for an exact phrase.

Search by topic, command, or code identifier.

    GitHub ↗

    Run a private Unix daemon

    Start a durable local host, attach multiple terminal clients, and reconnect to a session.

    View Markdown source ↗

    Create a durable session, disconnect its client, and reattach to the same history.

    Complete installation and private example setup. All commands use dune exec from the repository root with the active opam environment. Terminal A owns the daemon and provider environment; clients run in separate terminals with the same absolute OCHAT_DEMO. Discovery and attachment are offline; submitting messages invokes a billable provider.

    Read the current provider TLS and permission boundaries before model work or deployment. Build troubleshooting includes the Apple Silicon/OpenBLAS setup path.

    Complete example setup, retaining the absolute OCHAT_DEMO directory. Provider credentials are needed only for model work, and belong in the daemon environment, not just the TUI environment.

    Terminal window
    dune exec bin/ochat_agent_server.exe -- -config "$OCHAT_DEMO/unix.sexp" -validate-only
    dune exec bin/ochat_agent_server.exe -- -config "$OCHAT_DEMO/unix.sexp" -print-config

    Validation must exit successfully. The printed normalized config contains paths and identity configuration; treat it as operator data when sharing diagnostics.

    Terminal window
    export API_URL=api.openai.com
    dune exec bin/ochat_agent_server.exe -- -config "$OCHAT_DEMO/unix.sexp"

    Leave this foreground process running. The socket parent created by mktemp is private. Do not run the HTTP config concurrently: both configs own the same store.

    Set OCHAT_DEMO in this terminal to the path from step 1, then:

    Terminal window
    dune exec bin/chat_tui.exe -- --no-config --connect "unix://$OCHAT_DEMO/agent.sock" \
    --new-daemon-session --prompt hello --workspace project --detached

    The CLI resolves configured names hello and project to protocol catalog IDs. Submitting a message now calls the provider. Quit with the normal TUI :q workflow: only this client disconnects.

    Terminal window
    dune exec bin/chat_tui.exe -- --no-config --connect "unix://$OCHAT_DEMO/agent.sock" --list-sessions

    Copy the returned opaque session ID into OCHAT_SESSION, then:

    Terminal window
    dune exec bin/chat_tui.exe -- --no-config --connect "unix://$OCHAT_DEMO/agent.sock" \
    --session "$OCHAT_SESSION"

    Open another terminal with the same directory/session variables and repeat with --read-only. It receives updates but cannot send messages or approve tools. Unix clients authenticate as the same effective user; read-only attachment is not a separate low-scope credential. For transcript-only credentials use HTTP.

    Create another session with --owner-bound --disconnect-grace-ms 30000 instead of --detached. It has an exclusive owner lease; loss starts a grace interval, not an instantaneous stop at every network hiccup. Reconnect within permitted lease/reclaim rules. Do not use --read-only with owner-bound mode.

    Terminal window
    dune exec bin/chat_tui.exe -- --no-config --connect "unix://$OCHAT_DEMO/agent.sock" \
    --stop-session "$OCHAT_SESSION"

    This stops session work; it does not delete the durable transcript. Quit attached clients. Use Ctrl+C in Terminal A for graceful daemon shutdown. Starting the same config again reopens the store. Recovery does not resume an interrupted tool’s process; see session recovery.

    Archive the private directory if you want to retain this tutorial’s state, or remove only that exact directory after shutdown. No normal Ochat state was used.

    Checkpoint, troubleshooting, and next step

    Section titled “Checkpoint, troubleshooting, and next step”

    Success means a detached session remains listed after the first client quits, a new client attaches to the same opaque ID, and the store survives a normal daemon restart. If connection fails, check the foreground daemon, socket path, private-directory permissions, and matching shell variables. A missing session ID is not the configured prompt name. Use troubleshooting; do not run two daemons against the same store. Follow step 6 for shutdown and cleanup. Next, schedule background work or connect a stdio client.

    View source · Background timer2 files

    Complete source files. Open a filename to read it here.

    timer.chatmdStart here
    <developer>This host demonstrates a background timer; no model request is needed.</developer>
    <script language="chatml" kind="moderator">
      type state = int
      type event = [ `Session_start | `Tick ]
      let initial_state = 0
      let on_event : context -> state -> event -> state task =
        fun ctx st ev ->
          match ev with
          | `Session_start ->
            Task.bind(Schedule.after_ms(10000, `Tick), fun timer_id ->
            Task.pure(st + 1))
          | `Tick ->
            Task.bind(Runtime.end_session("scheduled tutorial stop"), fun ignored_end ->
            Task.pure(st + 1))
    </script>
    

    Link to this fileDownload this file

    LICENSE.txtnotice
    MIT License
    
    Copyright (c) 2025 
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.

    Link to this fileDownload this file

    View source · Protocol discovery2 files

    Complete source files. Open a filename to read it here.

    discover.ndjsonStart here
    {"jsonrpc":"2.0","id":"initialize","method":"protocol.initialize","params":{"implementation":{"name":"tutorial","version":"1"},"protocol_min":{"major":1,"minor":0},"protocol_max":{"major":1,"minor":0},"features":[],"event_encodings":["json"],"max_inbound_event_bytes":16777216}}
    {"jsonrpc":"2.0","id":"info","method":"server.info","params":{}}
    {"jsonrpc":"2.0","id":"prompts","method":"prompt.list","params":{"limit":20}}
    {"jsonrpc":"2.0","id":"workspaces","method":"workspace.list","params":{"limit":20}}
    {"jsonrpc":"2.0","id":"sessions","method":"session.list","params":{"limit":20}}
    

    Link to this fileDownload this file

    LICENSE.txtnotice
    MIT License
    
    Copyright (c) 2025 
    
    Permission is hereby granted, free of charge, to any person obtaining a copy
    of this software and associated documentation files (the "Software"), to deal
    in the Software without restriction, including without limitation the rights
    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:
    
    The above copyright notice and this permission notice shall be included in all
    copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    SOFTWARE.

    Link to this fileDownload this file