@tangle-network/agent-app 0.60.192 → 0.60.194

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 (37) hide show
  1. package/dist/app-auth/index.js +3 -3
  2. package/dist/assistant/index.js +3 -3
  3. package/dist/chat-routes/index.js +8 -5
  4. package/dist/chat-routes/index.js.map +1 -1
  5. package/dist/chat-routes/model-failover-stream.d.ts +8 -0
  6. package/dist/chat-routes/sandbox-producer.d.ts +12 -0
  7. package/dist/chat-routes/turn-routes.d.ts +14 -0
  8. package/dist/{chunk-QAF7ZTO3.js → chunk-L5JLOC2F.js} +4 -4
  9. package/dist/{chunk-QW4UOEPH.js → chunk-SUIH5B55.js} +5 -3
  10. package/dist/chunk-SUIH5B55.js.map +1 -0
  11. package/dist/chunk-XELWWXJJ.js +101 -0
  12. package/dist/chunk-XELWWXJJ.js.map +1 -0
  13. package/dist/{chunk-Q2H5FKVG.js → chunk-XP77DJEF.js} +16 -1
  14. package/dist/chunk-XP77DJEF.js.map +1 -0
  15. package/dist/{chunk-63EKFZOE.js → chunk-ZLX4BA27.js} +15 -1
  16. package/dist/chunk-ZLX4BA27.js.map +1 -0
  17. package/dist/model-resolution/failover.d.ts +16 -2
  18. package/dist/model-resolution/index.d.ts +42 -0
  19. package/dist/model-resolution/index.js +30 -5
  20. package/dist/model-resolution/index.js.map +1 -1
  21. package/dist/policy-filters/index.d.ts +166 -0
  22. package/dist/policy-filters/index.js +23 -0
  23. package/dist/policy-filters/index.js.map +1 -0
  24. package/dist/public-consultation/index.d.ts +1 -1
  25. package/dist/public-consultation/index.js +2 -1
  26. package/dist/public-consultation/index.js.map +1 -1
  27. package/dist/sandbox/index.d.ts +1 -0
  28. package/dist/sandbox/index.js +3 -3
  29. package/dist/sandbox/model.d.ts +4 -0
  30. package/dist/settings-react/index.js +1 -1
  31. package/dist/tools/index.js +2 -2
  32. package/dist/web-react/index.js +7 -7
  33. package/package.json +6 -1
  34. package/dist/chunk-63EKFZOE.js.map +0 -1
  35. package/dist/chunk-Q2H5FKVG.js.map +0 -1
  36. package/dist/chunk-QW4UOEPH.js.map +0 -1
  37. /package/dist/{chunk-QAF7ZTO3.js.map → chunk-L5JLOC2F.js.map} +0 -0
@@ -50,6 +50,7 @@
50
50
  * byte-identical to no failover. A silent chain is now deliberately bounded.
51
51
  */
52
52
  import { ModelFailoverExhaustedError, type ModelFailoverAttempt } from '../model-resolution/failover';
53
+ import type { ModelPolicy } from '../policy-filters/index';
53
54
  /**
54
55
  * True when `event` puts content in front of the user (or in the persisted
55
56
  * transcript), making a restart on another model unsafe.
@@ -118,6 +119,13 @@ export interface ModelFailoverStreamOptions {
118
119
  /** Preferred model first, then fallbacks in descending preference. */
119
120
  models: readonly string[];
120
121
  open: OpenModelStream;
122
+ /**
123
+ * Product admission policy applied to EVERY chain member before its stream
124
+ * is opened — see `runWithModelFailover`'s `policy`. A member the policy
125
+ * refuses is skipped (never opened, never sent the turn's data) and the walk
126
+ * continues; an all-refused chain ends in `ModelFailoverExhaustedError`.
127
+ */
128
+ policy?: ModelPolicy;
121
129
  /**
122
130
  * Maximum time to open/start one model's event source, including its first
123
131
  * iterator pull. Default 120 seconds, matching the sandbox provisioning
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { type InteractionRequestWire } from '../interactions/contract';
17
17
  import { type JsonRecord } from '../stream/index';
18
+ import type { ModelPolicy } from '../policy-filters/index';
18
19
  import { type EmptyTurnRetryInfo, type ModelFallbackInfo, type OpenModelStream } from './model-failover-stream';
19
20
  import type { ChatTurnRouteProducer } from './turn-routes';
20
21
  /** Outcome of a `promoteFilePart` attempt. `key`, when given, becomes the
@@ -80,6 +81,17 @@ export interface SandboxChatProducerOptions {
80
81
  /** Opt out of failover while still using {@link openEvents}. `false` collapses
81
82
  * the chain to `model` alone. */
82
83
  modelFailover?: false;
84
+ /**
85
+ * Product admission policy applied to every chain member — the RESOLVED
86
+ * preferred model AND every fallback — before its stream is opened. This is
87
+ * the execution-time half of policy enforcement: it covers the model
88
+ * whatever its source (request body, env, product default), and it is what
89
+ * stops a compliant model's mid-turn 502 from re-running the turn's data
90
+ * through a non-compliant fallback. A refused member is skipped with the
91
+ * refusal recorded in `modelFailover().attempts`; an all-refused chain
92
+ * exhausts. Omit → availability only (today's behavior).
93
+ */
94
+ modelPolicy?: ModelPolicy;
83
95
  /** Maximum time to open/start one model event source through its first event.
84
96
  * Default 120 seconds. This is separate from provider first-output latency
85
97
  * so cold sandbox startup is not mislabeled as an inference failure. */
