@womp/spark-agent 8.0.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,37 @@ Notable changes to `@womp/spark-agent`, newest first. Versions follow
4
4
  [Semantic Versioning](https://semver.org/). Add an entry with each version bump; describe what
5
5
  changed for hosts and users, and how to migrate across breaking changes.
6
6
 
7
+ ## 9.0.0 — 2026-10-12
8
+
9
+ The scene operation journal is gone: every SDK scene adapter applies each edit directly to the
10
+ scene and saves it, as the browser has since it moved to scene events. The journal only deduped an
11
+ edit whose tool call ran again with the same operation id and settled uncertain edits that turned
12
+ out to change nothing; no host re-runs a tool call within a live run, and a restart ends the run.
13
+
14
+ ### Removed
15
+
16
+ - `SceneOperationStore`, `recoverSceneOperation` and the `operations` option of
17
+ `SdkSceneEditorOptions` (and so of `createSdkSceneEditor` and `createSdkSceneHost`).
18
+ - `SdkSceneEditor.getOperation`.
19
+ - `SceneOperation.revision`, which only versioned journal records.
20
+ - `executeSceneOperation`'s `store` option and the `reused` flag on its result.
21
+ - The standalone SQLite store's `scene_operations` table. Opening an older database drops it and
22
+ sets the schema version to 5.
23
+
24
+ ### Changed
25
+
26
+ - Every edit that fails after it began throws `SceneOperationError`, whose `operation` reports
27
+ whether it was committed, rolled back or left uncertain. Before, hosts that supplied
28
+ `operations` got the original error unwrapped; it is now the error's `cause`.
29
+ - Receipts no longer carry `details.synchronized`; `details.synchronizationError` still reports
30
+ a failed `onCommitted`.
31
+
32
+ ### Migrating
33
+
34
+ Stop passing `operations` and delete any `SceneOperationStore` implementation. A custom
35
+ `SdkSceneEditor` drops `getOperation`. Code that read an edit's outcome from the journal after a
36
+ failure reads `error.operation` from the `SceneOperationError` instead.
37
+
7
38
  ## 8.0.0 — 2026-10-12
8
39
 
9
40
  Geometry Nodes moves to FlowIR 0.5.0. The dialect is FlowIR's strict, flat format, the
package/README.md CHANGED
@@ -59,8 +59,9 @@ locks. The run stays active with `requires_action` progress and resumes the same
59
59
  input; the wait is excluded from the execution budget. Abort settles the wait and late answers
60
60
  cannot revive it. Custom executors must honor the optional host-owned `userWait` argument to `execute`.
61
61
 
62
- Shared SDK scene adapters may omit `operations` to edit and save directly. Supplying `operations`
63
- adds a durable operation journal and recovery of uncertain edits.
62
+ Shared SDK scene adapters apply each edit directly to the scene and save it; nothing is journaled
63
+ or replayed. An edit that fails after it began throws `SceneOperationError`, whose `operation`
64
+ reports whether the edit was committed, rolled back or left uncertain.
64
65
 
65
66
  ### Persistence and run lifecycle
66
67
 
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { applyCompaction, latestCompaction, type SparkCompactionLimits } from ".
5
5
  export * from "./context-window.js";
6
6
  export * from "./capabilities.js";
7
7
  export { createSdkSceneEditor, createSdkSceneHost, type SdkSceneEditor, type SdkSceneEditorOptions, type SdkSceneEditIdentity, type SdkSceneServices, } from "./sdk-scene-host.js";
8
- export { recoverSceneOperation, type SceneOperation, type SceneOperationStore } from "./scene-operations.js";
8
+ export type { SceneOperation } from "./scene-operations.js";
9
9
  export type { JavaScriptExecutor, JavaScriptGlobals, JavaScriptUserWait } from "./executor.js";
10
10
  export { DEFAULT_MODEL_ID, getSparkModel, REASONING_EFFORT_LABELS, resolveReasoningEffort, SPARK_MODELS, } from "./models.js";
11
11
  export type { ModelProvider, ReasoningEffort, SparkModel } from "./models.js";
package/dist/index.js CHANGED
@@ -5,6 +5,5 @@ export { applyCompaction, latestCompaction } from "./compaction.js";
5
5
  export * from "./context-window.js";
6
6
  export * from "./capabilities.js";
7
7
  export { createSdkSceneEditor, createSdkSceneHost, } from "./sdk-scene-host.js";
8
- export { recoverSceneOperation } from "./scene-operations.js";
9
8
  export { DEFAULT_MODEL_ID, getSparkModel, REASONING_EFFORT_LABELS, resolveReasoningEffort, SPARK_MODELS, } from "./models.js";
10
9
  export { SPARK_AGENT_PROMPT, sparkSystemPrompt } from "./prompt.js";
package/dist/kakapo.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { KakapoRuntime } from "./runtime.js";
2
2
  export { createSdkSceneDraft, createSdkSceneEditor, createSdkSceneHost, type SdkSceneEditor, type SdkSceneEditorOptions, type SdkSceneEditIdentity, type SdkSceneServices, } from "./sdk-scene-host.js";
3
- export type { SceneOperation, SceneOperationStore, } from "./scene-operations.js";
3
+ export type { SceneOperation } from "./scene-operations.js";
4
4
  export { createWompSceneApi, NodeType, OperationType, PrimitiveTypeValue, } from "./womp-scene-api.js";
5
5
  export type { WompSceneApi, WompSceneApiContext } from "./womp-scene-api.js";
6
6
  export { createSdkGeometryHost, type SdkGeometryHostOptions, } from "./sdk-geometry-host.js";
@@ -4,10 +4,10 @@ export type SceneEditResult = {
4
4
  } | {
5
5
  empty: true;
6
6
  };
7
+ /** One scene edit's outcome, held for the invocation that made it. */
7
8
  export type SceneOperation = {
8
9
  id: string;
9
10
  targetKey: string;
10
- revision: number;
11
11
  status: "started" | "prepared" | "committed" | "rolled_back" | "unknown";
12
12
  result?: SceneEditResult;
13
13
  changed?: boolean;
@@ -17,23 +17,9 @@ export type SceneOperation = {
17
17
  };
18
18
  completedAt?: string;
19
19
  };
20
- export interface SceneOperationStore {
21
- getSceneOperation(targetKey: string, id: string): Promise<SceneOperation | undefined>;
22
- createSceneOperation(operation: SceneOperation): Promise<boolean>;
23
- saveSceneOperation(operation: SceneOperation): Promise<SceneOperation>;
24
- }
25
- /** Recover acknowledged/no-op results without replaying or refetching an uncertain edit. */
26
- export declare function recoverSceneOperation(options: {
27
- api: KakapoAPI;
28
- store: SceneOperationStore;
29
- targetKey: string;
30
- id: string;
31
- assertActive(): void | Promise<void>;
32
- }): Promise<SceneOperation | undefined>;
33
- /** Hosts may omit persistence; journal-backed hosts retain duplicate-operation protection. */
20
+ /** Applies one edit directly to the scene and reports its outcome; nothing is journaled or replayed. */
34
21
  export declare function executeSceneOperation<T>(options: {
35
22
  api: KakapoAPI;
36
- store?: SceneOperationStore;
37
23
  onOutcome?(operation: SceneOperation): void;
38
24
  operation: Pick<SceneOperation, "id" | "targetKey">;
39
25
  assertEditable(): void | Promise<void>;
@@ -44,5 +30,4 @@ export declare function executeSceneOperation<T>(options: {
44
30
  }): Promise<{
45
31
  value: T;
46
32
  operation: SceneOperation;
47
- reused?: boolean;
48
33
  }>;
@@ -42,44 +42,15 @@ function resultValue(operation) {
42
42
  function complete(operation, status) {
43
43
  return { ...operation, status, completedAt: operation.completedAt ?? new Date().toISOString() };
44
44
  }
45
- /** Recover acknowledged/no-op results without replaying or refetching an uncertain edit. */
46
- export async function recoverSceneOperation(options) {
47
- await options.assertActive();
48
- const previous = await options.store.getSceneOperation(options.targetKey, options.id);
49
- if (!previous || previous.status === "committed" || previous.status === "rolled_back")
50
- return previous;
51
- await options.assertActive();
52
- if (previous.changed === false && previous.result) {
53
- return options.store.saveSceneOperation(complete(previous, "committed"));
54
- }
55
- return previous;
56
- }
57
- /** Hosts may omit persistence; journal-backed hosts retain duplicate-operation protection. */
45
+ /** Applies one edit directly to the scene and reports its outcome; nothing is journaled or replayed. */
58
46
  export async function executeSceneOperation(options) {
59
- const { api, store, operation: identity } = options;
47
+ const { api, operation: identity } = options;
60
48
  const savesScene = options.saveToRenderer === true;
61
49
  await options.assertEditable();
62
- const previous = await store?.getSceneOperation(identity.targetKey, identity.id);
63
- if (previous && store) {
64
- if ((previous.save !== undefined) !== savesScene)
65
- throw new Error("Scene operation identity was reused with a different save policy");
66
- if (previous.status === "committed")
67
- return { value: resultValue(previous), operation: previous, reused: true };
68
- if (previous.status === "rolled_back")
69
- throw new Error(previous.error ?? "Scene operation was rolled back");
70
- const recovered = await recoverSceneOperation({
71
- api, store, targetKey: identity.targetKey, id: identity.id, assertActive: options.assertEditable,
72
- });
73
- if (recovered?.status === "committed")
74
- return { value: resultValue(recovered), operation: recovered, reused: true };
75
- throw new Error("Scene edit outcome is uncertain. Inspect the scene before making a new edit; this operation was not replayed.");
76
- }
77
50
  let operation = {
78
- ...identity, revision: 0, status: "started",
51
+ ...identity, status: "started",
79
52
  ...(savesScene ? { save: { status: "unknown" } } : {}),
80
53
  };
81
- if (store && !await store.createSceneOperation(operation))
82
- throw new Error("Scene operation is already in progress");
83
54
  try {
84
55
  const edit = async (draft) => {
85
56
  await options.assertEditable();
@@ -94,8 +65,6 @@ export async function executeSceneOperation(options) {
94
65
  ...operation, status: "prepared", changed,
95
66
  ...(savesScene && !changed ? { save: { status: "not_needed" } } : {}),
96
67
  };
97
- if (store)
98
- operation = await store.saveSceneOperation(operation);
99
68
  await options.assertEditable();
100
69
  if (changed)
101
70
  await options.prepareCommit?.(operation);
@@ -118,16 +87,11 @@ export async function executeSceneOperation(options) {
118
87
  ...(operation.save && status === "rolled_back" ? { save: { status: "not_needed" } } : {}),
119
88
  };
120
89
  options.onOutcome?.(operation);
121
- if (store)
122
- operation = await store.saveSceneOperation(operation);
123
90
  }
124
91
  catch {
125
- // Keep the original error; recovery can inspect the prepared record.
92
+ // Keep the original error.
126
93
  }
127
94
  throw error;
128
95
  }
129
- // A prepared record alone never proves an uncertain commit succeeded.
130
- if (store)
131
- operation = await store.saveSceneOperation(complete(operation, "committed"));
132
96
  return { value: resultValue(operation), operation };
133
97
  }
@@ -246,8 +246,7 @@ export function createSdkGeometryHost(options) {
246
246
  }
247
247
  catch (error) {
248
248
  if (operationId !== undefined && repairKey !== undefined) {
249
- const operation = error instanceof SceneOperationError ? error.operation : await editor.getOperation(operationId);
250
- if (operation?.status === "rolled_back")
249
+ if (error instanceof SceneOperationError && error.operation.status === "rolled_back")
251
250
  await repairs.refund(repairKey, operationId);
252
251
  }
253
252
  throw error;
@@ -238,9 +238,7 @@ export function createSdkOpenScadHost(options) {
238
238
  }
239
239
  catch (error) {
240
240
  if (creating === false && operationId !== "") {
241
- const operation = error instanceof SceneOperationError
242
- ? error.operation : await editor.getOperation(operationId);
243
- if (operation?.status === "rolled_back") {
241
+ if (error instanceof SceneOperationError && error.operation.status === "rolled_back") {
244
242
  await geometryRepairs.refund(resolved.repairKey, operationId);
245
243
  await printabilityRepairs.refund(resolved.repairKey, operationId);
246
244
  }
@@ -1,7 +1,7 @@
1
1
  import type { FontFamily, KakapoAPI, SceneEdit, MaterialResource, NativeSceneSnapshot } from "@womp/kakapo-sdk";
2
2
  import type { ArtifactRef, SparkInvocationContext } from "./capabilities.js";
3
3
  import type { SceneHost, SceneHealthHost, SceneScreenshotOptions } from "./capabilities/scene.js";
4
- import { type SceneOperation, type SceneOperationStore } from "./scene-operations.js";
4
+ import { type SceneOperation } from "./scene-operations.js";
5
5
  import type { SceneHdr } from "./scene-environment.js";
6
6
  export type SdkSceneServices = {
7
7
  fonts: FontFamily[];
@@ -19,7 +19,6 @@ export type SdkSceneServices = {
19
19
  export type SdkSceneEditorOptions = {
20
20
  targetKey: string;
21
21
  projectId?: number;
22
- operations?: SceneOperationStore;
23
22
  saveToRenderer?: boolean;
24
23
  withConnection<T>(context: SparkInvocationContext, action: (api: KakapoAPI, beginSettlement: () => void,
25
24
  /** Supply this when the host adds a stricter connection lifetime. */
@@ -27,7 +26,7 @@ export type SdkSceneEditorOptions = {
27
26
  assertEditable(context: SparkInvocationContext): void | Promise<void>;
28
27
  /** Suspend for the complete access, including reads and failed preparation. */
29
28
  acquireAccess?(context: SparkInvocationContext): Promise<(synchronized: boolean) => void | Promise<void>>;
30
- /** Must adopt each operation ID at most once, including during recovery. */
29
+ /** Must adopt each operation ID at most once. */
31
30
  onCommitted?(operation: SceneOperation, api: KakapoAPI, context: SparkInvocationContext, identity: SdkSceneEditIdentity, scene: NativeSceneSnapshot): Promise<Record<string, unknown> | void>;
32
31
  };
33
32
  export type SdkSceneEditIdentity = {
@@ -35,13 +34,12 @@ export type SdkSceneEditIdentity = {
35
34
  operation: string;
36
35
  target?: Record<string, unknown> | (() => Record<string, unknown>);
37
36
  };
38
- /** Carries this invocation's outcome without requiring a persistent journal. */
37
+ /** A failed edit's outcome, for callers that settle per-edit state such as repair budgets. */
39
38
  export declare class SceneOperationError extends Error {
40
39
  readonly operation: SceneOperation;
41
40
  constructor(operation: SceneOperation, cause: unknown);
42
41
  }
43
42
  export type SdkSceneEditor = {
44
- getOperation(operationId: string): Promise<SceneOperation | undefined>;
45
43
  withConnection<T>(context: SparkInvocationContext, action: (api: KakapoAPI, beginSettlement: () => void) => T | Promise<T>): Promise<T>;
46
44
  read<T>(context: SparkInvocationContext, action: (api: KakapoAPI, beginSettlement: () => void) => T | Promise<T>): Promise<T>;
47
45
  access<T>(identity: SdkSceneEditIdentity, callback: (api: KakapoAPI, draft: SceneEdit, operationId: string) => T | Promise<T>, context: SparkInvocationContext, afterCommitted?: (operation: SceneOperation, api: KakapoAPI) => Promise<Record<string, unknown> | void>): Promise<{
@@ -10,7 +10,7 @@ function assertSceneSaved(operation) {
10
10
  if (operation.save?.status === "unknown" || operation.save?.status === "requested")
11
11
  throw new Error("The scene edit was applied, but its save outcome is unknown. Inspect persistence before continuing; do not repeat the edit.");
12
12
  }
13
- /** Carries this invocation's outcome without requiring a persistent journal. */
13
+ /** A failed edit's outcome, for callers that settle per-edit state such as repair budgets. */
14
14
  export class SceneOperationError extends Error {
15
15
  operation;
16
16
  constructor(operation, cause) {
@@ -74,7 +74,6 @@ export function createSdkSceneDraft(api, scene, services) {
74
74
  export function createSdkSceneEditor(options) {
75
75
  const ordinals = new WeakMap();
76
76
  return {
77
- getOperation: (operationId) => options.operations?.getSceneOperation(options.targetKey, operationId) ?? Promise.resolve(undefined),
78
77
  withConnection: (context, action) => options.withConnection(context, async (api, settle, active = context) => {
79
78
  active.signal.throwIfAborted();
80
79
  return action(api, settle);
@@ -131,7 +130,6 @@ export function createSdkSceneEditor(options) {
131
130
  result: operation.result,
132
131
  save: operation.save,
133
132
  error: operation.error,
134
- ...(options.operations ? { synchronized } : {}),
135
133
  }),
136
134
  });
137
135
  };
@@ -142,7 +140,6 @@ export function createSdkSceneEditor(options) {
142
140
  try {
143
141
  result = await executeSceneOperation({
144
142
  api,
145
- store: options.operations,
146
143
  onOutcome: operation => { outcome = operation; },
147
144
  saveToRenderer: options.saveToRenderer,
148
145
  operation: {
@@ -168,10 +165,9 @@ export function createSdkSceneEditor(options) {
168
165
  catch (error) {
169
166
  // Receipt persistence must not replace the original SDK/tool error.
170
167
  try {
171
- const operation = outcome ?? await options.operations?.getSceneOperation(options.targetKey, id);
172
- if (operation) {
173
- synchronized = operation.status === "rolled_back";
174
- await record(operation);
168
+ if (outcome) {
169
+ synchronized = outcome.status === "rolled_back";
170
+ await record(outcome);
175
171
  }
176
172
  }
177
173
  catch {
@@ -180,12 +176,6 @@ export function createSdkSceneEditor(options) {
180
176
  throw error;
181
177
  }
182
178
  saveSettled = !result.operation.changed || !["unknown", "requested"].includes(result.operation.save?.status ?? "");
183
- // A duplicate returns its journaled result; retain its original receipt
184
- // and let explicit recovery handle any earlier synchronization failure.
185
- if (result.reused) {
186
- assertSceneSaved(result.operation);
187
- return result;
188
- }
189
179
  synchronized = !result.operation.changed || !options.onCommitted;
190
180
  await record(result.operation);
191
181
  if (!synchronized) {
@@ -216,7 +206,7 @@ export function createSdkSceneEditor(options) {
216
206
  return result;
217
207
  }
218
208
  catch (error) {
219
- if (!options.operations && outcome)
209
+ if (outcome)
220
210
  throw new SceneOperationError(outcome, error);
221
211
  throw error;
222
212
  }
@@ -2,11 +2,10 @@ import type { SparkGoal } from "../goals.js";
2
2
  import type { ExecutionScreenshot } from "../types.js";
3
3
  import type { SparkArtifact, StoredSparkChunk } from "../ui.js";
4
4
  import type { SparkArtifactStore, StoredSparkArtifact } from "./artifacts.js";
5
- import type { SceneOperation, SceneOperationStore } from "../scene-operations.js";
6
5
  import { type RepairStateStore } from "../repair-state.js";
7
6
  import type { SparkAgentStore, SparkConversation, SparkConversationSummary, SparkRun, SparkRunSettings } from "./types.js";
8
7
  /** Local development storage. Execution ownership belongs to the host service. */
9
- export declare class SqliteSparkStore implements SparkAgentStore, SparkArtifactStore, SceneOperationStore {
8
+ export declare class SqliteSparkStore implements SparkAgentStore, SparkArtifactStore {
10
9
  private readonly artifactBaseUrl;
11
10
  private readonly database;
12
11
  private ownershipToken;
@@ -15,9 +14,6 @@ export declare class SqliteSparkStore implements SparkAgentStore, SparkArtifactS
15
14
  close(): void;
16
15
  claimExecutionOwnership(): void;
17
16
  listInterruptedRuns(): Promise<SparkRun[]>;
18
- getSceneOperation(targetKey: string, id: string): Promise<SceneOperation | undefined>;
19
- createSceneOperation(operation: SceneOperation): Promise<boolean>;
20
- saveSceneOperation(operation: SceneOperation): Promise<SceneOperation>;
21
17
  createConversation(value: SparkConversation): Promise<void>;
22
18
  getConversation(id: string): Promise<SparkConversation | undefined>;
23
19
  listConversations(ownerId: string): Promise<SparkConversationSummary[]>;
@@ -2,7 +2,6 @@ import { mkdirSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { DatabaseSync } from "node:sqlite";
4
4
  import { emptyRepairState, } from "../repair-state.js";
5
- const completedSceneOperationLimit = 128;
6
5
  /** Local development storage. Execution ownership belongs to the host service. */
7
6
  export class SqliteSparkStore {
8
7
  artifactBaseUrl;
@@ -13,7 +12,7 @@ export class SqliteSparkStore {
13
12
  mkdirSync(dirname(path), { recursive: true });
14
13
  this.database = new DatabaseSync(path);
15
14
  const version = this.database.prepare("PRAGMA user_version").get()?.user_version;
16
- if (version !== 0 && version !== 1 && version !== 2 && version !== 3 && version !== 4) {
15
+ if (version !== 0 && version !== 1 && version !== 2 && version !== 3 && version !== 4 && version !== 5) {
17
16
  this.database.close();
18
17
  throw new Error(`Unsupported Spark database version: ${version}`);
19
18
  }
@@ -39,14 +38,11 @@ export class SqliteSparkStore {
39
38
  CREATE TABLE IF NOT EXISTS execution_owner (
40
39
  singleton INTEGER PRIMARY KEY CHECK (singleton = 1), pid INTEGER NOT NULL, token TEXT NOT NULL
41
40
  );
42
- CREATE TABLE IF NOT EXISTS scene_operations (
43
- target_key TEXT NOT NULL, id TEXT NOT NULL, revision INTEGER NOT NULL, data TEXT NOT NULL,
44
- PRIMARY KEY (target_key, id)
45
- );
41
+ DROP TABLE IF EXISTS scene_operations;
46
42
  CREATE TABLE IF NOT EXISTS repair_states (
47
43
  target_key TEXT PRIMARY KEY, revision INTEGER NOT NULL, data TEXT NOT NULL
48
44
  );
49
- PRAGMA user_version = 4;
45
+ PRAGMA user_version = 5;
50
46
  `);
51
47
  }
52
48
  repairStateStore(targetKey) {
@@ -111,39 +107,6 @@ export class SqliteSparkStore {
111
107
  throw new Error("Claim execution ownership before recovering runs");
112
108
  return this.database.prepare("SELECT data FROM runs WHERE json_extract(data, '$.status') IN ('queued', 'running')").all().map((row) => JSON.parse(String(row.data)));
113
109
  }
114
- async getSceneOperation(targetKey, id) {
115
- const row = this.database.prepare("SELECT data FROM scene_operations WHERE target_key = ? AND id = ?").get(targetKey, id);
116
- return row ? JSON.parse(String(row.data)) : undefined;
117
- }
118
- async createSceneOperation(operation) {
119
- const result = this.database.prepare("INSERT OR IGNORE INTO scene_operations VALUES (?, ?, ?, ?)").run(operation.targetKey, operation.id, operation.revision, JSON.stringify(operation));
120
- return result.changes === 1;
121
- }
122
- async saveSceneOperation(operation) {
123
- const next = { ...operation, revision: operation.revision + 1 };
124
- this.database.exec("BEGIN IMMEDIATE");
125
- try {
126
- const result = this.database.prepare("UPDATE scene_operations SET revision = ?, data = ? WHERE target_key = ? AND id = ? AND revision = ?").run(next.revision, JSON.stringify(next), operation.targetKey, operation.id, operation.revision);
127
- if (result.changes !== 1)
128
- throw new Error("Scene operation changed concurrently or is missing");
129
- if (next.status === "committed" || next.status === "rolled_back") {
130
- this.database.prepare(`
131
- DELETE FROM scene_operations WHERE rowid IN (
132
- SELECT rowid FROM scene_operations
133
- WHERE target_key = ? AND json_extract(data, '$.status') IN ('committed', 'rolled_back')
134
- ORDER BY COALESCE(json_extract(data, '$.completedAt'), '') DESC
135
- LIMIT -1 OFFSET ?
136
- )
137
- `).run(next.targetKey, completedSceneOperationLimit);
138
- }
139
- this.database.exec("COMMIT");
140
- return next;
141
- }
142
- catch (error) {
143
- this.database.exec("ROLLBACK");
144
- throw error;
145
- }
146
- }
147
110
  async createConversation(value) {
148
111
  this.database.prepare("INSERT INTO conversations VALUES (?, ?, ?, ?)")
149
112
  .run(value.id, value.ownerId, value.updatedAt, JSON.stringify(value));
@@ -102,7 +102,6 @@ export async function createStandaloneSparkAgentApp(options) {
102
102
  const targetKey = `${context.ownerId}:${sceneIdentity}`;
103
103
  const editorOptions = {
104
104
  targetKey,
105
- operations: store,
106
105
  saveToRenderer: true,
107
106
  withConnection: (invocation, action) => sceneAccess.run(invocation.signal, async (signal, beginSettlement) => {
108
107
  if (!api.isConnected)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@womp/spark-agent",
3
- "version": "8.0.0",
3
+ "version": "9.0.0",
4
4
  "description": "Portable skills-based AI agent with local and durable chat transports for Womp",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",