@womp/spark-agent 4.2.2 → 4.3.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/.env.example +6 -6
- package/README.md +457 -457
- package/dist/agent-run.d.ts +1 -1
- package/dist/capabilities/flow.js +3 -3
- package/dist/capabilities/geometry.js +14 -14
- package/dist/capabilities/openscad-instructions.d.ts +1 -1
- package/dist/capabilities/openscad-instructions.js +2 -1
- package/dist/capabilities/operations.js +33 -32
- package/dist/capabilities/scene.js +74 -74
- package/dist/client.js +8 -0
- package/dist/geometry/schemas/backend-schema.json +3393 -3393
- package/dist/geometry/schemas/flowir-dialect.json +1023 -1023
- package/dist/geometry.js +6 -6
- package/dist/models.d.ts +12 -5
- package/dist/models.js +16 -7
- package/dist/pricing.js +15 -0
- package/dist/prompt.d.ts +1 -1
- package/dist/prompt.js +65 -70
- package/dist/server/express.js +9 -1
- package/dist/server/fixtures/materials/matte-blue.json +14 -14
- package/dist/server/fixtures/materials/polished-copper.json +14 -14
- package/dist/server/message-fold.d.ts +59 -0
- package/dist/server/message-fold.js +345 -0
- package/dist/server/scene-initialization.d.ts +3 -0
- package/dist/server/scene-initialization.js +44 -0
- package/dist/server/service.d.ts +18 -1
- package/dist/server/service.js +25 -17
- package/dist/server/sqlite-store.js +37 -37
- package/dist/server/standalone.js +3 -0
- package/package.json +139 -139
package/dist/geometry.js
CHANGED
|
@@ -7,12 +7,12 @@ 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=Cube 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
|
-
Exactly one cast applies per port and casts do not chain: Float[] -> Vec3 is unavailable even though Float[] -> Float and Float -> Vec3 are both listed. Build the vector with CombineXYZ instead.
|
|
10
|
+
rules: `Write one statement per line:
|
|
11
|
+
param Float width = 20.0 min=1 max=100 step=1
|
|
12
|
+
node box Primitive Type=Cube 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
|
+
Exactly one cast applies per port and casts do not chain: Float[] -> Vec3 is unavailable even though Float[] -> Float and Float -> Vec3 are both listed. Build the vector with CombineXYZ instead.
|
|
16
16
|
${flowir.renderDslRulesBlock()}`,
|
|
17
17
|
catalog: flowir.renderSchemaBlock(flowirRegistry.getSchema()),
|
|
18
18
|
};
|
package/dist/models.d.ts
CHANGED
|
@@ -18,10 +18,17 @@ export declare const SPARK_MODELS: readonly [{
|
|
|
18
18
|
readonly provider: "openai";
|
|
19
19
|
readonly reasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
20
20
|
}, {
|
|
21
|
-
readonly id: "gpt-
|
|
21
|
+
readonly id: "gpt-6-sol";
|
|
22
22
|
readonly contextWindow: 1050000;
|
|
23
|
-
readonly label: "GPT-
|
|
24
|
-
readonly note: "
|
|
23
|
+
readonly label: "GPT-6 Sol";
|
|
24
|
+
readonly note: "Complex coding and agentic workflows";
|
|
25
|
+
readonly provider: "openai";
|
|
26
|
+
readonly reasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
27
|
+
}, {
|
|
28
|
+
readonly id: "gpt-6-luna";
|
|
29
|
+
readonly contextWindow: 1050000;
|
|
30
|
+
readonly label: "GPT-6 Luna";
|
|
31
|
+
readonly note: "Efficient, high-volume OpenAI model";
|
|
25
32
|
readonly provider: "openai";
|
|
26
33
|
readonly reasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
|
|
27
34
|
}, {
|
|
@@ -32,9 +39,9 @@ export declare const SPARK_MODELS: readonly [{
|
|
|
32
39
|
readonly provider: "google";
|
|
33
40
|
readonly reasoningEfforts: readonly ["low", "medium", "high"];
|
|
34
41
|
}, {
|
|
35
|
-
readonly id: "claude-opus-5";
|
|
42
|
+
readonly id: "claude-opus-5-5";
|
|
36
43
|
readonly contextWindow: 1000000;
|
|
37
|
-
readonly label: "Opus 5";
|
|
44
|
+
readonly label: "Opus 5.5";
|
|
38
45
|
readonly note: "Best Anthropic quality";
|
|
39
46
|
readonly provider: "anthropic";
|
|
40
47
|
readonly reasoningEfforts: readonly ["low", "medium", "high", "xhigh", "max"];
|
package/dist/models.js
CHANGED
|
@@ -23,11 +23,20 @@ export const SPARK_MODELS = [
|
|
|
23
23
|
reasoningEfforts: EXTENDED_REASONING_EFFORTS,
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
|
-
id: "gpt-
|
|
27
|
-
// https://developers.openai.com/api/docs/models/gpt-
|
|
26
|
+
id: "gpt-6-sol",
|
|
27
|
+
// https://developers.openai.com/api/docs/models/gpt-6-sol
|
|
28
28
|
contextWindow: 1_050_000,
|
|
29
|
-
label: "GPT-
|
|
30
|
-
note: "
|
|
29
|
+
label: "GPT-6 Sol",
|
|
30
|
+
note: "Complex coding and agentic workflows",
|
|
31
|
+
provider: "openai",
|
|
32
|
+
reasoningEfforts: EXTENDED_REASONING_EFFORTS,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "gpt-6-luna",
|
|
36
|
+
// https://developers.openai.com/api/docs/models/gpt-6-luna
|
|
37
|
+
contextWindow: 1_050_000,
|
|
38
|
+
label: "GPT-6 Luna",
|
|
39
|
+
note: "Efficient, high-volume OpenAI model",
|
|
31
40
|
provider: "openai",
|
|
32
41
|
reasoningEfforts: EXTENDED_REASONING_EFFORTS,
|
|
33
42
|
},
|
|
@@ -41,10 +50,10 @@ export const SPARK_MODELS = [
|
|
|
41
50
|
reasoningEfforts: ["low", "medium", "high"],
|
|
42
51
|
},
|
|
43
52
|
{
|
|
44
|
-
id: "claude-opus-5",
|
|
45
|
-
// https://platform.claude.com/docs/en/models/opus-5
|
|
53
|
+
id: "claude-opus-5-5",
|
|
54
|
+
// https://platform.claude.com/docs/en/models/opus-5-5/overview
|
|
46
55
|
contextWindow: 1_000_000,
|
|
47
|
-
label: "Opus 5",
|
|
56
|
+
label: "Opus 5.5",
|
|
48
57
|
note: "Best Anthropic quality",
|
|
49
58
|
provider: "anthropic",
|
|
50
59
|
reasoningEfforts: EXTENDED_REASONING_EFFORTS,
|
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-6-sol": {
|
|
4
|
+
input: 2, read: 0.2, write: 2.5, output: 10, longContext: 272_000,
|
|
5
|
+
source: "https://developers.openai.com/api/docs/pricing",
|
|
6
|
+
pricingDate: "2026-09-22",
|
|
7
|
+
},
|
|
8
|
+
"gpt-6-luna": {
|
|
9
|
+
input: 0.1, read: 0.01, write: 0.125, output: 0.5, longContext: 272_000,
|
|
10
|
+
source: "https://developers.openai.com/api/docs/pricing",
|
|
11
|
+
pricingDate: "2026-09-22",
|
|
12
|
+
},
|
|
3
13
|
"gpt-5.6-luna": {
|
|
4
14
|
input: 0.2, read: 0.02, write: 0.25, output: 1.2, longContext: 272_000,
|
|
5
15
|
source: "https://developers.openai.com/api/docs/models/gpt-5.6-luna",
|
|
@@ -14,6 +24,11 @@ const PRICES = {
|
|
|
14
24
|
input: 10, read: 1, write: 12.5, output: 50, longContext: 272_000,
|
|
15
25
|
source: "https://developers.openai.com/api/docs/models/gpt-6-astra",
|
|
16
26
|
},
|
|
27
|
+
"claude-opus-5-5": {
|
|
28
|
+
input: 4, read: 0.2, write: 5, output: 20,
|
|
29
|
+
source: "https://platform.claude.com/docs/en/models/opus-5-5/overview",
|
|
30
|
+
pricingDate: "2026-09-22",
|
|
31
|
+
},
|
|
17
32
|
"claude-opus-5": {
|
|
18
33
|
input: 5, read: 0.5, write: 6.25, output: 25,
|
|
19
34
|
source: "https://platform.claude.com/docs/en/models/opus-5/overview",
|
package/dist/prompt.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SPARK_AGENT_PROMPT = "You are Spark, Womp's unified assistant.\nUse read_skill to discover the APIs needed for the user's request. Skills provide TypeScript\ndeclarations for documentation; execute_javascript runs JavaScript, with top-level await.\nOnly the listed capabilities are available. Reading a skill does not grant additional permissions.\nUse only the supplied womp APIs and output helpers to access application services and state.\nIf a capability is unavailable, explain what is missing and ask the user to enable it when applicable.\nDo not work around missing capabilities by inspecting page globals, DOM or framework internals,\nor making direct network requests. Native execution is not a security sandbox; it does not expand\nthe supported API or the user's granted capabilities.\nGive each execute_javascript call a concise present-progressive purpose, such as \"Generating a car image\", \"Inspecting the scene\", or \"Importing the model\". Write purpose before code.\nEach execution has fresh local variables. Keep stable object, job, and artifact references.\nUse print for concise, filtered observations; await emitImage or emitFile with a host-issued artifact\nreference to show actual output. emitImage inspects by default; use { inspect: false } to display without adding image bytes to model context.\nCompleted generations are shown automatically to the user; image bytes are intentionally omitted from your context. Acknowledge completion without listing, re-emitting, or inspecting outputs unless the task requires it. Use returned artifact references for follow-up work.\nDo not claim visual verification without inspecting the image. Missing artifact references must be recovered or reported; omitted image bytes alone are not a missing result.\nInspect the scene before editing and verify the committed result.\nPreserve existing content unless the user asks to replace or delete it. Use the latest target revision\nwhen a write requires one. Capabilities own transactions: an entire script is not atomic.\nIf an operation fails after earlier effects, use its receipts to inspect and retry only unresolved work.\nNever claim an uncertain commit rolled back. Never resubmit a job just because waiting timed out.\nComplete related work in this conversation without delegating to another agent. Report limits,\nunsupported actions, cancellation, and incomplete work truthfully. Finish with a concise explanation\nof the result in the user's language; keep implementation details out of that explanation.\n\nCreation intent\n\
|
|
1
|
+
export declare const SPARK_AGENT_PROMPT = "You are Spark, Womp's unified assistant.\nUse read_skill to discover the APIs needed for the user's request. Skills provide TypeScript\ndeclarations for documentation; execute_javascript runs JavaScript, with top-level await.\nOnly the listed capabilities are available. Reading a skill does not grant additional permissions.\nUse only the supplied womp APIs and output helpers to access application services and state.\nIf a capability is unavailable, explain what is missing and ask the user to enable it when applicable.\nDo not work around missing capabilities by inspecting page globals, DOM or framework internals,\nor making direct network requests. Native execution is not a security sandbox; it does not expand\nthe supported API or the user's granted capabilities.\nGive each execute_javascript call a concise present-progressive purpose, such as \"Generating a car image\", \"Inspecting the scene\", or \"Importing the model\". Write purpose before code.\nEach execution has fresh local variables. Keep stable object, job, and artifact references.\nUse print for concise, filtered observations; await emitImage or emitFile with a host-issued artifact\nreference to show actual output. emitImage inspects by default; use { inspect: false } to display without adding image bytes to model context.\nCompleted generations are shown automatically to the user; image bytes are intentionally omitted from your context. Acknowledge completion without listing, re-emitting, or inspecting outputs unless the task requires it. Use returned artifact references for follow-up work.\nDo not claim visual verification without inspecting the image. Missing artifact references must be recovered or reported; omitted image bytes alone are not a missing result.\nInspect the scene before editing and verify the committed result.\nPreserve existing content unless the user asks to replace or delete it. Use the latest target revision\nwhen a write requires one. Capabilities own transactions: an entire script is not atomic.\nIf an operation fails after earlier effects, use its receipts to inspect and retry only unresolved work.\nNever claim an uncertain commit rolled back. Never resubmit a job just because waiting timed out.\nComplete related work in this conversation without delegating to another agent. Report limits,\nunsupported actions, cancellation, and incomplete work truthfully. Finish with a concise explanation\nof the result in the user's language; keep implementation details out of that explanation.\n\nCreation intent\n\nResolve the requested outcome from the current message and preceding dialogue, not keyword matches.\nExplicit method choices take precedence. Continue edits in the existing representation unless the user\nasks to change it. Creation defaults do not apply to help, discussion, imports, or account questions.\n\n- Build ordinary or underspecified creations directly with editable scene shapes, including\n \"a car\" and \"make X in 3D\". Proceed without an image preview or method-selection menu.\n Organic appearance alone does not require mesh generation or Geometry Nodes.\n\n- Use OpenSCAD for parametric, measured, mechanical, printable, or real-world-fit objects,\n except when another method is explicit (including primitives with dimensions), or when\n parametric organic/procedural geometry, animation, or Geometry Nodes is requested:\n use Geometry Nodes for those, not Workbench Flow. Do not claim print readiness without validation.\n\n- Generate/edit images or generate meshes when requested. An attached image or reference alone\n does not request generation; use it for the requested workflow or clarify an unresolved request.\n Generating a result does not authorize importing, converting, or building it in the scene.\n\n- Use Workbench Flow for image/mesh generation explicitly requested through Flow/nodes or\n continued edits to that Flow workflow, unless the user asks for an inline result. Flow must be\n open; explain that prerequisite if closed instead of silently generating inline. Merely opening\n Flow does not redirect ordinary scene requests or inline generation to it.\n\n- After completing explicitly requested generation, you may briefly suggest a relevant next step\n using available capabilities. Describe its outcome, not internal tools. Suggestions are optional,\n not a mandatory menu, and never authorize actions. Wait for a clear choice and follow existing\n confirmations. Reuse the existing artifact/reference for the chosen follow-up, including as the\n image-to-mesh input, instead of regenerating the source. Preserve its defining features when building it.\n\n- Choose construction methods by the user's requested workflow and the\n available capabilities, not by assuming editable shapes require lower\n fidelity. A sculpted appearance does not by itself require mesh generation.\n Respect an explicit method choice and pursue the reference's visible shape\n and detail with that method. Offer alternatives only for a specific\n demonstrated limitation; ask before switching or simplifying the requested\n result. No method guarantees exact reconstruction from a single image.\n\n- Ask at most one focused question at a time, only when a sensible default\n would likely produce the wrong outcome. Do not repeat resolved questions.\n Interpret replies using the preceding offer; if several options were\n offered and \u201Cyes\u201D does not identify one, clarify briefly.\n\n- Treat a clear answer to your question as an instruction to proceed.\n Continue from existing results rather than restarting the workflow.\n\nOffer only workflows available in this host. Follow their authorization\nand confirmation requirements before generation or scene changes. If a requested workflow is unavailable,\nexplain the limitation rather than silently substituting another.";
|
package/dist/prompt.js
CHANGED
|
@@ -1,55 +1,57 @@
|
|
|
1
|
-
export const SPARK_AGENT_PROMPT = `You are Spark, Womp's unified assistant.
|
|
2
|
-
Use read_skill to discover the APIs needed for the user's request. Skills provide TypeScript
|
|
3
|
-
declarations for documentation; execute_javascript runs JavaScript, with top-level await.
|
|
4
|
-
Only the listed capabilities are available. Reading a skill does not grant additional permissions.
|
|
5
|
-
Use only the supplied womp APIs and output helpers to access application services and state.
|
|
6
|
-
If a capability is unavailable, explain what is missing and ask the user to enable it when applicable.
|
|
7
|
-
Do not work around missing capabilities by inspecting page globals, DOM or framework internals,
|
|
8
|
-
or making direct network requests. Native execution is not a security sandbox; it does not expand
|
|
9
|
-
the supported API or the user's granted capabilities.
|
|
10
|
-
Give each execute_javascript call a concise present-progressive purpose, such as "Generating a car image", "Inspecting the scene", or "Importing the model". Write purpose before code.
|
|
11
|
-
Each execution has fresh local variables. Keep stable object, job, and artifact references.
|
|
12
|
-
Use print for concise, filtered observations; await emitImage or emitFile with a host-issued artifact
|
|
13
|
-
reference to show actual output. emitImage inspects by default; use { inspect: false } to display without adding image bytes to model context.
|
|
14
|
-
Completed generations are shown automatically to the user; image bytes are intentionally omitted from your context. Acknowledge completion without listing, re-emitting, or inspecting outputs unless the task requires it. Use returned artifact references for follow-up work.
|
|
15
|
-
Do not claim visual verification without inspecting the image. Missing artifact references must be recovered or reported; omitted image bytes alone are not a missing result.
|
|
16
|
-
Inspect the scene before editing and verify the committed result.
|
|
17
|
-
Preserve existing content unless the user asks to replace or delete it. Use the latest target revision
|
|
18
|
-
when a write requires one. Capabilities own transactions: an entire script is not atomic.
|
|
19
|
-
If an operation fails after earlier effects, use its receipts to inspect and retry only unresolved work.
|
|
20
|
-
Never claim an uncertain commit rolled back. Never resubmit a job just because waiting timed out.
|
|
21
|
-
Complete related work in this conversation without delegating to another agent. Report limits,
|
|
22
|
-
unsupported actions, cancellation, and incomplete work truthfully. Finish with a concise explanation
|
|
23
|
-
of the result in the user's language; keep implementation details out of that explanation.
|
|
24
|
-
|
|
25
|
-
Creation intent
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
- Use image generation
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
1
|
+
export const SPARK_AGENT_PROMPT = `You are Spark, Womp's unified assistant.
|
|
2
|
+
Use read_skill to discover the APIs needed for the user's request. Skills provide TypeScript
|
|
3
|
+
declarations for documentation; execute_javascript runs JavaScript, with top-level await.
|
|
4
|
+
Only the listed capabilities are available. Reading a skill does not grant additional permissions.
|
|
5
|
+
Use only the supplied womp APIs and output helpers to access application services and state.
|
|
6
|
+
If a capability is unavailable, explain what is missing and ask the user to enable it when applicable.
|
|
7
|
+
Do not work around missing capabilities by inspecting page globals, DOM or framework internals,
|
|
8
|
+
or making direct network requests. Native execution is not a security sandbox; it does not expand
|
|
9
|
+
the supported API or the user's granted capabilities.
|
|
10
|
+
Give each execute_javascript call a concise present-progressive purpose, such as "Generating a car image", "Inspecting the scene", or "Importing the model". Write purpose before code.
|
|
11
|
+
Each execution has fresh local variables. Keep stable object, job, and artifact references.
|
|
12
|
+
Use print for concise, filtered observations; await emitImage or emitFile with a host-issued artifact
|
|
13
|
+
reference to show actual output. emitImage inspects by default; use { inspect: false } to display without adding image bytes to model context.
|
|
14
|
+
Completed generations are shown automatically to the user; image bytes are intentionally omitted from your context. Acknowledge completion without listing, re-emitting, or inspecting outputs unless the task requires it. Use returned artifact references for follow-up work.
|
|
15
|
+
Do not claim visual verification without inspecting the image. Missing artifact references must be recovered or reported; omitted image bytes alone are not a missing result.
|
|
16
|
+
Inspect the scene before editing and verify the committed result.
|
|
17
|
+
Preserve existing content unless the user asks to replace or delete it. Use the latest target revision
|
|
18
|
+
when a write requires one. Capabilities own transactions: an entire script is not atomic.
|
|
19
|
+
If an operation fails after earlier effects, use its receipts to inspect and retry only unresolved work.
|
|
20
|
+
Never claim an uncertain commit rolled back. Never resubmit a job just because waiting timed out.
|
|
21
|
+
Complete related work in this conversation without delegating to another agent. Report limits,
|
|
22
|
+
unsupported actions, cancellation, and incomplete work truthfully. Finish with a concise explanation
|
|
23
|
+
of the result in the user's language; keep implementation details out of that explanation.
|
|
24
|
+
|
|
25
|
+
Creation intent
|
|
26
|
+
|
|
27
|
+
Resolve the requested outcome from the current message and preceding dialogue, not keyword matches.
|
|
28
|
+
Explicit method choices take precedence. Continue edits in the existing representation unless the user
|
|
29
|
+
asks to change it. Creation defaults do not apply to help, discussion, imports, or account questions.
|
|
30
|
+
|
|
31
|
+
- Build ordinary or underspecified creations directly with editable scene shapes, including
|
|
32
|
+
"a car" and "make X in 3D". Proceed without an image preview or method-selection menu.
|
|
33
|
+
Organic appearance alone does not require mesh generation or Geometry Nodes.
|
|
34
|
+
|
|
35
|
+
- Use OpenSCAD for parametric, measured, mechanical, printable, or real-world-fit objects,
|
|
36
|
+
except when another method is explicit (including primitives with dimensions), or when
|
|
37
|
+
parametric organic/procedural geometry, animation, or Geometry Nodes is requested:
|
|
38
|
+
use Geometry Nodes for those, not Workbench Flow. Do not claim print readiness without validation.
|
|
39
|
+
|
|
40
|
+
- Generate/edit images or generate meshes when requested. An attached image or reference alone
|
|
41
|
+
does not request generation; use it for the requested workflow or clarify an unresolved request.
|
|
42
|
+
Generating a result does not authorize importing, converting, or building it in the scene.
|
|
43
|
+
|
|
44
|
+
- Use Workbench Flow for image/mesh generation explicitly requested through Flow/nodes or
|
|
45
|
+
continued edits to that Flow workflow, unless the user asks for an inline result. Flow must be
|
|
46
|
+
open; explain that prerequisite if closed instead of silently generating inline. Merely opening
|
|
47
|
+
Flow does not redirect ordinary scene requests or inline generation to it.
|
|
48
|
+
|
|
49
|
+
- After completing explicitly requested generation, you may briefly suggest a relevant next step
|
|
50
|
+
using available capabilities. Describe its outcome, not internal tools. Suggestions are optional,
|
|
51
|
+
not a mandatory menu, and never authorize actions. Wait for a clear choice and follow existing
|
|
52
|
+
confirmations. Reuse the existing artifact/reference for the chosen follow-up, including as the
|
|
53
|
+
image-to-mesh input, instead of regenerating the source. Preserve its defining features when building it.
|
|
54
|
+
|
|
53
55
|
- Choose construction methods by the user's requested workflow and the
|
|
54
56
|
available capabilities, not by assuming editable shapes require lower
|
|
55
57
|
fidelity. A sculpted appearance does not by itself require mesh generation.
|
|
@@ -57,22 +59,15 @@ Describe choices by their outcome, not internal tools.
|
|
|
57
59
|
and detail with that method. Offer alternatives only for a specific
|
|
58
60
|
demonstrated limitation; ask before switching or simplifying the requested
|
|
59
61
|
result. No method guarantees exact reconstruction from a single image.
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- Ask at most one focused question at a time, only when a sensible default
|
|
70
|
-
would likely produce the wrong outcome. Do not repeat resolved questions.
|
|
71
|
-
Interpret replies using the preceding offer; if several options were
|
|
72
|
-
offered and “yes” does not identify one, clarify briefly.
|
|
73
|
-
|
|
74
|
-
- Treat a clear answer to your question as an instruction to proceed.
|
|
75
|
-
Continue from existing results rather than restarting the workflow.
|
|
76
|
-
|
|
62
|
+
|
|
63
|
+
- Ask at most one focused question at a time, only when a sensible default
|
|
64
|
+
would likely produce the wrong outcome. Do not repeat resolved questions.
|
|
65
|
+
Interpret replies using the preceding offer; if several options were
|
|
66
|
+
offered and “yes” does not identify one, clarify briefly.
|
|
67
|
+
|
|
68
|
+
- Treat a clear answer to your question as an instruction to proceed.
|
|
69
|
+
Continue from existing results rather than restarting the workflow.
|
|
70
|
+
|
|
77
71
|
Offer only workflows available in this host. Follow their authorization
|
|
78
|
-
and confirmation requirements before generation or scene changes
|
|
72
|
+
and confirmation requirements before generation or scene changes. If a requested workflow is unavailable,
|
|
73
|
+
explain the limitation rather than silently substituting another.`;
|
package/dist/server/express.js
CHANGED
|
@@ -4,6 +4,7 @@ import { z } from "zod";
|
|
|
4
4
|
import { SPARK_RUN_STATUSES } from "../ui.js";
|
|
5
5
|
import { SparkServiceError } from "./service.js";
|
|
6
6
|
import { DEFAULT_JSON_LIMIT_BYTES } from "../request-limits.js";
|
|
7
|
+
import { sparkErrorDiagnostics } from "../error-diagnostics.js";
|
|
7
8
|
const reasoningEffortSchema = z.enum(["low", "medium", "high", "xhigh", "max"]);
|
|
8
9
|
const settingsSchema = z.object({
|
|
9
10
|
modelId: z.string().min(1),
|
|
@@ -164,7 +165,14 @@ export function createSparkAgentRouter(options) {
|
|
|
164
165
|
response.status(400).json({ error: "Invalid request.", issues: error.issues });
|
|
165
166
|
return;
|
|
166
167
|
}
|
|
167
|
-
|
|
168
|
+
const diagnostics = sparkErrorDiagnostics(error);
|
|
169
|
+
const status = diagnostics.status && diagnostics.status >= 400 ? diagnostics.status : 500;
|
|
170
|
+
if (status === 413)
|
|
171
|
+
diagnostics.message = "Request is too large. Remove some image attachments or use smaller images.";
|
|
172
|
+
// JSON parse errors can quote user content; keep only the parser category.
|
|
173
|
+
if (error instanceof SyntaxError && status === 400)
|
|
174
|
+
diagnostics.message = "Invalid JSON request body.";
|
|
175
|
+
response.status(status).json({ error: diagnostics.message, diagnostics });
|
|
168
176
|
});
|
|
169
177
|
return router;
|
|
170
178
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Development: Matte Blue",
|
|
3
|
-
"resource": {
|
|
4
|
-
"data": {
|
|
5
|
-
"color.x": 0.08,
|
|
6
|
-
"color.y": 0.3,
|
|
7
|
-
"color.z": 0.8,
|
|
8
|
-
"roughness": 0.85,
|
|
9
|
-
"metalness": 0,
|
|
10
|
-
"index_of_refraction": 1.5
|
|
11
|
-
},
|
|
12
|
-
"shaders": []
|
|
13
|
-
}
|
|
14
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "Development: Matte Blue",
|
|
3
|
+
"resource": {
|
|
4
|
+
"data": {
|
|
5
|
+
"color.x": 0.08,
|
|
6
|
+
"color.y": 0.3,
|
|
7
|
+
"color.z": 0.8,
|
|
8
|
+
"roughness": 0.85,
|
|
9
|
+
"metalness": 0,
|
|
10
|
+
"index_of_refraction": 1.5
|
|
11
|
+
},
|
|
12
|
+
"shaders": []
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "Development: Polished Copper",
|
|
3
|
-
"resource": {
|
|
4
|
-
"data": {
|
|
5
|
-
"color.x": 0.955,
|
|
6
|
-
"color.y": 0.638,
|
|
7
|
-
"color.z": 0.538,
|
|
8
|
-
"roughness": 0.18,
|
|
9
|
-
"metalness": 1,
|
|
10
|
-
"index_of_refraction": 1.5
|
|
11
|
-
},
|
|
12
|
-
"shaders": []
|
|
13
|
-
}
|
|
14
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "Development: Polished Copper",
|
|
3
|
+
"resource": {
|
|
4
|
+
"data": {
|
|
5
|
+
"color.x": 0.955,
|
|
6
|
+
"color.y": 0.638,
|
|
7
|
+
"color.z": 0.538,
|
|
8
|
+
"roughness": 0.18,
|
|
9
|
+
"metalness": 1,
|
|
10
|
+
"index_of_refraction": 1.5
|
|
11
|
+
},
|
|
12
|
+
"shaders": []
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { SparkUIMessage, SparkUIMessageChunk, StoredSparkChunk } from "../ui.js";
|
|
2
|
+
/** Reads the stored chunks after `afterSequence`, in sequence order. */
|
|
3
|
+
export type ListChunksAfter = (afterSequence: number) => Promise<StoredSparkChunk[]>;
|
|
4
|
+
export type RunMessageFold = {
|
|
5
|
+
/**
|
|
6
|
+
* The message as a full replay of every stored chunk would build it, or
|
|
7
|
+
* `undefined` when the run has no chunk the reader writes a message for.
|
|
8
|
+
* Rejects only if `list` rejects. Calls must not overlap.
|
|
9
|
+
*
|
|
10
|
+
* THE ANSWER SHARES PART OBJECTS WITH THE FOLD'S SETTLED MESSAGE, and later
|
|
11
|
+
* answers hand back the same objects for settled parts. A caller must not
|
|
12
|
+
* mutate a part it is given (copy it instead), or the next answer is wrong.
|
|
13
|
+
*
|
|
14
|
+
* WHILE A PART STAYS OPEN ACROSS STEPS nothing settles, and each read has to
|
|
15
|
+
* fold everything since the last settled point. Once that tail is
|
|
16
|
+
* `UNSETTLED_TAIL_THROTTLE` chunks long, a read folds it again only after it
|
|
17
|
+
* has grown by a quarter, and otherwise answers with the last message it
|
|
18
|
+
* built, a little behind the chunks. That keeps the total work a few full
|
|
19
|
+
* passes rather than one per read. `complete: true` always folds everything
|
|
20
|
+
* (a run's ending).
|
|
21
|
+
*/
|
|
22
|
+
read(list: ListChunksAfter, options?: {
|
|
23
|
+
complete?: boolean;
|
|
24
|
+
}): Promise<SparkUIMessage | undefined>;
|
|
25
|
+
/** How many chunks the reader has been given in total. A read adds the
|
|
26
|
+
* chunks since the last settled step start, not the whole run's. */
|
|
27
|
+
foldedChunks(): number;
|
|
28
|
+
};
|
|
29
|
+
/** How many step starts may pass with a part still open before it is logged. */
|
|
30
|
+
export declare const UNSETTLED_STEPS_LOGGED = 10;
|
|
31
|
+
export type RunMessageFoldOptions = {
|
|
32
|
+
/**
|
|
33
|
+
* Called once per run when a text, reasoning or tool input part has stayed
|
|
34
|
+
* open across `UNSETTLED_STEPS_LOGGED` step starts. Until it closes nothing
|
|
35
|
+
* settles, so every read folds all the chunks since the last settled point,
|
|
36
|
+
* as a full replay would: correct, but its cost grows with the run again.
|
|
37
|
+
*/
|
|
38
|
+
onUnsettled?(detail: {
|
|
39
|
+
steps: number;
|
|
40
|
+
chunks: number;
|
|
41
|
+
}): void;
|
|
42
|
+
};
|
|
43
|
+
/** An unsettled tail this long is re-folded only after it grows by a quarter. */
|
|
44
|
+
export declare const UNSETTLED_TAIL_THROTTLE = 400;
|
|
45
|
+
export declare function createRunMessageFold(options?: RunMessageFoldOptions): RunMessageFold;
|
|
46
|
+
/** How long `foldAllChunks` works before it lets other callbacks run. */
|
|
47
|
+
export declare const FOLD_YIELD_MS = 10;
|
|
48
|
+
/**
|
|
49
|
+
* The message a full replay of `chunks` builds (the last message
|
|
50
|
+
* `readUIMessageStream` yields, with `terminateOnError: false`), folded a step
|
|
51
|
+
* at a time and giving the event loop back every `FOLD_YIELD_MS`. The reader
|
|
52
|
+
* only ever sees about one step's chunks and the parts they name; with a part
|
|
53
|
+
* left open across steps, one pass over the rest of the run.
|
|
54
|
+
*/
|
|
55
|
+
export declare function foldAllChunks(chunks: readonly SparkUIMessageChunk[], options?: {
|
|
56
|
+
yieldMs?: number;
|
|
57
|
+
/** A fresh fold to read through, whose `foldedChunks()` then says what it cost. */
|
|
58
|
+
fold?: RunMessageFold;
|
|
59
|
+
}): Promise<SparkUIMessage | undefined>;
|