veryfront 0.1.755 → 0.1.756

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 (100) hide show
  1. package/esm/cli/auth/callback-server.d.ts +4 -1
  2. package/esm/cli/auth/callback-server.d.ts.map +1 -1
  3. package/esm/cli/auth/callback-server.js +52 -13
  4. package/esm/cli/auth/index.d.ts +1 -1
  5. package/esm/cli/auth/index.d.ts.map +1 -1
  6. package/esm/cli/auth/index.js +1 -1
  7. package/esm/cli/auth/login.d.ts +2 -0
  8. package/esm/cli/auth/login.d.ts.map +1 -1
  9. package/esm/cli/auth/login.js +18 -6
  10. package/esm/cli/commands/demo/demo.d.ts.map +1 -1
  11. package/esm/cli/commands/demo/demo.js +6 -7
  12. package/esm/deno.js +1 -1
  13. package/esm/src/agent/runtime/index.d.ts +3 -96
  14. package/esm/src/agent/runtime/index.d.ts.map +1 -1
  15. package/esm/src/agent/runtime/index.js +21 -341
  16. package/esm/src/agent/runtime/model-capabilities.d.ts +3 -0
  17. package/esm/src/agent/runtime/model-capabilities.d.ts.map +1 -0
  18. package/esm/src/agent/runtime/model-capabilities.js +18 -0
  19. package/esm/src/agent/runtime/runtime-tool-config.d.ts +14 -0
  20. package/esm/src/agent/runtime/runtime-tool-config.d.ts.map +1 -0
  21. package/esm/src/agent/runtime/runtime-tool-config.js +37 -0
  22. package/esm/src/agent/runtime/skill-policy-enforcement.d.ts +16 -0
  23. package/esm/src/agent/runtime/skill-policy-enforcement.d.ts.map +1 -0
  24. package/esm/src/agent/runtime/skill-policy-enforcement.js +55 -0
  25. package/esm/src/agent/runtime/tool-result-continuation.d.ts +34 -0
  26. package/esm/src/agent/runtime/tool-result-continuation.d.ts.map +1 -0
  27. package/esm/src/agent/runtime/tool-result-continuation.js +194 -0
  28. package/esm/src/agent/schemas/agent.schema.d.ts +7 -0
  29. package/esm/src/agent/schemas/agent.schema.d.ts.map +1 -1
  30. package/esm/src/agent/schemas/agent.schema.js +9 -3
  31. package/esm/src/agent/schemas/index.d.ts +1 -1
  32. package/esm/src/agent/schemas/index.d.ts.map +1 -1
  33. package/esm/src/agent/schemas/index.js +1 -1
  34. package/esm/src/modules/server/module-server.d.ts.map +1 -1
  35. package/esm/src/modules/server/module-server.js +31 -9
  36. package/esm/src/modules/server/rate-limiter.d.ts +3 -2
  37. package/esm/src/modules/server/rate-limiter.d.ts.map +1 -1
  38. package/esm/src/platform/adapters/base.d.ts +24 -3
  39. package/esm/src/platform/adapters/base.d.ts.map +1 -1
  40. package/esm/src/platform/adapters/base.js +15 -1
  41. package/esm/src/platform/adapters/runtime/bun/websocket-adapter.d.ts +2 -0
  42. package/esm/src/platform/adapters/runtime/bun/websocket-adapter.d.ts.map +1 -1
  43. package/esm/src/platform/adapters/runtime/bun/websocket-adapter.js +33 -1
  44. package/esm/src/platform/adapters/runtime/node/websocket-adapter.d.ts +1 -1
  45. package/esm/src/platform/adapters/runtime/node/websocket-adapter.d.ts.map +1 -1
  46. package/esm/src/platform/adapters/runtime/node/websocket-adapter.js +3 -10
  47. package/esm/src/proxy/handler.d.ts.map +1 -1
  48. package/esm/src/proxy/handler.js +25 -116
  49. package/esm/src/proxy/local-project-resolver.d.ts +18 -0
  50. package/esm/src/proxy/local-project-resolver.d.ts.map +1 -0
  51. package/esm/src/proxy/local-project-resolver.js +63 -0
  52. package/esm/src/proxy/proxy-token-resolution.d.ts +37 -0
  53. package/esm/src/proxy/proxy-token-resolution.d.ts.map +1 -0
  54. package/esm/src/proxy/proxy-token-resolution.js +51 -0
  55. package/esm/src/rendering/orchestrator/module-loader/index.d.ts +10 -0
  56. package/esm/src/rendering/orchestrator/module-loader/index.d.ts.map +1 -1
  57. package/esm/src/rendering/orchestrator/module-loader/index.js +23 -158
  58. package/esm/src/rendering/orchestrator/module-loader/module-persistence.d.ts +20 -0
  59. package/esm/src/rendering/orchestrator/module-loader/module-persistence.d.ts.map +1 -0
  60. package/esm/src/rendering/orchestrator/module-loader/module-persistence.js +80 -0
  61. package/esm/src/rendering/orchestrator/module-loader/module-transform-cache.d.ts +59 -0
  62. package/esm/src/rendering/orchestrator/module-loader/module-transform-cache.d.ts.map +1 -0
  63. package/esm/src/rendering/orchestrator/module-loader/module-transform-cache.js +97 -0
  64. package/esm/src/routing/api/handler.d.ts +2 -1
  65. package/esm/src/routing/api/handler.d.ts.map +1 -1
  66. package/esm/src/routing/api/handler.js +2 -1
  67. package/esm/src/routing/api/route-executor.d.ts +3 -0
  68. package/esm/src/routing/api/route-executor.d.ts.map +1 -1
  69. package/esm/src/routing/api/route-executor.js +28 -0
  70. package/esm/src/runtime/runtime-bridge.js +2 -2
  71. package/esm/src/security/http/base-handler.d.ts +3 -2
  72. package/esm/src/security/http/base-handler.d.ts.map +1 -1
  73. package/esm/src/security/http/base-handler.js +1 -1
  74. package/esm/src/security/sandbox/project-worker.d.ts +1 -0
  75. package/esm/src/security/sandbox/project-worker.d.ts.map +1 -1
  76. package/esm/src/security/sandbox/project-worker.js +17 -1
  77. package/esm/src/security/sandbox/worker-egress-guard.d.ts +15 -0
  78. package/esm/src/security/sandbox/worker-egress-guard.d.ts.map +1 -0
  79. package/esm/src/security/sandbox/worker-egress-guard.js +201 -0
  80. package/esm/src/security/sandbox/worker-permissions.d.ts +6 -2
  81. package/esm/src/security/sandbox/worker-permissions.d.ts.map +1 -1
  82. package/esm/src/security/sandbox/worker-permissions.js +34 -3
  83. package/esm/src/security/sandbox/worker-pool.d.ts +1 -1
  84. package/esm/src/security/sandbox/worker-pool.d.ts.map +1 -1
  85. package/esm/src/security/sandbox/worker-pool.js +35 -9
  86. package/esm/src/server/handlers/preview/hmr-client-manager.d.ts +3 -2
  87. package/esm/src/server/handlers/preview/hmr-client-manager.d.ts.map +1 -1
  88. package/esm/src/server/handlers/preview/hmr.handler.d.ts.map +1 -1
  89. package/esm/src/server/handlers/preview/hmr.handler.js +4 -1
  90. package/esm/src/server/handlers/request/api/api-handler-wrapper.js +1 -1
  91. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fallback.d.ts +32 -0
  92. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fallback.d.ts.map +1 -0
  93. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/http-fallback.js +27 -0
  94. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.d.ts.map +1 -1
  95. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/import-rewriter.js +23 -3
  96. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.d.ts.map +1 -1
  97. package/esm/src/transforms/mdx/esm-module-loader/module-fetcher/index.js +15 -15
  98. package/esm/src/utils/version-constant.d.ts +1 -1
  99. package/esm/src/utils/version-constant.js +1 -1
  100. package/package.json +1 -1
