@hotmeshio/long-tail 0.31.0 → 0.31.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.
@@ -6,10 +6,12 @@
6
6
  * npm run bambu:boat
7
7
  *
8
8
  * 1. Download the model once into files/.
9
- * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default: about ten minutes on a P1S).
9
+ * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default).
10
10
  * 3. Slice it with the printer, process and filament presets. Each is an
11
11
  * OrcaSlicer system preset name or a path to a preset JSON, which may
12
- * inherit a system preset by name.
12
+ * inherit a system preset by name. Unset, a P1S with a 0.4 nozzle and PLA;
13
+ * the presets in examples/workflows/bambu-printer/boat/presets slice the
14
+ * example's boat (0.8 nozzle, TPU, about 11 minutes).
13
15
  *
14
16
  * Env: BAMBU_BOAT_PRINTER, BAMBU_BOAT_PROCESS, BAMBU_BOAT_FILAMENT, BAMBU_BOAT_SCALE,
15
17
  * ORCA_SLICER (the OrcaSlicer executable) and ORCA_PROFILES (its BBL profiles directory).
@@ -7,10 +7,12 @@
7
7
  * npm run bambu:boat
8
8
  *
9
9
  * 1. Download the model once into files/.
10
- * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default: about ten minutes on a P1S).
10
+ * 2. Scale it (BAMBU_BOAT_SCALE, 0.5 by default).
11
11
  * 3. Slice it with the printer, process and filament presets. Each is an
12
12
  * OrcaSlicer system preset name or a path to a preset JSON, which may
13
- * inherit a system preset by name.
13
+ * inherit a system preset by name. Unset, a P1S with a 0.4 nozzle and PLA;
14
+ * the presets in examples/workflows/bambu-printer/boat/presets slice the
15
+ * example's boat (0.8 nozzle, TPU, about 11 minutes).
14
16
  *
15
17
  * Env: BAMBU_BOAT_PRINTER, BAMBU_BOAT_PROCESS, BAMBU_BOAT_FILAMENT, BAMBU_BOAT_SCALE,
16
18
  * ORCA_SLICER (the OrcaSlicer executable) and ORCA_PROFILES (its BBL profiles directory).
@@ -10,7 +10,8 @@
10
10
  * 1. Put the file on the printer (it prints only files on its own storage) and hash it: the unit's artifact.
11
11
  * 2. Start the unit route: one print step at the station, then a person unloads.
12
12
  * 3. Print the route's rows and their lifecycle items as they change, until the
13
- * route ends. The unload row is resolved by a person on the dashboard.
13
+ * route ends. The unload row is resolved by a person on the dashboard, and
14
+ * so is a failed print's decision, on the line's operator role.
14
15
  *
15
16
  * Env: LT_USERNAME and LT_PASSWORD (a Long Tail login that may invoke the route), BASE_URL
