@opengeni/core 0.28.1 → 1.0.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 (224) hide show
  1. package/README.md +1 -1
  2. package/dist/access/external-actor-authority.d.ts +47 -0
  3. package/dist/access/index.d.ts +182 -3
  4. package/dist/access/service-initiator.d.ts +3 -0
  5. package/dist/application/api-integration-servers.d.ts +20 -0
  6. package/dist/application/archived-session-imports.d.ts +6 -0
  7. package/dist/application/composer-submit.d.ts +24 -0
  8. package/dist/application/connect-authority.d.ts +13 -0
  9. package/dist/application/connect-operation.d.ts +31 -0
  10. package/dist/application/external-continuation.d.ts +15 -0
  11. package/dist/application/external-identity-lifecycle.d.ts +20 -0
  12. package/dist/application/external-link-work-admission.d.ts +12 -0
  13. package/dist/application/external-workspace-members.d.ts +34 -0
  14. package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
  15. package/dist/application/new-session-drafts.d.ts +39 -2
  16. package/dist/application/sandbox-recovery.d.ts +58 -0
  17. package/dist/application/session-commands.d.ts +26 -13
  18. package/dist/application/session-mcp-credential-rotation.d.ts +29 -0
  19. package/dist/application/session-tenancy.d.ts +19 -0
  20. package/dist/application/user-resource-grants.d.ts +20 -0
  21. package/dist/billing/limits.d.ts +11 -0
  22. package/dist/canonical-human-identities.d.ts +7 -2
  23. package/dist/canonical-human-identities.js +17 -4
  24. package/dist/canonical-human-identities.js.map +1 -1
  25. package/dist/{chunk-6WKPWE5S.js → chunk-2MKMRGSY.js} +108 -24
  26. package/dist/chunk-2MKMRGSY.js.map +1 -0
  27. package/dist/{chunk-NYPMQ7NO.js → chunk-GVO3N37G.js} +205 -37
  28. package/dist/chunk-GVO3N37G.js.map +1 -0
  29. package/dist/{chunk-JJU6I5XD.js → chunk-LCQXNR62.js} +36 -10
  30. package/dist/chunk-LCQXNR62.js.map +1 -0
  31. package/dist/chunk-MM6N7CTO.js +387 -0
  32. package/dist/chunk-MM6N7CTO.js.map +1 -0
  33. package/dist/chunk-QO5GVFFO.js +235 -0
  34. package/dist/chunk-QO5GVFFO.js.map +1 -0
  35. package/dist/codex-model-availability.d.ts +14 -0
  36. package/dist/default-session-model.d.ts +139 -0
  37. package/dist/dependencies.d.ts +87 -4
  38. package/dist/developer-setup-credential-ceiling.d.ts +10 -0
  39. package/dist/domain/agent-config-resolution.d.ts +49 -0
  40. package/dist/domain/automations.d.ts +58 -0
  41. package/dist/domain/capabilities.d.ts +22 -4
  42. package/dist/domain/company-profile-agent-admin.d.ts +25 -0
  43. package/dist/domain/connection-account-selection-error.d.ts +8 -0
  44. package/dist/domain/connector-tool-permissions.d.ts +36 -0
  45. package/dist/domain/direct-model-provider.d.ts +3 -0
  46. package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
  47. package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
  48. package/dist/domain/editable-artifacts/ports.d.ts +10 -0
  49. package/dist/domain/editable-artifacts/service.d.ts +4 -3
  50. package/dist/domain/environments.d.ts +5 -9
  51. package/dist/domain/external-creation-attribution.d.ts +6 -0
  52. package/dist/domain/file-owner.d.ts +8 -0
  53. package/dist/domain/github-action-policies.d.ts +36 -0
  54. package/dist/domain/github-repository-bindings.d.ts +117 -0
  55. package/dist/domain/github-skill-source.d.ts +5 -0
  56. package/dist/domain/governed-learning-slack-publication.d.ts +45 -0
  57. package/dist/domain/insights-timing.d.ts +16 -0
  58. package/dist/domain/insights-usage.d.ts +27 -0
  59. package/dist/domain/insights.d.ts +28 -1
  60. package/dist/domain/knowledge-files.d.ts +20 -0
  61. package/dist/domain/knowledge-messages.d.ts +39 -0
  62. package/dist/domain/knowledge-messages.test.d.ts +1 -0
  63. package/dist/domain/knowledge-preparation.d.ts +10 -0
  64. package/dist/domain/knowledge-preparation.test.d.ts +1 -0
  65. package/dist/domain/knowledge-search.d.ts +15 -0
  66. package/dist/domain/knowledge-search.test.d.ts +1 -0
  67. package/dist/domain/knowledge.d.ts +9 -0
  68. package/dist/domain/mcp-account-bindings.d.ts +19 -0
  69. package/dist/domain/mcp-account-routes.d.ts +21 -0
  70. package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
  71. package/dist/domain/organization-integration-catalog.d.ts +15 -0
  72. package/dist/domain/organization-membership-lifecycle.d.ts +1 -0
  73. package/dist/domain/personal-connection-delegations.d.ts +87 -4
  74. package/dist/domain/pr-review.d.ts +249 -0
  75. package/dist/domain/resources.d.ts +24 -3
  76. package/dist/domain/scheduled-task-access.d.ts +247 -0
  77. package/dist/domain/scheduled-tasks.d.ts +103 -6
  78. package/dist/domain/session-connection-accounts.d.ts +16 -0
  79. package/dist/domain/session-file-access.d.ts +4 -0
  80. package/dist/domain/session-native-connection-replacement.d.ts +14 -0
  81. package/dist/domain/session-start-timing.d.ts +7 -0
  82. package/dist/domain/session-tool-policy.d.ts +93 -4
  83. package/dist/domain/sessions.d.ts +275 -28
  84. package/dist/domain/skill-imports.d.ts +1 -0
  85. package/dist/domain/skill-search.d.ts +30 -0
  86. package/dist/domain/skills.d.ts +117 -0
  87. package/dist/domain/slack-bot.d.ts +46 -1
  88. package/dist/domain/workspace-members.d.ts +8 -1
  89. package/dist/editable-artifact-live/application.d.ts +12 -3
  90. package/dist/editable-artifact-live/ports.d.ts +0 -1
  91. package/dist/editable-artifact-live/server.d.ts +5 -2
  92. package/dist/editable-artifact-live/ticket.d.ts +2 -2
  93. package/dist/editable-artifact-live/types.d.ts +14 -2
  94. package/dist/editable-artifact-live.js +2 -2
  95. package/dist/editable-artifacts.js +10 -4
  96. package/dist/index.d.ts +49 -3
  97. package/dist/index.js +18812 -6833
  98. package/dist/index.js.map +1 -1
  99. package/dist/managed-auth-session-sets.d.ts +131 -0
  100. package/dist/managed-auth-session-sets.js +51 -0
  101. package/dist/managed-auth-session-sets.js.map +1 -0
  102. package/dist/managed-session.d.ts +98 -11
  103. package/dist/model-catalog.d.ts +117 -0
  104. package/dist/product-usage-metrics.d.ts +30 -0
  105. package/dist/rigs/index.d.ts +22 -5
  106. package/dist/rigs/provider-images.d.ts +1 -1
  107. package/dist/sandbox/fleet.d.ts +59 -10
  108. package/dist/sandbox/routing.d.ts +22 -2
  109. package/dist/sandbox/runtime-settings.d.ts +56 -0
  110. package/dist/session-authorization.d.ts +38 -1
  111. package/dist/site-session-origin.d.ts +9 -0
  112. package/dist/transcription.d.ts +12 -1
  113. package/dist/turn-surface.d.ts +18 -0
  114. package/dist/user-presence.d.ts +32 -0
  115. package/package.json +18 -11
  116. package/src/access/external-actor-authority.ts +94 -0
  117. package/src/access/index.ts +1386 -44
  118. package/src/access/service-initiator.ts +50 -0
  119. package/src/application/api-integration-servers.ts +215 -0
  120. package/src/application/archived-session-imports.ts +161 -0
  121. package/src/application/composer-submit.ts +77 -0
  122. package/src/application/connect-authority.ts +77 -0
  123. package/src/application/connect-operation.ts +80 -0
  124. package/src/application/external-continuation.ts +129 -0
  125. package/src/application/external-identity-lifecycle.ts +48 -0
  126. package/src/application/external-link-work-admission.ts +90 -0
  127. package/src/application/external-workspace-members.ts +232 -0
  128. package/src/application/modal-native-worker-host-transport.ts +263 -0
  129. package/src/application/new-session-drafts.ts +222 -29
  130. package/src/application/sandbox-recovery.ts +78 -0
  131. package/src/application/session-commands.ts +430 -73
  132. package/src/application/session-mcp-credential-rotation.ts +217 -0
  133. package/src/application/session-tenancy.ts +445 -0
  134. package/src/application/user-resource-grants.ts +154 -0
  135. package/src/billing/limits.ts +103 -24
  136. package/src/canonical-human-identities.ts +22 -3
  137. package/src/codex-model-availability.ts +136 -0
  138. package/src/default-session-model.ts +656 -0
  139. package/src/dependencies.ts +97 -5
  140. package/src/developer-setup-credential-ceiling.ts +60 -0
  141. package/src/domain/agent-config-resolution.ts +148 -0
  142. package/src/domain/automations.ts +270 -0
  143. package/src/domain/capabilities.ts +244 -151
  144. package/src/domain/company-profile-agent-admin.ts +56 -0
  145. package/src/domain/connection-account-selection-error.ts +19 -0
  146. package/src/domain/connector-tool-permissions.ts +371 -0
  147. package/src/domain/direct-model-provider.ts +62 -0
  148. package/src/domain/editable-artifacts/agent-application.ts +61 -15
  149. package/src/domain/editable-artifacts/durable-export.ts +100 -5
  150. package/src/domain/editable-artifacts/in-memory.ts +6 -0
  151. package/src/domain/editable-artifacts/ports.ts +11 -0
  152. package/src/domain/editable-artifacts/service.ts +32 -1
  153. package/src/domain/editable-artifacts/snapshot-compaction.ts +9 -5
  154. package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +10 -8
  155. package/src/domain/editable-artifacts/snapshot-verifier.ts +10 -3
  156. package/src/domain/environments.ts +25 -45
  157. package/src/domain/external-creation-attribution.ts +22 -0
  158. package/src/domain/file-owner.ts +67 -0
  159. package/src/domain/github-action-policies.ts +169 -0
  160. package/src/domain/github-repository-bindings.ts +295 -0
  161. package/src/domain/github-skill-source.ts +233 -0
  162. package/src/domain/governed-learning-slack-publication.ts +157 -0
  163. package/src/domain/insights-timing.ts +95 -0
  164. package/src/domain/insights-usage.ts +67 -0
  165. package/src/domain/insights.ts +270 -169
  166. package/src/domain/knowledge-files.ts +46 -0
  167. package/src/domain/knowledge-messages.test.ts +91 -0
  168. package/src/domain/knowledge-messages.ts +106 -0
  169. package/src/domain/knowledge-preparation.test.ts +276 -0
  170. package/src/domain/knowledge-preparation.ts +147 -0
  171. package/src/domain/knowledge-search.test.ts +561 -0
  172. package/src/domain/knowledge-search.ts +256 -0
  173. package/src/domain/knowledge.ts +133 -0
  174. package/src/domain/mcp-account-bindings.ts +171 -0
  175. package/src/domain/mcp-account-routes.ts +121 -0
  176. package/src/domain/native-mcp-connection-admission.ts +14 -0
  177. package/src/domain/organization-integration-catalog.ts +88 -0
  178. package/src/domain/organization-membership-lifecycle.ts +10 -0
  179. package/src/domain/personal-connection-delegations.ts +758 -115
  180. package/src/domain/pr-review.ts +687 -0
  181. package/src/domain/resources.ts +182 -25
  182. package/src/domain/scheduled-task-access.ts +1052 -0
  183. package/src/domain/scheduled-tasks.ts +1952 -215
  184. package/src/domain/session-connection-accounts.ts +67 -0
  185. package/src/domain/session-file-access.ts +47 -0
  186. package/src/domain/session-native-connection-replacement.ts +64 -0
  187. package/src/domain/session-start-timing.ts +55 -0
  188. package/src/domain/session-tool-policy.ts +443 -19
  189. package/src/domain/sessions.ts +3417 -619
  190. package/src/domain/skill-imports.ts +137 -17
  191. package/src/domain/skill-search.ts +221 -0
  192. package/src/domain/skills.ts +104 -0
  193. package/src/domain/slack-bot.ts +128 -3
  194. package/src/domain/workspace-members.ts +34 -2
  195. package/src/editable-artifact-live/application.ts +29 -4
  196. package/src/editable-artifact-live/ports.ts +0 -1
  197. package/src/editable-artifact-live/server.ts +167 -13
  198. package/src/editable-artifact-live/ticket.ts +87 -6
  199. package/src/editable-artifact-live/types.ts +16 -2
  200. package/src/editable-artifact-live/wire.ts +0 -10
  201. package/src/index.ts +69 -4
  202. package/src/managed-auth-session-sets.ts +371 -0
  203. package/src/managed-session.ts +520 -2
  204. package/src/model-catalog.ts +873 -0
  205. package/src/product-usage-metrics.ts +101 -0
  206. package/src/rigs/index.ts +179 -63
  207. package/src/rigs/provider-images.ts +2 -3
  208. package/src/sandbox/fleet.ts +471 -59
  209. package/src/sandbox/routing.ts +160 -33
  210. package/src/sandbox/runtime-settings.ts +281 -0
  211. package/src/session-authorization.ts +262 -78
  212. package/src/site-session-origin.ts +22 -0
  213. package/src/transcription.ts +13 -1
  214. package/src/turn-surface.ts +45 -0
  215. package/src/user-presence.ts +134 -0
  216. package/dist/chunk-6WKPWE5S.js.map +0 -1
  217. package/dist/chunk-IBOEYG6N.js +0 -34
  218. package/dist/chunk-IBOEYG6N.js.map +0 -1
  219. package/dist/chunk-JJU6I5XD.js.map +0 -1
  220. package/dist/chunk-NYPMQ7NO.js.map +0 -1
  221. package/dist/domain/durable-learning-slack-publication.d.ts +0 -72
  222. package/dist/domain/packs.d.ts +0 -55
  223. package/src/domain/durable-learning-slack-publication.ts +0 -202
  224. package/src/domain/packs.ts +0 -556
