@inkeep/agents-run-api 0.3.0 → 0.6.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.
package/dist/index.cjs CHANGED
@@ -5,6 +5,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var agentsCore = require('@inkeep/agents-core');
6
6
  var z5 = require('zod');
7
7
  var nanoid = require('nanoid');
8
+ var otel = require('@hono/otel');
9
+ var zodOpenapi = require('@hono/zod-openapi');
10
+ var api = require('@opentelemetry/api');
11
+ var hono = require('hono');
12
+ var cors = require('hono/cors');
13
+ var httpException = require('hono/http-exception');
14
+ var requestId = require('hono/request-id');
8
15
  var autoInstrumentationsNode = require('@opentelemetry/auto-instrumentations-node');
9
16
  var baggageSpanProcessor = require('@opentelemetry/baggage-span-processor');
10
17
  var contextAsyncHooks = require('@opentelemetry/context-async-hooks');
@@ -14,13 +21,6 @@ var resources = require('@opentelemetry/resources');
14
21
  var sdkNode = require('@opentelemetry/sdk-node');
15
22
  var sdkTraceBase = require('@opentelemetry/sdk-trace-base');
16
23
  var semanticConventions = require('@opentelemetry/semantic-conventions');
17
- var otel = require('@hono/otel');
18
- var zodOpenapi = require('@hono/zod-openapi');
19
- var api = require('@opentelemetry/api');
20
- var hono = require('hono');
21
- var cors = require('hono/cors');
22
- var httpException = require('hono/http-exception');
23
- var requestId = require('hono/request-id');
24
24
  var factory = require('hono/factory');
25
25
  var swaggerUi = require('@hono/swagger-ui');
26
26
  var streaming = require('hono/streaming');
@@ -28,8 +28,10 @@ var destr = require('destr');
28
28
  var traverse = require('traverse');
29
29
  var ai = require('ai');
30
30
  var anthropic = require('@ai-sdk/anthropic');
31
+ var gateway = require('@ai-sdk/gateway');
31
32
  var google = require('@ai-sdk/google');
32
33
  var openai = require('@ai-sdk/openai');
34
+ var aiSdkProvider = require('@openrouter/ai-sdk-provider');
33
35
  var jmespath = require('jmespath');
34
36
  var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
35
37
  var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
@@ -67,8 +69,7 @@ var init_env = __esm({
67
69
  NANGO_SECRET_KEY: z5.z.string().optional(),
68
70
  OPENAI_API_KEY: z5.z.string().optional(),
69
71
  ANTHROPIC_API_KEY: z5.z.string(),
70
- INKEEP_AGENTS_RUN_API_BYPASS_SECRET: z5.z.string().optional(),
71
- OTEL_MAX_EXPORT_BATCH_SIZE: z5.z.coerce.number().optional()
72
+ INKEEP_AGENTS_RUN_API_BYPASS_SECRET: z5.z.string().optional()
72
73
  });
