@holon-run/agentinbox 1.0.0-beta.3 → 1.0.0-beta.5

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.
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.RemoteSourceModuleRegistry = void 0;
7
7
  exports.builtInModuleIdForSourceType = builtInModuleIdForSourceType;
8
+ exports.builtinRemoteSourceTypes = builtinRemoteSourceTypes;
8
9
  exports.createGithubRepoRemoteModule = createGithubRepoRemoteModule;
9
10
  exports.moduleConfigForSource = moduleConfigForSource;
10
11
  const node_fs_1 = __importDefault(require("node:fs"));
@@ -15,11 +16,16 @@ const github_ci_1 = require("./github_ci");
15
16
  const feishu_1 = require("./feishu");
16
17
  const REMOTE_USER_MODULE_ROOT_DIR = "source-modules";
17
18
  const BUILTIN_MODULE_IDS = new Set(["builtin.github_repo", "builtin.github_repo_ci", "builtin.feishu_bot"]);
19
+ const BUILTIN_REMOTE_SOURCE_TYPES = ["github_repo", "github_repo_ci", "feishu_bot"];
18
20
  class RemoteSourceModuleRegistry {
19
21
  moduleCache = new Map();
22
+ githubRepoModule;
23
+ constructor(options) {
24
+ this.githubRepoModule = createGithubRepoRemoteModule({ callClient: options?.githubCallClient });
25
+ }
20
26
  resolve(source, homeDir) {
21
27
  if (source.sourceType === "github_repo") {
22
- return Promise.resolve(GITHUB_REPO_MODULE);
28
+ return Promise.resolve(this.githubRepoModule);
23
29
  }
24
30
  if (source.sourceType === "github_repo_ci") {
25
31
  return Promise.resolve(GITHUB_REPO_CI_MODULE);
@@ -75,6 +81,9 @@ function builtInModuleIdForSourceType(sourceType) {
75
81
  }
76
82
  return null;
77
83
  }
84
+ function builtinRemoteSourceTypes() {
85
+ return [...BUILTIN_REMOTE_SOURCE_TYPES];
86
+ }
78
87
  function validateModuleContract(module, sourcePath) {
79
88
  if (!module.id || typeof module.id !== "string") {
80
89
  throw new Error(`remote_source module id must be a non-empty string: ${sourcePath}`);
@@ -94,6 +103,8 @@ function validateModuleContract(module, sourcePath) {
94
103
  validateOptionalHook(module.describeCapabilities, "describeCapabilities", sourcePath);
95
104
  validateOptionalHook(module.listSubscriptionShortcuts, "listSubscriptionShortcuts", sourcePath);
96
105
  validateOptionalHook(module.expandSubscriptionShortcut, "expandSubscriptionShortcut", sourcePath);
106
+ validateOptionalHook(module.listFollowTemplates, "listFollowTemplates", sourcePath);
107
+ validateOptionalHook(module.expandFollowTemplate, "expandFollowTemplate", sourcePath);
97
108
  validateOptionalHook(module.deriveTrackedResource, "deriveTrackedResource", sourcePath);
98
109
  validateOptionalHook(module.projectLifecycleSignal, "projectLifecycleSignal", sourcePath);
99
110
  validateOptionalHook(module.deriveInlinePreview, "deriveInlinePreview", sourcePath);
@@ -135,6 +146,7 @@ function asNonEmptyString(value) {
135
146
  return trimmed.length > 0 ? trimmed : null;
136
147
  }
137
148
  function createGithubRepoRemoteModule(options) {
149
+ const githubClient = new github_1.GithubUxcClient(options?.callClient);
138
150
  return {
139
151
  id: "builtin.github_repo",
140
152
  listDeliveryOperations(input) {
@@ -199,8 +211,14 @@ function createGithubRepoRemoteModule(options) {
199
211
  listSubscriptionShortcuts() {
200
212
  return (0, github_1.githubSubscriptionShortcutSpec)();
201
213
  },
202
- expandSubscriptionShortcut(input) {
203
- return (0, github_1.expandGithubSubscriptionShortcut)(input);
214
+ async expandSubscriptionShortcut(input) {
215
+ return (0, github_1.expandGithubSubscriptionShortcut)(input, githubClient);
216
+ },
217
+ listFollowTemplates() {
218
+ return (0, github_1.githubFollowTemplateSpec)();
219
+ },
220
+ async expandFollowTemplate(input) {
221
+ return (0, github_1.expandGithubFollowTemplate)(input, githubClient);
204
222
  },
205
223
  deriveTrackedResource(filter, source) {
206
224
  return (0, github_1.deriveGithubTrackedResource)(filter, source);
@@ -323,6 +341,7 @@ const GITHUB_REPO_CI_MODULE = {
323
341
  { name: "conclusion", type: "string|null", description: "Workflow run conclusion when completed." },
324
342
  { name: "event", type: "string|null", description: "GitHub trigger event for the workflow run." },
325
343
  { name: "headBranch", type: "string|null", description: "Head branch for the workflow run." },
344
+ { name: "headRepositoryFullName", type: "string|null", description: "Head repository full name for the workflow run when available." },
326
345
  { name: "headSha", type: "string|null", description: "Head commit SHA for the workflow run." },
327
346
  { name: "pullRequestNumbers", type: "number[]", description: "Pull request numbers associated with the workflow run." },
328
347
  { name: "actor", type: "string|null", description: "Actor login for the workflow run." },
package/dist/src/store.js CHANGED
@@ -1327,8 +1327,8 @@ class AgentInboxStore {
1327
1327
  this.db.run(`
1328
1328
  insert into activations (
1329
1329
  activation_id, kind, agent_id, inbox_id, target_id, target_kind,
1330
- subscription_ids_json, source_ids_json, new_item_count, summary, items_json, created_at, delivered_at
1331
- ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1330
+ subscription_ids_json, source_ids_json, latest_entry_id, new_entry_count, new_item_count, summary, items_json, created_at, delivered_at
1331
+ ) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
1332
1332
  `, [
1333
1333
  activation.activationId,
1334
1334
  activation.kind,
@@ -1338,6 +1338,8 @@ class AgentInboxStore {
1338
1338
  activation.targetKind,
1339
1339
  JSON.stringify(activation.subscriptionIds),
1340
1340
  JSON.stringify(activation.sourceIds),
1341
+ activation.latestEntryId,
1342
+ activation.newEntryCount,
1341
1343
  activation.newItemCount,
1342
1344
  activation.summary,
1343
1345
  activation.entries ? JSON.stringify(activation.entries) : (activation.items ? JSON.stringify(activation.items) : null),
@@ -1868,6 +1870,7 @@ class AgentInboxStore {
1868
1870
  };
1869
1871
  }
1870
1872
  mapActivation(row) {
1873
+ const entries = row.items_json ? parseJson(row.items_json) : undefined;
1871
1874
  return {
1872
1875
  kind: "agentinbox.activation",
1873
1876
  activationId: String(row.activation_id),
@@ -1877,10 +1880,11 @@ class AgentInboxStore {
1877
1880
  targetKind: row.target_kind,
1878
1881
  subscriptionIds: parseJson(row.subscription_ids_json),
1879
1882
  sourceIds: parseJson(row.source_ids_json),
1880
- newEntryCount: row.items_json ? parseJson(row.items_json)?.length ?? 0 : Number(row.new_item_count),
1883
+ latestEntryId: row.latest_entry_id == null ? null : String(row.latest_entry_id),
1884
+ newEntryCount: Number(row.new_entry_count ?? (entries?.length ?? row.new_item_count ?? 0)),
1881
1885
  newItemCount: Number(row.new_item_count),
1882
1886
  summary: String(row.summary),
1883
- entries: row.items_json ? parseJson(row.items_json) : undefined,
1887
+ entries,
1884
1888
  createdAt: String(row.created_at),
1885
1889
  deliveredAt: row.delivered_at ? String(row.delivered_at) : null,
1886
1890
  };
@@ -73,14 +73,15 @@ function renderAgentPrompt(input) {
73
73
  const totalUnackedCount = input.totalUnackedCount;
74
74
  const itemWord = totalUnackedCount === 1 ? "item" : "items";
75
75
  const base = `AgentInbox: ${totalUnackedCount} unacked ${itemWord} in inbox ${input.inboxId}.`;
76
+ const latestEntryIdSuffix = input.latestEntryId ? ` Latest entryId: ${input.latestEntryId}.` : "";
76
77
  if (totalUnackedCount === 1 && input.preview) {
77
78
  const suffix = /(?:[.!?…]|\.{3})$/.test(input.preview) ? "" : ".";
78
- return `${base} Preview: ${input.preview}${suffix} Read the inbox for full details if needed.`;
79
+ return `${base}${latestEntryIdSuffix} Preview: ${input.preview}${suffix} Read the inbox for full details if needed.`;
79
80
  }
80
81
  if (input.summary) {
81
- return `${base} Summary: ${input.summary}. Please read the inbox, process them, and ack when finished.`;
82
+ return `${base}${latestEntryIdSuffix} Summary: ${input.summary}. Please read the inbox, process them, and ack when finished.`;
82
83
  }
83
- return `${base} Please read the inbox, process them, and ack when finished.`;
84
+ return `${base}${latestEntryIdSuffix} Please read the inbox, process them, and ack when finished.`;
84
85
  }
85
86
  const MAX_INLINE_PREVIEW_INPUT_CHARS = 240;
86
87
  const MAX_INLINE_PREVIEW_CHARS = 96;
@@ -0,0 +1,11 @@
1
+ alter table activations add column latest_entry_id text;
2
+ alter table activations add column new_entry_count integer not null default 0;
3
+
4
+ update activations
5
+ set latest_entry_id = (
6
+ select json_extract(items_json, '$[#-1].entryId')
7
+ ),
8
+ new_entry_count = case
9
+ when items_json is not null then json_array_length(items_json)
10
+ else new_item_count
11
+ end;
package/drizzle/schema.ts CHANGED
@@ -259,6 +259,8 @@ export const activations = sqliteTable("activations", {
259
259
  targetKind: text("target_kind").notNull(),
260
260
  subscriptionIdsJson: text("subscription_ids_json").notNull(),
261
261
  sourceIdsJson: text("source_ids_json").notNull(),
262
+ latestEntryId: text("latest_entry_id"),
263
+ newEntryCount: integer("new_entry_count").notNull(),
262
264
  newItemCount: integer("new_item_count").notNull(),
263
265
  summary: text("summary").notNull(),
264
266
  itemsJson: text("items_json"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holon-run/agentinbox",
3
- "version": "1.0.0-beta.3",
3
+ "version": "1.0.0-beta.5",
4
4
  "description": "Local event subscription and delivery service for agents.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@fastify/swagger": "^9.5.2",
46
- "@holon-run/uxc-daemon-client": "^0.15.0",
46
+ "@holon-run/uxc-daemon-client": "^0.15.3",
47
47
  "fastify": "^5.6.1",
48
48
  "jexl": "^2.3.0",
49
49
  "sql.js": "^1.13.0"