Spring Boot Over Unix Domain Sockets

This guide continues from Spring Response Recording and Resumption. Keep the same checkpoint app and switch the client transport by setting one Spring property.

Local Memory Service

Note: The memory-service CLI has not yet been released as a standalone binary. You can install it from source with Go:

go install -tags "sqlite_fts5 sqlite_json" github.com/chirino/memory-service@latest
memory-service serve \
  --db-kind=sqlite \
  --db-url=file:$HOME/.local/share/memory-service/memory.db \
  --vector-kind=sqlite \
  --cache-kind=local \
  --unix-socket=$HOME/.local/run/memory-service/api.sock

Those options keep the Spring example focused on transport, not infrastructure: SQLite provides both durable storage and vector indexing, cache-kind=local keeps caching inside the process, the database file is persisted under $HOME/.local/share, and the socket is placed under $HOME/.local/run so the access boundary stays in the user’s home directory instead of /tmp.

Agent Configuration

Update your Spring Boot configuration file. In the checkpoint app, edit java/spring/examples/doc-checkpoints/05-response-resumption/src/main/resources/application.properties. In your own app, that same block lives in src/main/resources/application.properties.

application.properties
# Memory Service
memory-service.client.url=unix://${HOME}/.local/run/memory-service/api.sock
memory-service.client.api-key=agent-api-key-1

Replace the old memory-service.client.url=http://... line with memory-service.client.url=unix://${HOME}/.local/run/memory-service/api.sock. The Spring REST client wrapper and the gRPC response-recorder channel will both follow that URL automatically.

function get-token() {
  curl -sSfX POST http://localhost:8081/realms/memory-service/protocol/openid-connect/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "client_id=memory-service-client" \
    -d "client_secret=change-me" \
    -d "grant_type=password" \
    -d "username=bob" \
    -d "password=bob" \
    | jq -r '.access_token'
}

Start a streaming response, but disconnect before it finishes:

curl -NsSfX POST http://localhost:9090/chat/0b8c8c2f-4304-45f7-9cb8-e1ff666a1c8c \
  --max-time 0.2 \
  -H "Content-Type: text/plain" \
  -H "Authorization: Bearer $(get-token)" \
  -d "Write a short story about a cat."

Example output:

data: {"text":"Once "}
curl -sSfX POST http://localhost:9090/v1/conversations/resume-check \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $(get-token)" \
  -d '["0b8c8c2f-4304-45f7-9cb8-e1ff666a1c8c"]'

Example output:

[
  "0b8c8c2f-4304-45f7-9cb8-e1ff666a1c8c"
]

Resume the interrupted response:

curl -NsSfX GET http://localhost:9090/v1/conversations/0b8c8c2f-4304-45f7-9cb8-e1ff666a1c8c/resume \
  --max-time 0.5 \
  -H "Authorization: Bearer $(get-token)"

Example output:

data: {"text":"Once "}
curl -sSfX GET http://localhost:9090/v1/conversations/0b8c8c2f-4304-45f7-9cb8-e1ff666a1c8c \
  -H "Authorization: Bearer $(get-token)"

Example output:

{
  "id": "0b8c8c2f-4304-45f7-9cb8-e1ff666a1c8c"
}