@re-cinq/floor-station 0.1.1 → 0.1.4

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/dist/floor.d.ts CHANGED
@@ -1,49 +1,22 @@
1
- export interface Claimed {
2
- id: string;
3
- name: string;
4
- payload: {
5
- visitId: string;
6
- };
7
- }
8
- export type BriefNeed = {
9
- name: string;
10
- kind: "value";
11
- value: string;
12
- } | {
13
- name: string;
14
- kind: "file";
15
- path: string;
16
- url: string;
17
- } | {
18
- name: string;
19
- kind: "git";
20
- path: string;
21
- repoUrl: string;
22
- ref: string;
23
- };
24
- export interface VisitBrief {
25
- visitId: string;
26
- iteration: number;
27
- token: string;
28
- deadlineMinutes: number;
29
- needs: BriefNeed[];
30
- }
1
+ import type { ClaimedEvent, Report, VisitBrief } from "@re-cinq/floor-contracts";
2
+ export type { BriefNeed, VisitBrief } from "@re-cinq/floor-contracts";
3
+ export type Claimed = ClaimedEvent;
31
4
  export interface FloorAccess {
32
5
  floorUrl: string;
33
6
  token: string;
34
7
  }
35
8
  export declare class Floor {
36
9
  private readonly access;
10
+ private readonly client;
37
11
  constructor(access: FloorAccess);
38
12
  claim(tags: string[], limit: number): Promise<Claimed[]>;
39
13
  ack(eventId: string): Promise<void>;
40
14
  fail(eventId: string, error: string): Promise<void>;
41
- /** Null when the visit is already done: a dispatch delivered again after its visit reported. */
15
+ /** Null when the visit is already done, or gone: a dispatch delivered again after its visit reported. */
42
16
  brief(visitId: string): Promise<VisitBrief | null>;
43
- read(url: string, visitToken: string): Promise<Buffer>;
44
- store(bytes: Buffer, visitToken: string): Promise<string>;
45
- record(visitId: string, body: unknown, visitToken: string): Promise<void>;
46
- report(visitId: string, report: unknown, worker: string): Promise<void>;
47
- private send;
48
- private request;
17
+ read(url: string, token: string): Promise<Buffer>;
18
+ store(bytes: Buffer, token: string): Promise<string>;
19
+ record(visitId: string, body: unknown, token: string): Promise<void>;
20
+ report(visitId: string, report: Report, worker: string): Promise<void>;
21
+ private visit;
49
22
  }