73
74
  parseEnv = () => {
74
75
  try {
@@ -282,48 +283,48 @@ var init_conversations = __esm({
282
283
  init_dbClient();
283
284
  }
284
285
  });
285
-
286
- // src/instrumentation.ts
287
- init_env();
288
- var maxExportBatchSize = env.OTEL_MAX_EXPORT_BATCH_SIZE ?? (env.ENVIRONMENT === "development" ? 1 : 512);
289
286
  var otlpExporter = new exporterTraceOtlpHttp.OTLPTraceExporter();
290
- var batchProcessor = new sdkTraceBase.BatchSpanProcessor(otlpExporter, {
291
- maxExportBatchSize
292
- });
293
- var resource = resources.resourceFromAttributes({
287
+ var defaultBatchProcessor = new sdkTraceBase.BatchSpanProcessor(otlpExporter);
288
+ var defaultResource = resources.resourceFromAttributes({
294
289
  [semanticConventions.ATTR_SERVICE_NAME]: "inkeep-agents-run-api"
295
290
  });
296
- var sdk = new sdkNode.NodeSDK({
297
- resource,
298
- contextManager: new contextAsyncHooks.AsyncLocalStorageContextManager(),
299
- textMapPropagator: new core.CompositePropagator({
300
- propagators: [new core.W3CTraceContextPropagator(), new core.W3CBaggagePropagator()]
301
- }),
302
- spanProcessors: [new baggageSpanProcessor.BaggageSpanProcessor(baggageSpanProcessor.ALLOW_ALL_BAGGAGE_KEYS), batchProcessor],
303
- instrumentations: [
304
- autoInstrumentationsNode.getNodeAutoInstrumentations({
305
- "@opentelemetry/instrumentation-http": {
306
- enabled: true,
307
- requestHook: (span, request) => {
308
- const url = request?.url ?? request?.path;
309
- if (!url) return;
310
- const u = new URL(url, "http://localhost");
311
- span.updateName(`${request?.method || "UNKNOWN"} ${u.pathname}`);
312
- }
313
- },
314
- "@opentelemetry/instrumentation-undici": {
315
- requestHook: (span) => {
316
- const method = span.attributes?.["http.request.method"];
317
- const host = span.attributes?.["server.address"];
318
- const path = span.attributes?.["url.path"];
319
- if (method && path)
320
- span.updateName(host ? `${method} ${host}${path}` : `${method} ${path}`);
321
- }
291
+ var defaultInstrumentations = [
292
+ autoInstrumentationsNode.getNodeAutoInstrumentations({
293
+ "@opentelemetry/instrumentation-http": {
294
+ enabled: true,
295
+ requestHook: (span, request) => {
296
+ const url = request?.url ?? request?.path;
297
+ if (!url) return;
298
+ const u = new URL(url, "http://localhost");
299
+ span.updateName(`${request?.method || "UNKNOWN"} ${u.pathname}`);
322
300
  }
323
- })
324
- ]
301
+ },
302
+ "@opentelemetry/instrumentation-undici": {
303
+ requestHook: (span) => {
304
+ const method = span.attributes?.["http.request.method"];
305
+ const host = span.attributes?.["server.address"];
306
+ const path = span.attributes?.["url.path"];
307
+ if (method && path)
308
+ span.updateName(host ? `${method} ${host}${path}` : `${method} ${path}`);
309
+ }
310
+ }
311
+ })
312
+ ];
313
+ var defaultSpanProcessors = [
314
+ new baggageSpanProcessor.BaggageSpanProcessor(baggageSpanProcessor.ALLOW_ALL_BAGGAGE_KEYS),
315
+ defaultBatchProcessor
316
+ ];
317
+ var defaultContextManager = new contextAsyncHooks.AsyncLocalStorageContextManager();
318
+ var defaultTextMapPropagator = new core.CompositePropagator({
319
+ propagators: [new core.W3CTraceContextPropagator(), new core.W3CBaggagePropagator()]
320
+ });
321
+ new sdkNode.NodeSDK({
322
+ resource: defaultResource,
323
+ contextManager: defaultContextManager,
324
+ textMapPropagator: defaultTextMapPropagator,
325
+ spanProcessors: defaultSpanProcessors,
326
+ instrumentations: defaultInstrumentations
325
327
  });
326
- sdk.start();
327
328
  init_dbClient();
328
329
  init_env();
329
330
 
@@ -1398,6 +1399,17 @@ __publicField(_ArtifactReferenceSchema, "ARTIFACT_PROPS_SCHEMA", {
1398
1399
  required: ["artifact_id", "task_id"]
1399
1400
  });
1400
1401
  var ArtifactReferenceSchema = _ArtifactReferenceSchema;
1402
+
1403
+ // src/utils/default-status-schemas.ts
1404
+ var retrieveStatusSchema = {
1405
+ type: "retrieve",
1406
+ description: 'Use this when the system found or retrieved specific information from searches, queries, or lookups. ONLY report ACTUAL findings that appear explicitly in the tool results - never make up data, names, numbers, or details. The label must state the SPECIFIC discovery (e.g., "Found 3 authentication methods", "Database contains 500 records", "API supports JSON format") not the act of searching. Every detail must be traceable to actual tool output. NEVER invent placeholder names, fictional data, or information not present in the activities.'
1407
+ };
1408
+ var actionStatusSchema = {
1409
+ type: "action",
1410
+ description: 'Use this when the system executed a tool or performed an operation that modified state or had side effects. ONLY report ACTUAL tool executions and their results as they appear in the tool outputs - never make up tool names, parameters, or outcomes. The label must describe what specific action was performed and its concrete result based on actual tool execution data. DO NOT make up examples like "Ran test suite with X passes" unless a test suite was ACTUALLY run and reported X passes. DO NOT say "Executed database query" unless a database query was ACTUALLY executed. Only report what literally happened. NEVER invent tool names, execution results, or details not explicitly present in the tool execution activities. If a tool failed, report the actual failure, not imagined success.'
1411
+ };
1412
+ var defaultStatusSchemas = [retrieveStatusSchema, actionStatusSchema];
1401
1413
  var logger5 = agentsCore.getLogger("ModelFactory");
1402
1414
  var _ModelFactory = class _ModelFactory {
1403
1415
  /**
@@ -1411,6 +1423,18 @@ var _ModelFactory = class _ModelFactory {
1411
1423
  return openai.createOpenAI(config);
1412
1424
  case "google":
1413
1425
  return google.createGoogleGenerativeAI(config);
1426
+ case "openrouter":
1427
+ return {
1428
+ ...aiSdkProvider.createOpenRouter(config),
1429
+ textEmbeddingModel: () => {
1430
+ throw new Error("OpenRouter does not support text embeddings");
1431
+ },
1432
+ imageModel: () => {
1433
+ throw new Error("OpenRouter does not support image generation");
1434
+ }
1435
+ };
1436
+ case "gateway":
1437
+ return gateway.createGateway(config);
1414
1438
  default:
1415
1439
  throw new Error(`Unsupported provider: ${provider}`);
1416
1440
  }
@@ -1470,26 +1494,29 @@ var _ModelFactory = class _ModelFactory {
1470
1494
  return openai.openai(modelName);
1471
1495
  case "google":
1472
1496
  return google.google(modelName);
1497
+ case "openrouter":
1498
+ return aiSdkProvider.openrouter(modelName);
1499
+ case "gateway":
1500
+ return gateway.gateway(modelName);
1473
1501
  default:
1474
- throw new Error(`Unsupported provider: ${provider}`);
1502
+ throw new Error(
1503
+ `Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.BUILT_IN_PROVIDERS.join(", ")}. To access other models, use OpenRouter (openrouter/model-id) or Vercel AI Gateway (gateway/model-id).`
1504
+ );
1475
1505
  }
1476
1506
  }
1477
1507
  /**
1478
1508
  * Parse model string to extract provider and model name
1479
1509
  * Examples: "anthropic/claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" }
1510
+ * "openrouter/anthropic/claude-sonnet-4" -> { provider: "openrouter", modelName: "anthropic/claude-sonnet-4" }
1480
1511
  * "claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" } (default to anthropic)
1481
1512
  */
1482
1513
  static parseModelString(modelString) {
1483
1514
  if (modelString.includes("/")) {
1484
1515
  const [provider, ...modelParts] = modelString.split("/");
1485
1516
  const normalizedProvider = provider.toLowerCase();
1486
- if (!_ModelFactory.SUPPORTED_PROVIDERS.includes(normalizedProvider)) {
1487
- logger5.error(
1488
- { provider: normalizedProvider, modelName: modelParts.join("/") },
1489
- "Unsupported provider detected, falling back to anthropic"
1490
- );
1517
+ if (!_ModelFactory.BUILT_IN_PROVIDERS.includes(normalizedProvider)) {
1491
1518
  throw new Error(
1492
- `Unsupported provider: ${normalizedProvider}. Please provide a model in the format of provider/model-name.`
1519
+ `Unsupported provider: ${normalizedProvider}. Supported providers are: ${_ModelFactory.BUILT_IN_PROVIDERS.join(", ")}. To access other models, use OpenRouter (openrouter/model-id) or Vercel AI Gateway (gateway/model-id).`
1493
1520
  );
1494
1521
  }
1495
1522
  return {
@@ -1498,9 +1525,7 @@ var _ModelFactory = class _ModelFactory {
1498
1525
  // In case model name has slashes
1499
1526
  };
1500
1527
  }
1501
- throw new Error(
1502
- `Invalid model provided: ${modelString}. Please provide a model in the format of provider/model-name.`
1503
- );
1528
+ throw new Error(`No provider specified in model string: ${modelString}`);
1504
1529
  }
1505
1530
  /**
1506
1531
  * Get generation parameters from provider options
@@ -1564,9 +1589,15 @@ var _ModelFactory = class _ModelFactory {
1564
1589
  }
1565
1590
  };
1566
1591
  /**
1567
- * Supported providers for security validation
1592
+ * Built-in providers that have special handling
1568
1593
  */
1569
- __publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai", "google"]);
1594
+ __publicField(_ModelFactory, "BUILT_IN_PROVIDERS", [
1595
+ "anthropic",
1596
+ "openai",
1597
+ "google",
1598
+ "openrouter",
1599
+ "gateway"
1600
+ ]);
1570
1601
  var ModelFactory = _ModelFactory;
1571
1602
 
1572
1603
  // src/utils/graph-session.ts
@@ -1908,68 +1939,52 @@ var GraphSession = class {
1908
1939
  }
1909
1940
  const now = Date.now();
1910
1941
  const elapsedTime = now - statusUpdateState.startTime;
1911
- let summaryToSend;
1912
- if (statusUpdateState.config.statusComponents && statusUpdateState.config.statusComponents.length > 0) {
1913
- const result = await this.generateStructuredStatusUpdate(
1914
- this.events.slice(statusUpdateState.lastEventCount),
1915
- elapsedTime,
1916
- statusUpdateState.config.statusComponents,
1917
- statusUpdateState.summarizerModel,
1918
- this.previousSummaries
1919
- );
1920
- if (result.summaries && result.summaries.length > 0) {
1921
- for (const summary of result.summaries) {
1922
- if (!summary || !summary.type || !summary.data || !summary.data.label || Object.keys(summary.data).length === 0) {
1923
- logger6.warn(
1924
- {
1925
- sessionId: this.sessionId,
1926
- summary
1927
- },
1928
- "Skipping empty or invalid structured operation"
1929
- );
1930
- continue;
1931
- }
1932
- const summaryToSend2 = {
1933
- type: summary.data.type || summary.type,
1934
- // Preserve the actual custom type from LLM
1935
- label: summary.data.label,
1936
- details: Object.fromEntries(
1937
- Object.entries(summary.data).filter(([key]) => !["label", "type"].includes(key))
1938
- )
1939
- };
1940
- await streamHelper.writeSummary(summaryToSend2);
1941
- }
1942
- const summaryTexts = result.summaries.map(
1943
- (summary) => JSON.stringify({ type: summary.type, data: summary.data })
1944
- );
1945
- this.previousSummaries.push(...summaryTexts);
1946
- if (this.statusUpdateState) {
1947
- this.statusUpdateState.lastUpdateTime = now;
1948
- this.statusUpdateState.lastEventCount = this.events.length;
1942
+ const statusComponents = statusUpdateState.config.statusComponents && statusUpdateState.config.statusComponents.length > 0 ? statusUpdateState.config.statusComponents : defaultStatusSchemas;
1943
+ const result = await this.generateStructuredStatusUpdate(
1944
+ this.events.slice(statusUpdateState.lastEventCount),
1945
+ elapsedTime,
1946
+ statusComponents,
1947
+ statusUpdateState.summarizerModel,
1948
+ this.previousSummaries
1949
+ );
1950
+ if (result.summaries && result.summaries.length > 0) {
1951
+ for (const summary of result.summaries) {
1952
+ if (!summary || !summary.type || !summary.data || !summary.data.label || Object.keys(summary.data).length === 0) {
1953
+ logger6.warn(
1954
+ {
1955
+ sessionId: this.sessionId,
1956
+ summary
1957
+ },
1958
+ "Skipping empty or invalid structured operation"
1959
+ );
1960
+ continue;
1949
1961
  }
1950
- return;
1962
+ const summaryToSend = {
1963
+ type: summary.data.type || summary.type,
1964
+ // Preserve the actual custom type from LLM
1965
+ label: summary.data.label,
1966
+ details: Object.fromEntries(
1967
+ Object.entries(summary.data).filter(([key]) => !["label", "type"].includes(key))
1968
+ )
1969
+ };
1970
+ await streamHelper.writeSummary(summaryToSend);
1951
1971
  }
1952
- } else {
1953
- const summary = await this.generateProgressSummary(
1954
- this.events.slice(statusUpdateState.lastEventCount),
1955
- elapsedTime,
1956
- statusUpdateState.summarizerModel,
1957
- this.previousSummaries
1972
+ const summaryTexts = result.summaries.map(
1973
+ (summary) => JSON.stringify({ type: summary.type, data: summary.data })
1958
1974
  );
1959
- this.previousSummaries.push(summary);
1975
+ this.previousSummaries.push(...summaryTexts);
1976
+ if (this.statusUpdateState) {
1977
+ this.statusUpdateState.lastUpdateTime = now;
1978
+ this.statusUpdateState.lastEventCount = this.events.length;
1979
+ }
1980
+ return;
1960
1981
  }
1961
1982
  if (this.previousSummaries.length > 3) {
1962
1983
  this.previousSummaries.shift();
1963
1984
  }
1964
- {
1965
- logger6.warn(
1966
- {
1967
- sessionId: this.sessionId,
1968
- summaryToSend
1969
- },
1970
- "Skipping empty or invalid status update operation"
1971
- );
1972
- return;
1985
+ if (this.statusUpdateState) {
1986
+ this.statusUpdateState.lastUpdateTime = now;
1987
+ this.statusUpdateState.lastEventCount = this.events.length;
1973
1988
  }
1974
1989
  } catch (error) {
1975
1990
  logger6.error(
@@ -2050,106 +2065,6 @@ var GraphSession = class {
2050
2065
  this.statusUpdateState.updateLock = false;
2051
2066
  }
2052
2067
  }
2053
- /**
2054
- * Generate user-focused progress summary hiding internal operations
2055
- */
2056
- async generateProgressSummary(newEvents, elapsedTime, summarizerModel, previousSummaries = []) {
2057
- return tracer.startActiveSpan(
2058
- "graph_session.generate_progress_summary",
2059
- {
2060
- attributes: {
2061
- "graph_session.id": this.sessionId,
2062
- "events.count": newEvents.length,
2063
- "elapsed_time.seconds": Math.round(elapsedTime / 1e3),
2064
- "llm.model": summarizerModel?.model,
2065
- "previous_summaries.count": previousSummaries.length
2066
- }
2067
- },
2068
- async (span) => {
2069
- try {
2070
- const userVisibleActivities = this.extractUserVisibleActivities(newEvents);
2071
- let conversationContext = "";
2072
- if (this.tenantId && this.projectId) {
2073
- try {
2074
- const conversationHistory = await getFormattedConversationHistory({
2075
- tenantId: this.tenantId,
2076
- projectId: this.projectId,
2077
- conversationId: this.sessionId,
2078
- options: {
2079
- limit: 10,
2080
- // Get recent conversation context
2081
- maxOutputTokens: 2e3
2082
- },
2083
- filters: {}
2084
- });
2085
- conversationContext = conversationHistory.trim() ? `
2086
- User's Question/Context:
2087
- ${conversationHistory}
2088
- ` : "";
2089
- } catch (error) {
2090
- logger6.warn(
2091
- { sessionId: this.sessionId, error },
2092
- "Failed to fetch conversation history for status update"
2093
- );
2094
- }
2095
- }
2096
- const previousSummaryContext = previousSummaries.length > 0 ? `
2097
- Previous updates provided to user:
2098
- ${previousSummaries.map((s, i) => `${i + 1}. ${s}`).join("\n")}
2099
- ` : "";
2100
- const basePrompt = `Generate a meaningful status update that tells the user what specific information or result was just found/achieved.${conversationContext}${previousSummaries.length > 0 ? `
2101
- ${previousSummaryContext}` : ""}
2102
-
2103
- Activities:
2104
- ${userVisibleActivities.join("\n") || "No New Activities"}
2105
-
2106
- Create a short 3-5 word label describing the ACTUAL finding. Use sentence case (only capitalize the first word and proper nouns). Examples: "Found admin permissions needed", "Identified three channel types", "OAuth token required".
2107
-
2108
- ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
2109
- const prompt = basePrompt;
2110
- let modelToUse = summarizerModel;
2111
- if (!summarizerModel?.model?.trim()) {
2112
- if (!this.statusUpdateState?.baseModel?.model?.trim()) {
2113
- throw new Error(
2114
- "Either summarizer or base model is required for progress summary generation. Please configure models at the project level."
2115
- );
2116
- }
2117
- modelToUse = this.statusUpdateState.baseModel;
2118
- }
2119
- if (!modelToUse) {
2120
- throw new Error("No model configuration available");
2121
- }
2122
- const model = ModelFactory.createModel(modelToUse);
2123
- const { text } = await ai.generateText({
2124
- model,
2125
- prompt,
2126
- experimental_telemetry: {
2127
- isEnabled: true,
2128
- functionId: `status_update_${this.sessionId}`,
2129
- recordInputs: true,
2130
- recordOutputs: true,
2131
- metadata: {
2132
- operation: "progress_summary_generation",
2133
- sessionId: this.sessionId
2134
- }
2135
- }
2136
- });
2137
- span.setAttributes({
2138
- "summary.length": text.trim().length,
2139
- "user_activities.count": userVisibleActivities.length
2140
- });
2141
- span.setStatus({ code: api.SpanStatusCode.OK });
2142
- return text.trim();
2143
- } catch (error) {
2144
- agentsCore.setSpanWithError(span, error);
2145
- logger6.error({ error }, "Failed to generate summary, using fallback");
2146
- return this.generateFallbackSummary(newEvents, elapsedTime);
2147
- } finally {
2148
- span.end();
2149
- }
2150
- }
2151
- );
2152
- }
2153
2068
  /**
2154
2069
  * Generate structured status update using configured data components
2155
2070
  */
@@ -2228,17 +2143,45 @@ Rules:
2228
2143
  - Fill in data for relevant components only
2229
2144
  - Use 'no_relevant_updates' if nothing substantially new to report. DO NOT WRITE LABELS OR USE OTHER COMPONENTS IF YOU USE THIS COMPONENT.
2230
2145
  - Never repeat previous values, make every update EXTREMELY unique. If you cannot do that the update is not worth mentioning.
2231
- - Labels MUST be short 3-5 word phrases with ACTUAL information discovered. NEVER MAKE UP SOMETHING WITHOUT BACKING IT UP WITH ACTUAL INFORMATION.
2146
+ - Labels MUST be short 3-7 word phrases with ACTUAL information discovered. NEVER MAKE UP SOMETHING WITHOUT BACKING IT UP WITH ACTUAL INFORMATION.
2232
2147
  - Use sentence case: only capitalize the first word and proper nouns (e.g., "Admin permissions required", not "Admin Permissions Required"). ALWAYS capitalize the first word of the label.
2233
2148
  - DO NOT use action words like "Searching", "Processing", "Analyzing" - state what was FOUND
2234
2149
  - Include specific details, numbers, requirements, or insights discovered
2235
2150
  - Examples: "Admin permissions required", "Three OAuth steps found", "Token expires daily"
2236
- - You are ONE unified AI system - NEVER mention agents, transfers, delegations, or routing
2237
- - CRITICAL: NEVER use the words "transfer", "delegation", "agent", "routing", "artifact", or any internal system terminology in labels or any names of agents, tools, or systems.
2238
- - Present all operations as seamless actions by a single system
2239
- - Anonymize all internal operations so that the information appears descriptive and USER FRIENDLY. HIDE ALL INTERNAL OPERATIONS!
2240
- - Bad examples: "Transferring to search agent", "continuing transfer to qa agent", "Delegating task", "Routing request", "Processing request", "Artifact found", "Artifact saved", or not using the no_relevant_updates
2241
- - Good examples: "Slack bot needs admin privileges", "Found 3-step OAuth flow required", "Channel limit is 500 per workspace", or use the no_relevant_updates component if nothing new to report.
2151
+
2152
+ CRITICAL - HIDE ALL INTERNAL SYSTEM OPERATIONS:
2153
+ - You are ONE unified AI system presenting results to the user
2154
+ - ABSOLUTELY FORBIDDEN WORDS/PHRASES: "transfer", "transferring", "delegation", "delegating", "delegate", "agent", "routing", "route", "artifact", "saving artifact", "stored artifact", "artifact saved", "continuing", "passing to", "handing off", "switching to"
2155
+ - NEVER reveal internal architecture: No mentions of different agents, components, systems, or modules working together
2156
+ - NEVER mention artifact operations: Users don't need to know about data being saved, stored, or organized internally
2157
+ - NEVER describe handoffs or transitions: Present everything as one seamless operation
2158
+ - If you see "transfer", "delegation_sent", "delegation_returned", or "artifact_saved" events - IGNORE THEM or translate to user-facing information only
2159
+ - Focus ONLY on actual discoveries, findings, and results that matter to the user
2160
+
2161
+ - Bad examples:
2162
+ * "Transferring to search agent"
2163
+ * "Delegating research task"
2164
+ * "Routing to QA specialist"
2165
+ * "Artifact saved successfully"
2166
+ * "Storing results for later"
2167
+ * "Passing request to tool handler"
2168
+ * "Continuing with analysis"
2169
+ * "Handing off to processor"
2170
+ - Good examples:
2171
+ * "Slack bot needs admin privileges"
2172
+ * "Found 3-step OAuth flow required"
2173
+ * "Channel limit is 500 per workspace"
2174
+ * Use no_relevant_updates if nothing new to report
2175
+
2176
+ CRITICAL ANTI-HALLUCINATION RULES:
2177
+ - NEVER MAKE UP SOMETHING WITHOUT BACKING IT UP WITH ACTUAL INFORMATION. EVERY SINGLE UPDATE MUST BE BACKED UP WITH ACTUAL INFORMATION.
2178
+ - DO NOT MAKE UP PEOPLE, NAMES, PLACES, THINGS, ORGANIZATIONS, OR INFORMATION. IT IS OBVIOUS WHEN A PERSON/ENTITY DOES NOT EXIST.
2179
+ - Only report facts that are EXPLICITLY mentioned in the activities or tool results
2180
+ - If you don't have concrete information about something, DO NOT mention it
2181
+ - Never invent names like "John Doe", "Alice", "Bob", or any other placeholder names
2182
+ - Never create fictional companies, products, or services
2183
+ - If a tool returned no results or an error, DO NOT pretend it found something
2184
+ - Every detail in your status update must be traceable back to the actual activities provided
2242
2185
 
2243
2186
  REMEMBER YOU CAN ONLY USE 'no_relevant_updates' ALONE! IT CANNOT BE CONCATENATED WITH OTHER STATUS UPDATES!
2244
2187
 
@@ -2311,7 +2254,7 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
2311
2254
  }
2312
2255
  return z5.z.object({
2313
2256
  label: z5.z.string().describe(
2314
- 'A short 3-5 word phrase, that is a descriptive label for the update component. This Label must be EXTREMELY unique to represent the UNIQUE update we are providing. The ACTUAL finding or result, not the action. What specific information was discovered? (e.g., "Slack requires OAuth 2.0 setup", "Found 5 integration methods", "API rate limit is 100/minute"). Include the actual detail or insight, not just that you searched or processed.'
2257
+ 'A short 3-5 word phrase, that is a descriptive label for the update component. This Label must be EXTREMELY unique to represent the UNIQUE update we are providing. The ACTUAL finding or result, not the action. What specific information was discovered? (e.g., "Slack requires OAuth 2.0 setup", "Found 5 integration methods", "API rate limit is 100/minute"). Include the actual detail or insight, not just that you searched or processed. CRITICAL: Only use facts explicitly found in the activities - NEVER invent names, people, organizations, or details that are not present in the actual tool results.'
2315
2258
  )
2316
2259
  });
2317
2260
  }
@@ -2321,7 +2264,7 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
2321
2264
  buildZodSchemaFromJson(jsonSchema) {
2322
2265
  const properties = {};
2323
2266
  properties["label"] = z5.z.string().describe(
2324
- 'A short 3-5 word phrase, that is a descriptive label for the update component. This Label must be EXTREMELY unique to represent the UNIQUE update we are providing. The SPECIFIC finding, result, or insight discovered (e.g., "Slack bot needs workspace admin role", "Found ingestion requires 3 steps", "Channel history limited to 10k messages"). State the ACTUAL information found, not that you searched. What did you LEARN or DISCOVER? What specific detail is now known?'
2267
+ 'A short 3-5 word phrase, that is a descriptive label for the update component. This Label must be EXTREMELY unique to represent the UNIQUE update we are providing. The SPECIFIC finding, result, or insight discovered (e.g., "Slack bot needs workspace admin role", "Found ingestion requires 3 steps", "Channel history limited to 10k messages"). State the ACTUAL information found, not that you searched. What did you LEARN or DISCOVER? What specific detail is now known? CRITICAL: Only use facts explicitly found in the activities - NEVER invent names, people, organizations, or details that are not present in the actual tool results.'
2325
2268
  );
2326
2269
  for (const [key, value] of Object.entries(jsonSchema.properties)) {
2327
2270
  let zodType;
@@ -2398,41 +2341,12 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
2398
2341
  );
2399
2342
  break;
2400
2343
  }
2401
- case "transfer": {
2402
- const data = event.data;
2403
- activities.push(
2404
- `\u{1F504} **Continuing**: ${data.reason || "Processing request"}
2405
- ${data.context ? `Context: ${JSON.stringify(data.context, null, 2)}` : ""}`
2406
- );
2407
- break;
2408
- }
2409
- case "delegation_sent": {
2410
- const data = event.data;
2411
- activities.push(
2412
- `\u{1F4E4} **Processing**: ${data.taskDescription}
2413
- ${data.context ? `Context: ${JSON.stringify(data.context, null, 2)}` : ""}`
2414
- );
2415
- break;
2416
- }
2417
- case "delegation_returned": {
2418
- const data = event.data;
2419
- activities.push(
2420
- `\u{1F4E5} **Completed subtask**
2421
- Result: ${JSON.stringify(data.result, null, 2)}`
2422
- );
2423
- break;
2424
- }
2425
- case "artifact_saved": {
2426
- const data = event.data;
2427
- activities.push(
2428
- `\u{1F4BE} **Artifact Saved**: ${data.artifactType}
2429
- ID: ${data.artifactId}
2430
- Task: ${data.taskId}
2431
- ${data.summaryData ? `Summary: ${data.summaryData}` : ""}
2432
- ${data.fullData ? `Full Data: ${data.fullData}` : ""}`
2433
- );
2344
+ // INTERNAL OPERATIONS - DO NOT EXPOSE TO STATUS UPDATES
2345
+ case "transfer":
2346
+ case "delegation_sent":
2347
+ case "delegation_returned":
2348
+ case "artifact_saved":
2434
2349
  break;
2435
- }
2436
2350
  case "agent_reasoning": {
2437
2351
  const data = event.data;
2438
2352
  activities.push(
@@ -2457,21 +2371,6 @@ ${this.statusUpdateState?.config.prompt?.trim() || ""}`;
2457
2371
  }
2458
2372
  return activities;
2459
2373
  }
2460
- /**
2461
- * Generate fallback summary when LLM fails
2462
- */
2463
- generateFallbackSummary(events, elapsedTime) {
2464
- const timeStr = Math.round(elapsedTime / 1e3);
2465
- const toolCalls = events.filter((e) => e.eventType === "tool_execution").length;
2466
- const artifacts = events.filter((e) => e.eventType === "artifact_saved").length;
2467
- if (artifacts > 0) {
2468
- return `Generated ${artifacts} result${artifacts > 1 ? "s" : ""} so far (${timeStr}s elapsed)`;
2469
- } else if (toolCalls > 0) {
2470
- return `Used ${toolCalls} tool${toolCalls > 1 ? "s" : ""} to gather information (${timeStr}s elapsed)`;
2471
- } else {
2472
- return `Processing your request... (${timeStr}s elapsed)`;
2473
- }
2474
- }
2475
2374
  /**
2476
2375
  * Process a single artifact to generate name and description using conversation context
2477
2376
  */
@@ -3225,7 +3124,7 @@ var _IncrementalStreamParser = class _IncrementalStreamParser {
3225
3124
  await this.streamPart(part);
3226
3125
  }
3227
3126
  if (this.pendingTextBuffer) {
3228
- const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
3127
+ const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/artifact:ref>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
3229
3128
  if (cleanedText) {
3230
3129
  this.collectedParts.push({
3231
3130
  kind: "text",
@@ -3303,7 +3202,7 @@ var _IncrementalStreamParser = class _IncrementalStreamParser {
3303
3202
  if (part.kind === "text" && part.text) {
3304
3203
  this.pendingTextBuffer += part.text;
3305
3204
  if (!this.artifactParser.hasIncompleteArtifact(this.pendingTextBuffer)) {
3306
- const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
3205
+ const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/artifact:ref>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
3307
3206
  if (cleanedText) {
3308
3207
  await this.streamHelper.streamText(cleanedText, 50);
3309
3208
  }
@@ -3311,7 +3210,7 @@ var _IncrementalStreamParser = class _IncrementalStreamParser {
3311
3210
  }
3312
3211
  } else if (part.kind === "data" && part.data) {
3313
3212
  if (this.pendingTextBuffer) {
3314
- const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
3213
+ const cleanedText = this.pendingTextBuffer.replace(/<\/?artifact:ref(?:\s[^>]*)?>\/?>/g, "").replace(/<\/?artifact(?:\s[^>]*)?>\/?>/g, "").replace(/<\/artifact:ref>/g, "").replace(/<\/(?:\w+:)?artifact>/g, "");
3315
3214
  if (cleanedText) {
3316
3215
  await this.streamHelper.streamText(cleanedText, 50);
3317
3216
  }
@@ -7298,7 +7197,7 @@ var _VercelDataStreamHelper = class _VercelDataStreamHelper {
7298
7197
  __publicField(this, "queuedEvents", []);
7299
7198
  // Timing tracking for text sequences (text-end to text-start gap)
7300
7199
  __publicField(this, "lastTextEndTimestamp", 0);
7301
- __publicField(this, "TEXT_GAP_THRESHOLD", 50);
7200
+ __publicField(this, "TEXT_GAP_THRESHOLD", 2e3);
7302
7201
  // milliseconds - if gap between text sequences is less than this, queue operations
7303
7202
  // Connection management and forced cleanup
7304
7203
  __publicField(this, "connectionDropTimer");
@@ -9314,21 +9213,21 @@ function createExecutionHono(serverConfig, credentialStores) {
9314
9213
  app6.route("/v1/mcp", mcp_default);
9315
9214
  app6.route("/agents", agents_default);
9316
9215
  setupOpenAPIRoutes(app6);
9317
- app6.use("/tenants/*", async (c, next) => {
9216
+ app6.use("/tenants/*", async (_c, next) => {
9318
9217
  await next();
9319
- await batchProcessor.forceFlush();
9218
+ await defaultBatchProcessor.forceFlush();
9320
9219
  });
9321
- app6.use("/agents/*", async (c, next) => {
9220
+ app6.use("/agents/*", async (_c, next) => {
9322
9221
  await next();
9323
- await batchProcessor.forceFlush();
9222
+ await defaultBatchProcessor.forceFlush();
9324
9223
  });
9325
- app6.use("/v1/*", async (c, next) => {
9224
+ app6.use("/v1/*", async (_c, next) => {
9326
9225
  await next();
9327
- await batchProcessor.forceFlush();
9226
+ await defaultBatchProcessor.forceFlush();
9328
9227
  });
9329
- app6.use("/api/*", async (c, next) => {
9228
+ app6.use("/api/*", async (_c, next) => {
9330
9229
  await next();
9331
- await batchProcessor.forceFlush();
9230
+ await defaultBatchProcessor.forceFlush();
9332
9231
  });
9333
9232
  const baseApp = new hono.Hono();
9334
9233
  baseApp.route("/", app6);