@womp/spark-agent 6.5.0 → 8.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 +86 -0
- package/README.md +7 -4
- package/dist/agent.d.ts +3 -6
- package/dist/agent.js +41 -23
- package/dist/capabilities/geometry.d.ts +17 -5
- package/dist/capabilities/geometry.js +11 -12
- package/dist/compaction.d.ts +41 -8
- package/dist/compaction.js +241 -77
- package/dist/context-window.d.ts +23 -0
- package/dist/context-window.js +141 -0
- package/dist/generated/geometry-declarations.d.ts +1 -1
- package/dist/generated/geometry-declarations.js +1 -1
- package/dist/geometry/backendRegistry.d.ts +1 -0
- package/dist/geometry/common.d.ts +5 -2
- package/dist/geometry/common.js +18 -3
- package/dist/geometry/compiler.js +2 -2
- package/dist/geometry/diagnostics.d.ts +2 -7
- package/dist/geometry/diagnostics.js +3 -51
- package/dist/geometry/graph.d.ts +1 -1
- package/dist/geometry/graph.js +1 -0
- package/dist/geometry/index.d.ts +0 -1
- package/dist/geometry/index.js +0 -3
- package/dist/geometry/lift.js +105 -113
- package/dist/geometry/lower.js +29 -49
- package/dist/geometry/schemas/flowir-dialect.json +117 -117
- package/dist/geometry/writeParamData.js +4 -4
- package/dist/geometry.d.ts +2 -5
- package/dist/geometry.js +7 -11
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -1
- package/dist/intent-bench.js +1 -1
- package/dist/sdk-geometry-host.d.ts +1 -1
- package/dist/sdk-geometry-host.js +253 -251
- package/dist/ui.d.ts +7 -0
- package/dist/ui.js +1 -0
- package/dist/womp-scene-api.d.ts +9 -1
- package/dist/womp-scene-api.js +41 -32
- package/package.json +2 -2
- package/dist/context-budget.d.ts +0 -65
- package/dist/context-budget.js +0 -364
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,92 @@ 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
|
+
## 8.0.0 — 2026-10-12
|
|
8
|
+
|
|
9
|
+
Geometry Nodes moves to FlowIR 0.5.0. The dialect is FlowIR's strict, flat format, the
|
|
10
|
+
`geometry-nodes-reference` skill is the prompt FlowIR renders from it, and the names the agent
|
|
11
|
+
writes come back when it reads the graph, so a follow-up edit can refer to them.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- `@womp/flowir` is 0.5.0. The geometry dialect declares its types, enum ports, casts and the
|
|
16
|
+
`Geometry` program output. `param` and `const` declare Int, Float and Vec3; other types are
|
|
17
|
+
rejected instead of being dropped when the graph is written.
|
|
18
|
+
- A write stores each statement's name in `graphExt.nodes[id].flowirSymbol`, and a read returns
|
|
19
|
+
those names. Graphs written without stored names read back as before.
|
|
20
|
+
- Compiler diagnostics are formatted by FlowIR, within the existing count and size bounds.
|
|
21
|
+
- `geometry-nodes` (skill version 6) and `geometry-nodes-reference` (version 3) are rewritten
|
|
22
|
+
for the new dialect.
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- `GeometryTarget.transform` and `GeometryTarget.bounds`: the target's position, rotation and
|
|
27
|
+
size relative to its parent, and its world-space extent, in project units. Both are `null`
|
|
28
|
+
where they do not apply.
|
|
29
|
+
- An applied `GeometryWriteResult` also carries the committed `source`, `transform` and
|
|
30
|
+
`bounds`, read back from the scene.
|
|
31
|
+
|
|
32
|
+
### Removed
|
|
33
|
+
|
|
34
|
+
- `loadGeoNodesDialect` from `@womp/spark-agent/geometry`.
|
|
35
|
+
|
|
36
|
+
### Migration
|
|
37
|
+
|
|
38
|
+
- `geometryReference()` returns a string instead of `{ rules, catalog }`, and
|
|
39
|
+
`createGeometryCapability` takes that string. Pass `geometryReference()` through unchanged.
|
|
40
|
+
- A host that builds `GeometryTarget` values itself, rather than through
|
|
41
|
+
`createSdkGeometryHost`, must set `transform` and `bounds` (`null` when unknown).
|
|
42
|
+
|
|
43
|
+
## 7.0.0 — 2026-10-12
|
|
44
|
+
|
|
45
|
+
Compaction is now the only thing that takes messages out of what the model reads, and it can run
|
|
46
|
+
before any step of a turn, not just the first. The per-step trimming that replaced earlier images,
|
|
47
|
+
tool results and whole turns with placeholder text is gone: it rewrote the start of the prompt
|
|
48
|
+
whenever it fired, which threw away the provider's prompt cache on every later step. A request
|
|
49
|
+
that is still over the model's context window after compaction is sent as it is and fails with
|
|
50
|
+
the provider's error.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- A run given `history` checks the conversation before every step. Once it reaches the compaction
|
|
55
|
+
threshold during a turn, everything before the current user message and the turn's steps before
|
|
56
|
+
its most recent `COMPACTION_KEEP_RECENT_TOKENS` are summarized; the user's message is kept
|
|
57
|
+
verbatim. The summary request is the first kept step's request plus one instruction, so it is
|
|
58
|
+
served from the prompt cache. A compaction that would save less than
|
|
59
|
+
`COMPACTION_MIN_SAVED_RATIO` of the threshold is skipped, so a turn whose own message is over
|
|
60
|
+
the threshold does not summarize on every step.
|
|
61
|
+
- A summary covers only the messages it replaces, before a turn as well as during one. It used to
|
|
62
|
+
tell of the kept messages too, and the model, reading them again after it, took that work for
|
|
63
|
+
done twice.
|
|
64
|
+
- `SparkCompaction.firstKeptStep` records a compaction written during its turn: the first step of
|
|
65
|
+
the recording assistant message the model still reads. `applyCompaction` (and so
|
|
66
|
+
`convertSparkMessages`) leaves the earlier steps out, so the next turn rebuilds exactly the
|
|
67
|
+
messages the last step was sent. A run may now record more than one `data-compaction` part; the
|
|
68
|
+
latest is the one in force. Hosts must store and reload message parts in order, including
|
|
69
|
+
`step-start`.
|
|
70
|
+
- When to compact is measured from the provider's count for the conversation's last step after the
|
|
71
|
+
latest compaction, including the steps of the message that recorded it.
|
|
72
|
+
|
|
73
|
+
### Added
|
|
74
|
+
|
|
75
|
+
- `applyCompaction` and `latestCompaction` are exported from the package root, so a host can tell
|
|
76
|
+
which stored messages, and which of their images, the model will be sent.
|
|
77
|
+
|
|
78
|
+
### Removed
|
|
79
|
+
|
|
80
|
+
- `fitMessagesToContext`, `ContextBudgetOptions`, `ContextBudgetReport`, `ContextBudgetResult`,
|
|
81
|
+
`TRIM_TRIGGER_RATIO`, `TRIM_TARGET_RATIO`, `SMALL_TOOL_OUTPUT_TOKENS`,
|
|
82
|
+
`PROTECTED_CURRENT_STEPS` and the `OMITTED_HISTORY_TEXT`, `OMITTED_HISTORY_IMAGE_TEXT` and
|
|
83
|
+
`OMITTED_TOOL_OUTPUT_TEXT` notes.
|
|
84
|
+
- `SparkAgentOptions.onContextBudget`.
|
|
85
|
+
|
|
86
|
+
### Migration
|
|
87
|
+
|
|
88
|
+
- Remove any `onContextBudget` handler and any host-side trimming. Pass `history` to have long
|
|
89
|
+
conversations compacted; a run given `messages` is sent exactly what it is given.
|
|
90
|
+
- `contextWindowFor`, `estimateMessagesTokens`, `estimateRequestTokens`, `CHARS_PER_TOKEN` and
|
|
91
|
+
`IMAGE_TOKENS` are unchanged; they now live in `src/context-window.ts`.
|
|
92
|
+
|
|
7
93
|
## 6.5.0 — 2026-10-12
|
|
8
94
|
|
|
9
95
|
The agent proposes a goal during its turn, instead of the host asking a separate model call to
|
package/README.md
CHANGED
|
@@ -75,9 +75,11 @@ The default model-step limit is 100; reaching it returns `status: "incomplete"`,
|
|
|
75
75
|
restart automatically to bypass it. A generation that ends on any other non-`stop` reason fails the
|
|
76
76
|
run with the unified and provider finish reasons in its error and diagnostics.
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
When a run is given its stored `history`, Spark compacts it before any model step once the
|
|
79
|
+
conversation reaches the compaction threshold: earlier turns, and earlier steps of a long turn, are
|
|
80
|
+
replaced by a summary recorded on the run's message as a `data-compaction` part. Nothing else
|
|
81
|
+
shortens a request; one that is still over the model's context window fails with the provider's
|
|
82
|
+
error.
|
|
81
83
|
|
|
82
84
|
### Artifacts
|
|
83
85
|
|
|
@@ -355,7 +357,8 @@ features, patch for backward-compatible fixes.
|
|
|
355
357
|
|
|
356
358
|
- `src/agent.ts` — AI SDK stream and Spark tool orchestration
|
|
357
359
|
- `src/prompt.ts` — shared system prompt
|
|
358
|
-
- `src/
|
|
360
|
+
- `src/compaction.ts` — conversation compaction before each model step
|
|
361
|
+
- `src/context-window.ts` — model context windows and request size estimates
|
|
359
362
|
- `src/ui.ts` — browser-safe protocol types and validation schemas
|
|
360
363
|
- `src/client.ts` — durable `ChatTransport` implementation
|
|
361
364
|
- `src/server/` — service, storage contracts, Express adapter, artifacts, and standalone composition
|
package/dist/agent.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { streamText, type LanguageModel, type ModelMessage } from "ai";
|
|
|
2
2
|
import { type SparkGoalOffer, type SparkPersistence } from "./agent-tools.js";
|
|
3
3
|
import type { SparkArtifactResolver, SparkCapabilities } from "./capabilities.js";
|
|
4
4
|
import type { JavaScriptExecutor } from "./executor.js";
|
|
5
|
-
import { type ContextBudgetReport } from "./context-budget.js";
|
|
6
5
|
import { type SparkCompactionLimits } from "./compaction.js";
|
|
7
6
|
import type { SparkUIMessage, SparkUIMessageChunk } from "./ui.js";
|
|
8
7
|
export type SparkAgentResult = {
|
|
@@ -17,8 +16,8 @@ export type SparkAgentOptions = {
|
|
|
17
16
|
messages?: ModelMessage[];
|
|
18
17
|
/**
|
|
19
18
|
* The stored conversation. It is converted with `convertSparkMessages`, and
|
|
20
|
-
* compacted
|
|
21
|
-
* compaction is written to this run's message as a `data-compaction` part.
|
|
19
|
+
* compacted before any step once it is long enough (./compaction.ts); each
|
|
20
|
+
* new compaction is written to this run's message as a `data-compaction` part.
|
|
22
21
|
*/
|
|
23
22
|
history?: SparkUIMessage[];
|
|
24
23
|
model: LanguageModel;
|
|
@@ -38,12 +37,10 @@ export type SparkAgentOptions = {
|
|
|
38
37
|
/** Gives the model `propose_goal`; absent, it has no way to offer a goal. */
|
|
39
38
|
proposeGoal?: SparkGoalOffer;
|
|
40
39
|
prepareMessages?(messages: ModelMessage[]): Promise<ModelMessage[]>;
|
|
41
|
-
/** The model's context window. Absent: `contextWindowFor(modelId)`. */
|
|
40
|
+
/** The model's context window, which caps when `history` is compacted. Absent: `contextWindowFor(modelId)`. */
|
|
42
41
|
contextWindow?: number;
|
|
43
42
|
/** When `history` is compacted. Absent: the defaults in ./compaction.ts. */
|
|
44
43
|
compaction?: SparkCompactionLimits;
|
|
45
|
-
/** Called when a step's messages had to be trimmed to fit, or still do not fit. */
|
|
46
|
-
onContextBudget?(report: ContextBudgetReport): void;
|
|
47
44
|
};
|
|
48
45
|
export type SparkAgentRun = {
|
|
49
46
|
stream: ReadableStream<SparkUIMessageChunk>;
|
package/dist/agent.js
CHANGED
|
@@ -4,8 +4,8 @@ import { createUIMessageStream, stepCountIs, streamText, } from "ai";
|
|
|
4
4
|
import { createSparkTools } from "./agent-tools.js";
|
|
5
5
|
import { sparkSystemPrompt } from "./prompt.js";
|
|
6
6
|
import { calculateStepCost } from "./pricing.js";
|
|
7
|
-
import { contextWindowFor
|
|
8
|
-
import { compactSparkHistory } from "./compaction.js";
|
|
7
|
+
import { contextWindowFor } from "./context-window.js";
|
|
8
|
+
import { compactSparkHistory, createStepCompaction, latestCompaction } from "./compaction.js";
|
|
9
9
|
import { convertSparkMessages } from "./model-history.js";
|
|
10
10
|
function errorMessage(error) {
|
|
11
11
|
return sparkErrorDiagnostics(error).message;
|
|
@@ -131,11 +131,14 @@ export function runSparkAgent(options) {
|
|
|
131
131
|
});
|
|
132
132
|
const readSystem = () => sparkSystemPrompt(options.capabilities.skills, options.instructions);
|
|
133
133
|
let messages = options.messages ?? [];
|
|
134
|
+
// Compaction before each later step; only for a stored conversation,
|
|
135
|
+
// where the compaction can be recorded.
|
|
136
|
+
let compactStep;
|
|
134
137
|
if (options.history !== undefined) {
|
|
135
138
|
const history = options.history;
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
const skills = options.capabilities.skills;
|
|
140
|
+
let compactions = 0;
|
|
141
|
+
const summaryOptions = {
|
|
139
142
|
model: options.model,
|
|
140
143
|
modelId: options.modelId,
|
|
141
144
|
system: readSystem(),
|
|
@@ -149,12 +152,29 @@ export function runSparkAgent(options) {
|
|
|
149
152
|
type: "data-run-status",
|
|
150
153
|
data: { runId: options.runId, status: "running", label: "Making room so we can keep talking" },
|
|
151
154
|
}),
|
|
155
|
+
};
|
|
156
|
+
const record = (compaction) => writer.write({
|
|
157
|
+
type: "data-compaction",
|
|
158
|
+
id: `compaction-${options.messageId}${compactions++ === 0 ? "" : `-${compactions}`}`,
|
|
159
|
+
data: compaction,
|
|
160
|
+
});
|
|
161
|
+
const compacted = await compactSparkHistory({
|
|
162
|
+
...summaryOptions,
|
|
163
|
+
history,
|
|
164
|
+
convert: (compaction) => convertSparkMessages(history, tools, { compaction, skills }),
|
|
152
165
|
});
|
|
153
166
|
messages = compacted.messages;
|
|
154
|
-
if (compacted.compaction !== undefined)
|
|
155
|
-
|
|
156
|
-
}
|
|
167
|
+
if (compacted.compaction !== undefined)
|
|
168
|
+
record(compacted.compaction);
|
|
157
169
|
controller.signal.throwIfAborted();
|
|
170
|
+
compactStep = createStepCompaction({
|
|
171
|
+
...summaryOptions,
|
|
172
|
+
history,
|
|
173
|
+
previous: compacted.compaction ?? latestCompaction(history)?.compaction,
|
|
174
|
+
skills,
|
|
175
|
+
convert: (stored) => convertSparkMessages(stored, tools, { skills }),
|
|
176
|
+
onCompaction: record,
|
|
177
|
+
});
|
|
158
178
|
}
|
|
159
179
|
const generation = streamText({
|
|
160
180
|
model: options.model,
|
|
@@ -166,25 +186,23 @@ export function runSparkAgent(options) {
|
|
|
166
186
|
stopWhen: stepCountIs(maxSteps),
|
|
167
187
|
maxOutputTokens: options.maxOutputTokens,
|
|
168
188
|
providerOptions: options.providerOptions,
|
|
169
|
-
prepareStep: async ({ messages }) => {
|
|
189
|
+
prepareStep: async ({ messages, steps }) => {
|
|
170
190
|
controller.signal.throwIfAborted();
|
|
171
|
-
|
|
191
|
+
// The first step was compacted above, before the request was built.
|
|
192
|
+
// The AI SDK sends each later step what the one before it was sent,
|
|
193
|
+
// so a compaction here holds for the rest of the turn.
|
|
194
|
+
const last = steps.at(-1)?.usage;
|
|
195
|
+
const current = compactStep === undefined || steps.length === 0
|
|
172
196
|
? messages
|
|
173
|
-
: await
|
|
197
|
+
: await compactStep(messages, { inputTokens: last?.inputTokens, outputTokens: last?.outputTokens });
|
|
198
|
+
controller.signal.throwIfAborted();
|
|
199
|
+
const prepared = options.prepareMessages === undefined
|
|
200
|
+
? current
|
|
201
|
+
: await options.prepareMessages(current);
|
|
174
202
|
controller.signal.throwIfAborted();
|
|
175
|
-
const system = readSystem();
|
|
176
|
-
// After the host's own preparation, so what is measured is what is sent.
|
|
177
|
-
const fitted = fitMessagesToContext(prepared, {
|
|
178
|
-
contextWindow,
|
|
179
|
-
maxOutputTokens: options.maxOutputTokens,
|
|
180
|
-
system,
|
|
181
|
-
tools,
|
|
182
|
-
});
|
|
183
|
-
if (fitted.report && (fitted.messages !== prepared || !fitted.report.fits))
|
|
184
|
-
options.onContextBudget?.(fitted.report);
|
|
185
203
|
return {
|
|
186
|
-
system,
|
|
187
|
-
messages:
|
|
204
|
+
system: readSystem(),
|
|
205
|
+
messages: prepared,
|
|
188
206
|
};
|
|
189
207
|
},
|
|
190
208
|
onError: ({ error }) => {
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import type { SparkCapability, SparkInvocationContext } from "../capabilities.js";
|
|
2
|
-
export type
|
|
2
|
+
export type GeometryVector = {
|
|
3
3
|
x: number;
|
|
4
4
|
y: number;
|
|
5
5
|
z: number;
|
|
6
6
|
};
|
|
7
|
+
export type GeometryParamValue = number | GeometryVector;
|
|
8
|
+
export type GeometryTransform = {
|
|
9
|
+
position: GeometryVector;
|
|
10
|
+
rotation: GeometryVector;
|
|
11
|
+
size: GeometryVector;
|
|
12
|
+
};
|
|
13
|
+
export type GeometryBounds = {
|
|
14
|
+
min: GeometryVector;
|
|
15
|
+
max: GeometryVector;
|
|
16
|
+
};
|
|
7
17
|
export type GeometryInstance = {
|
|
8
18
|
instanceId: number;
|
|
9
19
|
objectIds: number[];
|
|
@@ -16,6 +26,8 @@ export type GeometryTarget = {
|
|
|
16
26
|
graphId?: number;
|
|
17
27
|
instanceId?: number;
|
|
18
28
|
source: string | null;
|
|
29
|
+
transform: GeometryTransform | null;
|
|
30
|
+
bounds: GeometryBounds | null;
|
|
19
31
|
instances: GeometryInstance[];
|
|
20
32
|
diagnostics: string[];
|
|
21
33
|
};
|
|
@@ -28,6 +40,9 @@ export type GeometryWriteResult = {
|
|
|
28
40
|
objectId: number;
|
|
29
41
|
graphId?: number;
|
|
30
42
|
instanceId?: number;
|
|
43
|
+
source?: string;
|
|
44
|
+
transform?: GeometryTransform | null;
|
|
45
|
+
bounds?: GeometryBounds | null;
|
|
31
46
|
affectedObjectIds: number[];
|
|
32
47
|
diagnostics: string[];
|
|
33
48
|
};
|
|
@@ -39,7 +54,4 @@ export interface GeometryHost {
|
|
|
39
54
|
read(objectId: number, context: SparkInvocationContext): Promise<GeometryTarget>;
|
|
40
55
|
write(options: GeometryWrite, context: SparkInvocationContext): Promise<GeometryWriteResult>;
|
|
41
56
|
}
|
|
42
|
-
export declare function createGeometryCapability(host: GeometryHost, reference:
|
|
43
|
-
rules: string;
|
|
44
|
-
catalog: string;
|
|
45
|
-
}): SparkCapability<WompGeometryApi>;
|
|
57
|
+
export declare function createGeometryCapability(host: GeometryHost, reference: string): SparkCapability<WompGeometryApi>;
|
|
@@ -12,23 +12,22 @@ export function createGeometryCapability(host, reference) {
|
|
|
12
12
|
skills: [
|
|
13
13
|
{
|
|
14
14
|
name: "geometry-nodes",
|
|
15
|
-
version: "
|
|
15
|
+
version: "6",
|
|
16
16
|
description: "Create and edit visual Geometry Nodes graphs with adjustable parameters and animation.",
|
|
17
17
|
instructions: `Use womp.geometry for requested Geometry Nodes, parametric organic/procedural geometry, or animation.
|
|
18
18
|
Keep follow-up edits to an existing Geometry Nodes object in its graph, preserving its adjustable parameters and instances.
|
|
19
|
-
|
|
19
|
+
An Area is a scene object that holds one Geometry Nodes graph; a Group is a container. read(0) reads the scene root as a creation container.
|
|
20
|
+
read returns the target's FlowIR source, its instances with their parameter overrides (in FlowIR units), its transform and its bounds. transform is position, rotation and size relative to the parent, in project units as the scene API reports them; an Area's size is a dimensionless scale, and the scene root's transform is null. bounds is the world-space extent in project units, null unless the target is a top-level Area whose graph renders geometry. Read the target again after another scene edit changes it.
|
|
21
|
+
If source is null and diagnostics is non-empty, the existing graph cannot be edited without loss. Explain the limitation; never treat it as empty or create a replacement to bypass the refusal.
|
|
22
|
+
Read geometry-nodes-reference before writing source. source is the complete FlowIR text for the target; JavaScript calls execute JavaScript, and source is a FlowIR string, not JavaScript or JSON.
|
|
20
23
|
write updates an existing shared graph, attaches a new graph to an Area without one, or creates a new Area beneath the root/Group target. Use the returned objectId for follow-up edits.
|
|
21
|
-
|
|
22
|
-
Inspect the current target before replacing its graph; preserve unrelated geometry and parameter overrides.
|
|
23
|
-
If source is null and diagnostics are present, the existing graph cannot be edited without loss. Explain the limitation; never treat it as empty or create a replacement to bypass the refusal.
|
|
24
|
-
Preserve unrelated statements, parameter names, and FlowIR node IDs from the read. Shared graph edits affect all listed instances; report the affected objects. Valid overrides migrate by parameter name and type. Removed or type-changed parameters return to graph defaults and are reported.
|
|
24
|
+
Preserve unrelated statements, parameter names, FlowIR node IDs and parameter overrides from the read. Shared graph edits affect all listed instances; report the affected objects. Valid overrides migrate by parameter name and type. Removed or type-changed parameters return to graph defaults and are reported.
|
|
25
25
|
Use min/max/step for naturally bounded parameters and omit ranges for free-form positions/rotations. Meaningful parameter names become editor labels. Do not invent label fields.
|
|
26
26
|
SetMaterial assigns one scene material to every primitive it receives. Its Material input is a scene material ID, not a color; 0 selects the scene default material.
|
|
27
|
-
Obtain that ID from the scene-editing skill inside
|
|
28
|
-
|
|
29
|
-
Positions and sizes are millimetres; Boolean Blend uses the conversion in geometry-nodes-reference. Coordinates are right-handed, +X right, +Y up, +Z forward. Rotations are degrees, intrinsic X-Z-Y.
|
|
27
|
+
Obtain that ID from the scene-editing skill inside womp.scene.access, in the same JavaScript call as the write and before it: materialList with materialGetName and materialGetColor to reuse an existing material, materialCreate with materialSetColor and materialSetName for a new one, or listSuperMaterials with materialImport for a library material. Prefer reusing a material that already matches the request over creating another, and do not recolor a shared material unless every object using it should change.
|
|
28
|
+
FlowIR positions and sizes are millimetres; Boolean Blend uses the conversion in geometry-nodes-reference. Coordinates are right-handed, +X right, +Y up, +Z forward. Rotations are degrees, intrinsic X-Z-Y.
|
|
30
29
|
On compiler errors, repair the source in this same conversation and retry with a fresh read. A rejected write made no change. Committed/unknown effects remain in execution receipts even if a later call fails; inspect before retrying.
|
|
31
|
-
|
|
30
|
+
When status is "applied", the write result also holds the committed target read back from the scene: source, transform and bounds. Print it; it verifies the graph, so do not read the target again to check it. When the target's latest source is already printed in this conversation, make its next edit in a single call: read, replace and write. Use the scene screenshot API with emitImage to inspect the applied result.`,
|
|
32
31
|
declarations: WOMP_GEOMETRY_DECLARATIONS,
|
|
33
32
|
examples: [
|
|
34
33
|
"const target = await womp.geometry.read(objectId); print(target);",
|
|
@@ -38,9 +37,9 @@ After applying, read the returned object and use the scene screenshot API with e
|
|
|
38
37
|
},
|
|
39
38
|
{
|
|
40
39
|
name: "geometry-nodes-reference",
|
|
41
|
-
version: "
|
|
40
|
+
version: "3",
|
|
42
41
|
description: "FlowIR syntax, types, enums, and supported Geometry Nodes catalog; read before writing a graph.",
|
|
43
|
-
instructions:
|
|
42
|
+
instructions: reference,
|
|
44
43
|
declarations: "",
|
|
45
44
|
examples: [],
|
|
46
45
|
},
|
package/dist/compaction.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ import type { SparkSkill } from "./capabilities.js";
|
|
|
3
3
|
import { type SparkCompaction, type SparkUIMessage } from "./ui.js";
|
|
4
4
|
/** Compact once the conversation reaches this many tokens. */
|
|
5
5
|
export declare const COMPACTION_THRESHOLD_TOKENS = 256000;
|
|
6
|
-
/** Recent whole turns kept verbatim, up to this many tokens
|
|
6
|
+
/** Recent whole turns, or recent steps of the current turn, kept verbatim, up to this many tokens. */
|
|
7
7
|
export declare const COMPACTION_KEEP_RECENT_TOKENS = 16000;
|
|
8
8
|
/** The user's newest images from the summarized messages that the summary message carries. */
|
|
9
9
|
export declare const COMPACTION_USER_IMAGES = 4;
|
|
10
|
+
/** A compaction during a turn saves at least this share of the threshold, or is not made. */
|
|
11
|
+
export declare const COMPACTION_MIN_SAVED_RATIO = 0.25;
|
|
10
12
|
/**
|
|
11
13
|
* When a conversation is compacted, for a host that exercises compaction
|
|
12
14
|
* without filling a production-sized conversation, such as local development.
|
|
@@ -19,27 +21,28 @@ export type SparkCompactionLimits = {
|
|
|
19
21
|
};
|
|
20
22
|
export declare const COMPACTION_PROMPT = "Write a checkpoint summary of this conversation so far. It replaces the earlier messages in your context, so the work must be able to continue from it alone. Reply with the summary only, without calling tools. This request is not part of the conversation: leave it out of the summary.\nIf the conversation begins with an earlier summary, carry its content forward and update it.\nUse these sections:\n## Goal\n## User preferences and constraints\n## Decisions and current scene state (objects with their names and IDs)\n## Done\n## Open and next steps\n## Artifacts and images (each artifact ID, and what each image the user attached shows)\n## Errors and approaches to avoid\nKeep exact names, IDs, numbers and the user's own wording for requirements. Stay under 1,500 words.";
|
|
21
23
|
export declare const COMPACTION_NOTE = "[Earlier messages in this conversation were replaced by the summary below. The scene itself is unchanged; inspect it for its exact state.]";
|
|
24
|
+
export declare const COMPACTION_STEPS_NOTE = "[Earlier messages in this conversation, and the earlier steps of your work on the message after this one, were replaced by the summary below. The scene itself is unchanged; inspect it for its exact state.]";
|
|
22
25
|
/** The latest compaction in the conversation whose kept message is still in it. */
|
|
23
26
|
export declare function latestCompaction(history: SparkUIMessage[]): {
|
|
24
27
|
compaction: SparkCompaction;
|
|
25
28
|
carrier: number;
|
|
29
|
+
part: number;
|
|
26
30
|
firstKept: number;
|
|
27
31
|
} | undefined;
|
|
28
32
|
/**
|
|
29
33
|
* The conversation as the model reads it: the messages before the compaction's
|
|
30
34
|
* kept message replaced by its summary, with the newest COMPACTION_USER_IMAGES
|
|
31
|
-
* images the user attached to them
|
|
32
|
-
*
|
|
33
|
-
*
|
|
35
|
+
* images the user attached to them, and -- for the latest compaction, when it was
|
|
36
|
+
* written during its turn -- the recording message's steps before
|
|
37
|
+
* `firstKeptStep` left out with them. `compaction` defaults to the latest one in
|
|
38
|
+
* `history`; `skills` are the host's, to send the current text of the skills it
|
|
39
|
+
* names. Without a compaction, `history` is returned as it is.
|
|
34
40
|
*/
|
|
35
41
|
export declare function applyCompaction(history: SparkUIMessage[], options?: {
|
|
36
42
|
compaction?: SparkCompaction;
|
|
37
43
|
skills?: readonly SparkSkill[];
|
|
38
44
|
}): SparkUIMessage[];
|
|
39
|
-
|
|
40
|
-
history: SparkUIMessage[];
|
|
41
|
-
/** `history` as model messages, with `compaction` applied when given. */
|
|
42
|
-
convert(compaction?: SparkCompaction): Promise<ModelMessage[]>;
|
|
45
|
+
type SummaryOptions = {
|
|
43
46
|
model: LanguageModel;
|
|
44
47
|
modelId: string;
|
|
45
48
|
system: string;
|
|
@@ -53,6 +56,11 @@ export type CompactSparkHistoryOptions = {
|
|
|
53
56
|
onCompacting?(): void;
|
|
54
57
|
limits?: SparkCompactionLimits;
|
|
55
58
|
};
|
|
59
|
+
export type CompactSparkHistoryOptions = SummaryOptions & {
|
|
60
|
+
history: SparkUIMessage[];
|
|
61
|
+
/** `history` as model messages, with `compaction` applied when given. */
|
|
62
|
+
convert(compaction?: SparkCompaction): Promise<ModelMessage[]>;
|
|
63
|
+
};
|
|
56
64
|
/**
|
|
57
65
|
* The turn's model messages, compacted first when the conversation has reached
|
|
58
66
|
* the threshold. `compaction` is the new one, for the host to record; it is
|
|
@@ -62,3 +70,28 @@ export declare function compactSparkHistory(options: CompactSparkHistoryOptions)
|
|
|
62
70
|
messages: ModelMessage[];
|
|
63
71
|
compaction?: SparkCompaction;
|
|
64
72
|
}>;
|
|
73
|
+
export type StepCompactionOptions = SummaryOptions & {
|
|
74
|
+
/** The stored conversation, ending with the current user message. */
|
|
75
|
+
history: SparkUIMessage[];
|
|
76
|
+
/** The compaction the turn started from: the one written before its first step, else `history`'s latest. */
|
|
77
|
+
previous?: SparkCompaction;
|
|
78
|
+
/** The host's skills, for the summary message's skill text. */
|
|
79
|
+
skills?: readonly SparkSkill[];
|
|
80
|
+
/** Stored messages as model messages. */
|
|
81
|
+
convert(messages: SparkUIMessage[]): Promise<ModelMessage[]>;
|
|
82
|
+
/** A new compaction, for the host to record on the turn's message. */
|
|
83
|
+
onCompaction(compaction: SparkCompaction): void;
|
|
84
|
+
};
|
|
85
|
+
/** What the provider reported for the step before. */
|
|
86
|
+
export type StepUsage = {
|
|
87
|
+
inputTokens?: number;
|
|
88
|
+
outputTokens?: number;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Compaction before each later step of a turn. Returns the step's messages,
|
|
92
|
+
* compacted when the conversation has reached the threshold; the AI SDK carries
|
|
93
|
+
* what a step was sent into the next, so a compaction holds for the rest of the
|
|
94
|
+
* turn.
|
|
95
|
+
*/
|
|
96
|
+
export declare function createStepCompaction(options: StepCompactionOptions): (messages: ModelMessage[], last?: StepUsage) => Promise<ModelMessage[]>;
|
|
97
|
+
export {};
|