bazis 0.110.1 → 0.111.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.
@@ -853,21 +853,6 @@ export class AgentToolExecutor {
853
853
  return this.finish(call, result, startedAt, metadata, options, audit, undefined, undefined, undefined, executionState);
854
854
  }
855
855
 
856
- if (
857
- (tool.metadata.sideEffect === "write" || tool.metadata.sideEffect === "external")
858
- && audit.sink === undefined
859
- && !(options.allowUnauditedSideEffects ?? this.allowUnauditedSideEffects)
860
- ) {
861
- const result = this.errorResult(
862
- call,
863
- "TOOL_AUDIT_REQUIRED",
864
- `Tool "${tool.metadata.name}" has side effects and requires an audit sink.`,
865
- metadata,
866
- startedAt,
867
- );
868
- return this.finish(call, result, startedAt, metadata, options, audit, tool, options.agentName, undefined, executionState);
869
- }
870
-
871
856
  const visibility = this.authorizeAgent(tool, options);
872
857
  if (!visibility.allowed) {
873
858
  const code = visibility.code ?? "TOOL_NOT_VISIBLE_TO_AGENT";
@@ -887,6 +872,22 @@ export class AgentToolExecutor {
887
872
  return this.finish(call, result, startedAt, metadata, options, audit, tool, options.agentName, undefined, executionState);
888
873
  }
889
874
 
875
+ // After visibility: a tool the agent cannot see is refused for that reason.
876
+ if (
877
+ (tool.metadata.sideEffect === "write" || tool.metadata.sideEffect === "external")
878
+ && audit.sink === undefined
879
+ && !(options.allowUnauditedSideEffects ?? this.allowUnauditedSideEffects)
880
+ ) {
881
+ const result = this.errorResult(
882
+ call,
883
+ "TOOL_AUDIT_REQUIRED",
884
+ `Tool "${tool.metadata.name}" has side effects and requires an audit sink.`,
885
+ metadata,
886
+ startedAt,
887
+ );
888
+ return this.finish(call, result, startedAt, metadata, options, audit, tool, options.agentName, undefined, executionState);
889
+ }
890
+
890
891
  const schema = this.schemaSettings(options);
891
892
  const schemaGate = this.ensureSchemaValidator(call, tool, schema, metadata, startedAt);
892
893
  if (schemaGate) {
@@ -6,10 +6,12 @@ import {
6
6
  Global,
7
7
  Module,
8
8
  singletonValue,
9
+ CLASS_PROVIDER_HOOK,
9
10
  type BazisModuleRef,
10
11
  } from "../di";
11
12
  import { loadBazisGeneratedRuntime } from "../generatedRuntime";
12
13
  import { missingCacheModuleCheck } from "../cache/http/missingCacheModuleCheck";
14
+ import { cacheableClassProviderHook } from "../cache/di/classProviderHook";
13
15
  import { httpModule, useModelValidator, type HttpModuleOptions, type ModelValidator } from "../http";
14
16
  import { grpcModule, type GrpcModuleOptions } from "../grpc";
15
17
  import { buildHttpOpenApiDocument } from "../http/OpenApi/openApiDocument";
@@ -322,6 +324,11 @@ export function composeApp(root: BazisModuleRef, options: RunAppOptions = {}): B
322
324
  // Warns about @OutputCache routes when no cache module is installed.
323
325
  globals.push({ global: true, providers: [missingCacheModuleCheck()] });
324
326
  }
327
+ // The cache wrapper of @Cacheable / @CacheableRedis classes, also without a cache
328
+ // module: it then needs ICache, and the graph check names the class and says to add
329
+ // cache: memory(). Without it the decorators would silently do nothing. The cache
330
+ // module registers the same hook, and DI keeps one.
331
+ globals.push({ global: true, providers: [singletonValue(CLASS_PROVIDER_HOOK, cacheableClassProviderHook)] });
325
332
  const appRoot: BazisModuleRef =
326
333
  globals.length > 0 || options.config !== undefined
327
334
  ? {
@@ -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.110.1" }, capabilities: { experimentalApi: true },
235
+ clientInfo: { name: "bazis", title: "Bazis", version: "0.111.1" }, 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");
@@ -12,6 +12,7 @@ import {
12
12
  type AgentModelResponse,
13
13
  } from "../../agent";
14
14
  import { InfraError, type InfraConnector } from "../InfraConnector";
15
+ import { identifyConnector } from "../connectorIdentity";
15
16
  import { redactSensitiveText } from "../../../library/redaction";
16
17
  import { awaitAbortable } from "../../kernel/internal/awaitAbortable";
17
18
  import {
@@ -426,7 +427,9 @@ export function llmRouter(
426
427
  ensureFallbacksValid(entries);
427
428
  const configs = Object.freeze(Array.from(new Set(entries.map(([, profile]) => profile.config))));
428
429
 
429
- return {
430
+ // The framework LLM connector, like llmConnect: it never touches the schema,
431
+ // so it may start before application services next to ormBazis ensureCreated.
432
+ return identifyConnector({
430
433
  token: AGENT_MODEL_PROVIDER,
431
434
  config: configs,
432
435
  providers: agentRuntimeProviders,
@@ -462,5 +465,5 @@ export function llmRouter(
462
465
  healthCheck(client, signal) {
463
466
  return client instanceof LlmModelRouter ? client.healthCheck(signal) : false;
464
467
  },
465
- };
468
+ }, "llm");
466
469
  }
@@ -467,12 +467,11 @@ export class OpenAiCompatibleModelProvider implements AgentModelProvider {
467
467
  const toolCalls = message.content
468
468
  .filter((part) => part.kind === "tool-call")
469
469
  .map((part) => {
470
- const providerName = mapping.bazisToProvider.get(part.call.name);
471
- if (providerName === undefined) {
472
- throw new OpenAiCompatibleProviderError(
473
- `Assistant transcript references tool "${part.call.name}" which is absent from the request contract.`,
474
- );
475
- }
470
+ // A call to a tool outside this request (one the agent may not use, or
471
+ // a made-up name) stays in the history next to its denial: the model must
472
+ // see both to recover. It gets a wire name that no request tool uses.
473
+ const providerName = mapping.bazisToProvider.get(part.call.name)
474
+ ?? providerToolName(part.call.name, new Set(mapping.providerToBazis.keys()));
476
475
  return Object.freeze({
477
476
  id: part.call.id,
478
477
  type: "function" as const,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bazis",
3
- "version": "0.110.1",
3
+ "version": "0.111.1",
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",