@@ -20,15 +20,17 @@ import { addSpanEvent, setSpanAttributes, withSpan, } from "../../observability/
20
20
  import { convertToTextGenerationRuntimeMessages } from "./text-generation-runtime-message-converter.js";
21
21
  import { convertToolsToRuntimeTools } from "./model-tool-converter.js";
22
22
  import { resolveProviderOptionsWithDefaults } from "./default-provider-options.js";
23
- import { getRuntimeRemoteToolSources, } from "./mcp-server-tool-sources.js";
23
+ import { getRuntimeRemoteToolSources } from "./mcp-server-tool-sources.js";
24
24
  import { createStreamState, processStream, } from "./chat-stream-handler.js";
25
25
  import { repairToolCall } from "./repair-tool-call.js";
26
- import { stripLeadingEmptyObjectPlaceholder } from "../streaming/data-stream.js";
27
26
  import { MiddlewareChain } from "../middleware/chain.js";
28
27
  import { AGENT_DEFAULTS } from "./defaults.js";
29
28
  import { tryGetCacheKeyContext } from "../../cache/cache-key-builder.js";
30
29
  import { isLocalModelRuntime } from "../../provider/runtime-inspection.js";
31
30
  import { generateText, streamText } from "../../runtime/runtime-bridge.js";
31
+ import { captureStreamedToolCallInput, collectFinalStreamToolResults, collectGeneratedToolResults, createToolErrorMessage, createToolResultMessage, getProviderExecutedToolNames, getToolResultError, isRecoverablePlaceholderToolCall, isStreamedToolCallIncomplete, materializeStreamedToolCall, shouldContinueAfterStreamStep, } from "./tool-result-continuation.js";
32
+ import { enforceSkillPolicy, extractSkillPolicy, hydrateActiveSkillStateFromMessages, LOAD_SKILL_TOOL_ID, } from "./skill-policy-enforcement.js";
33
+ import { getRuntimeAllowedRemoteTools, getRuntimeForwardedIntegrationToolDefs, getRuntimeProviderTools, } from "./runtime-tool-config.js";
32
34
  // Re-export from submodules
33
35
  export { closeSSEStream, generateMessageId, sendSSE } from "./sse-utils.js";
34
36
  export { RunAlreadyExistsError, RunCancelledError, RunNotActiveError, RunResumeSessionManager, WaitConflictError, WaitNotPendingError, } from "./resume-session.js";
