@inkeep/agents-work-apps 0.0.0-dev-20260213221002 → 0.0.0-dev-20260213222830

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.
@@ -1,7 +1,7 @@
1
- import * as hono1 from "hono";
1
+ import * as hono0 from "hono";
2
2
 
3
3
  //#region src/github/mcp/auth.d.ts
4
- declare const githubMcpAuth: () => hono1.MiddlewareHandler<{
4
+ declare const githubMcpAuth: () => hono0.MiddlewareHandler<{
5
5
  Variables: {
6
6
  toolId: string;
7
7
  };
@@ -1,11 +1,11 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types9 from "hono/types";
2
+ import * as hono_types3 from "hono/types";
3
3
 
4
4
  //#region src/github/mcp/index.d.ts
5
5
  declare const app: Hono<{
6
6
  Variables: {
7
7
  toolId: string;
8
8
  };
9
- }, hono_types9.BlankSchema, "/">;
9
+ }, hono_types3.BlankSchema, "/">;
10
10
  //#endregion
11
11
  export { app as default };
@@ -36,8 +36,8 @@ declare const ChangedFileSchema: z.ZodObject<{
36
36
  path: z.ZodString;
37
37
  status: z.ZodEnum<{
38
38
  added: "added";
39
- modified: "modified";
40
39
  removed: "removed";
40
+ modified: "modified";
41
41
  renamed: "renamed";
42
42
  copied: "copied";
43
43
  changed: "changed";
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types3 from "hono/types";
2
+ import * as hono_types4 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/setup.d.ts
5
- declare const app: Hono<hono_types3.BlankEnv, hono_types3.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types4.BlankEnv, hono_types4.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,7 +1,7 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types7 from "hono/types";
2
+ import * as hono_types6 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/tokenExchange.d.ts
5
- declare const app: Hono<hono_types7.BlankEnv, hono_types7.BlankSchema, "/">;
5
+ declare const app: Hono<hono_types6.BlankEnv, hono_types6.BlankSchema, "/">;
6
6
  //#endregion
7
7
  export { app as default };
@@ -1,5 +1,5 @@
1
1
  import { Hono } from "hono";
2
- import * as hono_types5 from "hono/types";
2
+ import * as hono_types8 from "hono/types";
3
3
 
4
4
  //#region src/github/routes/webhooks.d.ts
5
5
  interface WebhookVerificationResult {
@@ -7,6 +7,6 @@ interface WebhookVerificationResult {
7
7
  error?: string;
8
8
  }
9
9
  declare function verifyWebhookSignature(payload: string, signature: string | undefined, secret: string): WebhookVerificationResult;
10
- declare const app: Hono<hono_types5.BlankEnv, hono_types5.BlankSchema, "/">;
10
+ declare const app: Hono<hono_types8.BlankEnv, hono_types8.BlankSchema, "/">;
11
11
  //#endregion
12
12
  export { WebhookVerificationResult, app as default, verifyWebhookSignature };
@@ -63,6 +63,19 @@ app.post("/commands", async (c) => {
63
63
  return c.json(response);
64
64
  });
65
65
  app.post("/events", async (c) => {
66
+ const retryNum = c.req.header("x-slack-retry-num");
67
+ const retryReason = c.req.header("x-slack-retry-reason");
68
+ if (retryNum) return tracer.startActiveSpan(`${SLACK_SPAN_NAMES.WEBHOOK} retry`, (span) => {
69
+ span.setAttribute(SLACK_SPAN_KEYS.OUTCOME, "ignored_slack_retry");
70
+ span.setAttribute("slack.retry_num", retryNum);
71
+ if (retryReason) span.setAttribute("slack.retry_reason", retryReason);
72
+ logger.info({
73
+ retryNum,
74
+ retryReason
75
+ }, "Acknowledging Slack retry without re-processing");
76
+ span.end();
77
+ return c.json({ ok: true });
78
+ });
66
79
  return tracer.startActiveSpan(SLACK_SPAN_NAMES.WEBHOOK, async (span) => {
67
80
  let outcome = "ignored_unknown_event";
68
81
  try {
@@ -14,6 +14,8 @@ import { SLACK_SPAN_KEYS, SLACK_SPAN_NAMES, setSpanWithError, tracer } from "../
14
14
  const logger = getLogger("slack-streaming");
15
15
  const STREAM_TIMEOUT_MS = 12e4;
16
16
  const CHATSTREAM_OP_TIMEOUT_MS = 1e4;
17
+ /** Shorter timeout for best-effort cleanup in error paths to bound total error handling time. */
18
+ const CLEANUP_TIMEOUT_MS = 3e3;
17
19
  /**
18
20
  * Wrap a promise with a timeout to prevent indefinite blocking on Slack API calls.
19
21
  */
@@ -214,7 +216,17 @@ async function streamAgentResponse(params) {
214
216
  }
215
217
  clearTimeout(timeoutId);
216
218
  const contextBlock = createContextBlock({ agentName });
217
- await withTimeout(streamer.stop({ blocks: [contextBlock] }), CHATSTREAM_OP_TIMEOUT_MS, "streamer.stop");
219
+ try {
220
+ await withTimeout(streamer.stop({ blocks: [contextBlock] }), CHATSTREAM_OP_TIMEOUT_MS, "streamer.stop");
221
+ } catch (stopError) {
222
+ span.setAttribute(SLACK_SPAN_KEYS.STREAM_FINALIZATION_FAILED, true);
223
+ logger.warn({
224
+ stopError,
225
+ channel,
226
+ threadTs,
227
+ responseLength: fullText.length
228
+ }, "Failed to finalize chatStream — content was already delivered");
229
+ }
218
230
  if (thinkingMessageTs) try {
219
231
  await slackClient.chat.delete({
220
232
  channel,
@@ -235,8 +247,26 @@ async function streamAgentResponse(params) {
235
247
  } catch (streamError) {
236
248
  clearTimeout(timeoutId);
237
249
  if (streamError instanceof Error) setSpanWithError(span, streamError);
250
+ if (fullText.length > 0) {
251
+ span.setAttribute(SLACK_SPAN_KEYS.CONTENT_ALREADY_DELIVERED, true);
252
+ logger.warn({
253
+ streamError,
254
+ channel,
255
+ threadTs,
256
+ responseLength: fullText.length
257
+ }, "Error during Slack streaming after content was already delivered — suppressing user-facing error");
258
+ await withTimeout(streamer.stop(), CLEANUP_TIMEOUT_MS, "streamer.stop-cleanup").catch((e) => logger.warn({ error: e }, "Failed to stop streamer during error cleanup"));
259
+ if (thinkingMessageTs) try {
260
+ await slackClient.chat.delete({
261
+ channel,
262
+ ts: thinkingMessageTs
263
+ });
264
+ } catch {}
265
+ span.end();
266
+ return { success: true };
267
+ }
238
268
  logger.error({ streamError }, "Error during Slack streaming");
239
- await withTimeout(streamer.stop(), CHATSTREAM_OP_TIMEOUT_MS, "streamer.stop").catch((e) => logger.warn({ error: e }, "Failed to stop streamer during error cleanup"));
269
+ await withTimeout(streamer.stop(), CLEANUP_TIMEOUT_MS, "streamer.stop-cleanup").catch((e) => logger.warn({ error: e }, "Failed to stop streamer during error cleanup"));
240
270
  if (thinkingMessageTs) try {
241
271
  await slackClient.chat.delete({
242
272
  channel,
@@ -34,7 +34,9 @@ declare const SLACK_SPAN_KEYS: {
34
34
  readonly IS_BOT_MESSAGE: "slack.is_bot_message";
35
35
  readonly HAS_QUERY: "slack.has_query";
36
36
  readonly IS_IN_THREAD: "slack.is_in_thread";
37
+ readonly STREAM_FINALIZATION_FAILED: "slack.stream_finalization_failed";
38
+ readonly CONTENT_ALREADY_DELIVERED: "slack.content_already_delivered";
37
39
  };
38
- type SlackOutcome = 'handled' | 'ignored_bot_message' | 'ignored_unknown_event' | 'ignored_no_action_match' | 'url_verification' | 'validation_error' | 'signature_invalid' | 'error';
40
+ type SlackOutcome = 'handled' | 'ignored_bot_message' | 'ignored_unknown_event' | 'ignored_no_action_match' | 'ignored_slack_retry' | 'url_verification' | 'validation_error' | 'signature_invalid' | 'error';
39
41
  //#endregion
40
42
  export { SLACK_SPAN_KEYS, SLACK_SPAN_NAMES, SlackOutcome, setSpanWithError, tracer };
@@ -32,7 +32,9 @@ const SLACK_SPAN_KEYS = {
32
32
  OUTCOME: "slack.outcome",
33
33
  IS_BOT_MESSAGE: "slack.is_bot_message",
34
34
  HAS_QUERY: "slack.has_query",
35
- IS_IN_THREAD: "slack.is_in_thread"
35
+ IS_IN_THREAD: "slack.is_in_thread",
36
+ STREAM_FINALIZATION_FAILED: "slack.stream_finalization_failed",
37
+ CONTENT_ALREADY_DELIVERED: "slack.content_already_delivered"
36
38
  };
37
39
 
38
40
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-work-apps",
3
- "version": "0.0.0-dev-20260213221002",
3
+ "version": "0.0.0-dev-20260213222830",
4
4
  "description": "First party integrations for Inkeep Agents",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE.md",
@@ -33,7 +33,7 @@
33
33
  "jose": "^6.1.0",
34
34
  "minimatch": "^10.1.1",
35
35
  "slack-block-builder": "^2.8.0",
36
- "@inkeep/agents-core": "0.0.0-dev-20260213221002"
36
+ "@inkeep/agents-core": "0.0.0-dev-20260213222830"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@hono/zod-openapi": "^1.1.5",