SDK 教學 · 10 / 10

使用自有儲存層

Local JSON 是零設定預設值。Hosted 產品可以注入非同步、具 revision 的 session repository;目前 artifact repository 是同步介面,不能直接包裝一般的遠端 object-store SDK。

客製化深度

層級 5 · 正式環境 persistence

託管深度

本機檔案、session database 與同步 artifact store

文件狀態

支援的 SDK 邊界

前置假設

  • 產品已有受信任的 server-side persistence 與 tenancy model。
  • Database adapter 可以執行 atomic compare-and-swap update。
  • Deployment 為其餘 trace 與 memory state 提供耐久路徑。
Heddle 負責
  • 負責 session record、message、turn、lease、compaction state、optimistic mutation semantics 與 artifact metadata behavior。
  • 在 session lifecycle、turn persistence、artifact tool 與 result capture 中一致使用 injected repository。
  • 為本機與單機產品提供 file-backed repository。
產品端負責
  • 把 repository instance 綁定 authenticated tenant scope,並實作 production retention、encryption、backup 與 monitoring。
  • 保證 session 的 atomic revision check、deterministic catalog ordering,以及所使用之同步 artifact 邊界的耐久性。
  • 當 active run 跨越多個 process 時,另外提供 process routing 或 broker infrastructure。

從本機預設值開始

未注入 repository 時,createConversationEngine 會使用 file-backed session 與 artifact repositories:

TypeScript
import { createConversationEngine } from '@roackb2/heddle'

const engine = createConversationEngine({
  workspaceRoot,
  stateRoot: '/var/lib/my-agent',
  model: 'gpt-5.4',
})

請使用耐久的 application-data directory。File session adapter 會序列化 writers,使用 immutable revision body 與 atomic catalog replacement。它預期一般的 local filesystem locking 與 rename semantics;不要放在 eventually consistent object-store mount。

注入 session persistence

Hosted product 實作非同步、record-oriented 的 ChatSessionRepository port:

TypeScript
import {
  createConversationEngine,
  type ChatSessionRepository,
} from '@roackb2/heddle'

const sessionRepository: ChatSessionRepository = {
  list: async (input) => listSessionPage(input),
  read: async (sessionId) => readSessionRecord(sessionId),
  create: async (session) => createSessionRecord(session),
  update: async (input) => compareAndSwapSession(input),
  delete: async (input) => compareAndSwapSessionDelete(input),
}

const engine = createConversationEngine({
  workspaceRoot,
  stateRoot,
  model,
  sessionRepository,
})

Repository 只持久化 records;conversation policy 仍由 Heddle 負責。Update 與 delete 會帶 expected revision。Adapter 必須以 atomic 方式比較並遞增 revision,避免 concurrent turns 無聲覆寫彼此。

請用受信任的 server-side tenant scope 建立 adapter。不要接受 browser 傳入的 tenant ID,再直接信任它並用於 repository methods。Heddle 刻意不把 product account 與 row-level-security fields 放進 ChatSession

注入 artifact persistence

TypeScript
import type { ArtifactRepository } from '@roackb2/heddle'

const artifactRepository: ArtifactRepository = {
  readCatalog: () => synchronousArtifactStore.readCatalog(),
  writeCatalog: (store) => synchronousArtifactStore.writeCatalog(store),
  contentKey: (id, extension) => 'artifacts/' + id + '.' + extension,
  contentExists: (key) => synchronousArtifactStore.contentExists(key),
  writeContent: (key, content) => synchronousArtifactStore.writeContent(key, content),
  readContent: (key) => synchronousArtifactStore.readContent(key),
}

const engine = createConversationEngine({
  workspaceRoot,
  stateRoot,
  model,
  sessionRepository,
  artifactRepository,
})

contentKey 負責 addressing。它的回傳值會存成 RuntimeArtifact.path,但它是內部 content key,不是 public download URL。

目前每個 ArtifactRepository method 都是同步介面。Heddle 不會 await catalog 或 content operation,因此不要把一般的非同步 S3、database 或 network client 放到這個介面後方。請使用 file-backed repository、真正同步且耐久的 store,或把遠端 upload 放在此 port 之外;在 artifact repository 提供 async contract 前,不要把 remote blob storage 視為 drop-in adapter。

Session adapter 必須具備的行為

正式上線前,請確認:

  1. 兩個 writer 使用同一 revision 時,不會遺失其中一方的變更;
  2. missing、already-existing 與 revision-conflict record 是不同 outcome;
  3. timestamps 相同時,cursor page 不會漏掉或重複 rows;
  4. tenant、workspace 與 archive filter 都在 authorized scope 內執行;
  5. 第二個 engine process 能重新開啟 session,且 message、turn、queue、lease 與 compaction state 都完整;
  6. storage error 會以 failure 抵達 host,而不是被回報為 successful turn。

Public guide 提供實用的 PostgreSQL JSONB table 與 compare-and-swap query。請沿用產品既有的 driver 或 ORM,不要只為複製範例而增加一套 database stack。

仍以路徑儲存的狀態

Session 與 artifact repository 現在可以注入。Trace 與 Heddle-managed memory 仍持久化在 stateRoot 下,因此 hosted deployment 必須提供合適的 durable path,或明確接受這項限制。

共用 database persistence 也不會自動讓 active-run replay 跨 process。ConversationRunService 只在單一 process 保留 bounded active events;multi-process routing、draining 與 broker delivery 仍是產品 infrastructure。

權威來源