@flow-engineer/flow 0.2.3 → 0.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/README.md +3 -3
- package/coding-agents/skill.md +20 -7
- package/coding-agents/test-skill.md +50 -1
- package/dist/flow-messaging/src/index.js +8 -5
- package/dist/simulators/src/server.d.ts +2 -0
- package/dist/simulators/src/server.js +7 -1
- package/dist/src/agent.d.ts +32 -0
- package/dist/src/agent.js +38 -8
- package/dist/src/channels.d.ts +2 -0
- package/dist/src/channels.js +1 -0
- package/dist/src/conversation.d.ts +2 -0
- package/dist/src/conversation.js +8 -2
- package/dist/src/http.js +5 -2
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/local.d.ts +22 -0
- package/dist/src/local.js +85 -0
- package/dist/src/types.d.ts +6 -0
- package/dist/testing/src/account.d.ts +1 -1
- package/dist/testing/src/account.js +78 -20
- package/dist/testing/src/business.d.ts +42 -0
- package/dist/testing/src/business.js +145 -0
- package/dist/testing/src/cli.js +10 -8
- package/dist/testing/src/client.d.ts +4 -2
- package/dist/testing/src/client.js +20 -0
- package/dist/testing/src/index.d.ts +2 -2
- package/dist/testing/src/index.js +1 -1
- package/dist/testing/src/new.d.ts +9 -0
- package/dist/testing/src/new.js +44 -5
- package/dist/testing/src/protocol.d.ts +99 -1
- package/dist/testing/src/protocol.js +9 -0
- package/dist/testing/src/suite.d.ts +142 -3
- package/dist/testing/src/suite.js +94 -10
- package/docs/agents.md +31 -9
- package/examples/cafe/src/main.ts +23 -8
- package/examples/cafe/src/mcp.ts +24 -6
- package/package.json +1 -1
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
//
|
|
2
|
-
// FLOW_MESSAGING_KEY in .env (`npx @flow-engineer/flow link` puts it there),
|
|
1
|
+
// The agent in the playground: `npm start`, then open the printed link and pick a test person. With
|
|
2
|
+
// FLOW_MESSAGING_KEY in .env (`npx @flow-engineer/flow link` puts it there), it is on Telegram
|
|
3
3
|
// too (and WhatsApp and iMessage when .env names their senders), through Flow Messaging's event
|
|
4
|
-
// stream: an outbound connection, so no public URL or tunnel.
|
|
4
|
+
// stream: an outbound connection, so no public URL or tunnel. It listens on PORT, else 8788 or the
|
|
5
|
+
// next free port above it.
|
|
5
6
|
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { choosePort, markRunning } from "../../../src/index.ts";
|
|
6
9
|
import { flowMessaging } from "../../../flow-messaging/src/index.ts";
|
|
7
10
|
import { simulators } from "../../../simulators/src/index.ts";
|
|
8
11
|
import { buildAgent } from "./agent.ts";
|
|
9
12
|
import { channelNames, flowChannels } from "./channels.ts";
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
// What people call it: package.json's displayName (`npx @flow-engineer/flow link --display-name <name>` changes it).
|
|
15
|
+
const { displayName: name = "Pip" } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as { displayName?: string };
|
|
16
|
+
const play = simulators({ title: `${name} · Bean & Leaf` });
|
|
12
17
|
const fm = process.env.FLOW_MESSAGING_KEY ? flowMessaging() : undefined;
|
|
13
18
|
const channels = fm ? flowChannels(fm) : [];
|
|
14
19
|
let agent: ReturnType<typeof buildAgent>;
|
|
@@ -18,12 +23,22 @@ try {
|
|
|
18
23
|
console.error((error as Error).message); // such as no model key in .env
|
|
19
24
|
process.exit(1);
|
|
20
25
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
let url: string;
|
|
27
|
+
try {
|
|
28
|
+
const { port, note } = await choosePort("PORT", 8788, { command: "npm start" });
|
|
29
|
+
if (note) console.log(note);
|
|
30
|
+
({ url } = await play.listen(agent, port));
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error((error as Error).message); // such as the port PORT names being in use
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const port = Number(new URL(url).port);
|
|
36
|
+
// `npx @flow-engineer/flow link` reads it (.flow/running.json) to say whether to start or restart this.
|
|
37
|
+
markRunning(url);
|
|
38
|
+
console.log(`${name}'s playground: ${url}/`);
|
|
24
39
|
console.log(`Every channel side by side: ${url}/person`);
|
|
25
40
|
if (fm) {
|
|
26
|
-
// Events sent while
|
|
41
|
+
// Events sent while it was not running come when it starts again (.flow/ keeps the last one handled).
|
|
27
42
|
const live = fm.start(agent, { cursorFile: ".flow/flow-messaging-cursor", port: port + 1 });
|
|
28
43
|
console.log(`On ${channelNames(channels)} through Flow Messaging (${live.mode}). The phone link: npx @flow-engineer/flow link`);
|
|
29
44
|
live.stopped.then((why) => console.error(`Flow Messaging stopped: ${why.message} Then: npx @flow-engineer/flow setup`));
|
package/examples/cafe/src/mcp.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
//
|
|
1
|
+
// The agent's tools and skills as an MCP server, for Claude, ChatGPT or any MCP host: `npm run mcp`.
|
|
2
2
|
// The same tools the chat agent uses; no model key needed, since the host brings its own model.
|
|
3
3
|
|
|
4
|
+
import { readFileSync } from "node:fs";
|
|
4
5
|
import { createServer } from "node:http";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
6
7
|
import { mcpServer } from "../../../mcp/src/index.ts";
|
|
8
|
+
import { choosePort } from "../../../src/index.ts";
|
|
7
9
|
import { tools } from "./tools.ts";
|
|
8
10
|
|
|
9
11
|
export const mcp = mcpServer({
|
|
@@ -15,8 +17,24 @@ export const mcp = mcpServer({
|
|
|
15
17
|
// auth: { issuer, resource, scopes, verify } (the chinwag-auth skill).
|
|
16
18
|
});
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
// What people call it: package.json's displayName.
|
|
21
|
+
const { displayName: name = "Pip" } = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")) as { displayName?: string };
|
|
22
|
+
// MCP_PORT, else 8790 or the next free port above it.
|
|
23
|
+
let port: number;
|
|
24
|
+
try {
|
|
25
|
+
const chosen = await choosePort("MCP_PORT", 8790, { command: "npm run mcp" });
|
|
26
|
+
port = chosen.port;
|
|
27
|
+
if (chosen.note) console.log(`${chosen.note} The CLI then needs CAFE_SERVER=http://127.0.0.1:${port}/mcp.`);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error((error as Error).message);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
createServer((req, res) => void mcp.node(req, res))
|
|
33
|
+
.once("error", (error) => {
|
|
34
|
+
console.error(`${error.message}. Run: MCP_PORT=<port> npm run mcp`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
})
|
|
37
|
+
.listen(port, "127.0.0.1", () => {
|
|
38
|
+
console.log(`${name}'s MCP server: http://127.0.0.1:${port}/mcp`);
|
|
39
|
+
console.log(`Try it in Claude Code: claude mcp add --transport http bean-and-leaf http://127.0.0.1:${port}/mcp`);
|
|
40
|
+
});
|