@wenathlan/getry 2.0.166 → 2.0.168
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 +1 -1
- package/cli.ts +15 -6
- package/db.ts +33 -29
- package/docs/features.md +1 -2
- package/docs/gateway.md +2 -3
- package/gatewaycheck.ts +142 -0
- package/package.json +81 -89
- package/server.ts +9 -5
- package/{tests → test}/cli.test.ts +1 -1
- package/{tests → test}/design.test.ts +3 -3
- package/test/familyseats.test.ts +220 -0
- package/{tests → test}/gateway.test.ts +2 -2
- package/{tests → test}/gatewayversions.test.ts +1 -1
- package/{tests → test}/intelligence.test.ts +1 -1
- package/{tests → test}/keyrotation.test.ts +1 -1
- package/{tests → test}/onboardingstate.test.ts +1 -1
- package/{tests → test}/providerfixtures.ts +12 -12
- package/{tests → test}/researchfixtures.ts +1 -1
- package/{tests → test}/sandboxmodality.test.ts +1 -1
- package/gatewayprobe.ts +0 -61
- package/gatewaysmoke.ts +0 -64
- /package/{tests → test}/debonairlane.test.ts +0 -0
- /package/{tests → test}/family.test.ts +0 -0
- /package/{tests → test}/gatewayserver.ts +0 -0
- /package/{tests → test}/jsonpolicy.test.ts +0 -0
- /package/{tests → test}/llm.test.ts +0 -0
- /package/{tests → test}/modelroute.test.ts +0 -0
- /package/{tests → test}/promptlibrary.test.ts +0 -0
- /package/{tests → test}/providercli.test.ts +0 -0
- /package/{tests → test}/providerconstants.test.ts +0 -0
- /package/{tests → test}/providerfingerprint.test.ts +0 -0
- /package/{tests → test}/providermodels.test.ts +0 -0
- /package/{tests → test}/provideroauth.test.ts +0 -0
- /package/{tests → test}/routerotation.test.ts +0 -0
- /package/{tests → test}/serverauth.test.ts +0 -0
- /package/{tests → test}/serverengine.test.ts +0 -0
- /package/{tests → test}/serverproperty.test.ts +0 -0
- /package/{tests → test}/serverutils.test.ts +0 -0
- /package/{tests → test}/streamfallback.test.ts +0 -0
- /package/{tests → test}/thinkingladder.test.ts +0 -0
- /package/{tests → test}/torturellm.test.ts +0 -0
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ pnpm dev
|
|
|
20
20
|
# The family contract (wave 6-a)
|
|
21
21
|
|
|
22
22
|
- `family.ts` — the single table of the eight siblings beside getry with the
|
|
23
|
-
spec §12 accent of each one; the shell rail foot and `
|
|
23
|
+
spec §12 accent of each one; the shell rail foot and `test/family.test.ts`
|
|
24
24
|
both consume this one table.
|
|
25
25
|
- `familyurl.ts` — the verbatim relative-url contract (`"../" + slug + "/"`,
|
|
26
26
|
consolidated to the family variant) that keeps every cross-app link
|
package/cli.ts
CHANGED
|
@@ -727,7 +727,7 @@ async function cmdkeys(versionarg: string | undefined): Promise<void> {
|
|
|
727
727
|
if (key) keys.push(key);
|
|
728
728
|
}
|
|
729
729
|
// write to a seed script the user can run
|
|
730
|
-
const seedpath = resolve(process.cwd(), "
|
|
730
|
+
const seedpath = resolve(process.cwd(), "test", "seedkeys.mjs");
|
|
731
731
|
const seedcontent = [
|
|
732
732
|
"/** seed keys — generated by gateway cli */",
|
|
733
733
|
'import { PrismaClient } from "@prisma/client"',
|
|
@@ -748,9 +748,9 @@ async function cmdkeys(versionarg: string | undefined): Promise<void> {
|
|
|
748
748
|
`console.log(\`registered \${keys.length} keys\`)`,
|
|
749
749
|
"",
|
|
750
750
|
].join("\n");
|
|
751
|
-
mkdirSync(resolve(process.cwd(), "
|
|
751
|
+
mkdirSync(resolve(process.cwd(), "test"), { recursive: true });
|
|
752
752
|
writeFileSync(seedpath, seedcontent);
|
|
753
|
-
console.log(`\n${colors.green}created${colors.reset}
|
|
753
|
+
console.log(`\n${colors.green}created${colors.reset} test/seedkeys.mjs — run: node test/seedkeys.mjs`);
|
|
754
754
|
}
|
|
755
755
|
}
|
|
756
756
|
console.log("");
|
|
@@ -791,9 +791,18 @@ async function cmdmodels(versionarg: string | undefined): Promise<void> {
|
|
|
791
791
|
// ---------------------------------------------------------------------------
|
|
792
792
|
|
|
793
793
|
async function cmdserve(portarg: string | undefined): Promise<void> {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
794
|
+
/* the gateway ports law (host/porta sorteados, never localhost literal):
|
|
795
|
+
* the caller pin rides when it carries a positive port (the arg lands in
|
|
796
|
+
* the env the transport main reads), the env pin rides when the env
|
|
797
|
+
* carries one, and when both stay silent the transport main draws the
|
|
798
|
+
* host and the port (binddraw.ts) — never a literal fallback */
|
|
799
|
+
const argport = Number(portarg);
|
|
800
|
+
if (portarg !== undefined && Number.isFinite(argport) && argport > 0) process.env.PORT = String(argport);
|
|
801
|
+
const pinned = Number(process.env.PORT);
|
|
802
|
+
const pinnedport = Number.isFinite(pinned) && pinned > 0 ? pinned : undefined;
|
|
803
|
+
console.log(
|
|
804
|
+
`${colors.cyan}starting gateway${pinnedport !== undefined ? ` on port ${pinnedport}` : " — the bind draws (host and port) since no env pin rides"}${colors.reset}`,
|
|
805
|
+
);
|
|
797
806
|
/* the transport main loads lazily (the published-envelope law): the
|
|
798
807
|
* console family — init through export, chat, help — runs on node
|
|
799
808
|
* builtins alone inside the published envelope, and the serve seat
|
package/db.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
/// <reference types="better-sqlite3" />
|
|
22
22
|
|
|
23
|
+
import { createOnboardingStore, type OnboardingLane, type OnboardingStore } from "@wenathlan/vault/onboardingstore";
|
|
23
24
|
import { GATEWAYROUTES, GATEWAYVERSIONS, type GatewayRoute, type GatewayVersion } from "./gateway";
|
|
24
25
|
import { LABEL_MANIFEST, LABEL_REVISION } from "./labels";
|
|
25
26
|
|
|
@@ -399,12 +400,6 @@ CREATE TABLE IF NOT EXISTS gateway_versions (
|
|
|
399
400
|
);
|
|
400
401
|
`;
|
|
401
402
|
|
|
402
|
-
/** the prepared statements of the mirror, created once per process. */
|
|
403
|
-
type OnboardingStatements = {
|
|
404
|
-
select: import("better-sqlite3").Statement;
|
|
405
|
-
upsert: import("better-sqlite3").Statement;
|
|
406
|
-
};
|
|
407
|
-
|
|
408
403
|
/** the prepared label statements of the mirror, created once per process. */
|
|
409
404
|
type LabelStatements = {
|
|
410
405
|
select: import("better-sqlite3").Statement;
|
|
@@ -421,7 +416,7 @@ type VersionStatements = {
|
|
|
421
416
|
/** the cached driver bundle (null until the first node call). */
|
|
422
417
|
let mirror: {
|
|
423
418
|
db: import("better-sqlite3").Database;
|
|
424
|
-
|
|
419
|
+
onboarding: OnboardingStore;
|
|
425
420
|
labels: LabelStatements;
|
|
426
421
|
versions: VersionStatements;
|
|
427
422
|
} | null = null;
|
|
@@ -437,7 +432,7 @@ let mirror: {
|
|
|
437
432
|
*/
|
|
438
433
|
async function openMirror(): Promise<{
|
|
439
434
|
db: import("better-sqlite3").Database;
|
|
440
|
-
|
|
435
|
+
onboarding: OnboardingStore;
|
|
441
436
|
labels: LabelStatements;
|
|
442
437
|
versions: VersionStatements;
|
|
443
438
|
}> {
|
|
@@ -454,21 +449,31 @@ async function openMirror(): Promise<{
|
|
|
454
449
|
db.exec(ONBOARDING_SCHEMA);
|
|
455
450
|
db.exec(LABELS_SCHEMA);
|
|
456
451
|
db.exec(GATEWAYVERSIONS_SCHEMA);
|
|
452
|
+
/* the onboarding store rides the vault factory over the mirror's own
|
|
453
|
+
* connection (the structural lane — execute, queryOne, exec — answered
|
|
454
|
+
* through one memoized prepare cache, so every statement stays prepared
|
|
455
|
+
* once per process): the seen-wins upsert —
|
|
456
|
+
* ON CONFLICT(visitor) DO UPDATE SET introseen = MAX(introseen, excluded.introseen),
|
|
457
|
+
* onboardingseen = MAX(onboardingseen, excluded.onboardingseen) — rides
|
|
458
|
+
* the shared mechanism, never a local copy of the sql, and the browser
|
|
459
|
+
* graph never gains a storage import — the factory module owns zero
|
|
460
|
+
* imports (the labelstore precedent). */
|
|
461
|
+
const prepared = new Map<string, import("better-sqlite3").Statement>();
|
|
462
|
+
const prepareCached = (sql: string): import("better-sqlite3").Statement => {
|
|
463
|
+
const cached = prepared.get(sql);
|
|
464
|
+
if (cached) return cached;
|
|
465
|
+
const statement = db.prepare(sql);
|
|
466
|
+
prepared.set(sql, statement);
|
|
467
|
+
return statement;
|
|
468
|
+
};
|
|
469
|
+
const onboardinglane: OnboardingLane = {
|
|
470
|
+
execute: (sql, params = []) => prepareCached(sql).run(...params),
|
|
471
|
+
queryOne: (sql, params = []) => prepareCached(sql).get(...params),
|
|
472
|
+
exec: (ddl) => db.exec(ddl),
|
|
473
|
+
};
|
|
457
474
|
mirror = {
|
|
458
475
|
db,
|
|
459
|
-
|
|
460
|
-
select: db.prepare(
|
|
461
|
-
"SELECT id, visitor, introseen, onboardingseen, updatedAt FROM onboarding_states WHERE visitor = ?",
|
|
462
|
-
),
|
|
463
|
-
upsert: db.prepare(
|
|
464
|
-
`INSERT INTO onboarding_states (visitor, introseen, onboardingseen, updatedAt)
|
|
465
|
-
VALUES (?, ?, ?, datetime('now'))
|
|
466
|
-
ON CONFLICT(visitor) DO UPDATE SET
|
|
467
|
-
introseen = MAX(introseen, excluded.introseen),
|
|
468
|
-
onboardingseen = MAX(onboardingseen, excluded.onboardingseen),
|
|
469
|
-
updatedAt = datetime('now')`,
|
|
470
|
-
),
|
|
471
|
-
},
|
|
476
|
+
onboarding: createOnboardingStore(onboardinglane),
|
|
472
477
|
labels: {
|
|
473
478
|
select: db.prepare("SELECT id, text, revision, updatedAt, translated FROM labels WHERE id = ?"),
|
|
474
479
|
selectAll: db.prepare("SELECT id, text, revision, updatedAt, translated FROM labels ORDER BY id ASC"),
|
|
@@ -514,15 +519,14 @@ export type OnboardingFlags = { introseen: boolean; onboardingseen: boolean };
|
|
|
514
519
|
*/
|
|
515
520
|
export async function getonboardingstate(visitor: string): Promise<OnboardingFlags | undefined> {
|
|
516
521
|
if (!isnode()) return undefined;
|
|
517
|
-
const {
|
|
518
|
-
|
|
519
|
-
if (!row) return undefined;
|
|
520
|
-
return { introseen: row.introseen === 1, onboardingseen: row.onboardingseen === 1 };
|
|
522
|
+
const { onboarding } = await openMirror();
|
|
523
|
+
return onboarding.getOnboardingState(visitor);
|
|
521
524
|
}
|
|
522
525
|
|
|
523
526
|
/**
|
|
524
|
-
* Marks one onboarding stage seen for a visitor — idempotent seen-wins
|
|
525
|
-
* upsert (a stage seen anywhere stays seen
|
|
527
|
+
* Marks one onboarding stage seen for a visitor — the idempotent seen-wins
|
|
528
|
+
* upsert of the vault store (a stage seen anywhere stays seen; the later
|
|
529
|
+
* stage implies the earlier — the flow order), prepared and bound, never
|
|
526
530
|
* concatenated SQL.
|
|
527
531
|
*
|
|
528
532
|
* @param visitor the visitor key of the row.
|
|
@@ -531,8 +535,8 @@ export async function getonboardingstate(visitor: string): Promise<OnboardingFla
|
|
|
531
535
|
*/
|
|
532
536
|
export async function setonboardingstage(visitor: string, stage: "intro" | "onboarding"): Promise<OnboardingFlags> {
|
|
533
537
|
if (!isnode()) return { introseen: false, onboardingseen: false };
|
|
534
|
-
const {
|
|
535
|
-
|
|
538
|
+
const { onboarding } = await openMirror();
|
|
539
|
+
onboarding.setOnboardingStage(visitor, stage);
|
|
536
540
|
return (await getonboardingstate(visitor)) ?? { introseen: false, onboardingseen: false };
|
|
537
541
|
}
|
|
538
542
|
|
package/docs/features.md
CHANGED
|
@@ -16,8 +16,7 @@ every feature below is read from the code of the getry app root and the Sol them
|
|
|
16
16
|
- cors handling — preflight and cors headers on every route.
|
|
17
17
|
- response formats — chat completion, anthropic message and response shapes built from one pipeline.
|
|
18
18
|
- gateway cli — `cli.ts` scaffolds and inspects gateway configs.
|
|
19
|
-
- gateway
|
|
20
|
-
- container smoke — `gatewaysmoke.ts` runs one full offline request cycle against the recorded openaicompat fixture.
|
|
19
|
+
- gateway check — `gatewaycheck.ts` folds both check seats: the offline smoke (one full request cycle against the recorded openaicompat fixture) and the manual probe (a chat round trip against a deployed host).
|
|
21
20
|
|
|
22
21
|
## providers
|
|
23
22
|
|
package/docs/gateway.md
CHANGED
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
- `oauth.ts` / `accounts.ts` / `recovery.ts` / `project.ts` — the provider oauth family, multi-account manager, recovery and project id discovery.
|
|
30
30
|
- `db.ts` — the database contract: typed rows, in-memory seeds, HTTPS accessors, the health-aware round-robin key picker (`nextkeyrow`) and the better-sqlite3 mirror (onboarding states, labels and the `gateway_versions` route table).
|
|
31
31
|
- `prismaconfig.ts` / `prismashim.ts` / `nodeshim.ts` — prisma schema path resolution and runtime shims.
|
|
32
|
-
- `
|
|
33
|
-
- `gatewaysmoke.ts` — offline container smoke: one full request cycle against the recorded openaicompat fixture.
|
|
32
|
+
- `gatewaycheck.ts` — the two gateway check seats in one file: the offline container smoke (one full request cycle against the recorded openaicompat fixture) and the manual probe (chat round trip against a deployed gateway, `GET /v1/models`, `POST /v1/chat/completions`).
|
|
34
33
|
- `registernvidiakeys.ts` — registers the 22 nvidia api keys into the `nvidiaKey` table.
|
|
35
34
|
- `cli.ts` / `providercli.ts` — the gateway cli and the provider cli.
|
|
36
35
|
- `versionregistry.ts`, `request.ts`, `search.ts`, `fingerprint.ts`, `constants.ts`, `antigravity.ts` — the antigravity/gemini-cli provider lineage: version resolution, request building, search, fingerprinting, endpoint constants.
|
|
@@ -122,4 +121,4 @@ the 7-level thinking ladder (`thinking.ts`), each level bound to a token budget:
|
|
|
122
121
|
|
|
123
122
|
## tests
|
|
124
123
|
|
|
125
|
-
- 29 test files under `
|
|
124
|
+
- 29 test files under `test/` cover the gateway surface: gateway, gatewayversions (the 5/35 route table law, the sqlite mirror rows, the thinking chain), server (auth, engine, property, utils), llm, modelroute, promptlibrary, keyrotation (the health-aware key round-robin and the masking discipline), routerotation, thinkingladder (the registerable ladder and the tier/budget/chain/lane routing), streamfallback, intelligence, jsonpolicy, family, design, cli, providercli, onboardingstate, sandboxmodality, debonairlane, torture.llm, plus the provider lineage (constants, fingerprint, models, oauth) and the shared fixtures (`gatewayserver.ts`, `providerfixtures.ts`, `researchfixtures.ts`).
|
package/gatewaycheck.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gatewaycheck — consolidated gateway check lane of the getry family
|
|
3
|
+
* @module gatewaycheck
|
|
4
|
+
* @family wave/gatewaycheck
|
|
5
|
+
* One keyed file per family: the former variant arms (gatewayprobe, gatewaysmoke)
|
|
6
|
+
* retired into this seat with every behavior preserved under the same name.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { startgatewayfixtureserver } from "./test/gatewayserver.ts";
|
|
10
|
+
import type { baseurlconfig } from "./types.ts";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* the offline smoke seat of the 1.1.83 family: it starts the localhost fixture
|
|
14
|
+
* server, loads the built gateway module and runs one full request cycle
|
|
15
|
+
* against the recorded openaicompat fixture offline — no provider endpoint,
|
|
16
|
+
* no key, no external network — so the container image proves the gateway
|
|
17
|
+
* call path before it ships.
|
|
18
|
+
*/
|
|
19
|
+
export async function gatewaysmokeseat(): Promise<void> {
|
|
20
|
+
const server = await startgatewayfixtureserver();
|
|
21
|
+
try {
|
|
22
|
+
/* the smoke loads the BUILT gateway module — build/llm.js is a container
|
|
23
|
+
* build artifact a fresh checkout never carries, so the specifier rides a
|
|
24
|
+
* variable (tsc never fails on the absent artifact while the runtime
|
|
25
|
+
* keeps loading the built face) and the cast pins the module to the
|
|
26
|
+
* source contract that sits beside it. */
|
|
27
|
+
const builtpath = "./build/llm.js";
|
|
28
|
+
const gateway = (await import(builtpath)) as typeof import("./llm.ts");
|
|
29
|
+
const config: baseurlconfig = {
|
|
30
|
+
providerid: "smoke",
|
|
31
|
+
kind: "openaicompat",
|
|
32
|
+
baseurl: `http://127.0.0.1:${server.port}/openaicompat`,
|
|
33
|
+
enabled: true,
|
|
34
|
+
consented: true,
|
|
35
|
+
consentedat: Date.now(),
|
|
36
|
+
updatedat: Date.now(),
|
|
37
|
+
};
|
|
38
|
+
const outcome = await gateway.gatewaycall({
|
|
39
|
+
config,
|
|
40
|
+
model: "fixture-model-a",
|
|
41
|
+
messages: [{ role: "user", content: "draft one step" }],
|
|
42
|
+
requestid: "smoke-1",
|
|
43
|
+
transport: async (url: string, init: { method: string; headers: Record<string, string>; body?: string }) => {
|
|
44
|
+
const response = await fetch(url, { method: init.method, headers: init.headers, body: init.body });
|
|
45
|
+
return {
|
|
46
|
+
status: response.status,
|
|
47
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
48
|
+
body: await response.text(),
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
if (!outcome.text.includes("goal")) throw new Error("The gateway smoke answer carries no goal field.");
|
|
53
|
+
if (outcome.usage?.totaltokens !== 55) throw new Error("The gateway smoke usage did not parse.");
|
|
54
|
+
const streamed = await gateway.gatewaystream({
|
|
55
|
+
config: { ...config, providerid: "smoke-stream" },
|
|
56
|
+
model: "fixture-model-a",
|
|
57
|
+
messages: [{ role: "user", content: "stream" }],
|
|
58
|
+
transport: async (url: string, init: { method: string; headers: Record<string, string>; body?: string }) => {
|
|
59
|
+
const response = await fetch(url, { method: init.method, headers: init.headers, body: init.body });
|
|
60
|
+
return {
|
|
61
|
+
status: response.status,
|
|
62
|
+
headers: Object.fromEntries(response.headers.entries()),
|
|
63
|
+
body: await response.text(),
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
if (streamed.tokens.length !== 3)
|
|
68
|
+
throw new Error("The gateway smoke stream did not carry the three recorded deltas.");
|
|
69
|
+
console.log(
|
|
70
|
+
JSON.stringify({
|
|
71
|
+
valid: true,
|
|
72
|
+
requestid: outcome.requestid,
|
|
73
|
+
tokens: streamed.tokens.length,
|
|
74
|
+
usage: outcome.usage.totaltokens,
|
|
75
|
+
}),
|
|
76
|
+
);
|
|
77
|
+
} finally {
|
|
78
|
+
await server.close();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* the live probe seat: a manual chat round trip against a deployed DevThink
|
|
84
|
+
* gateway (the ZAI sandbox deploy of the getry template). this seat is NOT
|
|
85
|
+
* wired into the deterministic gates: it needs the live network and the
|
|
86
|
+
* deployed host is a runtime setting, never a tracked constant of a gate.
|
|
87
|
+
* it exercises the exact surface the Sol chat client consumes: GET
|
|
88
|
+
* /v1/models (the picker) and POST /v1/chat/completions with the model
|
|
89
|
+
* "devthink" (content + reasoning_content on the answer turn).
|
|
90
|
+
*/
|
|
91
|
+
export async function gatewayprobeseat(base: string): Promise<void> {
|
|
92
|
+
/* GET /v1/models — the chat picker surface. */
|
|
93
|
+
const models = await fetch(`${base}/v1/models`);
|
|
94
|
+
if (!models.ok) {
|
|
95
|
+
console.error(`models probe failed: ${models.status}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
const modellist = (await models.json()) as { data?: Array<{ id?: string }> };
|
|
99
|
+
const ids = (modellist.data ?? []).map((m) => m.id);
|
|
100
|
+
console.log(`models: ${ids.join(", ") || "(none)"}`);
|
|
101
|
+
|
|
102
|
+
/* POST /v1/chat/completions — one round trip on the chat surface. */
|
|
103
|
+
const chat = await fetch(`${base}/v1/chat/completions`, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: { "content-type": "application/json" },
|
|
106
|
+
body: JSON.stringify({
|
|
107
|
+
model: "devthink",
|
|
108
|
+
messages: [{ role: "user", content: "Reply with exactly: gateway ok" }],
|
|
109
|
+
max_tokens: 20,
|
|
110
|
+
}),
|
|
111
|
+
});
|
|
112
|
+
if (!chat.ok) {
|
|
113
|
+
console.error(`chat probe failed: ${chat.status}`);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
const answer = (await chat.json()) as {
|
|
117
|
+
choices?: Array<{ message?: { content?: string; reasoning_content?: string } }>;
|
|
118
|
+
usage?: unknown;
|
|
119
|
+
};
|
|
120
|
+
const turn = answer.choices?.[0]?.message;
|
|
121
|
+
console.log(`chat: ${JSON.stringify(turn?.content ?? "")}`);
|
|
122
|
+
console.log(`reasoning present: ${Boolean(turn?.reasoning_content)}`);
|
|
123
|
+
console.log(`usage: ${JSON.stringify(answer.usage ?? {})}`);
|
|
124
|
+
|
|
125
|
+
if (turn?.content !== "gateway ok") {
|
|
126
|
+
console.error("the gateway answered, but the round trip content drifted");
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
console.log("gateway probe: ok");
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* the dispatched entry the two seats ride: an http(s) URL argument answers
|
|
133
|
+
* the live probe seat (`node gatewaycheck.ts https://<deployed-gateway-host>`,
|
|
134
|
+
* the documented probe call), every other call answers the offline smoke
|
|
135
|
+
* seat (`node gatewaycheck.ts`, the container call). */
|
|
136
|
+
const firstarg = (process.argv[2] ?? "").replace(/\/+$/, "");
|
|
137
|
+
|
|
138
|
+
if (/^https?:\/\//.test(firstarg)) {
|
|
139
|
+
await gatewayprobeseat(firstarg);
|
|
140
|
+
} else {
|
|
141
|
+
await gatewaysmokeseat();
|
|
142
|
+
}
|