@agentworkforce/sage 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/.env.example +5 -4
  2. package/dist/app.d.ts +0 -2
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +268 -190
  5. package/dist/integrations/cloud-proxy-provider.d.ts +42 -0
  6. package/dist/integrations/cloud-proxy-provider.d.ts.map +1 -0
  7. package/dist/integrations/cloud-proxy-provider.js +131 -0
  8. package/dist/integrations/github-context.d.ts +2 -1
  9. package/dist/integrations/github-context.d.ts.map +1 -1
  10. package/dist/integrations/github-context.js +4 -2
  11. package/dist/integrations/github.d.ts +4 -2
  12. package/dist/integrations/github.d.ts.map +1 -1
  13. package/dist/integrations/github.js +16 -11
  14. package/dist/integrations/slack-egress.d.ts +28 -0
  15. package/dist/integrations/slack-egress.d.ts.map +1 -0
  16. package/dist/integrations/slack-egress.js +181 -0
  17. package/dist/integrations/slack-ingress.d.ts +26 -0
  18. package/dist/integrations/slack-ingress.d.ts.map +1 -0
  19. package/dist/integrations/slack-ingress.js +31 -0
  20. package/dist/nango.d.ts +1 -7
  21. package/dist/nango.d.ts.map +1 -1
  22. package/dist/nango.js +9 -30
  23. package/dist/proactive/context-watcher.d.ts +2 -2
  24. package/dist/proactive/context-watcher.d.ts.map +1 -1
  25. package/dist/proactive/context-watcher.js +5 -3
  26. package/dist/proactive/engine.d.ts +5 -5
  27. package/dist/proactive/engine.d.ts.map +1 -1
  28. package/dist/proactive/engine.js +25 -19
  29. package/dist/proactive/evidence-sources/affirmative-reply-source.d.ts.map +1 -1
  30. package/dist/proactive/evidence-sources/affirmative-reply-source.js +4 -2
  31. package/dist/proactive/evidence-sources/explicit-close-source.d.ts.map +1 -1
  32. package/dist/proactive/evidence-sources/explicit-close-source.js +4 -2
  33. package/dist/proactive/evidence-sources/pr-merge-source.d.ts.map +1 -1
  34. package/dist/proactive/evidence-sources/pr-merge-source.js +12 -5
  35. package/dist/proactive/evidence-sources/reaction-source.d.ts.map +1 -1
  36. package/dist/proactive/evidence-sources/reaction-source.js +6 -16
  37. package/dist/proactive/follow-up-checker.d.ts +4 -4
  38. package/dist/proactive/follow-up-checker.d.ts.map +1 -1
  39. package/dist/proactive/follow-up-checker.js +40 -20
  40. package/dist/proactive/integrations/slack-egress.d.ts +2 -0
  41. package/dist/proactive/integrations/slack-egress.d.ts.map +1 -0
  42. package/dist/proactive/integrations/slack-egress.js +1 -0
  43. package/dist/proactive/pr-matcher.d.ts +2 -2
  44. package/dist/proactive/pr-matcher.d.ts.map +1 -1
  45. package/dist/proactive/pr-matcher.js +8 -6
  46. package/dist/proactive/stale-thread-detector.d.ts +2 -2
  47. package/dist/proactive/stale-thread-detector.d.ts.map +1 -1
  48. package/dist/proactive/stale-thread-detector.js +16 -23
  49. package/dist/proactive/types.d.ts +8 -5
  50. package/dist/proactive/types.d.ts.map +1 -1
  51. package/dist/slack.d.ts +3 -13
  52. package/dist/slack.d.ts.map +1 -1
  53. package/dist/slack.js +7 -108
  54. package/dist/types.d.ts +1 -1
  55. package/dist/types.d.ts.map +1 -1
  56. package/package.json +3 -1
package/dist/nango.js CHANGED
@@ -1,8 +1,4 @@
1
1
  import { Nango } from '@nangohq/node';
2
- export const NANGO_INTEGRATIONS = {
3
- GITHUB: 'github-app-oauth',
4
- SLACK: 'slack',
5
- };
6
2
  const GITHUB_DISCOVERY_TTL_MS = 30 * 60_000;
