bazis 0.100.4 → 0.100.6
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.
|
@@ -232,7 +232,7 @@ export class CodexAppServerClient implements CodexClient {
|
|
|
232
232
|
if (method === "account/updated") this.modelCache = undefined;
|
|
233
233
|
}, () => { this.clearLogin(); this.modelCache = undefined; });
|
|
234
234
|
const initialized = await client.request("initialize", {
|
|
235
|
-
clientInfo: { name: "bazis", title: "Bazis", version: "0.100.
|
|
235
|
+
clientInfo: { name: "bazis", title: "Bazis", version: "0.100.6" }, capabilities: { experimentalApi: true },
|
|
236
236
|
}, 15_000, signal);
|
|
237
237
|
if (resolve(text(initialized.codexHome, 4096)) !== this.paths.home) throw new CodexError("PROTOCOL_ERROR");
|
|
238
238
|
client.notify("initialized");
|
|
@@ -31,7 +31,11 @@ export interface LlmConnectorOptions {
|
|
|
31
31
|
/**
|
|
32
32
|
* Check the provider at start (the adapter's `connect`: `GET /models` for an
|
|
33
33
|
* OpenAI-compatible API, five seconds), so a wrong key or address stops the
|
|
34
|
-
* start instead of the first agent request.
|
|
34
|
+
* start instead of the first agent request. By default it runs in
|
|
35
|
+
* development and production and not in the `test` environment, where a
|
|
36
|
+
* test replaces the model; `true` checks there too, `false` never checks.
|
|
37
|
+
* The same choice applies to `/health`: in tests `infra:llm` does not call
|
|
38
|
+
* the provider and reports healthy.
|
|
35
39
|
*/
|
|
36
40
|
readonly checkOnStart?: boolean;
|
|
37
41
|
}
|
|
@@ -92,7 +96,7 @@ export function llmConnect<T extends LlmConfigShape>(
|
|
|
92
96
|
adapter: LlmProviderAdapter,
|
|
93
97
|
options: LlmConnectorOptions = {},
|
|
94
98
|
): InfraConnector<AgentModelProvider> {
|
|
95
|
-
const described = new WeakMap<AgentModelProvider, { connection: LlmConnectionOptions; settings: string[] }>();
|
|
99
|
+
const described = new WeakMap<AgentModelProvider, { connection: LlmConnectionOptions; settings: string[]; check: boolean; offline: boolean }>();
|
|
96
100
|
return identifyConnector({
|
|
97
101
|
token: AGENT_MODEL_PROVIDER,
|
|
98
102
|
config,
|
|
@@ -101,11 +105,16 @@ export function llmConnect<T extends LlmConfigShape>(
|
|
|
101
105
|
create(configs) {
|
|
102
106
|
const connection = resolveLlmConnectionOptions(config, options, configs);
|
|
103
107
|
const provider = adapter.create(connection);
|
|
104
|
-
|
|
108
|
+
// The environment of this kernel's configuration: tests do not call the real provider.
|
|
109
|
+
const environment = (configs?.get(config) as { environment?: string } | undefined)?.environment;
|
|
110
|
+
const check = options.checkOnStart ?? environment !== "test";
|
|
111
|
+
// In tests the provider is not reached at all, unless checkOnStart: true asks for it.
|
|
112
|
+
const offline = environment === "test" && options.checkOnStart !== true;
|
|
113
|
+
described.set(provider, { connection, settings: settingNames(config, configs, ["baseUrl", "apiKey"]), check, offline });
|
|
105
114
|
return provider;
|
|
106
115
|
},
|
|
107
116
|
connect(provider, signal) {
|
|
108
|
-
if (options.checkOnStart === false) return;
|
|
117
|
+
if (described.get(provider)?.check === false || options.checkOnStart === false) return;
|
|
109
118
|
return adapter.connect?.(provider, signal);
|
|
110
119
|
},
|
|
111
120
|
describe(provider, { connected }) {
|
|
@@ -114,15 +123,16 @@ export function llmConnect<T extends LlmConfigShape>(
|
|
|
114
123
|
return {
|
|
115
124
|
kind: `${known.connection.provider} · ${known.connection.model}`,
|
|
116
125
|
address: known.connection.baseUrl,
|
|
117
|
-
details: connected &&
|
|
126
|
+
details: connected && known.check && adapter.connect !== undefined ? ["checked"] : [],
|
|
118
127
|
settings: known.settings,
|
|
119
128
|
};
|
|
120
129
|
},
|
|
121
130
|
dispose(provider) {
|
|
122
131
|
return adapter.dispose?.(provider);
|
|
123
132
|
},
|
|
133
|
+
// Like the start check: a test does not reach the real provider.
|
|
124
134
|
healthCheck: adapter.healthCheck
|
|
125
|
-
? (provider, signal) => adapter.healthCheck?.(provider, signal) ?? false
|
|
135
|
+
? (provider, signal) => described.get(provider)?.offline === true || (adapter.healthCheck?.(provider, signal) ?? false)
|
|
126
136
|
: undefined,
|
|
127
137
|
}, "llm");
|
|
128
138
|
}
|
|
@@ -14,6 +14,14 @@ export interface RedisReliableDeliveryOptions {
|
|
|
14
14
|
readonly maxReadBytes?: number;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
/** Redis settings without which an acknowledged write may be lost. */
|
|
18
|
+
const DURABLE_REDIS: Readonly<Record<string, string>> = Object.freeze({
|
|
19
|
+
appendonly: "yes",
|
|
20
|
+
appendfsync: "always",
|
|
21
|
+
"no-appendfsync-on-rewrite": "no",
|
|
22
|
+
"maxmemory-policy": "noeviction",
|
|
23
|
+
});
|
|
24
|
+
|
|
17
25
|
export class RedisRoomDeliveryStore implements ReliableRoomDelivery {
|
|
18
26
|
private readonly limits: Required<Omit<RedisReliableDeliveryOptions, "requireAof">>;
|
|
19
27
|
private readonly requireAof: boolean;
|
|
@@ -47,9 +55,18 @@ export class RedisRoomDeliveryStore implements ReliableRoomDelivery {
|
|
|
47
55
|
if (Array.isArray(settings)) for (let i = 0; i < settings.length; i += 2) values.set(settings[i]!, settings[i + 1]!);
|
|
48
56
|
else for (const [key, value] of Object.entries(settings)) values.set(key, value);
|
|
49
57
|
const info = await this.operations.send("INFO", ["persistence"]) as string;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
const problems = Object.entries(DURABLE_REDIS)
|
|
59
|
+
.filter(([name, needed]) => values.get(name) !== needed)
|
|
60
|
+
.map(([name, needed]) => `${name} is ${values.get(name) ?? "unknown"}, needs ${needed}`);
|
|
61
|
+
if (!info.includes("aof_last_write_status:ok")) problems.push("the last append-only file write failed (aof_last_write_status)");
|
|
62
|
+
if (!info.includes("loading:0")) problems.push("Redis is still loading its data");
|
|
63
|
+
if (problems.length > 0) {
|
|
64
|
+
throw new WebSocketDeliveryError(
|
|
65
|
+
"DURABILITY_CONFIGURATION",
|
|
66
|
+
`WebSocket delivery needs a Redis that does not lose writes: ${problems.join("; ")}. `
|
|
67
|
+
+ "Set them in redis.conf or with CONFIG SET; otherwise undelivered messages and sessions may be lost.",
|
|
68
|
+
);
|
|
69
|
+
}
|
|
53
70
|
}
|
|
54
71
|
|
|
55
72
|
async publish(request: ReliableRoomPublication): Promise<ReliableBroadcastReceipt> {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bazis",
|
|
3
|
-
"version": "0.100.
|
|
3
|
+
"version": "0.100.6",
|
|
4
4
|
"description": "Modular backend framework for Bun in TypeScript: DI wired by codegen, HTTP, a PostgreSQL ORM, JWT, WebSocket, agents and a CLI.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Alexander Alenin",
|