@@ -37,357 +39,30 @@ export { getProviderToolProfile, sanitizeProviderToolSchema, selectProviderCompa
37
39
  export { accumulateUsage, getMaxSteps, normalizeInput } from "./input-utils.js";
38
40
  export { createStreamState, processStream } from "./chat-stream-handler.js";
39
41
  export { DEFAULT_MAX_STEPS, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE, MAX_STREAM_BUFFER_SIZE, } from "./constants.js";
42
+ export { captureStreamedToolCallInput, collectFinalStreamToolResults, collectGeneratedToolResults, collectPersistedToolResults, isRecoverablePlaceholderToolCall, isStreamedToolCallIncomplete, materializeStreamedToolCall, shouldContinueAfterStreamStep, } from "./tool-result-continuation.js";
43
+ export { enforceSkillPolicy, extractSkillPolicy, } from "./skill-policy-enforcement.js";
40
44
  import { DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE, getModelMaxOutputTokens } from "./constants.js";
41
45
  import { closeSSEStream, generateMessageId, sendSSE } from "./sse-utils.js";
42
- import { executeConfiguredTool, getAvailableTools, isDynamicTool, parseToolArgs, } from "./tool-helpers.js";
46
+ import { executeConfiguredTool, getAvailableTools, isDynamicTool } from "./tool-helpers.js";
43
47
  import { accumulateUsage, getMaxSteps, normalizeInput } from "./input-utils.js";
44
- import { filterToolsForSkill, isToolAllowedBySkill, validateAllowedToolPatterns, } from "../../skill/allowed-tools.js";
48
+ import { filterToolsForSkill } from "../../skill/allowed-tools.js";
45
49
  import { resolveConfiguredAgentModel, resolveRuntimeModel } from "./model-resolution.js";
46
50
  import { stringifyToolError, throwIfAborted } from "./error-utils.js";
51
+ import { supportsTemperatureParameter } from "./model-capabilities.js";
47
52
  import { applySkillDelegationOverridesToToolInput, extractSkillDelegationOverrides, } from "./skill-delegation-overrides.js";
48
53
  const logger = serverLogger.component("agent");
49
- const LOAD_SKILL_TOOL_ID = "load_skill";
50
54
  function isAbortError(error, abortSignal) {
51
55
  if (abortSignal?.aborted && error === abortSignal.reason) {
52
56
  return true;
53
57
  }
54
58
  return error instanceof DOMException && error.name === "AbortError";
55
59
  }
56
- function getToolResultError(result) {
57
- if (!result || typeof result !== "object" || !("error" in result)) {
58
- return undefined;
59
- }
60
- return stringifyToolError(result.error);
61
- }
62
- function getSkillActivationRequiredError(toolName) {
63
- return `Tool "${toolName}" cannot run before load_skill succeeds in the same step. ` +
64
- `Call "${LOAD_SKILL_TOOL_ID}" first to establish the active skill context.`;
65
- }
66
60
  function warnLocalToolSkipping(agentId, modelId) {
67
61
  logger.warn(`Agent "${agentId}" has tools configured but is using local model "${modelId}". ` +
68
62
  "Local models don't support tool calling — tools will be skipped. " +
69
63
  "Set VERYFRONT_API_TOKEN and VERYFRONT_PROJECT_SLUG, or configure " +
70
64
  "OPENAI_API_KEY, ANTHROPIC_API_KEY, or GOOGLE_API_KEY for full tool support.");
71
65
  }
72
- function createToolResultMessage(toolCallId, toolName, result, providerExecuted = false) {
73
- return {
74
- id: `tool_${toolCallId}`,
75
- role: "tool",
76
- parts: [
77
- {
78
- type: "tool-result",
79
- toolCallId,
80
- toolName,
81
- result,
82
- ...(providerExecuted ? { providerExecuted: true } : {}),
83
- },
84
- ],
85
- timestamp: Date.now(),
86
- };
87
- }
88
- function createToolErrorMessage(toolCallId, toolName, error) {
89
- return {
90
- id: `tool_error_${toolCallId}`,
91
- role: "tool",
92
- parts: [
93
- {
94
- type: "tool-result",
95
- toolCallId,
96
- toolName,
97
- result: { error },
98
- },
99
- ],
100
- timestamp: Date.now(),
101
- };
102
- }
103
- function getProviderExecutedToolNames(runtimeTools) {
104
- if (!runtimeTools) {
105
- return [];
106
- }
107
- return Object.entries(runtimeTools).flatMap(([toolName, definition]) => {
108
- if (definition &&
109
- typeof definition === "object" &&
110
- "type" in definition &&
111
- definition.type === "provider") {
112
- return [toolName];
113
- }
114
- return [];
115
- });
116
- }
117
- export function collectFinalStreamToolResults(state) {
118
- const finalToolResults = new Map();
119
- for (const toolResult of state.toolResults) {
120
- if (toolResult.preliminary === true) {
121
- continue;
122
- }
123
- finalToolResults.set(toolResult.toolCallId, toolResult);
124
- }
125
- return finalToolResults;
126
- }
127
- export function collectPersistedToolResults(messages) {
128
- const persistedToolResults = new Map();
129
- for (const message of messages) {
130
- if (message.role !== "tool") {
131
- continue;
132
- }
133
- for (const part of message.parts) {
134
- if (!isToolResultPart(part)) {
135
- continue;
136
- }
137
- persistedToolResults.set(part.toolCallId, part);
138
- }
139
- }
140
- return persistedToolResults;
141
- }
142
- export function collectGeneratedToolResults(toolResults) {
143
- const generatedToolResults = new Map();
144
- for (const toolResult of toolResults ?? []) {
145
- generatedToolResults.set(toolResult.toolCallId, toolResult);
146
- }
147
- return generatedToolResults;
148
- }
149
- export function shouldContinueAfterStreamStep(state) {
150
- if (!state.toolCalls.size) {
151
- return false;
152
- }
153
- const streamedToolCalls = Array.from(state.toolCalls.values());
154
- const hasIncompleteToolCall = streamedToolCalls.some(isStreamedToolCallIncomplete);
155
- const hasFinalizedClientToolCall = streamedToolCalls.some((toolCall) => toolCall.inputAvailable === true && toolCall.providerExecuted !== true);
156
- const hasProviderExecutedToolCall = streamedToolCalls.some((toolCall) => toolCall.providerExecuted === true);
157
- // A non-finalized call whose only accumulated arguments are a bare
158
- // empty-object placeholder is provisional streamed input the model never
159
- // committed. We can recover by re-calling the model, so it must not block
160
- // continuation (unlike a truncated/dead partial-JSON call).
161
- const hasIncompleteDeadToolCall = streamedToolCalls.some((toolCall) => isStreamedToolCallIncomplete(toolCall) &&
162
- !isRecoverablePlaceholderToolCall(toolCall));
163
- const hasRecoverablePlaceholderToolCall = streamedToolCalls.some(isRecoverablePlaceholderToolCall);
164
- if (state.finishReason === "tool-calls") {
165
- if (hasIncompleteDeadToolCall) {
166
- return false;
167
- }
168
- if (hasProviderExecutedToolCall && !hasFinalizedClientToolCall) {
169
- return false;
170
- }
171
- // Recover provisional placeholders by re-calling the model even when no
172
- // client tool call finalized in this step.
173
- if (hasRecoverablePlaceholderToolCall && !hasFinalizedClientToolCall) {
174
- return true;
175
- }
176
- return !hasIncompleteToolCall && hasFinalizedClientToolCall;
177
- }
178
- if (state.finishReason !== "stop") {
179
- return false;
180
- }
181
- if (state.accumulatedText.trim().length > 0) {
182
- return false;
183
- }
184
- const finalToolResults = collectFinalStreamToolResults(state);
185
- if (!finalToolResults.size) {
186
- for (const toolCall of state.toolCalls.values()) {
187
- if (toolCall.inputAvailable !== true || toolCall.providerExecuted === true) {
188
- return false;
189
- }
190
- }
191
- return true;
192
- }
193
- for (const [toolCallId, toolCall] of state.toolCalls) {
194
- const toolResult = finalToolResults.get(toolCallId);
195
- if (!toolResult) {
196
- return false;
197
- }
198
- if (toolCall.providerExecuted !== true && toolResult.providerExecuted !== true) {
199
- return false;
200
- }
201
- }
202
- return true;
203
- }
204
- export function captureStreamedToolCallInput(toolCall) {
205
- const { args, error } = parseToolArgs(toolCall.arguments);
206
- return {
207
- args,
208
- ...(toolCall.arguments.length > 0 ? { inputText: toolCall.arguments } : {}),
209
- ...(error ? { parseError: error } : {}),
210
- };
211
- }
212
- /**
213
- * A streamed tool call is "incomplete" when the provider stream terminated
214
- * (abort, stall, timeout, transport error) before the SDK emitted the
215
- * finalizing `tool-call` event that sets `inputAvailable: true`. In that state
216
- * `arguments` only holds partial JSON fragments from `tool-input-delta` events,
217
- * so the tool call is NOT a committed model choice and must not be parsed or
218
- * executed. This is semantically distinct from a parse failure on a finalized
219
- * tool call (`inputAvailable: true` but malformed JSON — which only happens on
220
- * genuine provider bugs) and needs to be reported as a stream-termination
221
- * error rather than a tool-argument error.
222
- */
223
- export function isStreamedToolCallIncomplete(toolCall) {
224
- return toolCall.inputAvailable !== true;
225
- }
226
- /**
227
- * A non-finalized streamed tool call is a "recoverable placeholder" when its
228
- * accumulated `arguments` are empty or only the transient empty-object
229
- * placeholder `"{}"` (after stripping leading placeholders). This happens when
230
- * a provider emits `tool-input-start` + a `"{}"` `tool-input-delta` and then
231
- * finishes the step WITHOUT ever sending the finalizing `tool-call` /
232
- * `tool-input-end` event — the model never actually committed any arguments.
233
- *
234
- * Unlike an incomplete-dead tool call (which carries real truncated partial
235
- * JSON and must stop the loop to avoid retry storms), a recoverable
236
- * placeholder carries no committed intent, so the runtime can safely re-call
237
- * the model to recover the real tool call. Such placeholders must NOT be
238
- * executed and must NOT surface a stream-termination error.
239
- */
240
- export function isRecoverablePlaceholderToolCall(toolCall) {
241
- if (!isStreamedToolCallIncomplete(toolCall)) {
242
- return false;
243
- }
244
- const stripped = stripLeadingEmptyObjectPlaceholder(toolCall.arguments);
245
- return stripped === "" || stripped === "{}";
246
- }
247
- /**
248
- * Classify and build the persisted `MessagePart` for a single streamed tool
249
- * call. Pure function — no logging, no SSE, no memory. Callers decide what to
250
- * do with the result so this stays unit-testable.
251
- *
252
- * The resulting `part` is always pushed into the assistant message so the
253
- * conversation history is transparent: even incomplete tool calls leave a
254
- * visible trace with their partial `inputText`. What differs is the caller's
255
- * error-surfacing behavior (log warning, SSE event, tool-result error).
256
- */
257
- export function materializeStreamedToolCall(tc) {
258
- const providerExecutedPart = tc.providerExecuted === true
259
- ? { providerExecuted: true }
260
- : {};
261
- const basePart = {
262
- type: `tool-${tc.name}`,
263
- toolCallId: tc.id,
264
- toolName: tc.name,
265
- args: {},
266
- ...(tc.arguments.length > 0 ? { inputText: tc.arguments } : {}),
267
- ...providerExecutedPart,
268
- };
269
- if (isStreamedToolCallIncomplete(tc)) {
270
- return {
271
- kind: "incomplete",
272
- part: basePart,
273
- partialArgumentsLength: tc.arguments.length,
274
- partialArgumentsPreview: tc.arguments.slice(0, 200),
275
- };
276
- }
277
- const capturedInput = captureStreamedToolCallInput(tc);
278
- const part = {
279
- type: `tool-${tc.name}`,
280
- toolCallId: tc.id,
281
- toolName: tc.name,
282
- args: capturedInput.args,
283
- ...(capturedInput.inputText ? { inputText: capturedInput.inputText } : {}),
284
- ...providerExecutedPart,
285
- };
286
- if (capturedInput.parseError) {
287
- return { kind: "parse-error", part, parseError: capturedInput.parseError };
288
- }
289
- return { kind: "complete", part };
290
- }
291
- function isToolResultPart(part) {
292
- return part.type === "tool-result" && "result" in part;
293
- }
294
- function hydrateActiveSkillStateFromMessages(messages) {
295
- let activeSkillPolicy;
296
- let activeSkillDelegationOverrides;
297
- for (const message of messages) {
298
- for (const part of message.parts) {
299
- if (!isToolResultPart(part) || part.toolName !== LOAD_SKILL_TOOL_ID)
300
- continue;
301
- activeSkillPolicy = extractSkillPolicy(part.result);
302
- activeSkillDelegationOverrides = extractSkillDelegationOverrides(part.result);
303
- }
304
- }
305
- return { activeSkillPolicy, activeSkillDelegationOverrides };
306
- }
307
- /**
308
- * Extract and validate the skill policy from a load_skill tool result.
309
- * Returns `[]` (no tools allowed) for invalid/missing policies instead of
310
- * `undefined` (no restrictions), preventing accidental policy bypass.
311
- */
312
- export function extractSkillPolicy(result) {
313
- if (!result || typeof result !== "object")
314
- return undefined;
315
- const skillResult = result;
316
- // No allowedTools key means the skill has no restrictions
317
- if (!("allowedTools" in skillResult) || skillResult.allowedTools === undefined) {
318
- return undefined;
319
- }
320
- // Validate the shape: must be a string array
321
- const raw = skillResult.allowedTools;
322
- if (!Array.isArray(raw) || !raw.every((v) => typeof v === "string")) {
323
- // Invalid shape — fail closed (empty policy = no tools allowed)
324
- logger.warn("load_skill returned invalid allowedTools; falling back to empty policy (no tools)");
325
- return [];
326
- }
327
- // Validate each pattern against the regex
328
- try {
329
- return validateAllowedToolPatterns(raw);
330
- }
331
- catch (error) {
332
- logger.warn("load_skill returned invalid tool patterns; falling back to empty policy (no tools)", { error });
333
- return [];
334
- }
335
- }
336
- /**
337
- * Enforce skill policy on a single tool call.
338
- * Shared between generate() and stream() paths.
339
- */
340
- export function enforceSkillPolicy(toolName, activeSkillPolicy, mustLoadSkillFirst) {
341
- // Must load skill before other tools
342
- if (mustLoadSkillFirst && toolName !== LOAD_SKILL_TOOL_ID) {
343
- return { allowed: false, error: getSkillActivationRequiredError(toolName) };
344
- }
345
- // Check tool allowed by active skill policy (Layer 2: execution-time)
346
- if (activeSkillPolicy && !isToolAllowedBySkill(toolName, activeSkillPolicy)) {
347
- return {
348
- allowed: false,
349
- error: `Tool "${toolName}" is not allowed by the active skill policy. Allowed: ${activeSkillPolicy.join(", ")}`,
350
- };
351
- }
352
- return { allowed: true };
353
- }
354
- function getRuntimeAllowedRemoteTools(config) {
355
- const configWithRuntimeFilters = config;
356
- if (!Object.hasOwn(configWithRuntimeFilters, "__vfAllowedRemoteTools")) {
357
- return undefined;
358
- }
359
- const raw = configWithRuntimeFilters.__vfAllowedRemoteTools;
360
- if (!Array.isArray(raw)) {
361
- return [];
362
- }
363
- return raw.every((toolName) => typeof toolName === "string") ? raw : [];
364
- }
365
- function getRuntimeProviderTools(config) {
366
- const raw = config.providerTools;
367
- if (!Array.isArray(raw)) {
368
- return [];
369
- }
370
- return raw.every((toolName) => typeof toolName === "string") ? raw : [];
371
- }
372
- function getRuntimeForwardedIntegrationToolDefs(config) {
373
- const configWithFilters = config;
374
- const raw = configWithFilters.__vfForwardedIntegrationToolDefs;
375
- if (!Array.isArray(raw) || raw.length === 0)
376
- return undefined;
377
- return raw
378
- .filter((def) => typeof def === "object" &&
379
- def !== null &&
380
- typeof def.name === "string" &&
381
- typeof def.description === "string")
382
- .map((def) => ({
383
- name: def.name,
384
- description: def.description,
385
- parameters: typeof def.parameters === "object" && def.parameters !== null &&
386
- !Array.isArray(def.parameters)
387
- ? def.parameters
388
- : { type: "object", properties: {} },
389
- }));
390
- }
391
66
  /** Implement agent runtime. */
392
67
  export class AgentRuntime {
393
68
  id;
@@ -470,7 +145,7 @@ export class AgentRuntime {
470
145
  return chain.execute(agentContext, () => this.executeAgentLoop(systemPrompt, messages, {
471
146
  agentId: this.id,
472
147
  projectId: tryGetCacheKeyContext()?.projectId,
473
- }, context, resolvedModelString, transport.languageModel, transport.headers, transport.providerOptions, maxOutputTokensOverride));
148
+ }, context, resolvedModelString, transport.languageModel, transport.headers, transport.providerOptions, maxOutputTokensOverride, requestedModel));
474
149
  });
