On this page
Overview
Composes complete configured chat with an existing ChatEntity so each user, assistant, and structural tool turn has an explicit persistence and transport policy.
- Artifact
PersistentAIChatSession.js· esm - Classification
public first party - Availability
Browser or native WebView with the projected ChatEntity, DBOPFS, and a configured chat function or normalized Arcane.ai surface - Normalization
Preserves complete ordinary visible recurring provider history, one active raw structural continuation, every sanitized timestamped transcript record, and arbitrary nonempty caller-owned chat file names; commits live context atomically; falls back from optional streaming to configured non-stream transport; carries per-turn generation options while owning lifecycle callbacks; exposes complete data callbacks; accepts terminal-only structural calls; correlates every observed per-choice call against the exact validated terminal envelope before callback/persistence; atomically settles every pending ID once; and keeps malformed stored records readable without inventing or rewriting messages.
Import and lifecycle
import * as module from '/node_modules/arcane-os/runtime/arcane/modules/PersistentAIChatSession.js';
Construction creates or binds one ChatEntity and asynchronously loads existing JSONL history only when requested. open makes one transient application bootstrap request and atomically retains only its complete nonblank model-authored assistant response. send and stream settle pending memory, run one configured chat transaction, keep raw structural protocol only through its one active provider continuation, project the settled exchange into complete ordinary visible recurring context, project only human-readable records at the ChatEntity DBOPFS boundary, then commit both histories atomically. persist:false uses the request and response for that operation and rolls both out of subsequent model context, transcript, memory, and DBOPFS. Existing stored files are never rewritten merely by loading them. stream uses ai.streamRequest when supplied, buffers every observed structural call until the ordered array exactly matches the terminal calls, and otherwise falls back to the configured non-stream fetch/chat path.
Application-facing behavior: Per-turn persist:false and chatEntity.persist=false retain neither request nor response after the active operation; completed send/stream results expose retained outside provider content. New durable records contain role/content/timestamp and optional application display name or public tool name/status; existing stored records remain untouched. Default/named PersistentAIChatSession, createPersistentAIChatSession(); create(), ai, chatEntity, fileName, ready(), history(), transcript(), settleMemory(), open(), send(), and stream(). Optional constructor aiName and getter/setter accept a string; open/send/stream capture it before their first await. A nonblank application name is preserved exactly on the copied terminal message and retained assistant transcript, with the actual assistant record timestamp when available. Complete raw providerResponse stays unchanged; configured model context and memory omit the application display name. Existing history is never renamed or rewritten, and persist:false remains operation-only.
Protocol and host implementation
Existing ChatEntity/DBOPFS methods plus provider-neutral chat request/result records This detail does not widen the application-facing API or grant authority.
Exports, signatures, parameters, and results
| Binding | Form | Declaration or signature | Parameter syntax |
|---|---|---|---|
PersistentAIChatSession | class | class PersistentAIChatSession | — |
createPersistentAIChatSession | function | function createPersistentAIChatSession(options) | options |
default | default · class | class PersistentAIChatSession | — |
| Callable | Kind | Exact public signature | Parameter syntax |
|---|---|---|---|
createPersistentAIChatSession | exported-function | function createPersistentAIChatSession(options) | options |
PersistentAIChatSession.create | public-member | static async create(options={}) | options={} |
PersistentAIChatSession.ready | public-member | async ready() | — |
PersistentAIChatSession.history | public-member | async history() | — |
PersistentAIChatSession.transcript | public-member | async transcript() | — |
PersistentAIChatSession.settleMemory | public-member | async settleMemory() | — |
PersistentAIChatSession.send | public-member | async send(input) | input |
PersistentAIChatSession.stream | public-member | async stream(input,handlers={}) | input,handlers={} |
| Member | Kind | Exact public declaration | Parameter syntax |
|---|---|---|---|
PersistentAIChatSession.constructor | constructor | constructor(options={}) | options={} |
PersistentAIChatSession.create | static async method | static async create(options={}) | options={} |
PersistentAIChatSession.chatEntity | get | get chatEntity() | — |
PersistentAIChatSession.fileName | get | get fileName() | — |
PersistentAIChatSession.ai | get | get ai() | — |
PersistentAIChatSession.aiName | get | get aiName() | — |
PersistentAIChatSession.aiName | set | set aiName(value) | value |
PersistentAIChatSession.ready | async method | async ready() | — |
PersistentAIChatSession.history | async method | async history() | — |
PersistentAIChatSession.transcript | async method | async transcript() | — |
PersistentAIChatSession.settleMemory | async method | async settleMemory() | — |
PersistentAIChatSession.open | async method | async open(input) | input |
PersistentAIChatSession.send | async method | async send(input) | input |
PersistentAIChatSession.stream | async method | async stream(input,handlers={}) | input,handlers={} |
Parameter meanings and results
new PersistentAIChatSession({ai?|chat?,aiName?,chatEntity,chatFileName,contextBuilder,loadExisting,memory=true,request,responseLength,systemPrompt}); ai must expose fetchRequest and may expose streamRequest, while ai and chat are mutually exclusive. static create() and createPersistentAIChatSession() await readiness. ready() waits for initialization and resolves the same session. Optional aiName and its getter/setter accept a string; open/send/stream capture it before their first await. Exact nonblank application name is attached to the copied terminal message and retained assistant transcript, with the real assistant-record timestamp when available. Complete raw providerResponse is unchanged; configured model context and memory omit the display name. Name changes never rename or rewrite historical records. open({message:{content,persist:false?},request?,signal?}) retains only one sanitized assistant opening in an otherwise empty conversation and never retains its application-authored bootstrap. send accepts user messages or matching tool results; a tool result may supply message, name, and status while raw content and tool_call_id remain only in the active provider continuation. The public message becomes ordinary visible recurring content; message/name/status form its sanitized durable record, and name/status remain transcript-only metadata. Per-turn persist:false or entity-wide chatEntity.persist=false returns the completed one-operation response but retains neither side of the turn. The entity setting is captured at request acceptance and checked before the durable append; already accepted writes finish without rewriting saved records. Completed send/stream responses include the session-owned retained boolean outside message/provider payload. stream(input,{onChunk?,onDataChunk?,onDataResult?,onToolCall?}) resolves the same terminal response and exposes validated calls only after the terminal array matches. history() returns complete ordinary visible retained provider context plus only a currently unresolved raw structural-call tail. transcript() returns role/content/timestamp plus an optional exact nonblank application name for retained assistant turns, role/content/timestamp for user turns and role/content/timestamp plus optional tool name/status for retained tool turns. Neither recurring history nor transcript exposes settled reasoning, raw calls, IDs, arguments, raw results, nonpersistent turns, or provider/internal fields; settleMemory() waits for ChatEntity memory work.
Events, side effects, and errors
Source-literal CustomEvent dispatches
No source-literal CustomEvent dispatch is part of this artifact.
Lifecycle and event flow
This artifact has no additional documented lifecycle event flow.
Direct coded failures
This artifact directly assigns no stable coded failure.
Exported Error subclasses
This artifact exports no Error subclass.
Documented failure behavior
- AI_CHAT_UNAVAILABLE
- AI_CHAT_ABORTED
- AI_CHAT_AMBIGUOUS_PROVIDER
- AI_CHAT_BUSY
- AI_CHAT_INVALID_RESPONSE
- AI_CHAT_INVALID_OPENING_RESPONSE
- AI_CHAT_OPENING_EXISTS
- AI_CHAT_PERSISTENCE_UNAVAILABLE
- AI_CHAT_INVALID_TOOL_CALL
- AI_CHAT_INVALID_TOOL_MESSAGE
- AI_CHAT_TOOL_MESSAGE_REQUIRED
- AI_CHAT_TOOL_RESULT_REQUIRED
- AI_CHAT_STREAM_TOOL_CALL_MISMATCH
- AI_CHAT_INCOHERENT_PERSISTENCE
- AI_CHAT_TRANSACTION_SETTLED
- configured chat, ChatEntity, DBOPFS, and memory errors propagate
Availability and capabilities
Browser or native WebView with the projected ChatEntity, DBOPFS, and a configured chat function or normalized Arcane.ai surface. Preserves complete ordinary visible recurring provider history, one active raw structural continuation, every sanitized timestamped transcript record, and arbitrary nonempty caller-owned chat file names; commits live context atomically; falls back from optional streaming to configured non-stream transport; carries per-turn generation options while owning lifecycle callbacks; exposes complete data callbacks; accepts terminal-only structural calls; correlates every observed per-choice call against the exact validated terminal envelope before callback/persistence; atomically settles every pending ID once; and keeps malformed stored records readable without inventing or rewriting messages.
Portable persistent chat composition. The default chat calls normalized Arcane.ai.chat; an injected browser or cloud chat function can replace it. DBOPFS method names and ChatEntity semantics remain unchanged, and no provider or storage fallback is invented.
Contract example
import {
createPersistentAIChatSession
} from '/node_modules/arcane-os/runtime/arcane/modules/PersistentAIChatSession.js';
async function sendPersistentSupportTurnAfterUserChoice(documents){
const session=await createPersistentAIChatSession({
chatFileName:'support.jsonl',
loadExisting:true,
contextBuilder:documents.createContextBuilder()
});
const response=await session.send({
message:{role:'user',content:'Summarize the selected documents.',persist:true},
request:{toolChoice:'none'},
response:{persist:true}
});
console.log(response.message.content);
}
Related reference
No direct Core call is claimed for this artifact. Any injected provider or consuming module retains its own documented authority.