@usabledev/usable-chat 1.174.2 → 1.175.0

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.
Files changed (2) hide show
  1. package/cli.js +46 -3
  2. package/package.json +1 -1
package/cli.js CHANGED
@@ -91696,6 +91696,12 @@ var init_env2 = __esm({
91696
91696
  // (/api/oauth/register). Pre-configured in Keycloak (memory-mesh) with PKCE +
91697
91697
  // whitelisted redirect URIs — clients never hit Keycloak's DCR endpoint.
91698
91698
  MCP_OAUTH_CLIENT_ID: external_exports.string().min(1).default("mcp_oauth_client"),
91699
+ // Optional azp (authorized party) allowlist for Bearer JWT auth on API routes.
91700
+ // Comma-separated Keycloak client IDs. UNSET = no azp enforcement (issuer +
91701
+ // signature + expiry only — pre-existing behaviour, keeps embed integrations
91702
+ // working). SET = bearer tokens whose azp is not in the list are rejected
91703
+ // with 401 JWT_AZP_REJECTED. See docs/chat-v2-contract.md#authentication.
91704
+ CHAT_TRUSTED_CLIENT_IDS: external_exports.string().optional(),
91699
91705
  // Usable MCP
91700
91706
  USABLE_MCP_URL: external_exports.string().url().default("https://usable.dev/api/mcp"),
91701
91707
  USABLE_WORKSPACE_ID: external_exports.string().uuid(),
@@ -91803,6 +91809,7 @@ var init_env2 = __esm({
91803
91809
  USABLE_CLIENT_ID: process.env.USABLE_CLIENT_ID,
91804
91810
  USABLE_CLIENT_SECRET: process.env.USABLE_CLIENT_SECRET,
91805
91811
  MCP_OAUTH_CLIENT_ID: process.env.MCP_OAUTH_CLIENT_ID,
91812
+ CHAT_TRUSTED_CLIENT_IDS: process.env.CHAT_TRUSTED_CLIENT_IDS,
91806
91813
  // Usable MCP
91807
91814
  USABLE_MCP_URL: process.env.USABLE_MCP_URL,
91808
91815
  USABLE_WORKSPACE_ID: process.env.USABLE_WORKSPACE_ID,
@@ -91911,7 +91918,12 @@ var init_config = __esm({
91911
91918
  clientId: env.USABLE_CLIENT_ID,
91912
91919
  clientSecret: env.USABLE_CLIENT_SECRET,
91913
91920
  /** Static public client_id returned by the MCP OAuth registration endpoint. */
91914
- mcpOAuthClientId: env.MCP_OAUTH_CLIENT_ID || DEFAULT_MCP_OAUTH_CLIENT_ID2
91921
+ mcpOAuthClientId: env.MCP_OAUTH_CLIENT_ID || DEFAULT_MCP_OAUTH_CLIENT_ID2,
91922
+ /**
91923
+ * Optional azp allowlist for Bearer JWT auth (comma-separated client IDs).
91924
+ * Empty/unset disables enforcement. See docs/chat-v2-contract.md.
91925
+ */
91926
+ trustedClientIdsRaw: env.CHAT_TRUSTED_CLIENT_IDS
91915
91927
  },
91916
91928
  mcp: {
91917
91929
  url: env.USABLE_MCP_URL,
@@ -160161,6 +160173,12 @@ function adaptSchemaForGemini(schema) {
160161
160173
  return cloned;
160162
160174
  }
160163
160175
  function normalizeSchemaForGemini(schema) {
160176
+ if (schema.type === "array" && !isJsonSchemaRecord(schema.items)) {
160177
+ schema.items = { type: "string" };
160178
+ }
160179
+ if (schema.type === "object" && !isJsonSchemaRecord(schema.properties)) {
160180
+ schema.properties = {};
160181
+ }
160164
160182
  const properties = isJsonSchemaRecord(schema.properties) ? schema.properties : void 0;
160165
160183
  if (Array.isArray(schema.enum)) {
160166
160184
  schema.enum = schema.enum.map((enumValue) => String(enumValue));
@@ -199474,6 +199492,9 @@ function sanitizeSchemaForGemini(schema) {
199474
199492
  if (sanitized.type === "array" && !sanitized.items) {
199475
199493
  sanitized.items = { type: "string" };
199476
199494
  }
199495
+ if (sanitized.type === "object" && (!sanitized.properties || typeof sanitized.properties !== "object")) {
199496
+ sanitized.properties = {};
199497
+ }
199477
199498
  pruneRequiredFieldsForGemini(sanitized);
199478
199499
  return sanitized;
199479
199500
  }
@@ -214513,6 +214534,19 @@ Use this to discover the current state of background work \u2014 running, comple
214513
214534
  }
214514
214535
  });
214515
214536
 
214537
+ // src/core/billing/credit-authorization.ts
214538
+ async function authorizeCreditBeforeProvider(port, input) {
214539
+ if (!port) return void 0;
214540
+ const authorization = await port.authorize(input);
214541
+ port.current = authorization;
214542
+ return authorization;
214543
+ }
214544
+ var init_credit_authorization = __esm({
214545
+ "src/core/billing/credit-authorization.ts"() {
214546
+ "use strict";
214547
+ }
214548
+ });
214549
+
214516
214550
  // src/core/orchestrator/discoverable-skills-prompt.ts
214517
214551
  function buildDiscoverableSkillsPromptSection(skills) {
214518
214552
  if (skills.length === 0) {
@@ -289643,6 +289677,12 @@ Re-read them (working_memory on web, bash on the CLI \u2014 grep/sed projection,
289643
289677
  while (true) {
289644
289678
  let overflowMessage;
289645
289679
  try {
289680
+ if (!config3.__scriptedLlm) {
289681
+ await authorizeCreditBeforeProvider(context.creditAuthorization, {
289682
+ inputTokens,
289683
+ maxOutputTokens: maxTokens
289684
+ });
289685
+ }
289646
289686
  result = await callLLM({
289647
289687
  isClaude,
289648
289688
  selectedModelId,
@@ -290305,7 +290345,8 @@ Re-read them (working_memory on web, bash on the CLI \u2014 grep/sed projection,
290305
290345
  });
290306
290346
  }
290307
290347
  }
290308
- const errorCode = error41?.code === "CONTEXT_TOO_LARGE" ? "CONTEXT_TOO_LARGE" : "ORCHESTRATION_ERROR";
290348
+ const rawErrorCode = error41?.code;
290349
+ const errorCode = rawErrorCode === "CONTEXT_TOO_LARGE" || rawErrorCode === "MEMBER_CAP_EXCEEDED" || rawErrorCode === "CREDIT_LIMIT_REACHED" || rawErrorCode === "CREDIT_OVERAGE_CAP_REACHED" || rawErrorCode === "CREDIT_PREFLIGHT_UNAVAILABLE" ? rawErrorCode : "ORCHESTRATION_ERROR";
290309
290350
  const errorEvent = emitter.emit("error", {
290310
290351
  message: errorMessage,
290311
290352
  code: errorCode,
@@ -290348,6 +290389,7 @@ function createOrchestratorRequest(messages4, context, config3, persona, apiKey,
290348
290389
  abortSignal: context.abortSignal,
290349
290390
  sessionPathway: context.sessionPathway,
290350
290391
  // REQUIRED - validated above
290392
+ creditAuthorization: context.creditAuthorization,
290351
290393
  chatStore: context.chatStore,
290352
290394
  // Persistence port (Drizzle for Next.js, SQLite for CLI)
290353
290395
  metadata: context.metadata,
@@ -290447,6 +290489,7 @@ var init_orchestrator = __esm({
290447
290489
  init_redis();
290448
290490
  init_executor();
290449
290491
  init_tool_categories();
290492
+ init_credit_authorization();
290450
290493
  init_discoverable_skills_prompt();
290451
290494
  init_mcp_server_tools_prompt();
290452
290495
  init_spill_payload();
@@ -309129,7 +309172,7 @@ init_tui_select();
309129
309172
  init_model_registry();
309130
309173
 
309131
309174
  // package.json
309132
- var version2 = "1.174.2";
309175
+ var version2 = "1.175.0";
309133
309176
 
309134
309177
  // src/adapters/cli/model-catalog.ts
309135
309178
  init_codex_auth();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usabledev/usable-chat",
3
- "version": "1.174.2",
3
+ "version": "1.175.0",
4
4
  "description": "usable-chat — terminal harness for usable-chat (headless + TUI)",
5
5
  "type": "module",
6
6
  "bin": {