475
150
  }
476
151
  /**
@@ -551,7 +226,7 @@ export class AgentRuntime {
551
226
  model: effectiveModel,
552
227
  },
553
228
  });
554
- const response = await chain.execute(agentContext, () => this.executeAgentLoopStreaming(systemPrompt, memoryMessages, controller, encoder, callbacks, textPartId, toolContext, context, resolvedModelString, languageModel, transport.headers, transport.providerOptions, maxOutputTokensOverride, streamAbortSignal));
229
+ const response = await chain.execute(agentContext, () => this.executeAgentLoopStreaming(systemPrompt, memoryMessages, controller, encoder, callbacks, textPartId, toolContext, context, resolvedModelString, languageModel, transport.headers, transport.providerOptions, maxOutputTokensOverride, streamAbortSignal, requestedModel));
555
230
  throwIfAborted(streamAbortSignal);
556
231
  callbacks?.onFinish?.(response);
557
232
  throwIfAborted(streamAbortSignal);
@@ -583,7 +258,7 @@ export class AgentRuntime {
583
258
  /**
584
259
  * Execute agent loop (with tool calling)
585
260
  */
586
- async executeAgentLoop(systemPrompt, messages, toolContextBase, runtimeContext, modelString, resolvedModel, headers, providerOptions, maxOutputTokensOverride) {
261
+ async executeAgentLoop(systemPrompt, messages, toolContextBase, runtimeContext, modelString, resolvedModel, headers, providerOptions, maxOutputTokensOverride, temperatureModelString) {
587
262
  return withSpan("agent.execution_loop", async (loopSpan) => {
588
263
  const { maxAgentSteps } = getPlatformCapabilities();
589
264
  const maxSteps = this.computeMaxSteps(maxAgentSteps);
@@ -625,6 +300,7 @@ export class AgentRuntime {
625
300
  if (activeSkillPolicy) {
626
301
  tools = filterToolsForSkill(tools, activeSkillPolicy);
627
302
  }
303
+ const temperature = this.resolveTemperature(temperatureModelString ?? effectiveModel);
628
304
  const response = await withSpan("agent.generate_text", async (span) => {
629
305
  setSpanAttributes(span, {
630
306
  "model.id": effectiveModel,
@@ -640,7 +316,7 @@ export class AgentRuntime {
640
316
  }),
641
317
  experimental_repairToolCall: repairToolCall,
642
318
  maxOutputTokens: this.resolveMaxOutputTokens(effectiveModel, maxOutputTokensOverride),
643
- temperature: this.resolveTemperature(),
319
+ ...(temperature === undefined ? {} : { temperature }),
644
320
  ...(headers ? { headers } : {}),
645
321
  ...(providerOptions ? { providerOptions } : {}),
646
322
  });
@@ -803,7 +479,7 @@ export class AgentRuntime {
803
479
  * Emits veryfront stream events (message-start/message-finish + step-start/step-end)
804
480
  * while consuming model-runtime `streamText()` parts internally.
805
481
  */
806
- async executeAgentLoopStreaming(systemPrompt, messages, controller, encoder, callbacks, textPartId, toolContextBase, runtimeContext, modelString, resolvedModel, headers, providerOptions, maxOutputTokensOverride, abortSignal) {
482
+ async executeAgentLoopStreaming(systemPrompt, messages, controller, encoder, callbacks, textPartId, toolContextBase, runtimeContext, modelString, resolvedModel, headers, providerOptions, maxOutputTokensOverride, abortSignal, temperatureModelString) {
807
483
  const { maxAgentSteps } = getPlatformCapabilities();
808
484
  const maxSteps = this.computeMaxSteps(maxAgentSteps);
809
485
  const effectiveModel = resolveRuntimeModel(modelString || this.config.model);
@@ -851,6 +527,7 @@ export class AgentRuntime {
851
527
  model: effectiveModel,
852
528
  providerTools,
853
529
  });
530
+ const temperature = this.resolveTemperature(temperatureModelString ?? effectiveModel);
854
531
  const result = streamText({
855
532
  model: languageModel,
856
533
  system: currentSystemPrompt,
@@ -858,7 +535,7 @@ export class AgentRuntime {
858
535
  tools: runtimeTools,
859
536
  experimental_repairToolCall: repairToolCall,
860
537
  maxOutputTokens: this.resolveMaxOutputTokens(effectiveModel, maxOutputTokensOverride),
861
- temperature: this.resolveTemperature(),
538
+ ...(temperature === undefined ? {} : { temperature }),
862
539
  ...(headers ? { headers } : {}),
863
540
  ...(providerOptions ? { providerOptions } : {}),
864
541
  abortSignal,
@@ -1141,7 +818,10 @@ export class AgentRuntime {
1141
818
  const edgeMaxSteps = this.config.edge?.enabled ? this.config.edge.maxSteps : undefined;
1142
819
  return getMaxSteps(this.config.maxSteps, edgeMaxSteps, platformLimit);
1143
820
  }
1144
- resolveTemperature() {
821
+ resolveTemperature(modelString) {
822
+ if (!supportsTemperatureParameter(modelString)) {
823
+ return undefined;
824
+ }
1145
825
  return this.config.temperature ?? DEFAULT_TEMPERATURE;
1146
826
  }
1147
827
  resolveMaxOutputTokens(modelString, maxOutputTokensOverride) {
@@ -0,0 +1,3 @@
1
+ export declare function normalizeModelCapabilityId(modelString?: string): string | undefined;
2
+ export declare function supportsTemperatureParameter(modelString?: string): boolean;
3
+ //# sourceMappingURL=model-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-capabilities.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/model-capabilities.ts"],"names":[],"mappings":"AAOA,wBAAgB,0BAA0B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKnF;AAED,wBAAgB,4BAA4B,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAI1E"}
@@ -0,0 +1,18 @@
1
+ const VERYFRONT_CLOUD_MODEL_PREFIX = "veryfront-cloud/";
2
+ const MODELS_WITHOUT_TEMPERATURE_PARAMETER = new Set([
3
+ "anthropic/claude-opus-4-7",
4
+ "anthropic/claude-opus-4-8",
5
+ ]);
6
+ export function normalizeModelCapabilityId(modelString) {
7
+ if (!modelString)
8
+ return undefined;
9
+ return modelString.startsWith(VERYFRONT_CLOUD_MODEL_PREFIX)
10
+ ? modelString.slice(VERYFRONT_CLOUD_MODEL_PREFIX.length)
11
+ : modelString;
12
+ }
13
+ export function supportsTemperatureParameter(modelString) {
14
+ const normalizedModel = normalizeModelCapabilityId(modelString);
15
+ if (!normalizedModel)
16
+ return true;
17
+ return !MODELS_WITHOUT_TEMPERATURE_PARAMETER.has(normalizedModel);
18
+ }
@@ -0,0 +1,14 @@
1
+ import type { ToolDefinition } from "../../tool/index.js";
2
+ import type { AgentConfig } from "../types.js";
3
+ import type { RuntimeRemoteToolConfig } from "./mcp-server-tool-sources.js";
4
+ export type RuntimeToolFilterConfig = AgentConfig & {
5
+ __vfForwardedIntegrationToolDefs?: Array<{
6
+ name: string;
7
+ description: string;
8
+ parameters: Record<string, unknown>;
9
+ }>;
10
+ } & RuntimeRemoteToolConfig;
11
+ export declare function getRuntimeAllowedRemoteTools(config: AgentConfig): string[] | undefined;
12
+ export declare function getRuntimeProviderTools(config: AgentConfig): string[];
13
+ export declare function getRuntimeForwardedIntegrationToolDefs(config: AgentConfig): ToolDefinition[] | undefined;
14
+ //# sourceMappingURL=runtime-tool-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-tool-config.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/runtime-tool-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAE5E,MAAM,MAAM,uBAAuB,GAAG,WAAW,GAAG;IAClD,gCAAgC,CAAC,EAAE,KAAK,CACtC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAC3E,CAAC;CACH,GAAG,uBAAuB,CAAC;AAE5B,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,SAAS,CAUtF;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,EAAE,CAMrE;AAED,wBAAgB,sCAAsC,CACpD,MAAM,EAAE,WAAW,GAClB,cAAc,EAAE,GAAG,SAAS,CAoB9B"}
@@ -0,0 +1,37 @@
1
+ export function getRuntimeAllowedRemoteTools(config) {
2
+ const configWithRuntimeFilters = config;
3
+ if (!Object.hasOwn(configWithRuntimeFilters, "__vfAllowedRemoteTools")) {
4
+ return undefined;
5
+ }
6
+ const raw = configWithRuntimeFilters.__vfAllowedRemoteTools;
7
+ if (!Array.isArray(raw)) {
8
+ return [];
9
+ }
10
+ return raw.every((toolName) => typeof toolName === "string") ? raw : [];
11
+ }
12
+ export function getRuntimeProviderTools(config) {
13
+ const raw = config.providerTools;
14
+ if (!Array.isArray(raw)) {
15
+ return [];
16
+ }
17
+ return raw.every((toolName) => typeof toolName === "string") ? raw : [];
18
+ }
19
+ export function getRuntimeForwardedIntegrationToolDefs(config) {
20
+ const configWithFilters = config;
21
+ const raw = configWithFilters.__vfForwardedIntegrationToolDefs;
22
+ if (!Array.isArray(raw) || raw.length === 0)
23
+ return undefined;
24
+ return raw
25
+ .filter((def) => typeof def === "object" &&
26
+ def !== null &&
27
+ typeof def.name === "string" &&
28
+ typeof def.description === "string")
29
+ .map((def) => ({
30
+ name: def.name,
31
+ description: def.description,
32
+ parameters: typeof def.parameters === "object" && def.parameters !== null &&
33
+ !Array.isArray(def.parameters)
34
+ ? def.parameters
35
+ : { type: "object", properties: {} },
36
+ }));
37
+ }
@@ -0,0 +1,16 @@
1
+ import type { Message } from "../types.js";
2
+ import { type SkillDelegationOverrides } from "./skill-delegation-overrides.js";
3
+ export declare const LOAD_SKILL_TOOL_ID = "load_skill";
4
+ export declare function hydrateActiveSkillStateFromMessages(messages: readonly Message[]): {
5
+ activeSkillPolicy: string[] | undefined;
6
+ activeSkillDelegationOverrides: SkillDelegationOverrides | undefined;
7
+ };
8
+ export declare function extractSkillPolicy(result: unknown): string[] | undefined;
9
+ export type SkillPolicyResult = {
10
+ allowed: true;
11
+ } | {
12
+ allowed: false;
13
+ error: string;
14
+ };
15
+ export declare function enforceSkillPolicy(toolName: string, activeSkillPolicy: string[] | undefined, mustLoadSkillFirst: boolean): SkillPolicyResult;
16
+ //# sourceMappingURL=skill-policy-enforcement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-policy-enforcement.d.ts","sourceRoot":"","sources":["../../../../src/src/agent/runtime/skill-policy-enforcement.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,iCAAiC,CAAC;AAIzC,eAAO,MAAM,kBAAkB,eAAe,CAAC;AAO/C,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,SAAS,OAAO,EAAE,GAC3B;IACD,iBAAiB,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,8BAA8B,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACtE,CAaA;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAyBxE;AAED,MAAM,MAAM,iBAAiB,GACzB;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtC,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EAAE,GAAG,SAAS,EACvC,kBAAkB,EAAE,OAAO,GAC1B,iBAAiB,CAenB"}
@@ -0,0 +1,55 @@
1
+ import { serverLogger } from "../../utils/index.js";
2
+ import { isToolAllowedBySkill, validateAllowedToolPatterns, } from "../../skill/allowed-tools.js";
3
+ import { isToolResultPart } from "./tool-result-continuation.js";
4
+ import { extractSkillDelegationOverrides, } from "./skill-delegation-overrides.js";
5
+ const logger = serverLogger.component("agent");
6
+ export const LOAD_SKILL_TOOL_ID = "load_skill";
7
+ function getSkillActivationRequiredError(toolName) {
8
+ return `Tool "${toolName}" cannot run before load_skill succeeds in the same step. ` +
9
+ `Call "${LOAD_SKILL_TOOL_ID}" first to establish the active skill context.`;
10
+ }
11
+ export function hydrateActiveSkillStateFromMessages(messages) {
12
+ let activeSkillPolicy;
13
+ let activeSkillDelegationOverrides;
14
+ for (const message of messages) {
15
+ for (const part of message.parts) {
16
+ if (!isToolResultPart(part) || part.toolName !== LOAD_SKILL_TOOL_ID)
17
+ continue;
18
+ activeSkillPolicy = extractSkillPolicy(part.result);
19
+ activeSkillDelegationOverrides = extractSkillDelegationOverrides(part.result);
20
+ }
21
+ }
22
+ return { activeSkillPolicy, activeSkillDelegationOverrides };
23
+ }
24
+ export function extractSkillPolicy(result) {
25
+ if (!result || typeof result !== "object")
26
+ return undefined;
27
+ const skillResult = result;
28
+ if (!("allowedTools" in skillResult) || skillResult.allowedTools === undefined) {
29
+ return undefined;
30
+ }
31
+ const raw = skillResult.allowedTools;
32
+ if (!Array.isArray(raw) || !raw.every((v) => typeof v === "string")) {
33
+ logger.warn("load_skill returned invalid allowedTools; falling back to empty policy (no tools)");
34
+ return [];
35
+ }
36
+ try {
37
+ return validateAllowedToolPatterns(raw);
38
+ }
39
+ catch (error) {
40
+ logger.warn("load_skill returned invalid tool patterns; falling back to empty policy (no tools)", { error });
41
+ return [];
42
+ }
43
+ }
44
+ export function enforceSkillPolicy(toolName, activeSkillPolicy, mustLoadSkillFirst) {
45
+ if (mustLoadSkillFirst && toolName !== LOAD_SKILL_TOOL_ID) {
46
+ return { allowed: false, error: getSkillActivationRequiredError(toolName) };
47
+ }
48
+ if (activeSkillPolicy && !isToolAllowedBySkill(toolName, activeSkillPolicy)) {
49
+ return {
50
+ allowed: false,
51
+ error: `Tool "${toolName}" is not allowed by the active skill policy. Allowed: ${activeSkillPolicy.join(", ")}`,
52
+ };
53
+ }
54
+ return { allowed: true };
55
+ }
@@ -0,0 +1,34 @@
1
+ import { type Message, type MessagePart, type ToolResultPart } from "../types.js";
2
+ import type { ChatStreamState, StreamingToolCall, StreamingToolResult } from "./chat-stream-handler.js";
3
+ import type { RuntimeGenerateToolResult, RuntimeToolSet } from "./runtime-tool-types.js";
4
+ export declare function getToolResultError(result: unknown): string | undefined;
5
+ export declare function createToolResultMessage(toolCallId: string, toolName: string, result: unknown, providerExecuted?: boolean): Message;
6
+ export declare function createToolErrorMessage(toolCallId: string, toolName: string, error: string): Message;
7
+ export declare function getProviderExecutedToolNames(runtimeTools: RuntimeToolSet | undefined): string[];
8
+ export declare function collectFinalStreamToolResults(state: Pick<ChatStreamState, "toolResults">): Map<string, StreamingToolResult>;
9
+ export declare function collectPersistedToolResults(messages: Message[]): Map<string, ToolResultPart>;
10
+ export declare function collectGeneratedToolResults(toolResults: RuntimeGenerateToolResult[] | undefined): Map<string, RuntimeGenerateToolResult>;
11
+ export declare function shouldContinueAfterStreamStep(state: Pick<ChatStreamState, "accumulatedText" | "finishReason" | "toolCalls" | "toolResults">): boolean;
12
+ export declare function captureStreamedToolCallInput(toolCall: Pick<StreamingToolCall, "arguments">): {
13
+ args: Record<string, unknown>;
14
+ inputText?: string;
15
+ parseError?: string;
16
+ };
17
+ export declare function isStreamedToolCallIncomplete(toolCall: Pick<StreamingToolCall, "inputAvailable">): boolean;
18
+ export declare function isRecoverablePlaceholderToolCall(toolCall: Pick<StreamingToolCall, "inputAvailable" | "arguments">): boolean;
19
+ export type StreamedToolCallMaterialization = {
20
+ readonly kind: "complete";
21
+ readonly part: MessagePart;
22
+ } | {
23
+ readonly kind: "parse-error";
24
+ readonly part: MessagePart;
25
+ readonly parseError: string;
26
+ } | {
27
+ readonly kind: "incomplete";
28
+ readonly part: MessagePart;
29
+ readonly partialArgumentsLength: number;
30
+ readonly partialArgumentsPreview: string;
31
+ };
32
+ export declare function materializeStreamedToolCall(tc: StreamingToolCall): StreamedToolCallMaterialization;
33
+ export declare function isToolResultPart(part: MessagePart): part is ToolResultPart;
34
+ //# sourceMappingURL=tool-result-continuation.d.ts.map