@emseepea/create-progress-streaming-server 0.0.3 → 0.0.5
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 +13 -5
- package/initializer-dist/template/README.md +3 -4
- package/initializer-dist/template/eval/meaning.test.mjs +13 -12
- package/initializer-dist/template/package.json +2 -2
- package/initializer-dist/template/src/capabilities/tool.run-germination-trial.ts +26 -0
- package/initializer-dist/template/src/server.ts +3 -3
- package/initializer-dist/template/test/server.test.mjs +7 -6
- package/package.json +5 -5
- package/initializer-dist/template/src/capabilities/tool.roast-sample-batch.ts +0 -25
package/README.md
CHANGED
|
@@ -2,8 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
This directory is both the maintained example and its public npm initializer.
|
|
4
4
|
|
|
5
|
+
## Use This Template
|
|
6
|
+
|
|
7
|
+
Use this template for a tool that reports bounded progress while its HTTP call
|
|
8
|
+
remains open. Choose the [tool server](../tool-server/README.md) when the result
|
|
9
|
+
can return promptly. This template does not add replay, reconnectable sessions,
|
|
10
|
+
or subscriptions. [Compare all eight templates](https://emseepea.github.io/emseepea/examples/).
|
|
11
|
+
|
|
12
|
+
## Create a Project
|
|
13
|
+
|
|
5
14
|
```sh
|
|
6
|
-
npm init @emseepea/progress-streaming-server
|
|
15
|
+
npm init @emseepea/progress-streaming-server -- my-server
|
|
7
16
|
```
|
|
8
17
|
|
|
9
18
|
<!-- generated-project-readme -->
|
|
@@ -32,9 +41,8 @@ choose another port. This example starts locally and does not configure a proxy.
|
|
|
32
41
|
|
|
33
42
|
To adapt it for a public server, see
|
|
34
43
|
[Use Progress Behind a Proxy](https://github.com/emseepea/emseepea/blob/main/packages/framework/README.md#use-progress-behind-a-proxy).
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
after reconnecting.
|
|
44
|
+
It does not add saved sessions, replay, subscriptions, or recovery after
|
|
45
|
+
reconnecting.
|
|
38
46
|
|
|
39
47
|
## Check This Example
|
|
40
48
|
|
|
@@ -48,7 +56,7 @@ Run its build and progress-stream checks:
|
|
|
48
56
|
npm test
|
|
49
57
|
```
|
|
50
58
|
|
|
51
|
-
Check that Claude chooses the
|
|
59
|
+
Check that Claude chooses the germination tool and keeps progress separate from the result:
|
|
52
60
|
|
|
53
61
|
```sh
|
|
54
62
|
npm run test:llm
|
|
@@ -22,9 +22,8 @@ choose another port. This example starts locally and does not configure a proxy.
|
|
|
22
22
|
|
|
23
23
|
To adapt it for a public server, see
|
|
24
24
|
[Use Progress Behind a Proxy](https://github.com/emseepea/emseepea/blob/main/packages/framework/README.md#use-progress-behind-a-proxy).
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
after reconnecting.
|
|
25
|
+
It does not add saved sessions, replay, subscriptions, or recovery after
|
|
26
|
+
reconnecting.
|
|
28
27
|
|
|
29
28
|
## Check This Example
|
|
30
29
|
|
|
@@ -38,7 +37,7 @@ Run its build and progress-stream checks:
|
|
|
38
37
|
npm test
|
|
39
38
|
```
|
|
40
39
|
|
|
41
|
-
Check that Claude chooses the
|
|
40
|
+
Check that Claude chooses the germination tool and keeps progress separate from the result:
|
|
42
41
|
|
|
43
42
|
```sh
|
|
44
43
|
npm run test:llm
|
|
@@ -1,23 +1,24 @@
|
|
|
1
1
|
import { toolSelectionTest } from "@emseepea/testing/semantic";
|
|
2
2
|
|
|
3
|
-
toolSelectionTest("Progress stages remain distinct from the final
|
|
3
|
+
toolSelectionTest("Progress stages remain distinct from the final germination result", {
|
|
4
4
|
server: new URL("../dist/server.js", import.meta.url),
|
|
5
5
|
question:
|
|
6
|
-
"Run sample-
|
|
7
|
-
"final status and
|
|
6
|
+
"Run the sample-tray pea germination trial. Name the tray, list the progress " +
|
|
7
|
+
"stages, and report the final status and germination result. Keep progress and the completed result " +
|
|
8
8
|
"distinct.",
|
|
9
9
|
criticalFacts: [
|
|
10
|
-
"sample-
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
10
|
+
"sample-tray",
|
|
11
|
+
"soak",
|
|
12
|
+
"sow",
|
|
13
|
+
"sprout",
|
|
14
14
|
"complete",
|
|
15
|
-
"
|
|
15
|
+
"8",
|
|
16
|
+
"10"
|
|
16
17
|
],
|
|
17
18
|
criteria:
|
|
18
|
-
"The answer identifies
|
|
19
|
-
"separately reports the completed final result of
|
|
20
|
-
"sample-
|
|
19
|
+
"The answer identifies soak, sow, and sprout as progress stages, then " +
|
|
20
|
+
"separately reports the completed final result of 8 out of 10 germinated seeds " +
|
|
21
|
+
"for sample-tray. It does not treat an intermediate progress stage as the final " +
|
|
21
22
|
"result.",
|
|
22
|
-
expectedTools: ["
|
|
23
|
+
expectedTools: ["run-germination-trial"],
|
|
23
24
|
});
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"lint": "oxlint src test eval"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@emseepea/testing": "0.2.
|
|
17
|
+
"@emseepea/testing": "0.2.2",
|
|
18
18
|
"@types/node": "24.13.3",
|
|
19
19
|
"typescript": "6.0.3",
|
|
20
20
|
"oxlint": "1.80.0"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"private": true,
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@emseepea/server": "0.
|
|
27
|
+
"@emseepea/server": "0.3.0",
|
|
28
28
|
"zod": "4.4.3"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
+
import { defineStreamingTool, type CapabilityModuleFactory } from "@emseepea/server";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
export default (() => defineStreamingTool({
|
|
6
|
+
name: "run-germination-trial",
|
|
7
|
+
access: "public",
|
|
8
|
+
description: "Run a sample pea germination trial with bounded progress.",
|
|
9
|
+
inputSchema: z.object({ tray: z.literal("sample-tray") }),
|
|
10
|
+
outputSchema: z.object({
|
|
11
|
+
tray: z.literal("sample-tray"),
|
|
12
|
+
status: z.literal("complete"),
|
|
13
|
+
germinatedSeeds: z.literal(8),
|
|
14
|
+
totalSeeds: z.literal(10),
|
|
15
|
+
stages: z.tuple([z.literal("soak"), z.literal("sow"), z.literal("sprout")]),
|
|
16
|
+
}),
|
|
17
|
+
async handler({ tray }, { reportProgress, signal }) {
|
|
18
|
+
const stages: ["soak", "sow", "sprout"] = ["soak", "sow", "sprout"];
|
|
19
|
+
for (const [index, stage] of stages.entries()) {
|
|
20
|
+
await reportProgress({ progress: index + 1, total: stages.length, message: stage });
|
|
21
|
+
await delay(150, undefined, { signal });
|
|
22
|
+
}
|
|
23
|
+
const data = { tray, status: "complete" as const, germinatedSeeds: 8 as const, totalSeeds: 10 as const, stages };
|
|
24
|
+
return { text: `${tray} completed with 8 of 10 pea seeds germinated`, data };
|
|
25
|
+
},
|
|
26
|
+
})) satisfies CapabilityModuleFactory;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { createEmseepea, discoverCapabilities, serveEmseepea } from "@emseepea/server";
|
|
2
2
|
|
|
3
3
|
const running = await serveEmseepea(createEmseepea({
|
|
4
|
-
name: "emseepea-streaming-
|
|
4
|
+
name: "emseepea-progress-streaming-server",
|
|
5
5
|
version: "0.0.0",
|
|
6
|
-
instructions: "Use
|
|
6
|
+
instructions: "Use run-germination-trial for the sample pea germination trial.",
|
|
7
7
|
...await discoverCapabilities(new URL("./capabilities/", import.meta.url)),
|
|
8
8
|
}), { port: Number.parseInt(process.env.PORT ?? "3000", 10) });
|
|
9
9
|
|
|
10
|
-
console.log(`Em See Pea streaming-
|
|
10
|
+
console.log(`Em See Pea progress-streaming-server example listening at ${running.url}`);
|
|
11
11
|
|
|
12
12
|
async function shutdown(): Promise<void> {
|
|
13
13
|
await running.close();
|
|
@@ -3,20 +3,21 @@ import test from "node:test";
|
|
|
3
3
|
|
|
4
4
|
import { startMcpServer } from "@emseepea/testing";
|
|
5
5
|
|
|
6
|
-
test("reports bounded progress before returning the final
|
|
6
|
+
test("reports bounded progress before returning the final germination result", async (t) => {
|
|
7
7
|
const running = await startMcpServer(t, new URL("../dist/server.js", import.meta.url));
|
|
8
8
|
const client = await running.connect();
|
|
9
9
|
const progress = [];
|
|
10
10
|
const result = await client.callTool(
|
|
11
|
-
{ name: "
|
|
11
|
+
{ name: "run-germination-trial", arguments: { tray: "sample-tray" } },
|
|
12
12
|
{ onprogress: (update) => progress.push(update) },
|
|
13
13
|
);
|
|
14
14
|
|
|
15
|
-
assert.deepEqual(progress.map(({ message }) => message), ["
|
|
15
|
+
assert.deepEqual(progress.map(({ message }) => message), ["soak", "sow", "sprout"]);
|
|
16
16
|
assert.deepEqual(result.structuredContent, {
|
|
17
|
-
|
|
17
|
+
tray: "sample-tray",
|
|
18
18
|
status: "complete",
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
germinatedSeeds: 8,
|
|
20
|
+
totalSeeds: 10,
|
|
21
|
+
stages: ["soak", "sow", "sprout"],
|
|
21
22
|
});
|
|
22
23
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emseepea/create-progress-streaming-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Create an Em See Pea server that streams tool progress.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"prepack": "npm run build:initializer"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
-
"@emseepea/server": "0.
|
|
21
|
+
"@emseepea/server": "0.3.0",
|
|
22
22
|
"zod": "4.4.3",
|
|
23
|
-
"@emseepea/testing": "0.2.
|
|
23
|
+
"@emseepea/testing": "0.2.2",
|
|
24
24
|
"@types/node": "24.13.3",
|
|
25
25
|
"typescript": "6.0.3",
|
|
26
26
|
"oxlint": "1.80.0"
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=22"
|
|
30
30
|
},
|
|
31
|
-
"repository": { "type": "git", "url": "git+https://github.com/emseepea/emseepea.git", "directory": "examples/streaming-
|
|
31
|
+
"repository": { "type": "git", "url": "git+https://github.com/emseepea/emseepea.git", "directory": "examples/progress-streaming-server" },
|
|
32
32
|
"homepage": "https://emseepea.github.io/emseepea/examples/",
|
|
33
33
|
"bugs": "https://github.com/emseepea/emseepea/issues",
|
|
34
|
-
"publishConfig": { "access": "public", "provenance": true
|
|
34
|
+
"publishConfig": { "access": "public", "provenance": true },
|
|
35
35
|
"bin": { "create-progress-streaming-server": "./initializer-dist/create.mjs" },
|
|
36
36
|
"files": ["initializer-dist"]
|
|
37
37
|
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { setTimeout as delay } from "node:timers/promises";
|
|
2
|
-
import { defineStreamingTool, type CapabilityModuleFactory } from "@emseepea/server";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
|
|
5
|
-
export default (() => defineStreamingTool({
|
|
6
|
-
name: "roast-sample-batch",
|
|
7
|
-
access: "public",
|
|
8
|
-
description: "Run a sample coffee-roasting batch with bounded progress.",
|
|
9
|
-
inputSchema: z.object({ batch: z.literal("sample-batch") }),
|
|
10
|
-
outputSchema: z.object({
|
|
11
|
-
batch: z.literal("sample-batch"),
|
|
12
|
-
status: z.literal("complete"),
|
|
13
|
-
roastedGrams: z.literal(820),
|
|
14
|
-
stages: z.tuple([z.literal("charge"), z.literal("first crack"), z.literal("cool")]),
|
|
15
|
-
}),
|
|
16
|
-
async handler({ batch }, { reportProgress, signal }) {
|
|
17
|
-
const stages: ["charge", "first crack", "cool"] = ["charge", "first crack", "cool"];
|
|
18
|
-
for (const [index, stage] of stages.entries()) {
|
|
19
|
-
await reportProgress({ progress: index + 1, total: stages.length, message: stage });
|
|
20
|
-
await delay(150, undefined, { signal });
|
|
21
|
-
}
|
|
22
|
-
const data = { batch, status: "complete" as const, roastedGrams: 820 as const, stages };
|
|
23
|
-
return { text: `${batch} completed at 820 roasted grams`, data };
|
|
24
|
-
},
|
|
25
|
-
})) satisfies CapabilityModuleFactory;
|