Session 狀態與 Events
PedelecSession 維護 browser-side status,並提供 status、error 與 end lifecycle callbacks。
Status values
Section titled “Status values”type PedelecSessionStatus = | "idle" | "running" | "waiting_tool_result" | "ended" | "error";| Status | 意義 | 可呼叫 sendText()? |
|---|---|---|
idle |
沒有 active turn,可接收下一個 prompt | 可以 |
running |
Preparation 或 user turn active | 不可以 |
waiting_tool_result |
Agent 已要求 frontend tool,正在等待 | 不可以 |
ended |
Session 已結束;只要 Core 與記錄的 workspace 仍可恢復,同一個 attached handle 可明確呼叫 resume() |
resume() 成功前不可以 |
error |
Runtime 回報 session error | 不可以;依產品策略建立或 resume session |
新 PedelecSession object 的 local initial status 是 idle。resumeSession() 回傳的 handle 會在 promise resolve 前先和 Core 同步,因此初始也可能是 running、waiting_tool_result、error 或 ended。
Pedelec.resumeSession(sessionId) 只會重新 attach 到既有 thread,因此 ended thread 仍保持 ended。PedelecSession.resume() 才是同一個 handle 的明確 ended → idle transition;它保留 handle handlers 與 session state,provider runtime work 仍會等到下一個正常 operation 才 lazy 執行。
常見 transitions
Section titled “常見 transitions”沒有 tool 的 turn:
idle → running → idle包含 frontend tool:
idle → running → waiting_tool_result → running → idleActive state 也可能直接 error 或 ended:
running → errorrunning → endedwaiting_tool_result → errorwaiting_tool_result → ended不要假設每個理論 intermediate status 都一定會在 UI 出現。Event 可能被 normalize、de-duplicate,或非常接近地到達。idle 是可觀察的 thread state,單獨不代表特定的 prepare() 或 sendText() promise 已完成。
監聽 status changes
Section titled “監聽 status changes”const offStatus = session.onStatus((status, ctx) => { console.log(ctx.previousStatus, "→", status); console.log(ctx.type, ctx.source);});只有 value 改變時 callback 才執行。Registration 不會立即 emit initial status。
renderStatus(session.getStatus());const offStatus = session.onStatus(renderStatus);Local 與 Core-originated status
Section titled “Local 與 Core-originated status”為了 UI 即時反應,SDK 可在 Core response 前先 emit:
sendText()與prepare()local setrunning;- tool event 處理時 set
waiting_tool_result; end()request 成功後 local mark ended。session.resume()不會 optimistic setidle;這個狀態由 authoritative Core snapshot 與 operation-lessstatus_changedevent 設定。
Context 可辨識來源:
ctx.source // "sdk" | "core"ctx.type // "sdk_status_changed" | "status_changed"Core event 使用 source: "core";SDK 內部主動變更使用 source: "sdk"。
Status handler 會去重。SDK 已設為 running,Core 後續也回報 running 時,不會再 callback 一次。
Error events
Section titled “Error events”const offError = session.onError((error, ctx) => { console.error(error.code, error.message, error.details); console.debug(ctx.type, ctx.source, ctx.sessionId);});type ErrorEventContext = PedelecEventContext & { type: "error" | "sdk_error";};onError() 適合 session-wide observation、logging 與 UI;發起 action 的 promise 仍要 catch。
Error callback 不一定代表 status 變成 error。例如 tool result submission 失敗會 emit SDK SUBMIT_TOOL_RESULT_FAILED,最終 session state 仍由 Runtime 決定。Core operation error 是 diagnostic;語意上的 rejection 由相符的 operation completion 提供。
Ended events
Section titled “Ended events”const offEnded = session.onEnded((ctx) => { console.log("ended by", ctx.source);});type EndedEventContext = PedelecEventContext & { type: "ended" | "sdk_ended";};onEnded() 會在每次 transition 進入 ended 時執行一次,無論原因是 runtime event 或成功的 local end()。Handle 已經是 ended 時,重複的 ended notification 不會再次執行 callback。相同 handle 成功透過 resume() 由 ended 回到 idle 後,之後再次 transition 回 ended 會視為新的 lifecycle transition,再執行一次 callback。
Session end 時,pending sendText() 或 prepare() 會 reject SESSION_ENDED。
Common context fields
Section titled “Common context fields”type PedelecEventContext = { sessionId: string; provider: string; effortLevel?: "default" | "low" | "high"; sessionCreatedAt: number; eventReceivedAt?: number; eventEmittedAt: number; turnId?: string; turnStartedAt?: number; turnKind?: "user" | "prepare"; source: "core" | "sdk";};不是每個 event 都有所有欄位:
- Core chat/tool callback 有 received time 與 active turn metadata。
- Local status change 可能發生在 Core event 前,沒有
eventReceivedAt。 - Active turn 之外的 end/error 可能沒有 turn fields。
- 新的 resumed handle 若應用程式沒自行保存,可能有空 provider metadata。
Tool-call context
Section titled “Tool-call context”Tool handler 還會收到:
ctx.type; // "tool_call"ctx.toolRequestId; // Core tool request identifierctx.tool; // tool namectx.turnId;toolRequestId 可用於 diagnostics 與 application bookkeeping,不需要手動 submit result;SDK 會自動送出 handler return value。
Event order 與 duplicate protection
Section titled “Event order 與 duplicate protection”Core event 可包含 per-session sequence number。Client 會忽略 sequence 不比上一個更新的 event,且 operation-scoped event 只有在 operation ID 對應目前 active operation 時才會採用。Application 自己 handler 內的 async work 仍要能處理 rapid transition 與 late completion。
Subscription 重建時,SDK 會先收到 authoritative lifecycle snapshot,再接收 live event。Resume 或 recovery handle 會依 snapshot 採用 Core status 與 active operation;若 Core 回報 pending frontend tool,請在 resumeSession() 後註冊 handler,SDK 會先保留 recovered request,等相符 handler 可用後才 submit。同一個 handle 的 session.resume() 也會在 promise resolve 前 reconciliation reactivation 後的 snapshot,因此 await 後 getStatus() 一定是 idle。
UI mapping
Section titled “UI mapping”session.onStatus((status) => { setSendEnabled(status === "idle"); setBusy(status === "running" || status === "waiting_tool_result"); setToolWaiting(status === "waiting_tool_result"); setSessionClosed(status === "ended");});Interactive tool 正在等待使用者時,不要把 waiting_tool_result 只顯示成 frozen。應呈現對應 modal 或操作提示。