@wenathlan/getry 2.0.166 → 2.0.167
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 +3 -3
- package/docs/features.md +1 -2
- package/docs/gateway.md +2 -3
- package/gatewaycheck.ts +142 -0
- package/package.json +75 -80
- package/{tests → test}/cli.test.ts +1 -1
- 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}/design.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("");
|
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
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wenathlan/getry",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.167",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "getry is the AI gateway of the wenathlan family: five provider gateways (v1 zai, v2 babel, v3 nvidia, v4 opencode+kilo, v5 openrouter) serving 35 OpenAI-compatible routes with the 7-level thinking system, the session store and the key rotation, described by schema.prisma and served as one static Sol surface. The envelope distributes the documentation set and the tests directory as one package.",
|
|
6
|
+
"license": "GPL-3.0-only",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"db:generate": "prisma generate --schema schema.prisma",
|
|
8
9
|
"dev": "vite --host",
|
|
@@ -15,11 +16,11 @@
|
|
|
15
16
|
"restore:entry": "node -e \"const{readFileSync}=require('node:fs');const{execSync}=require('node:child_process');const script=/script[^>]*App\\.tsx/;const triad=/family=Bricolage\\+Grotesque[\\s\\S]*Outfit[\\s\\S]*JetBrains\\+Mono/;const face=(h)=>script.test(h)&&triad.test(h);if(face(readFileSync('index.html','utf8'))){console.log('index.html already rides the source face');process.exit(0)}if(!face(execSync('git show HEAD:./index.html',{encoding:'utf8'}))){console.error('refusing: HEAD index.html is not the canonical source face yet (script App.tsx + the font triad) - land the source-face fix first; nothing was touched');process.exit(1)}execSync('git checkout -- index.html',{stdio:'inherit'});console.log('index.html restored from HEAD (the source face)')\""
|
|
16
17
|
},
|
|
17
18
|
"dependencies": {
|
|
18
|
-
"@ai-sdk/openai": "^4.0.
|
|
19
|
-
"@ai-sdk/openai-compatible": "^3.0.
|
|
19
|
+
"@ai-sdk/openai": "^4.0.110",
|
|
20
|
+
"@ai-sdk/openai-compatible": "^3.0.86",
|
|
20
21
|
"@ai-sdk/provider-utils": "^5.0.75",
|
|
21
22
|
"@anthropic-ai/sdk": "^1.6.0",
|
|
22
|
-
"@biomejs/biome": "^2.6.
|
|
23
|
+
"@biomejs/biome": "^2.6.6",
|
|
23
24
|
"@capacitor/android": "^8.6.0",
|
|
24
25
|
"@capacitor/cli": "^8.6.0",
|
|
25
26
|
"@capacitor/core": "^8.6.0",
|
|
@@ -71,31 +72,31 @@
|
|
|
71
72
|
"@radix-ui/react-toggle-group": "^1.2.1",
|
|
72
73
|
"@radix-ui/react-tooltip": "^1.4.1",
|
|
73
74
|
"@reactuses/core": "^6.6.1",
|
|
74
|
-
"@tailwindcss/postcss": "^4.3.
|
|
75
|
+
"@tailwindcss/postcss": "^4.3.5",
|
|
75
76
|
"@tailwindcss/typography": "^0.5.20",
|
|
76
|
-
"@tailwindcss/vite": "^4.3.
|
|
77
|
-
"@tanstack/react-query": "^5.
|
|
77
|
+
"@tailwindcss/vite": "^4.3.5",
|
|
78
|
+
"@tanstack/react-query": "^5.107.1",
|
|
78
79
|
"@tanstack/react-table": "^9.3.1",
|
|
79
80
|
"@tsconfig/node26": "^26.0.1",
|
|
80
81
|
"@types/babel__core": "^7.20.5",
|
|
81
82
|
"@types/better-sqlite3": "^9.6.0",
|
|
82
83
|
"@types/chrome": "^0.3.7",
|
|
83
84
|
"@types/express": "^5.0.6",
|
|
84
|
-
"@types/google.maps": "^3.66.
|
|
85
|
+
"@types/google.maps": "^3.66.10",
|
|
85
86
|
"@types/node": "^26.6.6",
|
|
86
87
|
"@types/react": "^19.3.0",
|
|
87
88
|
"@types/react-dom": "^19.3.0",
|
|
88
89
|
"@types/three": "^0.187.0",
|
|
89
90
|
"@vitejs/plugin-react": "^6.2.1",
|
|
90
|
-
"@wenathlan/argan": "~2.0.
|
|
91
|
-
"@wenathlan/cadria": "~2.0.
|
|
92
|
-
"@wenathlan/debonair": "~2.0.
|
|
93
|
-
"@wenathlan/devthink": "~2.0.
|
|
94
|
-
"@wenathlan/getry": "~2.0.
|
|
95
|
-
"@wenathlan/saddle": "~2.0.
|
|
96
|
-
"@wenathlan/vault": "~2.0.
|
|
91
|
+
"@wenathlan/argan": "~2.0.166",
|
|
92
|
+
"@wenathlan/cadria": "~2.0.166",
|
|
93
|
+
"@wenathlan/debonair": "~2.0.166",
|
|
94
|
+
"@wenathlan/devthink": "~2.0.166",
|
|
95
|
+
"@wenathlan/getry": "~2.0.166",
|
|
96
|
+
"@wenathlan/saddle": "~2.0.166",
|
|
97
|
+
"@wenathlan/vault": "~2.0.166",
|
|
97
98
|
"add": "^2.0.9",
|
|
98
|
-
"ai": "^7.0.
|
|
99
|
+
"ai": "^7.0.164",
|
|
99
100
|
"autoprefixer": "^10.6.2",
|
|
100
101
|
"axios": "^1.21.0",
|
|
101
102
|
"baseline-browser-mapping": "^2.11.35",
|
|
@@ -121,7 +122,7 @@
|
|
|
121
122
|
"fast-check": "^4.10.2",
|
|
122
123
|
"fast-uri": "^4.2.3",
|
|
123
124
|
"follow-redirects": "^1.16.2",
|
|
124
|
-
"framer-motion": "^14.
|
|
125
|
+
"framer-motion": "^14.10.1",
|
|
125
126
|
"glob": "^14.0.4",
|
|
126
127
|
"gsap": "^3.15.1",
|
|
127
128
|
"hono": "^4.13.16",
|
|
@@ -130,16 +131,16 @@
|
|
|
130
131
|
"js-yaml": "^5.5.0",
|
|
131
132
|
"jsdom": "^31.0.0",
|
|
132
133
|
"katex": "^0.19.1",
|
|
133
|
-
"lucide-react": "^1.
|
|
134
|
+
"lucide-react": "^1.70.0",
|
|
134
135
|
"minimatch": "^11.0.5",
|
|
135
|
-
"motion": "^14.
|
|
136
|
+
"motion": "^14.10.1",
|
|
136
137
|
"mysql2": "^3.24.6",
|
|
137
138
|
"nanoid": "^6.0.2",
|
|
138
139
|
"next": "^16.4.5",
|
|
139
140
|
"next-auth": "^4.24.15",
|
|
140
141
|
"next-intl": "^4.14.9",
|
|
141
142
|
"next-themes": "^0.4.6",
|
|
142
|
-
"openai": "^7.
|
|
143
|
+
"openai": "^7.53.0",
|
|
143
144
|
"p-limit": "^7.3.3",
|
|
144
145
|
"p-retry": "^9.0.0",
|
|
145
146
|
"playwright": "^1.65.0",
|
|
@@ -155,7 +156,7 @@
|
|
|
155
156
|
"react-dom": "^19.3.1",
|
|
156
157
|
"react-hook-form": "^7.91.0",
|
|
157
158
|
"react-markdown": "^10.1.0",
|
|
158
|
-
"react-resizable-panels": "^4.
|
|
159
|
+
"react-resizable-panels": "^4.19.1",
|
|
159
160
|
"react-syntax-highlighter": "^16.1.2",
|
|
160
161
|
"recharts": "^3.10.1",
|
|
161
162
|
"request-ip": "^3.3.0",
|
|
@@ -166,7 +167,7 @@
|
|
|
166
167
|
"source-map-js": "^1.2.2",
|
|
167
168
|
"streamdown": "^2.7.1",
|
|
168
169
|
"tailwind-merge": "^3.7.0",
|
|
169
|
-
"tailwindcss": "^4.3.
|
|
170
|
+
"tailwindcss": "^4.3.5",
|
|
170
171
|
"tailwindcss-animate": "^1.0.7",
|
|
171
172
|
"three": "^0.187.0",
|
|
172
173
|
"ts-node": "^10.9.2",
|
|
@@ -186,14 +187,14 @@
|
|
|
186
187
|
"yaml": "^2.9.1",
|
|
187
188
|
"z-ai-web-dev-sdk": "^0.0.18",
|
|
188
189
|
"zod": "^4.6.7",
|
|
189
|
-
"zustand": "^5.0
|
|
190
|
+
"zustand": "^5.1.0"
|
|
190
191
|
},
|
|
191
192
|
"devDependencies": {
|
|
192
|
-
"@ai-sdk/openai": "^4.0.
|
|
193
|
-
"@ai-sdk/openai-compatible": "^3.0.
|
|
193
|
+
"@ai-sdk/openai": "^4.0.110",
|
|
194
|
+
"@ai-sdk/openai-compatible": "^3.0.86",
|
|
194
195
|
"@ai-sdk/provider-utils": "^5.0.75",
|
|
195
196
|
"@anthropic-ai/sdk": "^1.6.0",
|
|
196
|
-
"@biomejs/biome": "^2.6.
|
|
197
|
+
"@biomejs/biome": "^2.6.6",
|
|
197
198
|
"@capacitor/android": "^8.6.0",
|
|
198
199
|
"@capacitor/cli": "^8.6.0",
|
|
199
200
|
"@capacitor/core": "^8.6.0",
|
|
@@ -245,31 +246,31 @@
|
|
|
245
246
|
"@radix-ui/react-toggle-group": "^1.2.1",
|
|
246
247
|
"@radix-ui/react-tooltip": "^1.4.1",
|
|
247
248
|
"@reactuses/core": "^6.6.1",
|
|
248
|
-
"@tailwindcss/postcss": "^4.3.
|
|
249
|
+
"@tailwindcss/postcss": "^4.3.5",
|
|
249
250
|
"@tailwindcss/typography": "^0.5.20",
|
|
250
|
-
"@tailwindcss/vite": "^4.3.
|
|
251
|
-
"@tanstack/react-query": "^5.
|
|
251
|
+
"@tailwindcss/vite": "^4.3.5",
|
|
252
|
+
"@tanstack/react-query": "^5.107.1",
|
|
252
253
|
"@tanstack/react-table": "^9.3.1",
|
|
253
254
|
"@tsconfig/node26": "^26.0.1",
|
|
254
255
|
"@types/babel__core": "^7.20.5",
|
|
255
256
|
"@types/better-sqlite3": "^9.6.0",
|
|
256
257
|
"@types/chrome": "^0.3.7",
|
|
257
258
|
"@types/express": "^5.0.6",
|
|
258
|
-
"@types/google.maps": "^3.66.
|
|
259
|
+
"@types/google.maps": "^3.66.10",
|
|
259
260
|
"@types/node": "^26.6.6",
|
|
260
261
|
"@types/react": "^19.3.0",
|
|
261
262
|
"@types/react-dom": "^19.3.0",
|
|
262
263
|
"@types/three": "^0.187.0",
|
|
263
264
|
"@vitejs/plugin-react": "^6.2.1",
|
|
264
|
-
"@wenathlan/argan": "~2.0.
|
|
265
|
-
"@wenathlan/cadria": "~2.0.
|
|
266
|
-
"@wenathlan/debonair": "~2.0.
|
|
267
|
-
"@wenathlan/devthink": "~2.0.
|
|
268
|
-
"@wenathlan/getry": "~2.0.
|
|
269
|
-
"@wenathlan/saddle": "~2.0.
|
|
270
|
-
"@wenathlan/vault": "~2.0.
|
|
265
|
+
"@wenathlan/argan": "~2.0.166",
|
|
266
|
+
"@wenathlan/cadria": "~2.0.166",
|
|
267
|
+
"@wenathlan/debonair": "~2.0.166",
|
|
268
|
+
"@wenathlan/devthink": "~2.0.166",
|
|
269
|
+
"@wenathlan/getry": "~2.0.166",
|
|
270
|
+
"@wenathlan/saddle": "~2.0.166",
|
|
271
|
+
"@wenathlan/vault": "~2.0.166",
|
|
271
272
|
"add": "^2.0.9",
|
|
272
|
-
"ai": "^7.0.
|
|
273
|
+
"ai": "^7.0.164",
|
|
273
274
|
"autoprefixer": "^10.6.2",
|
|
274
275
|
"axios": "^1.21.0",
|
|
275
276
|
"baseline-browser-mapping": "^2.11.35",
|
|
@@ -295,7 +296,7 @@
|
|
|
295
296
|
"fast-check": "^4.10.2",
|
|
296
297
|
"fast-uri": "^4.2.3",
|
|
297
298
|
"follow-redirects": "^1.16.2",
|
|
298
|
-
"framer-motion": "^14.
|
|
299
|
+
"framer-motion": "^14.10.1",
|
|
299
300
|
"glob": "^14.0.4",
|
|
300
301
|
"gsap": "^3.15.1",
|
|
301
302
|
"hono": "^4.13.16",
|
|
@@ -304,16 +305,16 @@
|
|
|
304
305
|
"js-yaml": "^5.5.0",
|
|
305
306
|
"jsdom": "^31.0.0",
|
|
306
307
|
"katex": "^0.19.1",
|
|
307
|
-
"lucide-react": "^1.
|
|
308
|
+
"lucide-react": "^1.70.0",
|
|
308
309
|
"minimatch": "^11.0.5",
|
|
309
|
-
"motion": "^14.
|
|
310
|
+
"motion": "^14.10.1",
|
|
310
311
|
"mysql2": "^3.24.6",
|
|
311
312
|
"nanoid": "^6.0.2",
|
|
312
313
|
"next": "^16.4.5",
|
|
313
314
|
"next-auth": "^4.24.15",
|
|
314
315
|
"next-intl": "^4.14.9",
|
|
315
316
|
"next-themes": "^0.4.6",
|
|
316
|
-
"openai": "^7.
|
|
317
|
+
"openai": "^7.53.0",
|
|
317
318
|
"p-limit": "^7.3.3",
|
|
318
319
|
"p-retry": "^9.0.0",
|
|
319
320
|
"playwright": "^1.65.0",
|
|
@@ -329,7 +330,7 @@
|
|
|
329
330
|
"react-dom": "^19.3.1",
|
|
330
331
|
"react-hook-form": "^7.91.0",
|
|
331
332
|
"react-markdown": "^10.1.0",
|
|
332
|
-
"react-resizable-panels": "^4.
|
|
333
|
+
"react-resizable-panels": "^4.19.1",
|
|
333
334
|
"react-syntax-highlighter": "^16.1.2",
|
|
334
335
|
"recharts": "^3.10.1",
|
|
335
336
|
"request-ip": "^3.3.0",
|
|
@@ -340,7 +341,7 @@
|
|
|
340
341
|
"source-map-js": "^1.2.2",
|
|
341
342
|
"streamdown": "^2.7.1",
|
|
342
343
|
"tailwind-merge": "^3.7.0",
|
|
343
|
-
"tailwindcss": "^4.3.
|
|
344
|
+
"tailwindcss": "^4.3.5",
|
|
344
345
|
"tailwindcss-animate": "^1.0.7",
|
|
345
346
|
"three": "^0.187.0",
|
|
346
347
|
"ts-node": "^10.9.2",
|
|
@@ -360,14 +361,14 @@
|
|
|
360
361
|
"yaml": "^2.9.1",
|
|
361
362
|
"z-ai-web-dev-sdk": "^0.0.18",
|
|
362
363
|
"zod": "^4.6.7",
|
|
363
|
-
"zustand": "^5.0
|
|
364
|
+
"zustand": "^5.1.0"
|
|
364
365
|
},
|
|
365
366
|
"overrides": {
|
|
366
|
-
"@ai-sdk/openai": "^4.0.
|
|
367
|
-
"@ai-sdk/openai-compatible": "^3.0.
|
|
367
|
+
"@ai-sdk/openai": "^4.0.110",
|
|
368
|
+
"@ai-sdk/openai-compatible": "^3.0.86",
|
|
368
369
|
"@ai-sdk/provider-utils": "^5.0.75",
|
|
369
370
|
"@anthropic-ai/sdk": "^1.6.0",
|
|
370
|
-
"@biomejs/biome": "^2.6.
|
|
371
|
+
"@biomejs/biome": "^2.6.6",
|
|
371
372
|
"@capacitor/android": "^8.6.0",
|
|
372
373
|
"@capacitor/cli": "^8.6.0",
|
|
373
374
|
"@capacitor/core": "^8.6.0",
|
|
@@ -419,31 +420,31 @@
|
|
|
419
420
|
"@radix-ui/react-toggle-group": "^1.2.1",
|
|
420
421
|
"@radix-ui/react-tooltip": "^1.4.1",
|
|
421
422
|
"@reactuses/core": "^6.6.1",
|
|
422
|
-
"@tailwindcss/postcss": "^4.3.
|
|
423
|
+
"@tailwindcss/postcss": "^4.3.5",
|
|
423
424
|
"@tailwindcss/typography": "^0.5.20",
|
|
424
|
-
"@tailwindcss/vite": "^4.3.
|
|
425
|
-
"@tanstack/react-query": "^5.
|
|
425
|
+
"@tailwindcss/vite": "^4.3.5",
|
|
426
|
+
"@tanstack/react-query": "^5.107.1",
|
|
426
427
|
"@tanstack/react-table": "^9.3.1",
|
|
427
428
|
"@tsconfig/node26": "^26.0.1",
|
|
428
429
|
"@types/babel__core": "^7.20.5",
|
|
429
430
|
"@types/better-sqlite3": "^9.6.0",
|
|
430
431
|
"@types/chrome": "^0.3.7",
|
|
431
432
|
"@types/express": "^5.0.6",
|
|
432
|
-
"@types/google.maps": "^3.66.
|
|
433
|
+
"@types/google.maps": "^3.66.10",
|
|
433
434
|
"@types/node": "^26.6.6",
|
|
434
435
|
"@types/react": "^19.3.0",
|
|
435
436
|
"@types/react-dom": "^19.3.0",
|
|
436
437
|
"@types/three": "^0.187.0",
|
|
437
438
|
"@vitejs/plugin-react": "^6.2.1",
|
|
438
|
-
"@wenathlan/argan": "~2.0.
|
|
439
|
-
"@wenathlan/cadria": "~2.0.
|
|
440
|
-
"@wenathlan/debonair": "~2.0.
|
|
441
|
-
"@wenathlan/devthink": "~2.0.
|
|
442
|
-
"@wenathlan/getry": "~2.0.
|
|
443
|
-
"@wenathlan/saddle": "~2.0.
|
|
444
|
-
"@wenathlan/vault": "~2.0.
|
|
439
|
+
"@wenathlan/argan": "~2.0.166",
|
|
440
|
+
"@wenathlan/cadria": "~2.0.166",
|
|
441
|
+
"@wenathlan/debonair": "~2.0.166",
|
|
442
|
+
"@wenathlan/devthink": "~2.0.166",
|
|
443
|
+
"@wenathlan/getry": "~2.0.166",
|
|
444
|
+
"@wenathlan/saddle": "~2.0.166",
|
|
445
|
+
"@wenathlan/vault": "~2.0.166",
|
|
445
446
|
"add": "^2.0.9",
|
|
446
|
-
"ai": "^7.0.
|
|
447
|
+
"ai": "^7.0.164",
|
|
447
448
|
"autoprefixer": "^10.6.2",
|
|
448
449
|
"axios": "^1.21.0",
|
|
449
450
|
"baseline-browser-mapping": "^2.11.35",
|
|
@@ -469,7 +470,7 @@
|
|
|
469
470
|
"fast-check": "^4.10.2",
|
|
470
471
|
"fast-uri": "^4.2.3",
|
|
471
472
|
"follow-redirects": "^1.16.2",
|
|
472
|
-
"framer-motion": "^14.
|
|
473
|
+
"framer-motion": "^14.10.1",
|
|
473
474
|
"glob": "^14.0.4",
|
|
474
475
|
"gsap": "^3.15.1",
|
|
475
476
|
"hono": "^4.13.16",
|
|
@@ -478,16 +479,16 @@
|
|
|
478
479
|
"js-yaml": "^5.5.0",
|
|
479
480
|
"jsdom": "^31.0.0",
|
|
480
481
|
"katex": "^0.19.1",
|
|
481
|
-
"lucide-react": "^1.
|
|
482
|
+
"lucide-react": "^1.70.0",
|
|
482
483
|
"minimatch": "^11.0.5",
|
|
483
|
-
"motion": "^14.
|
|
484
|
+
"motion": "^14.10.1",
|
|
484
485
|
"mysql2": "^3.24.6",
|
|
485
486
|
"nanoid": "^6.0.2",
|
|
486
487
|
"next": "^16.4.5",
|
|
487
488
|
"next-auth": "^4.24.15",
|
|
488
489
|
"next-intl": "^4.14.9",
|
|
489
490
|
"next-themes": "^0.4.6",
|
|
490
|
-
"openai": "^7.
|
|
491
|
+
"openai": "^7.53.0",
|
|
491
492
|
"p-limit": "^7.3.3",
|
|
492
493
|
"p-retry": "^9.0.0",
|
|
493
494
|
"playwright": "^1.65.0",
|
|
@@ -503,7 +504,7 @@
|
|
|
503
504
|
"react-dom": "^19.3.1",
|
|
504
505
|
"react-hook-form": "^7.91.0",
|
|
505
506
|
"react-markdown": "^10.1.0",
|
|
506
|
-
"react-resizable-panels": "^4.
|
|
507
|
+
"react-resizable-panels": "^4.19.1",
|
|
507
508
|
"react-syntax-highlighter": "^16.1.2",
|
|
508
509
|
"recharts": "^3.10.1",
|
|
509
510
|
"request-ip": "^3.3.0",
|
|
@@ -514,7 +515,7 @@
|
|
|
514
515
|
"source-map-js": "^1.2.2",
|
|
515
516
|
"streamdown": "^2.7.1",
|
|
516
517
|
"tailwind-merge": "^3.7.0",
|
|
517
|
-
"tailwindcss": "^4.3.
|
|
518
|
+
"tailwindcss": "^4.3.5",
|
|
518
519
|
"tailwindcss-animate": "^1.0.7",
|
|
519
520
|
"three": "^0.187.0",
|
|
520
521
|
"ts-node": "^10.9.2",
|
|
@@ -534,7 +535,7 @@
|
|
|
534
535
|
"yaml": "^2.9.1",
|
|
535
536
|
"z-ai-web-dev-sdk": "^0.0.18",
|
|
536
537
|
"zod": "^4.6.7",
|
|
537
|
-
"zustand": "^5.0
|
|
538
|
+
"zustand": "^5.1.0",
|
|
538
539
|
"xcode": {
|
|
539
540
|
"uuid": "11.1.1"
|
|
540
541
|
}
|
|
@@ -689,15 +690,10 @@
|
|
|
689
690
|
"import": "./gateway.ts",
|
|
690
691
|
"default": "./gateway.ts"
|
|
691
692
|
},
|
|
692
|
-
"./
|
|
693
|
-
"types": "./
|
|
694
|
-
"import": "./
|
|
695
|
-
"default": "./
|
|
696
|
-
},
|
|
697
|
-
"./gatewaysmoke": {
|
|
698
|
-
"types": "./gatewaysmoke.ts",
|
|
699
|
-
"import": "./gatewaysmoke.ts",
|
|
700
|
-
"default": "./gatewaysmoke.ts"
|
|
693
|
+
"./gatewaycheck": {
|
|
694
|
+
"types": "./gatewaycheck.ts",
|
|
695
|
+
"import": "./gatewaycheck.ts",
|
|
696
|
+
"default": "./gatewaycheck.ts"
|
|
701
697
|
},
|
|
702
698
|
"./nodeshim": {
|
|
703
699
|
"types": "./nodeshim.ts",
|
|
@@ -718,7 +714,7 @@
|
|
|
718
714
|
"files": [
|
|
719
715
|
"README.md",
|
|
720
716
|
"docs",
|
|
721
|
-
"
|
|
717
|
+
"test",
|
|
722
718
|
"accounts.ts",
|
|
723
719
|
"antigravity.ts",
|
|
724
720
|
"auth.ts",
|
|
@@ -728,8 +724,7 @@
|
|
|
728
724
|
"engine.ts",
|
|
729
725
|
"fingerprint.ts",
|
|
730
726
|
"gateway.ts",
|
|
731
|
-
"
|
|
732
|
-
"gatewaysmoke.ts",
|
|
727
|
+
"gatewaycheck.ts",
|
|
733
728
|
"intelligence.ts",
|
|
734
729
|
"json.ts",
|
|
735
730
|
"labels.ts",
|
|
@@ -745,7 +740,7 @@
|
|
|
745
740
|
"search.ts",
|
|
746
741
|
"server.ts",
|
|
747
742
|
"streaming.ts",
|
|
748
|
-
"
|
|
743
|
+
"test/gatewayserver.ts",
|
|
749
744
|
"thinking.ts",
|
|
750
745
|
"types.ts",
|
|
751
746
|
"utils.ts",
|
|
@@ -289,7 +289,7 @@ describe("cli init with db keys", () => {
|
|
|
289
289
|
);
|
|
290
290
|
expect(keyscode).toBe(0);
|
|
291
291
|
expect(stdout).toContain("register keys");
|
|
292
|
-
const seed = join(dbworkdir, "
|
|
292
|
+
const seed = join(dbworkdir, "test", "seedkeys.mjs");
|
|
293
293
|
expect(existsSync(seed)).toBe(true);
|
|
294
294
|
const content = readFileSync(seed, "utf8");
|
|
295
295
|
expect(content).toContain("key-aaaaaaaaaa");
|
|
@@ -889,9 +889,9 @@ describe("hardcoded provider url scan of the source tree", () => {
|
|
|
889
889
|
const outsidescan = new Set([...gatewaysources, "providers.ts", "gateway.ts", "types.ts"]);
|
|
890
890
|
for (const entry of await readdir(root))
|
|
891
891
|
if (entry.endsWith(".ts") && !outsidescan.has(entry)) files.push(join(root, entry));
|
|
892
|
-
for (const entry of await readdir(join(root, "
|
|
892
|
+
for (const entry of await readdir(join(root, "test")))
|
|
893
893
|
if (entry.endsWith(".ts") && !entry.endsWith(".test.ts") && entry !== "reviewedorigins.ts")
|
|
894
|
-
files.push(join(root, "
|
|
894
|
+
files.push(join(root, "test", entry));
|
|
895
895
|
expect(files.length).toBeGreaterThan(40);
|
|
896
896
|
const providerhosts = [
|
|
897
897
|
/api\.openai\.com/,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* through the thinking seat. the suite pins its own DATABASE_URL before the
|
|
7
7
|
* db import so the mirror opens its own seat (one writer per wal file — the
|
|
8
8
|
* SQLITE_BUSY lesson). runnable with vitest:
|
|
9
|
-
* pnpm vitest run
|
|
9
|
+
* pnpm vitest run test/gatewayversions.test.ts
|
|
10
10
|
*/
|
|
11
11
|
import assert from "node:assert/strict";
|
|
12
12
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// provenance and metrics domain rides its new owner — the battery
|
|
6
6
|
// answers the same contracts the engine suite once pinned: the rag
|
|
7
7
|
// chunking, the retrieval provenance and the token budget trio).
|
|
8
|
-
// runnable with vitest: pnpm vitest run
|
|
8
|
+
// runnable with vitest: pnpm vitest run test/intelligence.test.ts
|
|
9
9
|
import assert from "node:assert/strict";
|
|
10
10
|
import { describe, it } from "vitest";
|
|
11
11
|
import {
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* the health-aware round-robin of nextkeyrow (the pr19 key rotation law —
|
|
4
4
|
* never expose keys, rotation periods, per-provider health) beside the
|
|
5
5
|
* masking discipline the render paths owe. runnable with vitest:
|
|
6
|
-
* pnpm vitest run
|
|
6
|
+
* pnpm vitest run test/keyrotation.test.ts
|
|
7
7
|
*/
|
|
8
8
|
import assert from "node:assert/strict";
|
|
9
9
|
import { describe, it } from "vitest";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// # onboardingstate.test — the pure contract of the seen flags: the host
|
|
2
2
|
// validation of the platform base (https only, public hosts only, mapped
|
|
3
3
|
// ipv6 normalized) and the seen-wins stage merge the accessor and the
|
|
4
|
-
// pages share. runnable with vitest: pnpm vitest run
|
|
4
|
+
// pages share. runnable with vitest: pnpm vitest run test/onboardingstate.test.ts
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
6
|
import { describe, it } from "vitest";
|
|
7
7
|
import { hostallowed, mergeStage } from "../onboardingstate.ts";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** The recorded provider wire fixtures of the gateway family as one dense typescript module: the streams, the completions, the model lists and the tags answer of the four provider shapes (anthropic, gemini, ollama and the openai compatible surface), each export holding the exact original file text of its tests root source. The localhost gateway fixture server serves them over plain http so the adapter suite and the container smoke run the full request cycle offline — no external network, no provider endpoint, no key — and the gateway tests parse the same bodies the stub transports answer. */
|
|
2
2
|
|
|
3
|
-
/** the anthropic message stream (sse events of the content block delta family) — the exact text of the former
|
|
3
|
+
/** the anthropic message stream (sse events of the content block delta family) — the exact text of the former test/anthropic-stream.txt. */
|
|
4
4
|
export const anthropicstream = `event: message_start
|
|
5
5
|
data: {"type":"message_start","message":{"id":"msg-fixture-1","role":"assistant"}}
|
|
6
6
|
|
|
@@ -24,7 +24,7 @@ data: {"type":"message_stop"}
|
|
|
24
24
|
|
|
25
25
|
`;
|
|
26
26
|
|
|
27
|
-
/** the anthropic completion answer (the stop reason and the usage record) — the exact text of the former
|
|
27
|
+
/** the anthropic completion answer (the stop reason and the usage record) — the exact text of the former test/anthropic-completion.json. */
|
|
28
28
|
export const anthropiccompletion = `{
|
|
29
29
|
"id": "msg-fixture-1",
|
|
30
30
|
"type": "message",
|
|
@@ -41,7 +41,7 @@ export const anthropiccompletion = `{
|
|
|
41
41
|
}
|
|
42
42
|
`;
|
|
43
43
|
|
|
44
|
-
/** the anthropic model list (the fixture claude shapes with their context windows) — the exact text of the former
|
|
44
|
+
/** the anthropic model list (the fixture claude shapes with their context windows) — the exact text of the former test/anthropic-models.json. */
|
|
45
45
|
export const anthropicmodels = `{
|
|
46
46
|
"data": [
|
|
47
47
|
{
|
|
@@ -61,7 +61,7 @@ export const anthropicmodels = `{
|
|
|
61
61
|
}
|
|
62
62
|
`;
|
|
63
63
|
|
|
64
|
-
/** the gemini generatecontent stream (the sse quoted-json chunks of the streamed answer) — the exact text of the former
|
|
64
|
+
/** the gemini generatecontent stream (the sse quoted-json chunks of the streamed answer) — the exact text of the former test/gemini-stream.txt. */
|
|
65
65
|
export const geministream = `data: {"candidates":[{"content":{"parts":[{"text":"gemini "}],"role":"model"},"index":0}]}
|
|
66
66
|
|
|
67
67
|
data: {"candidates":[{"content":{"parts":[{"text":"candidate parts "}],"role":"model"},"index":0}]}
|
|
@@ -70,7 +70,7 @@ data: {"candidates":[{"content":{"parts":[{"text":"stream"}],"role":"model"},"in
|
|
|
70
70
|
|
|
71
71
|
`;
|
|
72
72
|
|
|
73
|
-
/** the gemini completion answer (the candidates with the finish reason) — the exact text of the former
|
|
73
|
+
/** the gemini completion answer (the candidates with the finish reason) — the exact text of the former test/gemini-completion.json. */
|
|
74
74
|
export const geminicompletion = `{
|
|
75
75
|
"candidates": [
|
|
76
76
|
{
|
|
@@ -86,7 +86,7 @@ export const geminicompletion = `{
|
|
|
86
86
|
}
|
|
87
87
|
`;
|
|
88
88
|
|
|
89
|
-
/** the gemini model list (the fixture gemini shapes) — the exact text of the former
|
|
89
|
+
/** the gemini model list (the fixture gemini shapes) — the exact text of the former test/gemini-models.json. */
|
|
90
90
|
export const geminimodels = `{
|
|
91
91
|
"models": [
|
|
92
92
|
{
|
|
@@ -106,13 +106,13 @@ export const geminimodels = `{
|
|
|
106
106
|
}
|
|
107
107
|
`;
|
|
108
108
|
|
|
109
|
-
/** the ollama chat stream (the ndjson lines of the streamed answer) — the exact text of the former
|
|
109
|
+
/** the ollama chat stream (the ndjson lines of the streamed answer) — the exact text of the former test/ollama-stream.txt. */
|
|
110
110
|
export const ollamastream = `{"model":"fixture-local:7b","created_at":"2026-01-01T00:00:00Z","message":{"role":"assistant","content":"the local "},"done":false}
|
|
111
111
|
{"model":"fixture-local:7b","created_at":"2026-01-01T00:00:00Z","message":{"role":"assistant","content":"runtime streams "},"done":false}
|
|
112
112
|
{"model":"fixture-local:7b","created_at":"2026-01-01T00:00:00Z","message":{"role":"assistant","content":"line by line"},"done":true}
|
|
113
113
|
`;
|
|
114
114
|
|
|
115
|
-
/** the ollama chat completion answer (the message and the done record) — the exact text of the former
|
|
115
|
+
/** the ollama chat completion answer (the message and the done record) — the exact text of the former test/ollama-completion.json. */
|
|
116
116
|
export const ollamacompletion = `{
|
|
117
117
|
"model": "fixture-local:7b",
|
|
118
118
|
"created_at": "2026-01-01T00:00:00Z",
|
|
@@ -126,7 +126,7 @@ export const ollamacompletion = `{
|
|
|
126
126
|
}
|
|
127
127
|
`;
|
|
128
128
|
|
|
129
|
-
/** the ollama tags answer (the local model list with sizes and digests) — the exact text of the former
|
|
129
|
+
/** the ollama tags answer (the local model list with sizes and digests) — the exact text of the former test/ollama-tags.json. */
|
|
130
130
|
export const ollamatags = `{
|
|
131
131
|
"models": [
|
|
132
132
|
{
|
|
@@ -161,7 +161,7 @@ export const ollamatags = `{
|
|
|
161
161
|
}
|
|
162
162
|
`;
|
|
163
163
|
|
|
164
|
-
/** the openai compatible chat stream (the sse chunks of the streamed answer) — the exact text of the former
|
|
164
|
+
/** the openai compatible chat stream (the sse chunks of the streamed answer) — the exact text of the former test/openaicompat-stream.txt. */
|
|
165
165
|
export const openaicompatstream = `data: {"id":"chatcmpl-fixture-1","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":"{\\"goal\\":"}}]}
|
|
166
166
|
|
|
167
167
|
data: {"id":"chatcmpl-fixture-1","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"\\"streamed answer\\","}}]}
|
|
@@ -172,7 +172,7 @@ data: [DONE]
|
|
|
172
172
|
|
|
173
173
|
`;
|
|
174
174
|
|
|
175
|
-
/** the openai compatible chat completion answer (the choices with the message and the usage) — the exact text of the former
|
|
175
|
+
/** the openai compatible chat completion answer (the choices with the message and the usage) — the exact text of the former test/openaicompat-completion.json. */
|
|
176
176
|
export const openaicompatcompletion = `{
|
|
177
177
|
"id": "chatcmpl-fixture-1",
|
|
178
178
|
"object": "chat.completion",
|
|
@@ -191,7 +191,7 @@ export const openaicompatcompletion = `{
|
|
|
191
191
|
}
|
|
192
192
|
`;
|
|
193
193
|
|
|
194
|
-
/** the openai compatible model list (the fixture model shapes) — the exact text of the former
|
|
194
|
+
/** the openai compatible model list (the fixture model shapes) — the exact text of the former test/openaicompat-models.json. */
|
|
195
195
|
export const openaicompatmodels = `{
|
|
196
196
|
"object": "list",
|
|
197
197
|
"data": [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** The public research catalog sources as one dense typescript module: the twelve public github search exports beside the two markdown documents the catalog build derives from them, each export holding the exact original file text of its
|
|
1
|
+
/** The public research catalog sources as one dense typescript module: the twelve public github search exports beside the two markdown documents the catalog build derives from them, each export holding the exact original file text of its test/code source. The exports record source metadata only — the catalog build never downloads or executes repository code — and the markdown documents carry the licensed sample, the method notes and the comparative feature and flow matrix the research review reads. */
|
|
2
2
|
|
|
3
3
|
/** The public repository metadata of the browser agent search export (one recorded repository), harvested from the public github search index on 2026-08-27 — the exact text of the former reposagent.json. */
|
|
4
4
|
export const reposagent = `[
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// modality id pins the seat for the platform's join to validate at
|
|
10
10
|
// dispatch — this module never judges engine vocabulary). runnable with
|
|
11
11
|
// vitest:
|
|
12
|
-
// pnpm vitest run
|
|
12
|
+
// pnpm vitest run test/sandboxmodality.test.ts
|
|
13
13
|
import assert from "node:assert/strict";
|
|
14
14
|
import { describe, it } from "vitest";
|
|
15
15
|
import { lanesof } from "@wenathlan/saddle/workloadlaw";
|
package/gatewayprobe.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* gatewayprobe.ts — manual chat round trip against a deployed DevThink
|
|
3
|
-
* gateway (the ZAI sandbox deploy of the getry template). This probe is
|
|
4
|
-
* NOT wired into the deterministic gates: it needs the live network and
|
|
5
|
-
* the deployed host is a runtime setting, never a tracked constant of a
|
|
6
|
-
* gate. Run it by hand with the base URL as the first argument:
|
|
7
|
-
*
|
|
8
|
-
* node gatewayprobe.ts https://<deployed-gateway-host>
|
|
9
|
-
*
|
|
10
|
-
* The probe exercises the exact surface the Sol chat client consumes:
|
|
11
|
-
* GET /v1/models (the picker) and POST /v1/chat/completions with the
|
|
12
|
-
* model "devthink" (content + reasoning_content on the answer turn).
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const base = (process.argv[2] ?? "").replace(/\/+$/, "");
|
|
16
|
-
|
|
17
|
-
if (!/^https?:\/\//.test(base)) {
|
|
18
|
-
console.error("usage: node gatewayprobe.ts https://<deployed-gateway-host>");
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/* GET /v1/models — the chat picker surface. */
|
|
23
|
-
const models = await fetch(`${base}/v1/models`);
|
|
24
|
-
if (!models.ok) {
|
|
25
|
-
console.error(`models probe failed: ${models.status}`);
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
|
-
const modellist = (await models.json()) as { data?: Array<{ id?: string }> };
|
|
29
|
-
const ids = (modellist.data ?? []).map((m) => m.id);
|
|
30
|
-
console.log(`models: ${ids.join(", ") || "(none)"}`);
|
|
31
|
-
|
|
32
|
-
/* POST /v1/chat/completions — one round trip on the chat surface. */
|
|
33
|
-
const chat = await fetch(`${base}/v1/chat/completions`, {
|
|
34
|
-
method: "POST",
|
|
35
|
-
headers: { "content-type": "application/json" },
|
|
36
|
-
body: JSON.stringify({
|
|
37
|
-
model: "devthink",
|
|
38
|
-
messages: [{ role: "user", content: "Reply with exactly: gateway ok" }],
|
|
39
|
-
max_tokens: 20,
|
|
40
|
-
}),
|
|
41
|
-
});
|
|
42
|
-
if (!chat.ok) {
|
|
43
|
-
console.error(`chat probe failed: ${chat.status}`);
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
const answer = (await chat.json()) as {
|
|
47
|
-
choices?: Array<{ message?: { content?: string; reasoning_content?: string } }>;
|
|
48
|
-
usage?: unknown;
|
|
49
|
-
};
|
|
50
|
-
const turn = answer.choices?.[0]?.message;
|
|
51
|
-
console.log(`chat: ${JSON.stringify(turn?.content ?? "")}`);
|
|
52
|
-
console.log(`reasoning present: ${Boolean(turn?.reasoning_content)}`);
|
|
53
|
-
console.log(`usage: ${JSON.stringify(answer.usage ?? {})}`);
|
|
54
|
-
|
|
55
|
-
if (turn?.content !== "gateway ok") {
|
|
56
|
-
console.error("the gateway answered, but the round trip content drifted");
|
|
57
|
-
process.exit(1);
|
|
58
|
-
}
|
|
59
|
-
console.log("gateway probe: ok");
|
|
60
|
-
|
|
61
|
-
export {};
|
package/gatewaysmoke.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
/** The containerfile gateway smoke of the 1.1.83 family: it starts the localhost fixture server, loads the built gateway module and runs one full request cycle against the recorded openaicompat fixture offline — no provider endpoint, no key, no external network — so the container image proves the gateway call path before it ships. */
|
|
2
|
-
import { startgatewayfixtureserver } from "./tests/gatewayserver.ts";
|
|
3
|
-
import type { baseurlconfig } from "./types.ts";
|
|
4
|
-
|
|
5
|
-
const server = await startgatewayfixtureserver();
|
|
6
|
-
try {
|
|
7
|
-
/* the smoke loads the BUILT gateway module — build/llm.js is a container
|
|
8
|
-
* build artifact a fresh checkout never carries, so the specifier rides a
|
|
9
|
-
* variable (tsc never fails on the absent artifact while the runtime
|
|
10
|
-
* keeps loading the built face) and the cast pins the module to the
|
|
11
|
-
* source contract that sits beside it. */
|
|
12
|
-
const builtpath = "./build/llm.js";
|
|
13
|
-
const gateway = (await import(builtpath)) as typeof import("./llm.ts");
|
|
14
|
-
const config: baseurlconfig = {
|
|
15
|
-
providerid: "smoke",
|
|
16
|
-
kind: "openaicompat",
|
|
17
|
-
baseurl: `http://127.0.0.1:${server.port}/openaicompat`,
|
|
18
|
-
enabled: true,
|
|
19
|
-
consented: true,
|
|
20
|
-
consentedat: Date.now(),
|
|
21
|
-
updatedat: Date.now(),
|
|
22
|
-
};
|
|
23
|
-
const outcome = await gateway.gatewaycall({
|
|
24
|
-
config,
|
|
25
|
-
model: "fixture-model-a",
|
|
26
|
-
messages: [{ role: "user", content: "draft one step" }],
|
|
27
|
-
requestid: "smoke-1",
|
|
28
|
-
transport: async (url: string, init: { method: string; headers: Record<string, string>; body?: string }) => {
|
|
29
|
-
const response = await fetch(url, { method: init.method, headers: init.headers, body: init.body });
|
|
30
|
-
return {
|
|
31
|
-
status: response.status,
|
|
32
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
33
|
-
body: await response.text(),
|
|
34
|
-
};
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
if (!outcome.text.includes("goal")) throw new Error("The gateway smoke answer carries no goal field.");
|
|
38
|
-
if (outcome.usage?.totaltokens !== 55) throw new Error("The gateway smoke usage did not parse.");
|
|
39
|
-
const streamed = await gateway.gatewaystream({
|
|
40
|
-
config: { ...config, providerid: "smoke-stream" },
|
|
41
|
-
model: "fixture-model-a",
|
|
42
|
-
messages: [{ role: "user", content: "stream" }],
|
|
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 (streamed.tokens.length !== 3)
|
|
53
|
-
throw new Error("The gateway smoke stream did not carry the three recorded deltas.");
|
|
54
|
-
console.log(
|
|
55
|
-
JSON.stringify({
|
|
56
|
-
valid: true,
|
|
57
|
-
requestid: outcome.requestid,
|
|
58
|
-
tokens: streamed.tokens.length,
|
|
59
|
-
usage: outcome.usage.totaltokens,
|
|
60
|
-
}),
|
|
61
|
-
);
|
|
62
|
-
} finally {
|
|
63
|
-
await server.close();
|
|
64
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|