@womp/spark-agent 2.2.0 → 3.0.1
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/README.md +1 -0
- package/dist/agent-tools.js +29 -5
- package/dist/agent.js +1 -0
- package/dist/capabilities/operations.d.ts +8 -3
- package/dist/capabilities/operations.js +60 -37
- package/dist/capabilities.d.ts +3 -1
- package/dist/cli.js +1 -0
- package/dist/execution-lifetime.d.ts +1 -1
- package/dist/execution-lifetime.js +1 -1
- package/dist/generated/operations-declarations.d.ts +1 -1
- package/dist/generated/operations-declarations.js +1 -1
- package/dist/geometry/schemas/flowir-dialect.json +978 -978
- package/dist/geometry.js +5 -5
- package/dist/model-options.js +7 -0
- package/dist/models.d.ts +13 -1
- package/dist/models.js +14 -0
- package/dist/pricing.js +14 -1
- package/dist/server/fixtures/materials/matte-blue.json +1 -1
- package/dist/server/fixtures/materials/polished-copper.json +1 -1
- package/dist/server/sqlite-store.js +29 -29
- package/dist/server/standalone.d.ts +1 -0
- package/dist/server/standalone.js +12 -0
- package/dist/ui.d.ts +2 -0
- package/dist/ui.js +1 -0
- package/package.json +2 -1
package/dist/geometry.js
CHANGED
|
@@ -7,11 +7,11 @@ export { migrateParameterOverrides, readParameterOverrides, } from "./geometry/p
|
|
|
7
7
|
let reference;
|
|
8
8
|
export function geometryReference() {
|
|
9
9
|
reference ??= {
|
|
10
|
-
rules: `Write one statement per line:
|
|
11
|
-
param Float width = 20.0 min=1 max=100 step=1
|
|
12
|
-
node box Primitive Type=Box Position=Vec3(0.0,0.0,0.0) Rotation=Vec3(0.0,0.0,0.0) Size=width Roundness=0.0
|
|
13
|
-
out Geometry=box.Geometry
|
|
14
|
-
Use decimal components in Vec3 parameter/constant literals, e.g. Vec3(20.0,20.0,20.0). Output name is case-sensitive: Geometry.
|
|
10
|
+
rules: `Write one statement per line:
|
|
11
|
+
param Float width = 20.0 min=1 max=100 step=1
|
|
12
|
+
node box Primitive Type=Box Position=Vec3(0.0,0.0,0.0) Rotation=Vec3(0.0,0.0,0.0) Size=width Roundness=0.0
|
|
13
|
+
out Geometry=box.Geometry
|
|
14
|
+
Use decimal components in Vec3 parameter/constant literals, e.g. Vec3(20.0,20.0,20.0). Output name is case-sensitive: Geometry.
|
|
15
15
|
${flowir.renderDslRulesBlock()}`,
|
|
16
16
|
catalog: flowir.renderSchemaBlock(flowirRegistry.getSchema()),
|
|
17
17
|
};
|
package/dist/model-options.js
CHANGED
|
@@ -2,6 +2,13 @@ import { resolveReasoningEffort } from "./models.js";
|
|
|
2
2
|
/** Standalone provider policy; browser hosts supply their own deployed model settings. */
|
|
3
3
|
export function sparkModelOptions(modelId, provider, effort) {
|
|
4
4
|
const reasoningEffort = resolveReasoningEffort(modelId, effort);
|
|
5
|
+
if (provider === "google") {
|
|
6
|
+
return {
|
|
7
|
+
google: {
|
|
8
|
+
thinkingConfig: { thinkingLevel: reasoningEffort, includeThoughts: true },
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
}
|
|
5
12
|
if (provider === "anthropic") {
|
|
6
13
|
return {
|
|
7
14
|
anthropic: {
|
package/dist/models.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type ModelProvider = "openai" | "anthropic";
|
|
1
|
+
export type ModelProvider = "openai" | "anthropic" | "google";
|
|
2
2
|
export type ReasoningEffort = "low" | "medium" | "high" | "xhigh" | "max";
|
|
3
3
|
export declare const REASONING_EFFORT_LABELS: Record<ReasoningEffort, string>;
|
|
4
4
|
export type SparkModel = {
|
|
@@ -14,6 +14,18 @@ export declare const SPARK_MODELS: readonly [{
|
|
|
14
14
|
readonly note: "Best OpenAI quality";
|
|
15
15
|
readonly provider: "openai";
|
|
16
16
|
readonly reasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
17
|
+
}, {
|
|
18
|
+
readonly id: "gpt-5.6-luna";
|
|
19
|
+
readonly label: "GPT-5.6 Luna";
|
|
20
|
+
readonly note: "Fast, cost-efficient OpenAI model";
|
|
21
|
+
readonly provider: "openai";
|
|
22
|
+
readonly reasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
23
|
+
}, {
|
|
24
|
+
readonly id: "gemini-3.8-flash";
|
|
25
|
+
readonly label: "Gemini 3.8 Flash";
|
|
26
|
+
readonly note: "Fast Google model";
|
|
27
|
+
readonly provider: "google";
|
|
28
|
+
readonly reasoningEfforts: readonly ["low", "medium", "high"];
|
|
17
29
|
}, {
|
|
18
30
|
readonly id: "claude-opus-5";
|
|
19
31
|
readonly label: "Opus 5";
|
package/dist/models.js
CHANGED
|
@@ -20,6 +20,20 @@ export const SPARK_MODELS = [
|
|
|
20
20
|
provider: "openai",
|
|
21
21
|
reasoningEfforts: EXTENDED_REASONING_EFFORTS,
|
|
22
22
|
},
|
|
23
|
+
{
|
|
24
|
+
id: "gpt-5.6-luna",
|
|
25
|
+
label: "GPT-5.6 Luna",
|
|
26
|
+
note: "Fast, cost-efficient OpenAI model",
|
|
27
|
+
provider: "openai",
|
|
28
|
+
reasoningEfforts: EXTENDED_REASONING_EFFORTS,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "gemini-3.8-flash",
|
|
32
|
+
label: "Gemini 3.8 Flash",
|
|
33
|
+
note: "Fast Google model",
|
|
34
|
+
provider: "google",
|
|
35
|
+
reasoningEfforts: ["low", "medium", "high"],
|
|
36
|
+
},
|
|
23
37
|
{
|
|
24
38
|
id: "claude-opus-5",
|
|
25
39
|
label: "Opus 5",
|
package/dist/pricing.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
// Standard, global, direct API rates in USD per million tokens, checked 2026-09-09.
|
|
2
2
|
const PRICES = {
|
|
3
|
+
"gpt-5.6-luna": {
|
|
4
|
+
input: 0.2, read: 0.02, write: 0.25, output: 1.2, longContext: 272_000,
|
|
5
|
+
source: "https://developers.openai.com/api/docs/models/gpt-5.6-luna",
|
|
6
|
+
pricingDate: "2026-09-12",
|
|
7
|
+
},
|
|
8
|
+
"gemini-3.8-flash": {
|
|
9
|
+
input: 0.75, read: 0.075, write: 0.75, output: 3.75,
|
|
10
|
+
source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.8-flash",
|
|
11
|
+
pricingDate: "2026-09-12", validUntil: "2027-01-01",
|
|
12
|
+
},
|
|
3
13
|
"gpt-6-astra": {
|
|
4
14
|
input: 10, read: 1, write: 12.5, output: 50, longContext: 272_000,
|
|
5
15
|
source: "https://developers.openai.com/api/docs/models/gpt-6-astra",
|
|
@@ -16,12 +26,15 @@ const PRICES = {
|
|
|
16
26
|
export function calculateStepCost(modelId, usage) {
|
|
17
27
|
const price = PRICES[modelId];
|
|
18
28
|
const result = {
|
|
19
|
-
modelId, pricingDate: "2026-09-09", source: price?.source,
|
|
29
|
+
modelId, pricingDate: price?.pricingDate ?? "2026-09-09", source: price?.source,
|
|
20
30
|
totalUsd: null, lines: [],
|
|
21
31
|
};
|
|
22
32
|
const unavailable = (reason) => ({ ...result, reason });
|
|
23
33
|
if (price === undefined)
|
|
24
34
|
return unavailable("No verified pricing for this model.");
|
|
35
|
+
if (price.validUntil !== undefined && Date.now() >= Date.parse(price.validUntil)) {
|
|
36
|
+
return unavailable("Verified pricing has expired.");
|
|
37
|
+
}
|
|
25
38
|
const input = usage.inputTokens;
|
|
26
39
|
const output = usage.outputTokens;
|
|
27
40
|
const read = usage.inputTokenDetails.cacheReadTokens;
|
|
@@ -17,28 +17,28 @@ export class SqliteSparkStore {
|
|
|
17
17
|
this.database.close();
|
|
18
18
|
throw new Error(`Unsupported Spark database version: ${version}`);
|
|
19
19
|
}
|
|
20
|
-
this.database.exec(`
|
|
21
|
-
PRAGMA busy_timeout = 5000;
|
|
22
|
-
PRAGMA journal_mode = WAL;
|
|
23
|
-
PRAGMA synchronous = FULL;
|
|
24
|
-
PRAGMA foreign_keys = ON;
|
|
25
|
-
CREATE TABLE IF NOT EXISTS conversations (
|
|
26
|
-
id TEXT PRIMARY KEY, owner_id TEXT NOT NULL, updated_at TEXT NOT NULL, data TEXT NOT NULL
|
|
27
|
-
);
|
|
28
|
-
CREATE INDEX IF NOT EXISTS conversation_owner ON conversations(owner_id, updated_at);
|
|
29
|
-
CREATE TABLE IF NOT EXISTS runs (
|
|
30
|
-
id TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, data TEXT NOT NULL
|
|
31
|
-
);
|
|
32
|
-
CREATE TABLE IF NOT EXISTS chunks (
|
|
33
|
-
run_id TEXT NOT NULL REFERENCES runs(id), sequence INTEGER NOT NULL, data TEXT NOT NULL,
|
|
34
|
-
PRIMARY KEY (run_id, sequence)
|
|
35
|
-
);
|
|
36
|
-
CREATE TABLE IF NOT EXISTS artifacts (
|
|
37
|
-
id TEXT PRIMARY KEY, owner_id TEXT NOT NULL, metadata TEXT NOT NULL, bytes BLOB NOT NULL
|
|
38
|
-
);
|
|
39
|
-
CREATE TABLE IF NOT EXISTS execution_owner (
|
|
40
|
-
singleton INTEGER PRIMARY KEY CHECK (singleton = 1), pid INTEGER NOT NULL, token TEXT NOT NULL
|
|
41
|
-
);
|
|
20
|
+
this.database.exec(`
|
|
21
|
+
PRAGMA busy_timeout = 5000;
|
|
22
|
+
PRAGMA journal_mode = WAL;
|
|
23
|
+
PRAGMA synchronous = FULL;
|
|
24
|
+
PRAGMA foreign_keys = ON;
|
|
25
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
26
|
+
id TEXT PRIMARY KEY, owner_id TEXT NOT NULL, updated_at TEXT NOT NULL, data TEXT NOT NULL
|
|
27
|
+
);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS conversation_owner ON conversations(owner_id, updated_at);
|
|
29
|
+
CREATE TABLE IF NOT EXISTS runs (
|
|
30
|
+
id TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, data TEXT NOT NULL
|
|
31
|
+
);
|
|
32
|
+
CREATE TABLE IF NOT EXISTS chunks (
|
|
33
|
+
run_id TEXT NOT NULL REFERENCES runs(id), sequence INTEGER NOT NULL, data TEXT NOT NULL,
|
|
34
|
+
PRIMARY KEY (run_id, sequence)
|
|
35
|
+
);
|
|
36
|
+
CREATE TABLE IF NOT EXISTS artifacts (
|
|
37
|
+
id TEXT PRIMARY KEY, owner_id TEXT NOT NULL, metadata TEXT NOT NULL, bytes BLOB NOT NULL
|
|
38
|
+
);
|
|
39
|
+
CREATE TABLE IF NOT EXISTS execution_owner (
|
|
40
|
+
singleton INTEGER PRIMARY KEY CHECK (singleton = 1), pid INTEGER NOT NULL, token TEXT NOT NULL
|
|
41
|
+
);
|
|
42
42
|
CREATE TABLE IF NOT EXISTS scene_operations (
|
|
43
43
|
target_key TEXT NOT NULL, id TEXT NOT NULL, revision INTEGER NOT NULL, data TEXT NOT NULL,
|
|
44
44
|
PRIMARY KEY (target_key, id)
|
|
@@ -127,13 +127,13 @@ export class SqliteSparkStore {
|
|
|
127
127
|
if (result.changes !== 1)
|
|
128
128
|
throw new Error("Scene operation changed concurrently or is missing");
|
|
129
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
|
-
)
|
|
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
137
|
`).run(next.targetKey, completedSceneOperationLimit);
|
|
138
138
|
}
|
|
139
139
|
this.database.exec("COMMIT");
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
2
2
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
3
|
+
import { createGoogleGenerativeAI } from "@ai-sdk/google";
|
|
3
4
|
import express from "express";
|
|
4
5
|
import { getSparkModel, SPARK_MODELS } from "../models.js";
|
|
5
6
|
import { KakapoAPI, KakapoRpcError } from "@womp/kakapo-sdk";
|
|
@@ -184,6 +185,17 @@ export async function createStandaloneSparkAgentApp(options) {
|
|
|
184
185
|
maxOutputTokens: 48_000,
|
|
185
186
|
};
|
|
186
187
|
}
|
|
188
|
+
if (selected.provider === "google") {
|
|
189
|
+
if (!options.geminiApiKey?.trim()) {
|
|
190
|
+
throw new Error("GEMINI_API_KEY is required for this model.");
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
model: createGoogleGenerativeAI({ apiKey: options.geminiApiKey })(selected.id),
|
|
194
|
+
modelId: selected.id,
|
|
195
|
+
providerOptions: sparkModelOptions(selected.id, selected.provider, settings.reasoningEffort),
|
|
196
|
+
maxOutputTokens: 48_000,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
187
199
|
if (options.openAiApiKey?.trim() === "" ||
|
|
188
200
|
options.openAiApiKey === undefined) {
|
|
189
201
|
throw new Error("OPENAI_API_KEY is required for this model.");
|
package/dist/ui.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export type SparkStepMetricsData = {
|
|
|
53
53
|
toolNames: string[];
|
|
54
54
|
responseTimeMs: number;
|
|
55
55
|
cost?: SparkStepCost;
|
|
56
|
+
usage?: unknown;
|
|
56
57
|
};
|
|
57
58
|
export declare const sparkExecutionReceiptSchema: z.ZodObject<{
|
|
58
59
|
id: z.ZodString;
|
|
@@ -220,5 +221,6 @@ export declare const sparkDataPartSchemas: {
|
|
|
220
221
|
usd: z.ZodNumber;
|
|
221
222
|
}, z.core.$strip>>;
|
|
222
223
|
}, z.core.$strip>>;
|
|
224
|
+
usage: z.ZodOptional<z.ZodUnknown>;
|
|
223
225
|
}, z.core.$strip>;
|
|
224
226
|
};
|
package/dist/ui.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@womp/spark-agent",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
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",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
},
|
|
103
103
|
"dependencies": {
|
|
104
104
|
"@ai-sdk/anthropic": "4.0.50",
|
|
105
|
+
"@ai-sdk/google": "4.0.69",
|
|
105
106
|
"@ai-sdk/openai": "4.0.63",
|
|
106
107
|
"@jitl/quickjs-wasmfile-release-sync": "0.32.0",
|
|
107
108
|
"@womp/flowir": "0.3.0",
|