@@ -54,6 +54,7 @@ import { type DraftPersistenceTuning } from './draft-persistence';
54
54
  import { type InteractionAnswerRoute, type InteractionAnswerRouteOptions } from '../interactions/route';
55
55
  import { type PersistedChatMessageForTurn, type TurnEventStore } from '../stream/index';
56
56
  import type { ModelFailoverAttempt } from '../model-resolution/failover';
57
+ import { type ModelPolicy } from '../policy-filters/index';
57
58
  import { type TurnRoutePhase } from './turn-progress';
58
59
  import { type ChatTurnPartInput, type ChatTurnRequestPayload } from './wire';
59
60
  /** Usage receipt persisted onto the assistant message (the flattened
@@ -471,6 +472,19 @@ export interface CreateChatTurnRoutesOptions<TContext = void> {
471
472
  * a plain response without the progress header, a `turn.response` event
472
473
  * with it. Omit → nothing to prepare. */
473
474
  prepareTurn?(args: ChatTurnPrepareArgs<TContext>): ChatTurnPrepareResult | Promise<ChatTurnPrepareResult>;
475
+ /** Product admission policy over the model a turn NAMES. When the request
476
+ * body carries a `model`, it is checked here — after `authorize`, before
477
+ * the conversation loads, the lock is taken, or any row is written — and a
478
+ * refusal answers 403 with the policy's reason. Fail-closed: a named model
479
+ * carrying no policy metadata is refused.
480
+ *
481
+ * This is half the enforcement. A body without `model` resolves to a
482
+ * product default inside `produce`, which this seam never sees — enforce
483
+ * that half at execution with `createSandboxChatProducer`'s `modelPolicy`
484
+ * (or `runWithModelFailover`'s `policy` on a custom producer), which also
485
+ * covers every fallback the turn could fail over to. Wire the SAME policy
486
+ * object to both. Omit → no policy check (today's behavior). */
487
+ modelPolicy?: ModelPolicy;
474
488
  /** Thread/message persistence (`/chat-store`'s store or a product adapter). */
475
489
  store: ChatTurnMessageStore;
476
490
  /** Turn-event buffer (`createD1TurnEventStore(env.DB)` or `/turn-stream`'s
@@ -2,15 +2,15 @@ import {
2
2
  authenticateToolRequest,
3
3
  createMcpToolHandler
4
4
  } from "./chunk-6A7MYOUI.js";
5
+ import {
6
+ assertRenderUiSchema
7
+ } from "./chunk-2RCPPOQ4.js";
5
8
  import {
6
9
  base64UrlDecodeText,
7
10
  base64UrlEncodeText,
8
11
  constantTimeEqual,
9
12
  hmacSha256Base64Url
10
13
  } from "./chunk-S5SRJJQG.js";
11
- import {
12
- assertRenderUiSchema
13
- } from "./chunk-2RCPPOQ4.js";
14
14
  import {
15
15
  buildAppToolOpenAITools,
16
16
  findCustomTool,
@@ -270,4 +270,4 @@ export {
270
270
  createAppToolRuntimeExecutor,
271
271
  handleAppToolRequest
272
272
  };
273
- //# sourceMappingURL=chunk-QAF7ZTO3.js.map
273
+ //# sourceMappingURL=chunk-L5JLOC2F.js.map
@@ -47,6 +47,7 @@ function backendModelFields(model) {
47
47
  model: model.model,
48
48
  provider: model.provider,
49
49
  ...model.apiKey !== void 0 ? { apiKey: model.apiKey } : {},
50
+ ...model.apiKeyEnv !== void 0 ? { apiKeyEnv: model.apiKeyEnv } : {},
50
51
  ...model.baseUrl !== void 0 ? { baseUrl: model.baseUrl } : {}
51
52
  }
52
53
  };
@@ -66,7 +67,8 @@ function resolveModelSelection(config, override) {
66
67
  const source = overrideModel ? "override" : configModel ? "config" : "default";
67
68
  if (!provider) return { succeeded: false, error: "no_provider", model: modelName, source };
68
69
  const apiKey = explicitApiKey ?? (provider === "openai" ? openaiApiKey : void 0);
69
- if (!apiKey && !c.allowKeylessModel) {
70
+ const apiKeyEnv = apiKey ? null : trimOrNull(c.apiKeyEnv);
71
+ if (!apiKey && !apiKeyEnv && !c.allowKeylessModel) {
70
72
  return { succeeded: false, error: "no_api_key", model: modelName, provider, source };
71
73
  }
72
74
  return {
@@ -74,7 +76,7 @@ function resolveModelSelection(config, override) {
74
76
  value: {
75
77
  model: modelName,
76
78
  provider,
77
- ...apiKey ? { apiKey } : {},
79
+ ...apiKey ? { apiKey } : apiKeyEnv ? { apiKeyEnv } : {},
78
80
  ...explicitBaseUrl ? { baseUrl: explicitBaseUrl } : {}
79
81
  }
80
82
  };
@@ -3343,4 +3345,4 @@ export {
3343
3345
  isTerminalPromptEvent,
3344
3346
  detectInteractiveQuestion
3345
3347
  };
3346
- //# sourceMappingURL=chunk-QW4UOEPH.js.map
3348
+ //# sourceMappingURL=chunk-SUIH5B55.js.map