@womp/spark-agent 5.5.0 → 5.6.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 +16 -17
- package/dist/agent-tools.js +4 -7
- package/dist/ui.d.ts +1 -5
- package/package.json +3 -2
- package/dist/sdk-openscad-renderer.d.ts +0 -11
- package/dist/sdk-openscad-renderer.js +0 -71
package/README.md
CHANGED
|
@@ -395,7 +395,9 @@ yarn web:build
|
|
|
395
395
|
|
|
396
396
|
## Release procedure
|
|
397
397
|
|
|
398
|
-
|
|
398
|
+
Pushes to `main` run `.github/workflows/publish.yml`. Publication is driven by
|
|
399
|
+
`package.json`, not Git tags: already-published versions skip; unpublished stable versions
|
|
400
|
+
newer than npm's `latest` run release checks and publish automatically.
|
|
399
401
|
|
|
400
402
|
Versions follow **MAJOR.MINOR.PATCH** (for example, `4.4.0`):
|
|
401
403
|
|
|
@@ -405,22 +407,19 @@ Versions follow **MAJOR.MINOR.PATCH** (for example, `4.4.0`):
|
|
|
405
407
|
|
|
406
408
|
### Publishing
|
|
407
409
|
|
|
408
|
-
1.
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
2.
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
4.
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
and push the release commit and tag. An already published version cannot be replaced; corrections
|
|
422
|
-
need a new version.
|
|
423
|
-
5. In the consuming application, use `yarn add @womp/spark-agent@<version> --exact`. Commit its
|
|
410
|
+
1. Configure npm's trusted publisher once for `@womp/spark-agent`: organization `wompxyz`,
|
|
411
|
+
repository `spark-agent`, workflow filename `publish.yml`, no environment, and allow direct
|
|
412
|
+
`npm publish`. GitHub-hosted runners use OIDC; no publishing token is required.
|
|
413
|
+
2. Deliberately bump `package.json` to an unused stable MAJOR.MINOR.PATCH version and push
|
|
414
|
+
the release commit to `main`. Prereleases/build metadata are not published by this workflow.
|
|
415
|
+
3. CI installs the frozen Yarn lockfile, runs typechecks, tests and the UI build, then checks
|
|
416
|
+
package entry files and imports every exported module from a fresh tarball installation.
|
|
417
|
+
It rechecks npm before publishing that same archive and verifies registry integrity and `latest`.
|
|
418
|
+
Releases are serialized; newer pending pushes may supersede older pending runs.
|
|
419
|
+
Registry failures stop publication rather than being treated as missing versions.
|
|
420
|
+
4. If publication reports an uncertain result, inspect npm before rerunning the failed workflow.
|
|
421
|
+
Published versions cannot be replaced; corrections need a new version. No tags are required.
|
|
422
|
+
5. In the consuming application, use `yarn add @womp/spark-agent@<version> --exact`. Commit its
|
|
424
423
|
manifest and lockfile together, and verify a clean frozen-lockfile installation and production
|
|
425
424
|
build. Remove the temporary archive dependency. Application deployment and merge requirements
|
|
426
425
|
remain separate from package publication.
|
package/dist/agent-tools.js
CHANGED
|
@@ -79,11 +79,10 @@ export function createSparkTools(options) {
|
|
|
79
79
|
return {
|
|
80
80
|
read_skill: tool({
|
|
81
81
|
...inputLabels("name"),
|
|
82
|
-
description: "Read
|
|
83
|
-
inputSchema: z.
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
]),
|
|
82
|
+
description: "Read the skills listed in names. Returns instructions, TypeScript API declarations, and JavaScript examples from the available directory.",
|
|
83
|
+
inputSchema: z.object({
|
|
84
|
+
names: z.array(z.string().min(1).max(160)).min(1),
|
|
85
|
+
}).strict(),
|
|
87
86
|
execute: (input, { toolCallId }) => execute({ id: toolCallId, name: "read_skill", input }, async () => {
|
|
88
87
|
const read = (requested) => {
|
|
89
88
|
const skill = options.capabilities.skills.find(({ name }) => name === requested);
|
|
@@ -96,8 +95,6 @@ export function createSparkTools(options) {
|
|
|
96
95
|
}
|
|
97
96
|
return { ok: true, ...skill };
|
|
98
97
|
};
|
|
99
|
-
if ("name" in input)
|
|
100
|
-
return read(input.name);
|
|
101
98
|
const skills = [...new Set(input.names)].map(read);
|
|
102
99
|
return { ok: skills.every(skill => skill.ok), skills };
|
|
103
100
|
}),
|
package/dist/ui.d.ts
CHANGED
|
@@ -115,13 +115,9 @@ export type SparkUITools = {
|
|
|
115
115
|
};
|
|
116
116
|
read_skill: {
|
|
117
117
|
input: {
|
|
118
|
-
name: string;
|
|
119
|
-
names?: never;
|
|
120
|
-
} | {
|
|
121
118
|
names: string[];
|
|
122
|
-
name?: never;
|
|
123
119
|
};
|
|
124
|
-
output:
|
|
120
|
+
output: {
|
|
125
121
|
ok: boolean;
|
|
126
122
|
skills: SkillReadResult[];
|
|
127
123
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@womp/spark-agent",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.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,7 +102,8 @@
|
|
|
102
102
|
"web:build": "yarn build && tsc --noEmit -p web/tsconfig.json && vite build --config web/vite.config.ts",
|
|
103
103
|
"test": "yarn build && tsx --tsconfig tsconfig.json --test test/**/*.test.ts && node --input-type=module -e \"await Promise.all([import('@womp/spark-agent'), import('@womp/spark-agent/ui'), import('@womp/spark-agent/client'), import('@womp/spark-agent/server'), import('@womp/spark-agent/express'), import('@womp/spark-agent/kakapo'), import('@womp/spark-agent/geometry'), import('@womp/spark-agent/openscad')])\"",
|
|
104
104
|
"test:live": "tsx --tsconfig tsconfig.json test/womp-scene-api.live.ts",
|
|
105
|
-
"prepack": "yarn build"
|
|
105
|
+
"prepack": "yarn build",
|
|
106
|
+
"release:pack": "node scripts/npm-release.mjs pack"
|
|
106
107
|
},
|
|
107
108
|
"dependencies": {
|
|
108
109
|
"@ai-sdk/anthropic": "4.0.50",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { KakapoAPI } from "@womp/kakapo-sdk";
|
|
2
|
-
import type { OpenScadBoundingBox } from "./openscad.js";
|
|
3
|
-
export declare function waitForOpenScadRenderer(options: {
|
|
4
|
-
api: KakapoAPI;
|
|
5
|
-
objectId: number;
|
|
6
|
-
expectedBounds: OpenScadBoundingBox;
|
|
7
|
-
baselineBounds?: OpenScadBoundingBox;
|
|
8
|
-
signal: AbortSignal;
|
|
9
|
-
timeoutMs?: number;
|
|
10
|
-
pollIntervalMs?: number;
|
|
11
|
-
}): Promise<boolean>;
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
const OPENSCAD_RENDERER_WAIT_MS = 15_000;
|
|
2
|
-
const OPENSCAD_RENDERER_POLL_MS = 250;
|
|
3
|
-
function boundsMatch(actual, expected) {
|
|
4
|
-
const size = Math.max(expected.max.x - expected.min.x, expected.max.y - expected.min.y, expected.max.z - expected.min.z);
|
|
5
|
-
const tolerance = Math.max(size * 0.0001, 0.001);
|
|
6
|
-
return ["min", "max"].every((edge) => ["x", "y", "z"].every((axis) => Math.abs(actual[edge][axis] - expected[edge][axis]) <= tolerance));
|
|
7
|
-
}
|
|
8
|
-
function getBoundsBeforeDeadline(options) {
|
|
9
|
-
const remaining = options.deadline - Date.now();
|
|
10
|
-
if (remaining <= 0)
|
|
11
|
-
return Promise.resolve(undefined);
|
|
12
|
-
options.signal.throwIfAborted();
|
|
13
|
-
return new Promise((resolve, reject) => {
|
|
14
|
-
let settled = false;
|
|
15
|
-
const finish = (action) => {
|
|
16
|
-
if (settled)
|
|
17
|
-
return;
|
|
18
|
-
settled = true;
|
|
19
|
-
clearTimeout(timeout);
|
|
20
|
-
options.signal.removeEventListener("abort", onAbort);
|
|
21
|
-
action();
|
|
22
|
-
};
|
|
23
|
-
const onAbort = () => finish(() => reject(options.signal.reason ?? new Error("The operation was aborted.")));
|
|
24
|
-
const timeout = setTimeout(() => finish(() => resolve(undefined)), remaining);
|
|
25
|
-
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
26
|
-
if (options.signal.aborted) {
|
|
27
|
-
onAbort();
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
void options.api.getNodeBoundingBox(options.objectId).then((bounds) => finish(() => resolve(bounds)), () => finish(() => resolve(undefined)));
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
function waitForPoll(signal, milliseconds) {
|
|
34
|
-
signal.throwIfAborted();
|
|
35
|
-
return new Promise((resolve, reject) => {
|
|
36
|
-
const onAbort = () => {
|
|
37
|
-
clearTimeout(timeout);
|
|
38
|
-
reject(signal.reason ?? new Error("The operation was aborted."));
|
|
39
|
-
};
|
|
40
|
-
const timeout = setTimeout(() => {
|
|
41
|
-
signal.removeEventListener("abort", onAbort);
|
|
42
|
-
resolve();
|
|
43
|
-
}, milliseconds);
|
|
44
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
45
|
-
if (signal.aborted)
|
|
46
|
-
onAbort();
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
export async function waitForOpenScadRenderer(options) {
|
|
50
|
-
const deadline = Date.now() + (options.timeoutMs ?? OPENSCAD_RENDERER_WAIT_MS);
|
|
51
|
-
if (options.baselineBounds !== undefined &&
|
|
52
|
-
boundsMatch(options.baselineBounds, options.expectedBounds))
|
|
53
|
-
return false;
|
|
54
|
-
do {
|
|
55
|
-
const actual = await getBoundsBeforeDeadline({
|
|
56
|
-
api: options.api,
|
|
57
|
-
objectId: options.objectId,
|
|
58
|
-
signal: options.signal,
|
|
59
|
-
deadline,
|
|
60
|
-
});
|
|
61
|
-
options.signal.throwIfAborted();
|
|
62
|
-
if (Date.now() >= deadline)
|
|
63
|
-
return false;
|
|
64
|
-
if (actual !== undefined && boundsMatch(actual, options.expectedBounds))
|
|
65
|
-
return true;
|
|
66
|
-
const remaining = deadline - Date.now();
|
|
67
|
-
if (remaining <= 0)
|
|
68
|
-
return false;
|
|
69
|
-
await waitForPoll(options.signal, Math.min(options.pollIntervalMs ?? OPENSCAD_RENDERER_POLL_MS, remaining));
|
|
70
|
-
} while (true);
|
|
71
|
-
}
|