package/dist/floor.js CHANGED
@@ -1,59 +1,46 @@
1
- // The floor, as a station reaches it: over HTTP and nothing else. The service token claims and acks; everything about one visit goes under that visit's own token.
2
- const REQUEST_TIMEOUT_MS = 30_000;
3
- const HTTP_NO_CONTENT = 204;
4
- const HTTP_CONFLICT = 409;
1
+ // The floor, as a station reaches it: the shared client, with the service token claiming and acking and each visit's own token doing everything about that visit.
2
+ import { createFloorClient, createVisitClient, serviceToken, visitToken } from "@re-cinq/floor-client";
5
3
  export class Floor {
6
4
  access;
5
+ client;
7
6
  constructor(access) {
8
7
  this.access = access;
8
+ this.client = createFloorClient({ url: access.floorUrl, token: serviceToken(access.token) });
9
9
  }
10
10
  async claim(tags, limit) {
11
- const response = await this.send("/events/claim", { method: "POST", body: JSON.stringify({ tags, limit }) });
12
- return response.status === HTTP_NO_CONTENT ? [] : (await response.json());
11
+ return this.client.events.claim({ tags, limit });
13
12
  }
14
13
  async ack(eventId) {
15
- await this.send(`/events/${eventId}/ack`, { method: "POST" });
14
+ await this.client.events.ack(eventId);
16
15
  }
17
16
  async fail(eventId, error) {
18
- await this.send(`/events/${eventId}/fail`, { method: "POST", body: JSON.stringify({ error, permanent: false }) });
17
+ await this.client.events.fail(eventId, error);
19
18
  }
20
- /** Null when the visit is already done: a dispatch delivered again after its visit reported. */
19
+ /** Null when the visit is already done, or gone: a dispatch delivered again after its visit reported. */
21
20
  async brief(visitId) {
22
- const response = await this.request(`/station-runs/${visitId}/brief`, {}, this.access.token);
23
- if (response.status === HTTP_CONFLICT)
24
- return null;
25
- return (await accepted(response)).json();
21
+ const outcome = await this.client.stationRuns.brief(visitId);
22
+ return outcome.kind === "brief" ? outcome.brief : null;
26
23
  }
27
24
  // The brief gives a file's address as a pod would reach it. A station reaches the floor its own way, so only the path is taken from it.
28
- async read(url, visitToken) {
29
- const response = await accepted(await this.request(new URL(url).pathname, {}, visitToken));
30
- return Buffer.from(await response.arrayBuffer());
31
- }
32
- async store(bytes, visitToken) {
33
- const response = await this.request("/blobs", { method: "POST", body: new Uint8Array(bytes), headers: { "content-type": "application/octet-stream" } }, visitToken);
34
- const stored = (await (await accepted(response)).json());
25
+ async read(url, token) {
26
+ const stored = await this.visit("", token).readBlob(url);
27
+ if (!stored)
28
+ throw new Error(`the floor has no bytes at "${url}"`);
29
+ return Buffer.from(stored.bytes);
30
+ }
31
+ async store(bytes, token) {
32
+ const stored = await this.visit("", token).storeBlob(new Uint8Array(bytes));
35
33
  return stored.hash;
36
34
  }
37
- async record(visitId, body, visitToken) {
38
- const records = [{ kind: "llm_call", body, occurredAt: new Date().toISOString() }];
39
- await accepted(await this.request(`/station-runs/${visitId}/records`, { method: "POST", body: JSON.stringify({ records }) }, visitToken));
35
+ async record(visitId, body, token) {
36
+ await this.visit(visitId, token).append([{ kind: "llm_call", body, occurredAt: new Date() }]);
40
37
  }
41
38
  // Deduplicated on the visit, so posting it again after a lost answer reports once.
42
39
  async report(visitId, report, worker) {
43
- const event = { name: "station_run.reported", payload: { visitId, worker, report }, dedupeKey: `station_run.reported:${visitId}` };
44
- await this.send("/events", { method: "POST", body: JSON.stringify(event) });
45
- }
46
- async send(path, init) {
47
- return accepted(await this.request(path, init, this.access.token));
40
+ await this.visit(visitId, this.access.token).report({ report, worker });
48
41
  }
49
- request(path, init, token) {
50
- const headers = { "content-type": "application/json", ...init.headers, authorization: `Bearer ${token}` };
51
- return fetch(`${this.access.floorUrl}${path}`, { ...init, headers, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });
42
+ visit(visitId, token) {
43
+ return createVisitClient({ url: this.access.floorUrl, token: visitToken(token), visitId });
52
44
  }
53
45
  }
54
- async function accepted(response) {
55
- if (response.ok)
56
- return response;
57
- throw new Error(`the floor answered ${response.status} to ${response.url}: ${await response.text()}`);
58
- }
59
46
  //# sourceMappingURL=floor.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@re-cinq/floor-station",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "The floor's service station SDK: defineStation(name, handle) claims the station's dispatches from a floor's queue, hands each to one function as a brief, and posts what it returns as the visit's report. A station needs only a way out to the floor; the floor never calls it.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -44,6 +44,10 @@
44
44
  "test:watch": "vitest",
45
45
  "typecheck": "tsc --noEmit"
46
46
  },
47
+ "dependencies": {
48
+ "@re-cinq/floor-client": "0.1.4",
49
+ "@re-cinq/floor-contracts": "0.1.4"
50
+ },
47
51
  "devDependencies": {
48
52
  "@types/node": "^22.20.1",
49
53
  "@vitest/coverage-v8": "^5.0.0",