@@ -1,556 +0,0 @@
1
- import { createHash } from "node:crypto";
2
-
3
- import {
4
- CapabilityPack,
5
- stableJson,
6
- type CapabilityPackSkill,
7
- type PackComponentResolution,
8
- type PackInstallationPreview,
9
- type PackRigResolution,
10
- type ScheduledTaskAgentConfig,
11
- type SocialConnection,
12
- } from "@opengeni/contracts";
13
- import {
14
- getPackInstallation,
15
- getRig,
16
- getVariableSet,
17
- getWorkspacePack,
18
- listPackInstallations,
19
- listWorkspacePacks,
20
- resolvePackComponentReferences,
21
- resolvePackInlineSkillReferences,
22
- type Database,
23
- } from "@opengeni/db";
24
- import { buildPortableSkillArtifact } from "@opengeni/runtime/skill-library";
25
- import { HTTPException } from "hono/http-exception";
26
-
27
- export const MARKETING_SOCIAL_PACK_ID = "marketing-social-daily-analysis";
28
-
29
- const marketingSocialPack: CapabilityPack = {
30
- id: MARKETING_SOCIAL_PACK_ID,
31
- name: "Marketing social daily analysis",
32
- description:
33
- "Connect social accounts, attach marketing knowledge, and schedule agents to produce daily media performance analysis.",
34
- role: "marketing",
35
- category: "social-media",
36
- version: "0.1.0",
37
- // Built-in packs deliberately declare no sandboxImage and no skills: the
38
- // worker's pack-runtime resolution only reads manifest-registered packs
39
- // (see apps/worker/src/activities/packs.ts), and a test enforces this.
40
- skills: [],
41
- components: [],
42
- tools: [
43
- { kind: "mcp", id: "opengeni" },
44
- { kind: "mcp", id: "docs" },
45
- ],
46
- connectors: [
47
- {
48
- id: "x",
49
- name: "X",
50
- category: "social-media",
51
- authModel: "oauth2_authorization_code_pkce",
52
- providers: ["x"],
53
- scopes: ["tweet.read", "tweet.write", "users.read", "offline.access"],
54
- required: false,
55
- metadata: {
56
- docs: "https://docs.x.com/fundamentals/authentication/oauth-2-0/authorization-code",
57
- firstParty: true,
58
- oauthStartPath: "/social/oauth/start",
59
- },
60
- },
61
- {
62
- id: "reddit",
63
- name: "Reddit",
64
- category: "social-media",
65
- authModel: "oauth2_authorization_code",
66
- providers: ["reddit"],
67
- scopes: ["identity", "read", "submit", "privatemessages", "history"],
68
- required: false,
69
- metadata: {
70
- docs: "https://github.com/reddit-archive/reddit/wiki/OAuth2",
71
- firstParty: true,
72
- oauthStartPath: "/social/oauth/start",
73
- },
74
- },
75
- {
76
- id: "linkedin",
77
- name: "LinkedIn",
78
- category: "social-media",
79
- authModel: "oauth2_authorization_code",
80
- providers: ["linkedin"],
81
- scopes: ["r_organization_social", "rw_organization_admin"],
82
- required: false,
83
- metadata: {
84
- docs: "https://learn.microsoft.com/en-us/linkedin/marketing/community-management/community-management-overview",
85
- },
86
- },
87
- {
88
- id: "instagram",
89
- name: "Instagram",
90
- category: "social-media",
91
- authModel: "oauth2_authorization_code",
92
- providers: ["instagram", "facebook"],
93
- scopes: [
94
- "instagram_basic",
95
- "instagram_manage_insights",
96
- "pages_read_engagement",
97
- "pages_show_list",
98
- ],
99
- required: false,
100
- metadata: {
101
- docs: "https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/",
102
- },
103
- },
104
- {
105
- id: "tiktok",
106
- name: "TikTok",
107
- category: "social-media",
108
- authModel: "oauth2_authorization_code",
109
- providers: ["tiktok"],
110
- scopes: ["user.info.basic", "video.list"],
111
- required: false,
112
- metadata: {
113
- docs: "https://developers.tiktok.com/doc/tiktok-api-v2-introduction/",
114
- },
115
- },
116
- {
117
- id: "youtube",
118
- name: "YouTube",
119
- category: "social-media",
120
- authModel: "oauth2_authorization_code",
121
- providers: ["youtube"],
122
- scopes: [
123
- "https://www.googleapis.com/auth/youtube.readonly",
124
- "https://www.googleapis.com/auth/yt-analytics.readonly",
125
- ],
126
- required: false,
127
- metadata: {
128
- docs: "https://developers.google.com/youtube/v3",
129
- },
130
- },
131
- ],
132
- knowledge: [
133
- {
134
- type: "document_base",
135
- id: "marketing-playbook",
136
- name: "Marketing playbook",
137
- description:
138
- "Optional workspace document base with brand voice, campaign calendars, audience research, and reporting rules.",
139
- required: false,
140
- },
141
- ],
142
- scheduledTaskTemplates: [
143
- {
144
- id: "daily-social-analysis",
145
- name: "Daily social analysis",
146
- description: "Review the latest social posts and account signals every day.",
147
- defaultSchedule: {
148
- type: "calendar",
149
- timeZone: "UTC",
150
- hour: 9,
151
- minute: 0,
152
- },
153
- defaultRunMode: "new_session_per_run",
154
- defaultOverlapPolicy: "skip",
155
- },
156
- ],
157
- metadata: {
158
- skill: "social-media-marketing",
159
- firstPartyMcpTools: [
160
- "social_connections_list",
161
- "social_posts_recent",
162
- "social_daily_analysis_context",
163
- "x_accounts_list",
164
- "x_search_live",
165
- "x_mentions_live",
166
- "x_thread_fetch",
167
- "x_posts_sync",
168
- "x_post_reply",
169
- "reddit_accounts_list",
170
- "reddit_search_live",
171
- "reddit_mentions_live",
172
- "reddit_thread_fetch",
173
- "reddit_posts_sync",
174
- "reddit_post_reply",
175
- ],
176
- },
177
- };
178
-
179
- const packs = [marketingSocialPack] satisfies CapabilityPack[];
180
-
181
- export function listCapabilityPacks(): CapabilityPack[] {
182
- return packs;
183
- }
184
-
185
- export function getCapabilityPack(packId: string): CapabilityPack | null {
186
- return packs.find((pack) => pack.id === packId) ?? null;
187
- }
188
-
189
- export function isBuiltInCapabilityPack(packId: string): boolean {
190
- return getCapabilityPack(packId) !== null;
191
- }
192
-
193
- /**
194
- * Built-in packs plus the manifests registered for this workspace. Stored
195
- * manifests were validated at registration time; rows that no longer parse
196
- * (for example after a contract tightening) are skipped instead of breaking
197
- * the whole catalog.
198
- */
199
- export async function listWorkspaceCapabilityPacks(
200
- db: Database,
201
- workspaceId: string,
202
- ): Promise<CapabilityPack[]> {
203
- const registered = await listWorkspacePacks(db, workspaceId);
204
- const builtInIds = new Set(packs.map((pack) => pack.id));
205
- const registeredPacks = registered
206
- .filter((registration) => !builtInIds.has(registration.pack.id))
207
- .flatMap((registration) => {
208
- const parsed = CapabilityPack.safeParse(registration.pack);
209
- return parsed.success ? [parsed.data] : [];
210
- });
211
- return [...packs, ...registeredPacks];
212
- }
213
-
214
- export async function resolveCapabilityPack(
215
- db: Database,
216
- workspaceId: string,
217
- packId: string,
218
- ): Promise<CapabilityPack | null> {
219
- const builtIn = getCapabilityPack(packId);
220
- if (builtIn) {
221
- return builtIn;
222
- }
223
- const registration = await getWorkspacePack(db, workspaceId, packId);
224
- if (!registration) {
225
- return null;
226
- }
227
- const parsed = CapabilityPack.safeParse(registration.pack);
228
- return parsed.success ? parsed.data : null;
229
- }
230
-
231
- export function capabilityPackManifestDigest(pack: CapabilityPack): string {
232
- return createHash("sha256").update(stableJson(pack)).digest("hex");
233
- }
234
-
235
- /** True when the Pack must use the owner-aware V2 preview/install lifecycle. */
236
- export function capabilityPackRequiresInstallationPlan(pack: CapabilityPack): boolean {
237
- return (
238
- pack.components.length > 0 ||
239
- pack.skills.length > 0 ||
240
- pack.rig !== undefined ||
241
- pack.sandboxImage !== undefined ||
242
- pack.sandboxProviderImages !== undefined
243
- );
244
- }
245
-
246
- export type InlinePackSkillInstall = {
247
- componentKey: string;
248
- capabilityId: string;
249
- pluginKey: string;
250
- sourceUrl: string;
251
- repositoryUrl: string;
252
- sourceCommit: string;
253
- sourcePath: string;
254
- name: string;
255
- description: string;
256
- contentSha256: string;
257
- totalBytes: number;
258
- files: Array<{ path: string; content: string; byteSize: number; contentSha256: string }>;
259
- };
260
-
261
- /** Convert a legacy inline Pack Skill into the ordinary immutable Skill model. */
262
- export function inlinePackSkillInstall(
263
- pack: CapabilityPack,
264
- skill: CapabilityPackSkill,
265
- ): InlinePackSkillInstall {
266
- const artifact = buildPortableSkillArtifact(skill.files);
267
- if (artifact.name.toLowerCase() !== skill.name.toLowerCase()) {
268
- throw new HTTPException(422, {
269
- message: `Pack Skill ${skill.name} has SKILL.md name ${artifact.name}; the names must match`,
270
- });
271
- }
272
- const normalizedName = skill.name.toLowerCase();
273
- const encodedSkill = encodeURIComponent(normalizedName);
274
- const sourceUrl = `https://opengeni.invalid/pack-inline-skills/${encodedSkill}/${artifact.contentSha256}`;
275
- const capabilityId = `skill:pack-inline/${normalizedName}@${artifact.contentSha256}`;
276
- return {
277
- componentKey: `inline-skill/${normalizedName}`,
278
- capabilityId,
279
- pluginKey: `pack-skill/${normalizedName}/${artifact.contentSha256}`,
280
- sourceUrl,
281
- repositoryUrl: "https://opengeni.invalid/pack-inline-skills",
282
- sourceCommit: artifact.contentSha256,
283
- sourcePath: normalizedName,
284
- name: artifact.name,
285
- description: artifact.description,
286
- contentSha256: artifact.contentSha256,
287
- totalBytes: artifact.totalBytes,
288
- files: artifact.files.map((file) => ({
289
- path: file.path,
290
- content: file.content,
291
- byteSize: new TextEncoder().encode(file.content).byteLength,
292
- contentSha256: createHash("sha256").update(file.content).digest("hex"),
293
- })),
294
- };
295
- }
296
-
297
- export async function previewCapabilityPackInstallation(
298
- db: Database,
299
- workspaceId: string,
300
- pack: CapabilityPack,
301
- options: { rigId?: string; variableSetId?: string } = {},
302
- ): Promise<PackInstallationPreview> {
303
- const installation = await getPackInstallation(db, workspaceId, pack.id);
304
- const inlineInstalls = pack.skills.map((skill) => inlinePackSkillInstall(pack, skill));
305
- const [referencedComponents, inlineComponents] = await Promise.all([
306
- resolvePackComponentReferences(db, workspaceId, pack.components),
307
- resolvePackInlineSkillReferences(
308
- db,
309
- workspaceId,
310
- inlineInstalls.map((inline) => ({
311
- key: inline.componentKey,
312
- capabilityId: inline.capabilityId,
313
- name: inline.name,
314
- contentSha256: inline.contentSha256,
315
- })),
316
- installation?.id,
317
- ),
318
- ]);
319
- const manifestDigest = capabilityPackManifestDigest(pack);
320
- const components: PackComponentResolution[] = [...referencedComponents, ...inlineComponents];
321
- const blockers = components
322
- .filter((component) => component.required && component.status !== "ready")
323
- .map((component) =>
324
- component.status === "missing"
325
- ? `${component.label} is not installed in this workspace`
326
- : `${component.label} does not match the Pack's pinned version`,
327
- );
328
- const rig = await resolvePackRig(
329
- db,
330
- workspaceId,
331
- pack,
332
- options.rigId,
333
- installation?.selectedRigId,
334
- );
335
- if (
336
- rig.status !== "ready" &&
337
- rig.status !== "not_required" &&
338
- (rig.required || rig.requestedRigId !== null || rig.rigId !== null)
339
- ) {
340
- blockers.push(packRigBlocker(rig, pack.sandboxImage ?? null));
341
- }
342
- const variableSetId =
343
- options.variableSetId ?? storedVariableSetId(installation?.metadata) ?? null;
344
- if (pack.variableSet?.required && !variableSetId) {
345
- blockers.push("Choose saved configuration before installing this Pack");
346
- } else if (variableSetId) {
347
- const variableSet = await getVariableSet(db, workspaceId, variableSetId);
348
- if (!variableSet) {
349
- blockers.push("The selected configuration no longer exists in this workspace");
350
- } else {
351
- const missing = (pack.variableSet?.requiredVariables ?? []).filter(
352
- (name) => !variableSet.variables.some((variable) => variable.name === name),
353
- );
354
- if (missing.length > 0) {
355
- blockers.push(`Configuration is missing required value(s): ${missing.join(", ")}`);
356
- }
357
- }
358
- }
359
- const action =
360
- !installation || installation.status === "disabled"
361
- ? "install"
362
- : installation.manifestDigest === manifestDigest
363
- ? "repair"
364
- : "update";
365
- return {
366
- packId: pack.id,
367
- packVersion: pack.version,
368
- manifestDigest,
369
- installationVersion: installation?.version ?? null,
370
- action,
371
- ready: blockers.length === 0,
372
- blockers,
373
- components,
374
- rig,
375
- variableSetId,
376
- legacyInlineSkillCount: pack.skills.length,
377
- legacySandboxImage: pack.sandboxImage ?? null,
378
- };
379
- }
380
-
381
- async function resolvePackRig(
382
- db: Database,
383
- workspaceId: string,
384
- pack: CapabilityPack,
385
- requestedRigId: string | undefined,
386
- storedRigId: string | null | undefined,
387
- ): Promise<PackRigResolution> {
388
- const required = pack.rig?.required === true || Boolean(pack.sandboxImage);
389
- const selectedRigId = pack.rig?.rigId ?? requestedRigId ?? storedRigId ?? null;
390
- if (!required && !selectedRigId) {
391
- return {
392
- required: false,
393
- status: "not_required",
394
- requestedRigId: requestedRigId ?? null,
395
- rigId: null,
396
- rigVersionId: null,
397
- name: null,
398
- image: null,
399
- };
400
- }
401
- if (pack.rig?.rigId && requestedRigId && pack.rig.rigId !== requestedRigId) {
402
- return {
403
- required,
404
- status: "mismatch",
405
- requestedRigId,
406
- rigId: pack.rig.rigId,
407
- rigVersionId: null,
408
- name: null,
409
- image: null,
410
- };
411
- }
412
- if (!selectedRigId) {
413
- return {
414
- required,
415
- status: "missing",
416
- requestedRigId: requestedRigId ?? null,
417
- rigId: null,
418
- rigVersionId: null,
419
- name: null,
420
- image: null,
421
- };
422
- }
423
- const rig = await getRig(db, workspaceId, selectedRigId);
424
- if (!rig?.activeVersion) {
425
- return {
426
- required,
427
- status: "missing",
428
- requestedRigId: requestedRigId ?? null,
429
- rigId: selectedRigId,
430
- rigVersionId: null,
431
- name: rig?.name ?? null,
432
- image: null,
433
- };
434
- }
435
- const image = rig.activeVersion.image ?? null;
436
- const status =
437
- pack.sandboxImage && image !== pack.sandboxImage
438
- ? "mismatch"
439
- : pack.rig?.requireVerified && rig.activeVersionHealth?.checkHealth !== "passing"
440
- ? "unverified"
441
- : "ready";
442
- return {
443
- required,
444
- status,
445
- requestedRigId: requestedRigId ?? null,
446
- rigId: rig.id,
447
- rigVersionId: rig.activeVersion.id,
448
- name: rig.name,
449
- image,
450
- };
451
- }
452
-
453
- function packRigBlocker(rig: PackRigResolution, legacyImage: string | null): string {
454
- if (rig.status === "missing") {
455
- return "Choose an available compute environment before installing this Pack";
456
- }
457
- if (rig.status === "unverified") {
458
- return "Verify the selected compute environment before installing this Pack";
459
- }
460
- if (legacyImage) {
461
- return `The selected compute environment must use the Pack's previous image ${legacyImage}; the Pack will not replace workspace compute`;
462
- }
463
- return "The selected compute environment does not satisfy this Pack's requirement";
464
- }
465
-
466
- function storedVariableSetId(metadata: Record<string, unknown> | undefined): string | null {
467
- const value = metadata?.variableSetId ?? metadata?.environmentId;
468
- return typeof value === "string" && value.length > 0 ? value : null;
469
- }
470
-
471
- /**
472
- * v1 pack-scoped runtime rule: at most one enabled pack per workspace may
473
- * declare a `sandboxImage` — there is deliberately no image composition or
474
- * layering. Enforced when a pack is enabled (both the packs endpoint and the
475
- * generic capability enable path) and re-checked at session start by the
476
- * worker, which also covers manifests re-registered after enablement.
477
- */
478
- export async function assertPackSandboxImageCompatible(
479
- db: Database,
480
- workspaceId: string,
481
- pack: CapabilityPack,
482
- ): Promise<void> {
483
- if (!pack.sandboxImage) {
484
- return;
485
- }
486
- const installations = await listPackInstallations(db, workspaceId);
487
- for (const installation of installations) {
488
- if (installation.status !== "active" || installation.packId === pack.id) {
489
- continue;
490
- }
491
- const other = await resolveCapabilityPack(db, workspaceId, installation.packId);
492
- if (other?.sandboxImage) {
493
- throw new HTTPException(409, {
494
- message: `pack ${pack.id} declares a sandbox image, but enabled pack ${other.id} already declares one; only one enabled pack per workspace may declare sandboxImage — disable ${other.id} first`,
495
- });
496
- }
497
- }
498
- }
499
-
500
- export function buildMarketingDailyAnalysisAgentConfig(input: {
501
- connections: SocialConnection[];
502
- documentBaseIds: string[];
503
- promptInstructions?: string;
504
- }): ScheduledTaskAgentConfig {
505
- const connectionIds = input.connections.map((connection) => connection.id);
506
- return {
507
- prompt: marketingDailyAnalysisPrompt({
508
- connections: input.connections,
509
- documentBaseIds: input.documentBaseIds,
510
- ...(input.promptInstructions ? { promptInstructions: input.promptInstructions } : {}),
511
- }),
512
- resources: [],
513
- tools: marketingSocialPack.tools,
514
- metadata: {
515
- packId: MARKETING_SOCIAL_PACK_ID,
516
- packTemplateId: "daily-social-analysis",
517
- socialConnectionIds: connectionIds,
518
- documentBaseIds: input.documentBaseIds,
519
- analysisWindowHours: 24,
520
- },
521
- };
522
- }
523
-
524
- function marketingDailyAnalysisPrompt(input: {
525
- connections: SocialConnection[];
526
- documentBaseIds: string[];
527
- promptInstructions?: string;
528
- }): string {
529
- const connectionLines = input.connections
530
- .map((connection) => {
531
- return `- ${connection.provider}: ${connection.accountHandle} (${connection.id})`;
532
- })
533
- .join("\n");
534
- const knowledgeLine =
535
- input.documentBaseIds.length > 0
536
- ? `Use these document base IDs for brand/campaign knowledge through the docs MCP: ${input.documentBaseIds.join(", ")}.`
537
- : "No document base IDs were selected; rely only on social context returned by tools.";
538
- const extra = input.promptInstructions
539
- ? `\nAdditional operator instructions:\n${input.promptInstructions.trim()}\n`
540
- : "";
541
-
542
- return [
543
- "Run the daily social media analysis for the selected accounts.",
544
- "",
545
- "First call the OpenGeni MCP tool social_daily_analysis_context with the selected connection IDs and a 24 hour analysis window. Use social_posts_recent only if you need a narrower follow-up query.",
546
- knowledgeLine,
547
- "",
548
- "Selected accounts:",
549
- connectionLines,
550
- extra,
551
- "Produce a concise report with these sections: executive summary, notable account changes, winning posts, underperforming posts, audience and content signals, recommended actions for the next 24 hours, and data gaps.",
552
- "Use only metrics and posts returned by tools or document search. Do not invent metrics, posts, or account capabilities.",
553
- ]
554
- .filter(Boolean)
555
- .join("\n");
556
- }