16
17
  * (http://localhost:3000), BAMBU_SITE_DIR (deploy/bambu-site), and the printers in .env.
@@ -11,7 +11,8 @@
11
11
  * 1. Put the file on the printer (it prints only files on its own storage) and hash it: the unit's artifact.
12
12
  * 2. Start the unit route: one print step at the station, then a person unloads.
13
13
  * 3. Print the route's rows and their lifecycle items as they change, until the
14
- * route ends. The unload row is resolved by a person on the dashboard.
14
+ * route ends. The unload row is resolved by a person on the dashboard, and
15
+ * so is a failed print's decision, on the line's operator role.
15
16
  *
16
17
  * Env: LT_USERNAME and LT_PASSWORD (a Long Tail login that may invoke the route), BASE_URL
17
18
  * (http://localhost:3000), BAMBU_SITE_DIR (deploy/bambu-site), and the printers in .env.
@@ -27,6 +28,8 @@ const path_1 = require("path");
27
28
  const env_1 = require("../examples/workflows/bambu-printer/env");
28
29
  const files_1 = require("../examples/workflows/bambu-printer/files");
29
30
  const route_1 = require("../examples/workflows/machine-line/workflows/route");
31
+ const line_1 = require("../lib/machines/line");
32
+ const contracts_1 = require("../services/machines/contracts");
30
33
  const env = process.env;
31
34
  const BASE_URL = env.BASE_URL || 'http://localhost:3000';
32
35
  const SITE_DIR = env.BAMBU_SITE_DIR || 'deploy/bambu-site';
@@ -67,7 +70,8 @@ async function look(orderRef, workflowId, shown) {
67
70
  const facets = encodeURIComponent(JSON.stringify({ orderRef }));
68
71
  const { escalations } = await api('GET', `/escalations?facets=${facets}&limit=20&sort_by=created_at&order=asc`);
69
72
  for (const row of escalations) {
70
- const { items = [] } = await api('GET', `/escalations/${row.id}/items`);
73
+ // Handoff rows hold the lifecycle items; a decision row holds none.
74
+ const { items = [] } = row.type === contracts_1.ROW_TYPE.HANDOFF ? await api('GET', `/escalations/${row.id}/items`) : {};
71
75
  const view = `${row.type}/${row.role} ${row.status}${row.assigned_to ? ' claimed' : ''} [${items.map((i) => i.itemKey).join(', ')}]`;
72
76
  if (shown.get(row.id) !== view)
73
77
  say(`${row.id.slice(0, 8)} ${view}`);
@@ -100,7 +104,7 @@ async function main() {
100
104
  siteId: line.siteId, lineId: line.lineId, routeKey, orderRef: `ORD-${routeKey}`,
101
105
  units: [{ unitId: `U-${routeKey}`, carrierId: `PLATE-${routeKey}` }],
102
106
  steps: [{ machineId: station, process: env_1.PRINT_PROCESS, recipe: { ...env_1.PRINT_RECIPE } }],
103
- artifact: { url, sha256 }, exitRole: env_1.BAMBU_ROLES.UNLOAD, handoffTimeout: env.BAMBU_HANDOFF_TIMEOUT || '6h',
107
+ artifact: { url, sha256 }, exitRole: (0, line_1.exitRole)(line), operatorRole: (0, line_1.operatorRole)(line), handoffTimeout: env.BAMBU_HANDOFF_TIMEOUT || '6h',
104
108
  };
105
109
  const workflowId = `bambu-${routeKey}`;
106
110
  await api('POST', `/workflows/${route_1.UNIT_ROUTE_WORKFLOW}/invoke`, { data: input, metadata: { source: 'bambu-print' }, workflowId });
@@ -215,7 +215,8 @@ async function startRoutes(artifact) {
215
215
  const name = (0, manifests_1.automatedAt)(i, MIX) ? MANIFEST.AUTOMATED : MANIFEST.MANUAL;
216
216
  const data = {
217
217
  siteId: line.siteId, lineId: line.lineId, routeKey, orderRef: `ORD-${RUN}`, units,
218
- steps: (0, manifests_1.manifestSteps)(line, manifests[name]), exitRole: (0, line_1.exitRole)(line), artifact, handoffTimeout: HANDOFF_TIMEOUT,
218
+ steps: (0, manifests_1.manifestSteps)(line, manifests[name]), exitRole: (0, line_1.exitRole)(line), operatorRole: (0, line_1.operatorRole)(line), qualityRole: (0, line_1.qualityRole)(line),
219
+ artifact, handoffTimeout: HANDOFF_TIMEOUT,
219
220
  };
220
221
  const workflowId = `mur-${routeKey}`;
221
222
  await api('POST', `/workflows/${route_1.UNIT_ROUTE_WORKFLOW}/invoke`, { workflowId, data, metadata: { source: 'machine-line', manifest: name } });
package/docs/machines.md CHANGED
@@ -55,7 +55,7 @@ For each line, one replica leads (a Postgres advisory lock held on its own conne
55
55
  | `machines[].address` | The physical machine on the wire: its topic level, client id and certificate name, such as a permanent UUID that stays with the machine if it moves. Default `machineId`, which stays the station that rows, roles and routes name |
56
56
  | `addressing` | `declared` (default): each address is `machines[].address`, or the station's id. `learned`: a station with no `address` learns it from the machine that claims it. See [Learned addresses](#learned-addresses) |
57
57
  | `roles.exit` | The role of the person who receives units at the end of a route. Default `line-exit` |
58
- | `roles.operator` | The role that gets failed handoffs, stopping alarms, and offline or quiet machines. Default `line-operator` |
58
+ | `roles.operator` | The role that gets failed handoffs, stopping alarms, and offline or quiet machines. Default `line-operator`. A workflow that parks its own failure decisions reads it too: `machineUnitRoute` takes it as `operatorRole` |
59
59
  | `roles.quality` | The role that decides units a machine finished on hold: release, rework or scrap. Default `line-quality` |
60
60
  | `roles.receivers` | Other roles of people who take units straight from a machine. Machine bots join these roles and the exit role, so they can record their releases on those rows |
61
61
  | `machines[].allowedSoftware` | Versions the line accepts. A machine reporting another version is refused before any dispatch |
@@ -336,7 +336,7 @@ The built-in `long-tail-machines` server offers the same surface to agents, gate
336
336
  - **Rows are the authority:** an escalation event only tells the gateway which row to look at. It reads the row back as the controller and acts on the stored role, status and metadata. A row on a role the controller does not hold, or an event its stored row contradicts, does nothing.
337
337
  - **Roles carry the access:** dispatching to a machine or commanding one means parking a row on that machine's role, so Long Tail's role access decides who can. The gateway acts on a handoff into a machine only on that machine's role, and on a handoff to a person only on a receiver role. A row commands only the machine whose role it is on: cancelling a handoff withdraws the receiver's dispatch, and the sender's job is stopped only by a `cancel` command row on the sender's role.
338
338
  - **Rendering:** `Machines.renderSiteConf`, `renderMosquittoConf` and `renderMosquittoAcl(lines, codec)` render the configuration from one line or several on the same broker and site NATS: one bridge identity per line, one gateway user allowed every line's streams, and each line's stations and controller in the ACL. The ACL takes its topics from the codec's channels. Lines on different protocols pass a resolver instead of one codec, `renderMosquittoAcl(lines, (line) => codecOf(line))`, and a `root` resolver to `renderSiteConf` and `renderMosquittoConf`, so each line's bridge, subjects and ACL follow its own codec.
339
- - **Machines that host their own broker:** the machine broker connects out to each machine's broker with a Mosquitto bridge, carrying the machine's messages in and its commands out under the machine's level of the line's topics, and its codec reads them there. The bridge's notification topic, kept on the machine broker, is the machine's presence. `examples/workflows/bambu-printer` does this for 3D printers.
339
+ - **Machines that host their own broker:** the machine broker connects out to each machine's broker with a Mosquitto bridge, carrying the machine's messages in and its commands out under the machine's level of the line's topics, and its codec reads them there. The bridge's notification topic, kept on the machine broker, is the machine's presence. `examples/workflows/bambu-printer` does this for 3D printers, with a simulated printer (`--profile bambu-sim`) for running it without one.
340
340
 
341
341
  ### Learned addresses
342
342
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hotmeshio/long-tail",
3
- "version": "0.31.0",
3
+ "version": "0.31.1",
4
4
  "description": "Long Tail Workflows — Durable AI workflows with human-in-the-loop escalation. Powered by PostgreSQL.",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",