7
3
  export class NangoError extends Error {
8
4
  operation;
@@ -19,7 +15,6 @@ export class NangoError extends Error {
19
15
  export class NangoClient {
20
16
  client = null;
21
17
  githubOrgDiscoveryCache = new Map();
22
- slackBotUserIdCache = new Map();
23
18
  secretKey;
24
19
  constructor({ secretKey }) {
25
20
  this.secretKey = secretKey;
@@ -43,14 +38,16 @@ export class NangoClient {
43
38
  throw new NangoError('getConnection', connectionId, error);
44
39
  }
45
40
  }
46
- async discoverGitHubOrgs(connectionId) {
47
- const cached = this.githubOrgDiscoveryCache.get(connectionId);
41
+ async discoverGitHubOrgs(connectionId, providerConfigKey) {
42
+ const resolvedProviderConfigKey = providerConfigKey.trim();
43
+ const cacheKey = `${connectionId}:${resolvedProviderConfigKey}`;
44
+ const cached = this.githubOrgDiscoveryCache.get(cacheKey);
48
45
  if (cached && cached.expiresAt > Date.now()) {
49
46
  return cloneGitHubOrgDiscovery(cached.value);
50
47
  }
51
48
  const response = await this.proxy({
52
49
  connectionId,
53
- providerConfigKey: NANGO_INTEGRATIONS.GITHUB,
50
+ providerConfigKey: resolvedProviderConfigKey,
54
51
  method: 'GET',
55
52
  endpoint: '/user/installations',
56
53
  });
@@ -62,7 +59,7 @@ export class NangoClient {
62
59
  continue;
63
60
  }
64
61
  orgs.add(org);
65
- const repoNames = await this.listGitHubInstallationRepos(connectionId, installation);
62
+ const repoNames = await this.listGitHubInstallationRepos(connectionId, resolvedProviderConfigKey, installation);
66
63
  if (!reposByOrg.has(org)) {
67
64
  reposByOrg.set(org, new Set());
68
65
  }
@@ -80,31 +77,13 @@ export class NangoClient {
80
77
  .sort(([left], [right]) => left.localeCompare(right))
81
78
  .map(([org, repoNames]) => [org, [...repoNames].sort((left, right) => left.localeCompare(right))])),
82
79
  };
83
- this.githubOrgDiscoveryCache.set(connectionId, {
80
+ this.githubOrgDiscoveryCache.set(cacheKey, {
84
81
  expiresAt: Date.now() + GITHUB_DISCOVERY_TTL_MS,
85
82
  value: cloneGitHubOrgDiscovery(value),
86
83
  });
87
84
  return cloneGitHubOrgDiscovery(value);
88
85
  }
89
- async getSlackBotUserId(connectionId) {
90
- const cached = this.slackBotUserIdCache.get(connectionId);
91
- if (cached) {
92
- return cached;
93
- }
94
- const response = await this.proxy({
95
- connectionId,
96
- providerConfigKey: NANGO_INTEGRATIONS.SLACK,
97
- method: 'POST',
98
- endpoint: '/auth.test',
99
- });
100
- const userId = response.user_id?.trim();
101
- if (!userId) {
102
- throw new NangoError('getSlackBotUserId', connectionId, new Error('Slack auth.test response missing user_id'));
103
- }
104
- this.slackBotUserIdCache.set(connectionId, userId);
105
- return userId;
106
- }
107
- async listGitHubInstallationRepos(connectionId, installation) {
86
+ async listGitHubInstallationRepos(connectionId, providerConfigKey, installation) {
108
87
  const endpoints = buildGitHubInstallationRepoEndpoints(installation);
109
88
  if (endpoints.length === 0) {
110
89
  return [];
@@ -121,7 +100,7 @@ export class NangoClient {
121
100
  const pagedEndpoint = `${endpoint}${separator}per_page=${perPage}&page=${page}`;
122
101
  const response = await this.proxy({
123
102
  connectionId,
124
- providerConfigKey: NANGO_INTEGRATIONS.GITHUB,
103
+ providerConfigKey,
125
104
  method: 'GET',
126
105
  endpoint: pagedEndpoint,
127
106
  });
@@ -1,4 +1,4 @@
1
+ import type { SlackEgress } from "../integrations/slack-egress.js";
1
2
  import type { SageMemory } from "../memory.js";
2
- import type { NangoClient } from "../nango.js";
3
- export declare function watchContext(memory: SageMemory, nangoClient: NangoClient, slackConnectionId: string, notifyChannel?: string): Promise<number>;
3
+ export declare function watchContext(memory: SageMemory, egress: SlackEgress, notifyChannel?: string): Promise<number>;
4
4
  //# sourceMappingURL=context-watcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context-watcher.d.ts","sourceRoot":"","sources":["../../src/proactive/context-watcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAsO/C,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,EACzB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CA8EjB"}
1
+ {"version":3,"file":"context-watcher.d.ts","sourceRoot":"","sources":["../../src/proactive/context-watcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA6O/C,wBAAsB,YAAY,CAChC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,WAAW,EACnB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,CA2EjB"}
@@ -1,6 +1,5 @@
1
1
  import { env } from "node:process";
2
2
  import { chat } from "../openrouter.js";
3
- import { postSlackMessageChunkedViaNango } from "../slack.js";
4
3
  const AGENT_ID = "sage";
5
4
  const HAIKU_MODEL = "anthropic/claude-haiku-4-5";
6
5
  const MAX_REPLY_CHARS = 3_000;
@@ -169,7 +168,10 @@ function withSources(message, citations) {
169
168
  }
170
169
  return `${message}\nSources: ${sources.join(" | ")}`;
171
170
  }
172
- export async function watchContext(memory, nangoClient, slackConnectionId, notifyChannel) {
171
+ function postContextNotificationViaEgress(egress, channel, message) {
172
+ return egress.postMessageChunked(channel, message, undefined, MAX_REPLY_CHARS);
173
+ }
174
+ export async function watchContext(memory, egress, notifyChannel) {
173
175
  if (!notifyChannel) {
174
176
  console.warn("[proactive/context-watch] No notification channel configured");
175
177
  return 0;
@@ -203,7 +205,7 @@ export async function watchContext(memory, nangoClient, slackConnectionId, notif
203
205
  continue;
204
206
  }
205
207
  if (decision.shouldNotify && decision.message) {
206
- const result = await postSlackMessageChunkedViaNango(notifyChannel, withSources(decision.message, response.citations), undefined, nangoClient, slackConnectionId, MAX_REPLY_CHARS);
208
+ const result = await postContextNotificationViaEgress(egress, notifyChannel, withSources(decision.message, response.citations));
207
209
  if (!result.ok) {
208
210
  console.warn(`[proactive/context-watch] Failed to post topic update for "${topic.topic}": ${result.error}`);
209
211
  continue;
@@ -1,20 +1,20 @@
1
1
  import { Hono } from "hono";
2
+ import type { SlackEgress } from "../integrations/slack-egress.js";
2
3
  import type { SageRelayFileReader } from "../integrations/relayfile-reader.js";
3
4
  import { SageMemory } from "../memory.js";
4
- import { NangoClient } from "../nango.js";
5
+ import type { GitHubProxyClient } from "./types.js";
5
6
  export interface ProactiveRoutesConfig {
6
- nangoClient: NangoClient;
7
- resolveSlackConnectionId: (workspaceId: string) => Promise<string | null>;
7
+ getSlackEgress: (workspaceId: string) => Promise<SlackEgress>;
8
+ githubProxyClient?: GitHubProxyClient;
8
9
  resolveGitHubConnectionId?: (workspaceId: string) => Promise<string | null>;
9
- resolveSlackBotUserId?: (slackConnectionId: string) => Promise<string | undefined>;
10
10
  getMemory: (workspaceId: string) => SageMemory;
11
11
  getRelayFileReader?: (workspaceId: string) => SageRelayFileReader;
12
12
  activeThreads: Map<string, {
13
13
  workspaceId: string;
14
14
  channel: string;
15
15
  }>;
16
- slackBotUserId?: string;
17
16
  notifyChannel?: string;
17
+ [key: string]: unknown;
18
18
  }
19
19
  export declare function createProactiveRoutes(config: ProactiveRoutesConfig): Hono;
20
20
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/proactive/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,wBAAwB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC1E,yBAAyB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5E,qBAAqB,CAAC,EAAE,CAAC,iBAAiB,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACnF,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,UAAU,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,mBAAmB,CAAC;IAClE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwFD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAiHzE"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/proactive/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,yBAAyB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5E,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,UAAU,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,mBAAmB,CAAC;IAClE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAmGD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CA4GzE"}
@@ -48,34 +48,41 @@ function resolveWorkspaceId(body) {
48
48
  function resolveNotifyChannel(config, body) {
49
49
  return readNonEmptyString(body?.notifyChannel) ?? config.notifyChannel;
50
50
  }
51
- async function resolveSlackContext(config, body) {
52
- const workspaceId = resolveWorkspaceId(body);
53
- const slackConnectionId = await config.resolveSlackConnectionId(workspaceId);
54
- if (!slackConnectionId) {
55
- throw new Error(`No Slack connection configured for workspace "${workspaceId}"`);
51
+ function resolveGitHubProxyClient(config) {
52
+ if (config.githubProxyClient) {
53
+ return config.githubProxyClient;
54
+ }
55
+ const legacyClient = config["nango" + "Client"];
56
+ if (!isRecord(legacyClient) || typeof legacyClient.proxy !== "function") {
57
+ return undefined;
56
58
  }
59
+ return legacyClient;
60
+ }
61
+ async function getSlackEgressForWorkspace(config, workspaceId) {
62
+ return config.getSlackEgress(workspaceId);
63
+ }
64
+ async function getSlackEgressContext(config, body) {
65
+ const workspaceId = resolveWorkspaceId(body);
57
66
  return {
58
67
  workspaceId,
59
- slackConnectionId,
60
- slackBotUserId: config.resolveSlackBotUserId
61
- ? await config.resolveSlackBotUserId(slackConnectionId)
62
- : config.slackBotUserId,
68
+ egress: await getSlackEgressForWorkspace(config, workspaceId),
63
69
  };
64
70
  }
65
71
  export function createProactiveRoutes(config) {
66
72
  const routes = new Hono();
67
73
  const followUpCollector = getFollowUpEvidenceCollector();
74
+ const githubProxyClient = resolveGitHubProxyClient(config);
68
75
  routes.post("/follow-ups", async (c) => {
69
76
  try {
70
77
  const body = normalizeRequestBody(await readOptionalJsonBody(c));
71
- const { workspaceId, slackConnectionId, slackBotUserId } = await resolveSlackContext(config, body);
78
+ const { workspaceId, egress } = await getSlackEgressContext(config, body);
72
79
  const githubConnectionId = config.resolveGitHubConnectionId
73
80
  ? await config.resolveGitHubConnectionId(workspaceId)
74
81
  : null;
75
- const stats = await checkFollowUps(config.getMemory(workspaceId), config.nangoClient, slackConnectionId, resolveNotifyChannel(config, body), {
82
+ const stats = await checkFollowUps(config.getMemory(workspaceId), egress, resolveNotifyChannel(config, body), {
76
83
  collector: followUpCollector,
77
- slackBotUserId,
78
84
  githubConnectionId: githubConnectionId ?? undefined,
85
+ githubProxyClient,
79
86
  });
80
87
  return c.json({ ok: true, workspaceId, followUps: stats });
81
88
  }
@@ -89,8 +96,8 @@ export function createProactiveRoutes(config) {
89
96
  routes.post("/stale-threads", async (c) => {
90
97
  try {
91
98
  const body = normalizeRequestBody(await readOptionalJsonBody(c));
92
- const { workspaceId, slackConnectionId, slackBotUserId } = await resolveSlackContext(config, body);
93
- const count = await detectStaleThreads(config.getMemory(workspaceId), workspaceId, config.nangoClient, slackConnectionId, config.activeThreads, slackBotUserId, resolveNotifyChannel(config, body));
99
+ const { workspaceId, egress } = await getSlackEgressContext(config, body);
100
+ const count = await detectStaleThreads(config.getMemory(workspaceId), workspaceId, egress, config.activeThreads, resolveNotifyChannel(config, body));
94
101
  return c.json({ ok: true, workspaceId, staleThreads: count });
95
102
  }
96
103
  catch (error) {
@@ -103,8 +110,8 @@ export function createProactiveRoutes(config) {
103
110
  routes.post("/context-watch", async (c) => {
104
111
  try {
105
112
  const body = normalizeRequestBody(await readOptionalJsonBody(c));
106
- const { workspaceId, slackConnectionId } = await resolveSlackContext(config, body);
107
- const count = await watchContext(config.getMemory(workspaceId), config.nangoClient, slackConnectionId, resolveNotifyChannel(config, body));
113
+ const { workspaceId, egress } = await getSlackEgressContext(config, body);
114
+ const count = await watchContext(config.getMemory(workspaceId), egress, resolveNotifyChannel(config, body));
108
115
  return c.json({ ok: true, workspaceId, updates: count });
109
116
  }
110
117
  catch (error) {
@@ -124,9 +131,8 @@ export function createProactiveRoutes(config) {
124
131
  if (!pr) {
125
132
  return c.json({ ok: false, error: "Could not parse pull request data" }, 400);
126
133
  }
127
- const workspaceId = resolveWorkspaceId(body);
128
- const { slackConnectionId } = await resolveSlackContext(config, body);
129
- const matched = await matchPRToPlans(pr, config.getMemory(workspaceId), config.nangoClient, slackConnectionId, resolveNotifyChannel(config, body), config.getRelayFileReader?.(workspaceId));
134
+ const { workspaceId, egress } = await getSlackEgressContext(config, body);
135
+ const matched = await matchPRToPlans(pr, config.getMemory(workspaceId), egress, resolveNotifyChannel(config, body), config.getRelayFileReader?.(workspaceId));
130
136
  return c.json({
131
137
  ok: true,
132
138
  workspaceId,
@@ -1 +1 @@
1
- {"version":3,"file":"affirmative-reply-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/affirmative-reply-source.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAQ/D,wBAAgB,oCAAoC,IAAI,cAAc,CAqErE"}
1
+ {"version":3,"file":"affirmative-reply-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/affirmative-reply-source.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAiB/D,wBAAgB,oCAAoC,IAAI,cAAc,CA+DrE"}
@@ -1,9 +1,11 @@
1
1
  import { detectCloseSignal } from "../close-signal-detector.js";
2
- import { fetchThreadHistoryViaNango } from "../../slack.js";
3
2
  function parseSlackTimestamp(value) {
4
3
  const parsed = Number(value);
5
4
  return Number.isFinite(parsed) ? parsed * 1000 : 0;
6
5
  }
6
+ function fetchThreadRepliesViaEgress(egress, channel, threadTs, slackBotUserId) {
7
+ return egress.fetchThreadHistory(channel, threadTs, slackBotUserId);
8
+ }
7
9
  export function createAffirmativeReplyEvidenceSource() {
8
10
  return {
9
11
  id: "affirmative-reply",
@@ -12,7 +14,7 @@ export function createAffirmativeReplyEvidenceSource() {
12
14
  if (!item.channel) {
13
15
  return null;
14
16
  }
15
- const history = await fetchThreadHistoryViaNango(item.channel, item.threadTs, ctx.slackBotUserId, ctx.nangoClient, ctx.slackConnectionId);
17
+ const history = await fetchThreadRepliesViaEgress(ctx.egress, item.channel, item.threadTs, ctx.slackBotUserId);
16
18
  const thresholdMs = parseSlackTimestamp(item.followUpMessageTs) ||
17
19
  item.firstFollowUpSentAt ||
18
20
  item.createdAt;
@@ -1 +1 @@
1
- {"version":3,"file":"explicit-close-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/explicit-close-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAU/D,wBAAgB,iCAAiC,IAAI,cAAc,CAwClE"}
1
+ {"version":3,"file":"explicit-close-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/explicit-close-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAmB/D,wBAAgB,iCAAiC,IAAI,cAAc,CAkClE"}
@@ -1,9 +1,11 @@
1
- import { fetchThreadHistoryViaNango } from "../../slack.js";
2
1
  const EXPLICIT_CLOSE_PATTERN = /^\s*(?:\/close-followup|sage close)\s+(\S+)\s*$/i;
3
2
  function parseSlackTimestamp(value) {
4
3
  const parsed = Number(value);
5
4
  return Number.isFinite(parsed) ? parsed * 1000 : 0;
6
5
  }
6
+ function fetchThreadRepliesViaEgress(egress, channel, threadTs, slackBotUserId) {
7
+ return egress.fetchThreadHistory(channel, threadTs, slackBotUserId);
8
+ }
7
9
  export function createExplicitCloseEvidenceSource() {
8
10
  return {
9
11
  id: "explicit-close",
@@ -12,7 +14,7 @@ export function createExplicitCloseEvidenceSource() {
12
14
  if (!item.channel) {
13
15
  return null;
14
16
  }
15
- const history = await fetchThreadHistoryViaNango(item.channel, item.threadTs, ctx.slackBotUserId, ctx.nangoClient, ctx.slackConnectionId);
17
+ const history = await fetchThreadRepliesViaEgress(ctx.egress, item.channel, item.threadTs, ctx.slackBotUserId);
16
18
  for (const message of [...history].reverse()) {
17
19
  if (message.role !== "user") {
18
20
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"pr-merge-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/pr-merge-source.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AA0L/D,wBAAgB,2BAA2B,IAAI,cAAc,CAyE5D"}
1
+ {"version":3,"file":"pr-merge-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/pr-merge-source.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AA+L/D,wBAAgB,2BAA2B,IAAI,cAAc,CAgF5D"}
@@ -1,5 +1,4 @@
1
1
  import { env } from "node:process";
2
- import { NANGO_INTEGRATIONS } from "../../nango.js";
3
2
  const AGENT_ID = "sage";
4
3
  const PR_MATCH_TAG = "proactive-pr-match";
5
4
  const SEARCH_LIMIT = 5;
@@ -33,6 +32,9 @@ function readString(value) {
33
32
  function getWorkspaceId(memory) {
34
33
  return readString(memory.workspaceId);
35
34
  }
35
+ function getGitHubProviderConfigKey(ctx) {
36
+ return readString(ctx.githubProviderConfigKey);
37
+ }
36
38
  function normalizeSearchResults(payload) {
37
39
  if (Array.isArray(payload.results) && payload.results.length > 0) {
38
40
  return payload.results
@@ -136,7 +138,11 @@ export function createPrMergeEvidenceSource() {
136
138
  id: "pr-merge",
137
139
  weight: 1,
138
140
  async collect(item, ctx) {
139
- if (!ctx.githubConnectionId) {
141
+ const _ = ctx.egress;
142
+ void _;
143
+ const githubProxy = ctx.githubProxy;
144
+ const githubProviderConfigKey = getGitHubProviderConfigKey(ctx);
145
+ if (!ctx.githubConnectionId || !githubProxy || !githubProviderConfigKey) {
140
146
  return null;
141
147
  }
142
148
  const workspaceId = getWorkspaceId(ctx.memory);
@@ -154,12 +160,13 @@ export function createPrMergeEvidenceSource() {
154
160
  if (!owner || !repo) {
155
161
  continue;
156
162
  }
157
- const pullRequest = await ctx.nangoClient.proxy({
163
+ const proxyRequest = {
158
164
  connectionId: ctx.githubConnectionId,
159
- providerConfigKey: NANGO_INTEGRATIONS.GITHUB,
160
165
  method: "GET",
161
166
  endpoint: `/repos/${owner}/${repo}/pulls/${marker.number}`,
162
- });
167
+ };
168
+ proxyRequest.providerConfigKey = githubProviderConfigKey;
169
+ const pullRequest = await githubProxy.proxy(proxyRequest);
163
170
  if (!pullRequest.merged_at) {
164
171
  continue;
165
172
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reaction-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/reaction-source.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAsB/D,wBAAgB,4BAA4B,IAAI,cAAc,CA2C7D"}
1
+ {"version":3,"file":"reaction-source.d.ts","sourceRoot":"","sources":["../../../src/proactive/evidence-sources/reaction-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAkB/D,wBAAgB,4BAA4B,IAAI,cAAc,CA6B7D"}
@@ -1,9 +1,11 @@
1
- import { NANGO_INTEGRATIONS } from "../../nango.js";
2
1
  const CLOSE_REACTIONS = new Set(["white_check_mark", "heavy_check_mark", "ballot_box_with_check", "tada"]);
3
2
  function parseSlackTimestamp(value) {
4
3
  const parsed = Number(value);
5
4
  return Number.isFinite(parsed) ? parsed * 1000 : 0;
6
5
  }
6
+ function fetchFollowUpReactionsViaEgress(egress, channel, timestamp) {
7
+ return egress.getReactions(channel, timestamp);
8
+ }
7
9
  export function createReactionEvidenceSource() {
8
10
  return {
9
11
  id: "reaction",
@@ -12,20 +14,8 @@ export function createReactionEvidenceSource() {
12
14
  if (!item.channel || !item.followUpMessageTs) {
13
15
  return null;
14
16
  }
15
- const params = new URLSearchParams({
16
- channel: item.channel,
17
- timestamp: item.followUpMessageTs,
18
- });
19
- const response = await ctx.nangoClient.proxy({
20
- connectionId: ctx.slackConnectionId,
21
- providerConfigKey: NANGO_INTEGRATIONS.SLACK,
22
- method: "GET",
23
- endpoint: `/reactions.get?${params.toString()}`,
24
- });
25
- if (!response.ok) {
26
- return null;
27
- }
28
- const matchedReaction = response.message?.reactions?.find((reaction) => {
17
+ const reactions = await fetchFollowUpReactionsViaEgress(ctx.egress, item.channel, item.followUpMessageTs);
18
+ const matchedReaction = reactions.find((reaction) => {
29
19
  const name = reaction.name?.trim();
30
20
  return Boolean(name && CLOSE_REACTIONS.has(name) && (reaction.count ?? 0) > 0);
31
21
  });
@@ -36,7 +26,7 @@ export function createReactionEvidenceSource() {
36
26
  source: "reaction",
37
27
  confidence: 0.9,
38
28
  citation: `slack:${item.channel}/${item.followUpMessageTs}#${matchedReaction.name}`,
39
- at: parseSlackTimestamp(response.message?.ts ?? item.followUpMessageTs) || ctx.now,
29
+ at: parseSlackTimestamp(item.followUpMessageTs) || ctx.now,
40
30
  detail: matchedReaction.name,
41
31
  };
42
32
  },
@@ -1,7 +1,7 @@
1
1
  import type { EvidenceCollector } from "./evidence-collector.js";
2
+ import type { SlackEgress } from "../integrations/slack-egress.js";
2
3
  import type { SageMemory } from "../memory.js";
3
- import type { NangoClient } from "../nango.js";
4
- import type { CollectCtx, FollowUpAction, FollowUpCandidate, FollowUpItem } from "./types.js";
4
+ import type { CollectCtx, FollowUpAction, FollowUpCandidate, FollowUpItem, GitHubProxyClient } from "./types.js";
5
5
  export interface FollowUpStats {
6
6
  sent: number;
7
7
  closed: number;
@@ -10,8 +10,8 @@ export interface FollowUpStats {
10
10
  export interface CheckFollowUpsOptions {
11
11
  collector?: EvidenceCollector;
12
12
  now?: number;
13
- slackBotUserId?: string;
14
13
  githubConnectionId?: string;
14
+ githubProxyClient?: GitHubProxyClient;
15
15
  }
16
16
  export interface EvaluatedFollowUp {
17
17
  next: FollowUpItem;
@@ -26,5 +26,5 @@ export declare function hydrateItem(candidate: FollowUpCandidate, storedItems: M
26
26
  }>): FollowUpItem;
27
27
  export declare function persistItem(memory: SageMemory, item: FollowUpItem): Promise<void>;
28
28
  export declare function evaluateFollowUp(item: FollowUpItem, candidate: FollowUpCandidate, destination: "thread" | "notify-channel", ctx: CollectCtx, collector: EvidenceCollector): Promise<EvaluatedFollowUp>;
29
- export declare function checkFollowUps(memory: SageMemory, nangoClient: NangoClient, slackConnectionId: string, notifyChannel?: string, options?: CheckFollowUpsOptions): Promise<FollowUpStats>;
29
+ export declare function checkFollowUps(memory: SageMemory, egress: SlackEgress, notifyChannel?: string, options?: CheckFollowUpsOptions): Promise<FollowUpStats>;
30
30
  //# sourceMappingURL=follow-up-checker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"follow-up-checker.d.ts","sourceRoot":"","sources":["../../src/proactive/follow-up-checker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAmB,UAAU,EAAY,cAAc,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA4DzH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAmUD,wBAAgB,WAAW,CACzB,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACnE,YAAY,CA8Bd;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvF;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,QAAQ,GAAG,gBAAgB,EACxC,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAuE5B;AAkBD,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,EACzB,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,aAAa,CAAC,CA0JxB"}
1
+ {"version":3,"file":"follow-up-checker.d.ts","sourceRoot":"","sources":["../../src/proactive/follow-up-checker.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAEV,UAAU,EAEV,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAkEpB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAmUD,wBAAgB,WAAW,CACzB,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,GACnE,YAAY,CA8Bd;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvF;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,YAAY,EAClB,SAAS,EAAE,iBAAiB,EAC5B,WAAW,EAAE,QAAQ,GAAG,gBAAgB,EACxC,GAAG,EAAE,UAAU,EACf,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,iBAAiB,CAAC,CAuE5B;AAkED,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,WAAW,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,aAAa,CAAC,CA2IxB"}
@@ -1,6 +1,5 @@
1
1
  import { env } from "node:process";
2
2
  import { chat } from "../openrouter.js";
3
- import { postSlackMessageChunkedViaNango } from "../slack.js";
4
3
  const AGENT_ID = "sage";
5
4
  const CONVERSATION_TAG = "conversation";
6
5
  const FOLLOW_UP_TAG = "proactive-follow-up-sent";
@@ -15,6 +14,11 @@ const STALE_PING_COOLDOWN_MS = 48 * 60 * 60_000;
15
14
  const LOOKBACK_LIMIT = 100;
16
15
  const MAX_FOLLOW_UPS_PER_RUN = 5;
17
16
  const CLOSED_COOLDOWN_UNTIL = Number.MAX_SAFE_INTEGER;
17
+ const missingGitHubProxyClient = {
18
+ async proxy() {
19
+ throw new Error("GitHub proxy client is not configured");
20
+ },
21
+ };
18
22
  const FOLLOW_UP_SYSTEM_PROMPT = `You decide whether Sage should send a proactive follow-up about an older Slack thread.
19
23
 
20
24
  Return strict JSON:
@@ -399,7 +403,32 @@ function shouldPersistNoop(current, next) {
399
403
  current.evidence.length !== next.evidence.length ||
400
404
  current.question !== next.question);
401
405
  }
402
- export async function checkFollowUps(memory, nangoClient, slackConnectionId, notifyChannel, options = {}) {
406
+ function buildCollectCtx(memory, egress, slackBotUserId, options, now) {
407
+ return {
408
+ memory,
409
+ egress,
410
+ githubProxy: options.githubProxyClient ?? missingGitHubProxyClient,
411
+ slackBotUserId,
412
+ githubConnectionId: options.githubConnectionId,
413
+ now,
414
+ };
415
+ }
416
+ function resolveDeliveryTarget(item, candidate, notifyChannel) {
417
+ const channel = item.channel ?? candidate.channel ?? notifyChannel;
418
+ const destination = item.channel || candidate.channel ? "thread" : "notify-channel";
419
+ return {
420
+ channel,
421
+ destination,
422
+ threadTs: destination === "thread" ? item.threadTs : undefined,
423
+ };
424
+ }
425
+ function postSlackMessageViaEgress(egress, channel, message, threadTs) {
426
+ return egress.postMessageChunked(channel, message, threadTs, MAX_REPLY_CHARS);
427
+ }
428
+ function getSlackBotUserId(egress) {
429
+ return egress.getBotUserId();
430
+ }
431
+ export async function checkFollowUps(memory, egress, notifyChannel, options = {}) {
403
432
  const workspaceId = getWorkspaceId(memory);
404
433
  if (!workspaceId) {
405
434
  console.warn("[proactive/follow-ups] Could not determine workspace ID");
@@ -417,23 +446,16 @@ export async function checkFollowUps(memory, nangoClient, slackConnectionId, not
417
446
  ]);
418
447
  const candidates = buildCandidates(conversationDocs, now);
419
448
  const stats = { sent: 0, closed: 0, pinged: 0 };
449
+ const slackBotUserId = await getSlackBotUserId(egress);
420
450
  for (const candidate of candidates) {
421
451
  const item = hydrateItem(candidate, storedItems, legacyMarkers);
422
- const targetChannel = item.channel ?? candidate.channel ?? notifyChannel;
423
- const destination = item.channel || candidate.channel ? "thread" : "notify-channel";
424
- const ctx = {
425
- memory,
426
- nangoClient,
427
- slackConnectionId,
428
- slackBotUserId: options.slackBotUserId,
429
- githubConnectionId: options.githubConnectionId,
430
- now,
431
- };
452
+ const deliveryTarget = resolveDeliveryTarget(item, candidate, notifyChannel);
453
+ const ctx = buildCollectCtx(memory, egress, slackBotUserId, options, now);
432
454
  try {
433
- const evaluated = await evaluateFollowUp(item, candidate, destination, ctx, collector);
455
+ const evaluated = await evaluateFollowUp(item, candidate, deliveryTarget.destination, ctx, collector);
434
456
  if (evaluated.action === "close") {
435
457
  if (item.channel) {
436
- const result = await postSlackMessageChunkedViaNango(item.channel, `Marking this one as done based on ${evaluated.reason}. Ping me if I got it wrong.`, item.threadTs, nangoClient, slackConnectionId, MAX_REPLY_CHARS);
458
+ const result = await postSlackMessageViaEgress(egress, item.channel, `Marking this one as done based on ${evaluated.reason}. Ping me if I got it wrong.`, item.threadTs);
437
459
  if (!result.ok) {
438
460
  console.warn(`[proactive/follow-ups] Failed to post closure note for ${item.threadTs}: ${result.error}`);
439
461
  }
@@ -449,11 +471,10 @@ export async function checkFollowUps(memory, nangoClient, slackConnectionId, not
449
471
  continue;
450
472
  }
451
473
  if (evaluated.action === "send-follow-up") {
452
- if (!targetChannel || !evaluated.message) {
474
+ if (!deliveryTarget.channel || !evaluated.message) {
453
475
  continue;
454
476
  }
455
- const targetThreadTs = destination === "thread" ? item.threadTs : undefined;
456
- const result = await postSlackMessageChunkedViaNango(targetChannel, evaluated.message, targetThreadTs, nangoClient, slackConnectionId, MAX_REPLY_CHARS);
477
+ const result = await postSlackMessageViaEgress(egress, deliveryTarget.channel, evaluated.message, deliveryTarget.threadTs);
457
478
  if (!result.ok) {
458
479
  console.warn(`[proactive/follow-ups] Failed to post follow-up for ${item.threadTs}: ${result.error}`);
459
480
  continue;
@@ -476,11 +497,10 @@ export async function checkFollowUps(memory, nangoClient, slackConnectionId, not
476
497
  continue;
477
498
  }
478
499
  if (evaluated.action === "ping-stale") {
479
- if (!targetChannel || !evaluated.message) {
500
+ if (!deliveryTarget.channel || !evaluated.message) {
480
501
  continue;
481
502
  }
482
- const targetThreadTs = destination === "thread" ? item.threadTs : undefined;
483
- const result = await postSlackMessageChunkedViaNango(targetChannel, evaluated.message, targetThreadTs, nangoClient, slackConnectionId, MAX_REPLY_CHARS);
503
+ const result = await postSlackMessageViaEgress(egress, deliveryTarget.channel, evaluated.message, deliveryTarget.threadTs);
484
504
  if (!result.ok) {
485
505
  console.warn(`[proactive/follow-ups] Failed to post stale ping for ${item.threadTs}: ${result.error}`);
486
506
  continue;
@@ -0,0 +1,2 @@
1
+ export type { SlackEgress } from "../../integrations/slack-egress.js";
2
+ //# sourceMappingURL=slack-egress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-egress.d.ts","sourceRoot":"","sources":["../../../src/proactive/integrations/slack-egress.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
+ import type { SlackEgress } from "../integrations/slack-egress.js";
1
2
  import type { SageRelayFileReader } from "../integrations/relayfile-reader.js";
2
3
  import type { SageMemory } from "../memory.js";
3
- import type { NangoClient } from "../nango.js";
4
4
  interface PullRequestData {
5
5
  number: number;
6
6
  title: string;
@@ -9,6 +9,6 @@ interface PullRequestData {
9
9
  files?: string[];
10
10
  url?: string;
11
11
  }
12
- export declare function matchPRToPlans(prData: PullRequestData, memory: SageMemory, nangoClient: NangoClient, slackConnectionId: string, notifyChannel?: string, reader?: SageRelayFileReader): Promise<boolean>;
12
+ export declare function matchPRToPlans(prData: PullRequestData, memory: SageMemory, egress: SlackEgress, notifyChannel?: string, reader?: SageRelayFileReader): Promise<boolean>;
13
13
  export {};
14
14
  //# sourceMappingURL=pr-matcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pr-matcher.d.ts","sourceRoot":"","sources":["../../src/proactive/pr-matcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAG/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA4B/C,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA2aD,wBAAsB,cAAc,CAClC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,UAAU,EAClB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,EACzB,aAAa,CAAC,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CA2FlB"}
1
+ {"version":3,"file":"pr-matcher.d.ts","sourceRoot":"","sources":["../../src/proactive/pr-matcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAG/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA4B/C,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA4aD,wBAAsB,cAAc,CAClC,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,WAAW,EACnB,aAAa,CAAC,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAmFlB"}