@opengeni/worker-bundle 0.27.0-canary.1 → 0.27.2-canary.1

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 (60) hide show
  1. package/dist/activities/agent-turn/agent-build.d.ts +3 -4
  2. package/dist/activities/agent-turn/governance-model.d.ts +2 -3
  3. package/dist/activities/agent-turn/skill-checkout.d.ts +21 -0
  4. package/dist/activities/agent-turn/skill-install.d.ts +12 -0
  5. package/dist/activities/agent-turn/skill-read.d.ts +15 -0
  6. package/dist/activities/agent-turn/skill-save.d.ts +26 -0
  7. package/dist/activities/agent-turn/skill-search.d.ts +16 -0
  8. package/dist/activities/agent-turn/skill-selection.d.ts +17 -0
  9. package/dist/activities/agent-turn/skill-tools.d.ts +20 -0
  10. package/dist/activities/agent-turn/skill-transfer.d.ts +26 -0
  11. package/dist/activities/agent-turn/tool-environment.d.ts +7 -0
  12. package/dist/activities/parent-wake.d.ts +12 -2
  13. package/dist/activities/run-input.d.ts +11 -5
  14. package/dist/activities/sandbox-lease.d.ts +5 -4
  15. package/dist/activities/types.d.ts +4 -2
  16. package/dist/activities/workflow-wake.d.ts +2 -4
  17. package/dist/{activities-control-VMA3XMHE.js → activities-control-WZRFEIJH.js} +103 -26
  18. package/dist/activities-control-WZRFEIJH.js.map +1 -0
  19. package/dist/{activities-turn-57AOUNYN.js → activities-turn-V7J34ZOF.js} +945 -532
  20. package/dist/activities-turn-V7J34ZOF.js.map +1 -0
  21. package/dist/{chunk-D4ZEFOYH.js → chunk-BARTLVBK.js} +1 -1
  22. package/dist/chunk-BARTLVBK.js.map +1 -0
  23. package/dist/{chunk-7LS42PHP.js → chunk-C54VDT6I.js} +590 -34
  24. package/dist/chunk-C54VDT6I.js.map +1 -0
  25. package/dist/index.js +6 -4
  26. package/dist/index.js.map +1 -1
  27. package/dist/model-context-contributions.d.ts +2 -0
  28. package/dist/observability-metrics.d.ts +1 -1
  29. package/dist/workflow-bundle.js +1 -1
  30. package/package.json +17 -17
  31. package/src/activities/agent-turn/agent-build.ts +8 -34
  32. package/src/activities/agent-turn/errors.ts +4 -0
  33. package/src/activities/agent-turn/governance-model.ts +15 -19
  34. package/src/activities/agent-turn/run.ts +4 -6
  35. package/src/activities/agent-turn/sandbox-provision.ts +9 -0
  36. package/src/activities/agent-turn/skill-checkout.ts +124 -0
  37. package/src/activities/agent-turn/skill-install.ts +57 -0
  38. package/src/activities/agent-turn/skill-read.ts +117 -0
  39. package/src/activities/agent-turn/skill-save.ts +124 -0
  40. package/src/activities/agent-turn/skill-search.ts +110 -0
  41. package/src/activities/agent-turn/skill-selection.ts +53 -0
  42. package/src/activities/agent-turn/skill-tools.ts +268 -0
  43. package/src/activities/agent-turn/skill-transfer.ts +137 -0
  44. package/src/activities/agent-turn/tool-environment.ts +93 -1
  45. package/src/activities/automations.ts +3 -1
  46. package/src/activities/context-compaction.ts +26 -2
  47. package/src/activities/parent-wake.ts +66 -5
  48. package/src/activities/run-input.ts +88 -12
  49. package/src/activities/sandbox-lease.ts +77 -20
  50. package/src/activities/scheduled-tasks.ts +2 -0
  51. package/src/activities/types.ts +4 -2
  52. package/src/activities/workflow-wake.ts +42 -5
  53. package/src/index.ts +3 -1
  54. package/src/model-context-contributions.ts +18 -2
  55. package/src/observability-metrics.ts +2 -0
  56. package/src/sandbox-routing.ts +42 -1
  57. package/dist/activities-control-VMA3XMHE.js.map +0 -1
  58. package/dist/activities-turn-57AOUNYN.js.map +0 -1
  59. package/dist/chunk-7LS42PHP.js.map +0 -1
  60. package/dist/chunk-D4ZEFOYH.js.map +0 -1
@@ -23,6 +23,7 @@ import {
23
23
  compactionFailureReason,
24
24
  compactionFailureReasonFromError,
25
25
  computeIdleDelayMs,
26
+ createModelHistoryAttachmentProjector,
26
27
  createRuntimeBatcher,
27
28
  createSharedActivityServices,
28
29
  createTurnSandboxProvisioner,
@@ -44,6 +45,7 @@ import {
44
45
  persistOrSignalSessionAttemptQuiescence,
45
46
  postClaimDatabaseRecoveryFailure,
46
47
  preClaimAdmissionFailure,
48
+ projectRejectedProviderArtifacts,
47
49
  providerRecoveryCountAfterModelRequestPhase,
48
50
  providerRecoveryCountFromMetadata,
49
51
  providerRecoveryExhaustedFailure,
@@ -53,7 +55,6 @@ import {
53
55
  refreshExhaustedXaiQuota,
54
56
  releaseTurnSandboxAfterWriterDrain,
55
57
  requireAgentStreamFinalOutput,
56
- resolveWorkspaceInstalledSkillRuntime,
57
58
  resolveWorkspacePackRuntime,
58
59
  resumeBoxForTurn,
59
60
  rigProviderImageSourceImage,
@@ -75,6 +76,7 @@ import {
75
76
  startActivityHeartbeat,
76
77
  throwIfTurnOperationCancelled,
77
78
  turnFinalizerCancellationSignal,
79
+ turnInput,
78
80
  turnOperationCancellationFailure,
79
81
  unavailableMcpOperationalContext,
80
82
  validateIncidentTelemetrySystemUpdateAuthority,
@@ -84,7 +86,7 @@ import {
84
86
  withFirstPartyTools,
85
87
  wrapLazyTurnBoxWithRouting,
86
88
  wrapTurnBoxWithRouting
87
- } from "./chunk-7LS42PHP.js";
89
+ } from "./chunk-C54VDT6I.js";
88
90
  import {
89
91
  StreamTimingMetrics,
90
92
  makeMachineOpObserver,
@@ -110,7 +112,7 @@ import {
110
112
  recordTurnWorkerPreparationTotal,
111
113
  runtimeMetricsHooksForObservability,
112
114
  turnLifecycleMetricsFor
113
- } from "./chunk-D4ZEFOYH.js";
115
+ } from "./chunk-BARTLVBK.js";
114
116
 
115
117
  // src/activities-turn.ts
116
118
  import { createProductionAgentRuntime, summarizeForCompaction as summarizeForCompaction2 } from "@opengeni/runtime";
@@ -168,9 +170,6 @@ function summarizeCompanyBrainContributions(receipt) {
168
170
  }
169
171
  return Object.freeze([...bySource.values()].map((summary) => Object.freeze(summary)));
170
172
  }
171
- function modelVisibleCompanyBrainSkillActivations(sandboxBackend, skillActivations) {
172
- return sandboxBackend === "none" ? [] : skillActivations;
173
- }
174
173
  function buildCompanyBrainContributionReceipt(input) {
175
174
  const contributions = [];
176
175
  for (const entry of input.instructionPolicy.entries) {
@@ -195,7 +194,7 @@ function buildCompanyBrainContributionReceipt(input) {
195
194
  })
196
195
  );
197
196
  }
198
- for (const descriptor of input.preferences?.descriptors ?? []) {
197
+ for (const descriptor of input.skillCatalogText !== void 0 ? [] : input.preferences?.descriptors ?? []) {
199
198
  contributions.push(
200
199
  contribution({
201
200
  category: "skill_guide_descriptor",
@@ -228,7 +227,17 @@ function buildCompanyBrainContributionReceipt(input) {
228
227
  })
229
228
  );
230
229
  }
231
- for (const descriptor of composeRuntimeSkills(input.skillActivations).configuredDescriptors) {
230
+ if (input.skillCatalogText)
231
+ contributions.push(
232
+ contribution({
233
+ category: "skill_guide_descriptor",
234
+ source: "runtime_skill_catalog",
235
+ inclusionReason: "authorized_skill_descriptor",
236
+ authorityScope: "workspace",
237
+ text: input.skillCatalogText
238
+ })
239
+ );
240
+ for (const descriptor of input.skillCatalogText !== void 0 ? [] : composeRuntimeSkills(input.skillActivations).configuredDescriptors) {
232
241
  contributions.push(
233
242
  contribution({
234
243
  category: "skill_guide_descriptor",
@@ -6809,7 +6818,7 @@ import { serviceTierForLatencyMode } from "@opengeni/config";
6809
6818
  // src/activities/context-compaction.ts
6810
6819
  import {
6811
6820
  applyContextCompaction,
6812
- getActiveSessionHistoryItemsPaged as getActiveSessionHistoryItemsPaged3,
6821
+ getActiveSessionHistoryItemsPaged as getActiveSessionHistoryItemsPaged2,
6813
6822
  recordSkippedContextCompaction,
6814
6823
  recordStartedContextCompaction
6815
6824
  } from "@opengeni/db";
@@ -6830,463 +6839,6 @@ import {
6830
6839
  summarizeForCompaction
6831
6840
  } from "@opengeni/runtime";
6832
6841
  import { contextInputBudgetTokens } from "@opengeni/config";
6833
-
6834
- // src/activities/run-input.ts
6835
- import {
6836
- MODEL_ATTACHMENT_REFS_FIELD,
6837
- FileResourceRef,
6838
- resourceMountPath as resourceMountPath2
6839
- } from "@opengeni/contracts";
6840
- import { createHash as createHash8 } from "crypto";
6841
- import {
6842
- getActiveSessionHistoryItemsPaged as getActiveSessionHistoryItemsPaged2,
6843
- getFilesForSubject as getFilesForSubject2,
6844
- getSandboxSessionEnvelope,
6845
- listSessionSystemUpdatesForTurn,
6846
- listTurnOpenSuffixToolCalls
6847
- } from "@opengeni/db";
6848
- import {
6849
- projectHistoryForProvider,
6850
- projectRejectedProviderArtifactsFromSerializedRunState,
6851
- projectRejectedReasoningArtifact,
6852
- hasOpaqueProviderArtifact
6853
- } from "@opengeni/runtime";
6854
- function projectRejectedProviderArtifacts(rows) {
6855
- const out = [];
6856
- for (const row of rows) {
6857
- if (!row.providerArtifactInvalidatedAt) {
6858
- out.push(row.item);
6859
- continue;
6860
- }
6861
- const type = typeof row.item.type === "string" ? row.item.type : void 0;
6862
- if (type === "reasoning") {
6863
- out.push(projectRejectedReasoningArtifact(row.item));
6864
- continue;
6865
- }
6866
- if (type === "compaction") {
6867
- continue;
6868
- }
6869
- out.push(row.item);
6870
- }
6871
- return out;
6872
- }
6873
- async function measureHistoryPreparationPhase(options, phase, operation) {
6874
- const startedAt = performance.now();
6875
- let outcome = "completed";
6876
- try {
6877
- return await operation();
6878
- } catch (error) {
6879
- outcome = "failed";
6880
- throw error;
6881
- } finally {
6882
- try {
6883
- options.onPreparationPhase?.({
6884
- phase,
6885
- outcome,
6886
- durationSeconds: (performance.now() - startedAt) / 1e3
6887
- });
6888
- } catch {
6889
- }
6890
- }
6891
- }
6892
- var MAX_INLINE_MODEL_ATTACHMENT_BYTES = 20 * 1024 * 1024;
6893
- var MODEL_IMAGE_CONTENT_TYPES = /* @__PURE__ */ new Set(["image/gif", "image/jpeg", "image/png", "image/webp"]);
6894
- var MODEL_FILE_CONTENT_TYPES = /* @__PURE__ */ new Set([
6895
- "application/json",
6896
- "application/pdf",
6897
- "application/x-yaml",
6898
- "application/yaml"
6899
- ]);
6900
- var BLOCKED_TEXT_CONTENT_TYPES = /* @__PURE__ */ new Set([
6901
- "text/css",
6902
- "text/html",
6903
- "text/javascript",
6904
- "text/xml"
6905
- ]);
6906
- function safeErrorType(error) {
6907
- if (!(error instanceof Error)) return typeof error;
6908
- const name = error.name.trim();
6909
- return /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(name) ? name : "Error";
6910
- }
6911
- function modelAttachmentDescriptor(contentType) {
6912
- const normalized = contentType.toLowerCase().split(";", 1)[0]?.trim() ?? "";
6913
- if (MODEL_IMAGE_CONTENT_TYPES.has(normalized)) {
6914
- return { kind: "image", contentType: normalized };
6915
- }
6916
- if (MODEL_FILE_CONTENT_TYPES.has(normalized) || normalized.startsWith("text/") && !BLOCKED_TEXT_CONTENT_TYPES.has(normalized)) {
6917
- return { kind: "file", contentType: normalized };
6918
- }
6919
- return null;
6920
- }
6921
- async function modelAttachmentContentForFiles(files, readFileBytes) {
6922
- const selected = [];
6923
- let remainingBytes = MAX_INLINE_MODEL_ATTACHMENT_BYTES;
6924
- for (const file of files) {
6925
- const descriptor = modelAttachmentDescriptor(file.contentType);
6926
- const checksum = file.sha256?.trim().toLowerCase() ?? "";
6927
- if (file.status !== "ready" || !descriptor || descriptor.kind !== "image" || file.sizeBytes > remainingBytes || !/^[a-f0-9]{64}$/.test(checksum)) {
6928
- continue;
6929
- }
6930
- selected.push({ file, descriptor, checksum });
6931
- remainingBytes -= file.sizeBytes;
6932
- }
6933
- const attachments = new Array(selected.length);
6934
- let cursor = 0;
6935
- const worker = async () => {
6936
- while (cursor < selected.length) {
6937
- const index = cursor++;
6938
- const { file, descriptor, checksum } = selected[index];
6939
- try {
6940
- const bytes = await readFileBytes(file);
6941
- if (bytes.byteLength !== file.sizeBytes) {
6942
- console.error("model attachment bytes did not match finalized metadata", {
6943
- fileId: file.id,
6944
- expectedSizeBytes: file.sizeBytes,
6945
- actualSizeBytes: bytes.byteLength
6946
- });
6947
- continue;
6948
- }
6949
- if (createHash8("sha256").update(bytes).digest("hex") !== checksum) {
6950
- console.error("model attachment checksum did not match finalized metadata", {
6951
- fileId: file.id
6952
- });
6953
- continue;
6954
- }
6955
- attachments[index] = {
6956
- kind: descriptor.kind,
6957
- fileId: file.id,
6958
- filename: file.safeFilename,
6959
- contentType: descriptor.contentType,
6960
- dataUrl: `data:${descriptor.contentType};base64,${Buffer.from(bytes).toString("base64")}`
6961
- };
6962
- } catch (error) {
6963
- console.error("model attachment content read failed; retaining sandbox path fallback", {
6964
- fileId: file.id,
6965
- errorType: safeErrorType(error)
6966
- });
6967
- }
6968
- }
6969
- };
6970
- await Promise.all(
6971
- Array.from({ length: Math.min(8, selected.length) }, async () => await worker())
6972
- );
6973
- return attachments.filter(
6974
- (attachment) => attachment !== void 0
6975
- );
6976
- }
6977
- function attachmentRefsFromItem(item) {
6978
- const raw = item[MODEL_ATTACHMENT_REFS_FIELD];
6979
- if (!Array.isArray(raw)) return [];
6980
- const refs = [];
6981
- for (const candidate of raw) {
6982
- const parsed = FileResourceRef.safeParse(candidate);
6983
- if (parsed.success) refs.push(parsed.data);
6984
- }
6985
- return refs;
6986
- }
6987
- function attachmentReceiptText(ref, file) {
6988
- if (!file) {
6989
- return `[Earlier attachment: fileId=${ref.fileId}; mountDirectory=${resourceMountPath2(ref)}. Use the existing file there, or call files__files_get_download_url with this fileId and download it with the shell.]`;
6990
- }
6991
- const path = sandboxFilePath(ref, file);
6992
- return `[Attachment: ${file.safeFilename}; fileId=${file.id}; type=${file.contentType}; bytes=${file.sizeBytes}; path=${path}. If the local path is absent, call files__files_get_download_url with this fileId and download it with the shell.]`;
6993
- }
6994
- function createModelHistoryAttachmentProjector(policy, readFileBytes) {
6995
- const contentById = /* @__PURE__ */ new Map();
6996
- const attemptedContentIds = /* @__PURE__ */ new Set();
6997
- return async (items, options = {}) => {
6998
- const currentFileById = new Map((options.inlineFiles ?? []).map((file) => [file.id, file]));
6999
- const refsByIndex = /* @__PURE__ */ new Map();
7000
- const orderedFileIds = [];
7001
- const seenFileIds = /* @__PURE__ */ new Set();
7002
- for (let index = 0; index < items.length; index += 1) {
7003
- const refs = attachmentRefsFromItem(items[index]);
7004
- if (refs.length === 0) continue;
7005
- refsByIndex.set(index, refs);
7006
- for (const ref of refs) {
7007
- if (seenFileIds.has(ref.fileId)) continue;
7008
- seenFileIds.add(ref.fileId);
7009
- orderedFileIds.push(ref.fileId);
7010
- }
7011
- }
7012
- if (refsByIndex.size === 0) return items;
7013
- if (readFileBytes) {
7014
- const readable = [...orderedFileIds].reverse().map((id) => currentFileById.get(id)).filter((file) => {
7015
- if (!file || attemptedContentIds.has(file.id)) return false;
7016
- const descriptor = modelAttachmentDescriptor(file.contentType);
7017
- return Boolean(descriptor && descriptor.kind === "image" && policy.supportsImageInput);
7018
- });
7019
- for (const file of readable) attemptedContentIds.add(file.id);
7020
- const content = await modelAttachmentContentForFiles(readable, readFileBytes);
7021
- for (const attachment of content) contentById.set(attachment.fileId, attachment);
7022
- }
7023
- const projected = [...items];
7024
- for (const [index, refs] of refsByIndex) {
7025
- const original = items[index];
7026
- const existingContent = Array.isArray(original.content) ? [...original.content] : [{ type: "input_text", text: String(original.content ?? "") }];
7027
- const attachmentParts = refs.flatMap((ref) => {
7028
- const currentFile = currentFileById.get(ref.fileId);
7029
- const attachment = currentFile ? contentById.get(ref.fileId) : void 0;
7030
- const receipt = {
7031
- type: "input_text",
7032
- text: attachmentReceiptText(ref, currentFile)
7033
- };
7034
- if (!attachment || attachment.kind !== "image") {
7035
- return [receipt];
7036
- }
7037
- return [receipt, { type: "input_image", image: attachment.dataUrl }];
7038
- });
7039
- const clone = {
7040
- ...original,
7041
- content: [...existingContent, ...attachmentParts]
7042
- };
7043
- delete clone[MODEL_ATTACHMENT_REFS_FIELD];
7044
- projected[index] = clone;
7045
- }
7046
- return projected;
7047
- };
7048
- }
7049
- function withCurrentUserAttachmentRefs(historyItems, refs) {
7050
- if (refs.length === 0) return historyItems;
7051
- for (let index = historyItems.length - 1; index >= 0; index -= 1) {
7052
- const item = historyItems[index];
7053
- if (item.type !== "message" || item.role !== "user") continue;
7054
- const existing = attachmentRefsFromItem(item);
7055
- const existingIds = new Set(existing.map((ref) => ref.fileId));
7056
- const additions = refs.filter((ref) => !existingIds.has(ref.fileId));
7057
- if (additions.length === 0) return historyItems;
7058
- const projected = [...historyItems];
7059
- projected[index] = { ...item, [MODEL_ATTACHMENT_REFS_FIELD]: [...existing, ...additions] };
7060
- return projected;
7061
- }
7062
- return historyItems;
7063
- }
7064
- async function turnInput(db, runtime, agent, trigger, options) {
7065
- if (!trigger) {
7066
- throw new Error("Missing trigger event");
7067
- }
7068
- const updates = await measureHistoryPreparationPhase(
7069
- options,
7070
- "system_update_load",
7071
- async () => await listSessionSystemUpdatesForTurn(
7072
- db,
7073
- trigger.workspaceId,
7074
- trigger.sessionId,
7075
- options.turnId
7076
- )
7077
- );
7078
- if (updates.some((update) => !update.deliveredHistoryItemId)) {
7079
- throw new Error("Delivered internal update has no durable model-memory batch");
7080
- }
7081
- const internalContext = joinInternalContext(
7082
- options.recovering ? [
7083
- "[OpenGeni inference recovery]",
7084
- "Continue the same inference from durable conversation and sandbox state. A previous execution stopped before it could finish. Do not repeat completed side effects; inspect actual state when uncertain."
7085
- ].join("\n") : void 0,
7086
- options.unavailableSandboxFilesNote,
7087
- options.runCredentialsNote,
7088
- options.mcpAvailabilityNote
7089
- );
7090
- if (trigger.type === "user.message") {
7091
- const payload = trigger.payload;
7092
- const hasAnnotations = Array.isArray(payload.annotations) && payload.annotations.length > 0;
7093
- if (typeof payload.text !== "string" || payload.text.trim().length === 0 && !hasAnnotations) {
7094
- throw new Error("user.message payload is missing text and annotations");
7095
- }
7096
- const resources = Array.isArray(payload.resources) ? payload.resources : [];
7097
- const fileAttachments = await measureHistoryPreparationPhase(
7098
- options,
7099
- "current_attachment_resolution",
7100
- async () => await resolveUserMessageFileAttachments(
7101
- db,
7102
- options.fileAuthority.accountId,
7103
- trigger.workspaceId,
7104
- options.fileAuthority.subjectId,
7105
- resources
7106
- )
7107
- );
7108
- const attachmentContext = userMessageAttachmentsContext(fileAttachments);
7109
- return await messageInput(
7110
- db,
7111
- runtime,
7112
- agent,
7113
- trigger,
7114
- void 0,
7115
- joinInternalContext(internalContext, attachmentContext),
7116
- fileAttachments,
7117
- options.providerApi,
7118
- options.projectCanonicalHistory,
7119
- options.materializeModelHistory,
7120
- options.projectModelHistory,
7121
- options.loadActiveHistory,
7122
- options
7123
- );
7124
- }
7125
- if (trigger.type === "system.update.delivered") {
7126
- if (updates.length === 0) {
7127
- throw new Error("Internal update inference has no delivered updates");
7128
- }
7129
- return await messageInput(
7130
- db,
7131
- runtime,
7132
- agent,
7133
- trigger,
7134
- void 0,
7135
- internalContext,
7136
- [],
7137
- options.providerApi,
7138
- options.projectCanonicalHistory,
7139
- options.materializeModelHistory,
7140
- options.projectModelHistory,
7141
- options.loadActiveHistory,
7142
- options
7143
- );
7144
- }
7145
- if (trigger.type === "user.approvalDecision" || trigger.type === "user.humanInputResponse") {
7146
- return await openSuffixMessageInput(db, runtime, agent, trigger, internalContext, options);
7147
- }
7148
- throw new Error(`Unsupported trigger event type: ${trigger.type}`);
7149
- }
7150
- function joinInternalContext(...parts) {
7151
- const content = parts.map((part) => part?.trim()).filter((part) => Boolean(part));
7152
- return content.length > 0 ? content.join("\n\n") : void 0;
7153
- }
7154
- async function openSuffixMessageInput(db, runtime, agent, trigger, internalContext, options) {
7155
- const suffixRows = await listTurnOpenSuffixToolCalls(
7156
- db,
7157
- trigger.workspaceId,
7158
- trigger.sessionId,
7159
- options.turnId
7160
- );
7161
- if (suffixRows.length === 0) {
7162
- throw new Error("Open suffix resume has no interruption rows");
7163
- }
7164
- if (suffixRows.some((row) => row.resultItem == null)) {
7165
- throw new Error("Open suffix resume still has unresolved members");
7166
- }
7167
- return await messageInput(
7168
- db,
7169
- runtime,
7170
- agent,
7171
- trigger,
7172
- void 0,
7173
- internalContext,
7174
- [],
7175
- options.providerApi,
7176
- options.projectCanonicalHistory,
7177
- options.materializeModelHistory,
7178
- options.projectModelHistory,
7179
- options.loadActiveHistory,
7180
- options
7181
- );
7182
- }
7183
- async function messageInput(db, runtime, agent, trigger, text, internalContext, currentAttachments = [], providerApi = "responses", projectCanonicalHistory, materializeModelHistory, projectModelHistory, loadActiveHistory = getActiveSessionHistoryItemsPaged2, preparationOptions = {}) {
7184
- const currentAttachmentRefs = currentAttachments.map((attachment) => attachment.resource);
7185
- const [stored, envelope] = await Promise.all([
7186
- measureHistoryPreparationPhase(
7187
- preparationOptions,
7188
- "durable_history_load",
7189
- async () => loadActiveHistory(db, trigger.workspaceId, trigger.sessionId)
7190
- ),
7191
- measureHistoryPreparationPhase(
7192
- preparationOptions,
7193
- "sandbox_envelope_load",
7194
- async () => getSandboxSessionEnvelope(db, trigger.workspaceId, trigger.sessionId)
7195
- )
7196
- ]);
7197
- const canonicalView = await measureHistoryPreparationPhase(
7198
- preparationOptions,
7199
- "canonical_projection",
7200
- async () => {
7201
- const active = projectRejectedProviderArtifacts(stored);
7202
- return projectCanonicalHistory ? await projectCanonicalHistory(active) : active;
7203
- }
7204
- );
7205
- const providerView = await measureHistoryPreparationPhase(
7206
- preparationOptions,
7207
- "provider_projection",
7208
- () => projectHistoryForProvider(canonicalView, providerApi)
7209
- );
7210
- const referencedHistory = await measureHistoryPreparationPhase(
7211
- preparationOptions,
7212
- "attachment_ref_projection",
7213
- () => withCurrentUserAttachmentRefs(providerView, currentAttachmentRefs)
7214
- );
7215
- const materializedHistory = await measureHistoryPreparationPhase(
7216
- preparationOptions,
7217
- "screenshot_materialization",
7218
- async () => materializeModelHistory ? await materializeModelHistory(referencedHistory) : referencedHistory
7219
- );
7220
- const historyItems = await measureHistoryPreparationPhase(
7221
- preparationOptions,
7222
- "model_attachment_projection",
7223
- async () => projectModelHistory ? await projectModelHistory(materializedHistory, {
7224
- inlineFiles: currentAttachments.map((attachment) => attachment.file)
7225
- }) : materializedHistory
7226
- );
7227
- const prepared = await measureHistoryPreparationPhase(
7228
- preparationOptions,
7229
- "runtime_input_assembly",
7230
- async () => await runtime.prepareInput(agent, {
7231
- kind: "message",
7232
- ...text ? { text } : {},
7233
- ...internalContext ? { internalContext } : {},
7234
- historyItems,
7235
- sandboxEnvelope: envelope,
7236
- ...projectModelHistory ? { modelInputAlreadyProjected: true } : {}
7237
- })
7238
- );
7239
- const providerArtifactCandidates = await measureHistoryPreparationPhase(
7240
- preparationOptions,
7241
- "artifact_candidate_scan",
7242
- () => {
7243
- const preparedItems = Array.isArray(prepared.input) ? new Set(prepared.input) : /* @__PURE__ */ new Set();
7244
- return {
7245
- knownHistoryItemIds: stored.map((row) => row.id),
7246
- historyItemIds: stored.filter(
7247
- (row) => row.providerArtifactInvalidatedAt === null && hasOpaqueProviderArtifact(row.item) && preparedItems.has(row.item)
7248
- ).map((row) => row.id)
7249
- };
7250
- }
7251
- );
7252
- return {
7253
- input: prepared,
7254
- persistedHistoryCount: prepared.persistedHistoryCount,
7255
- providerArtifactCandidates
7256
- };
7257
- }
7258
- async function resolveUserMessageFileAttachments(db, accountId, workspaceId, subjectId, resources) {
7259
- const fileResources = resources.filter(
7260
- (resource) => resource.kind === "file"
7261
- );
7262
- if (fileResources.length === 0) return [];
7263
- const files = await getFilesForSubject2(db, {
7264
- accountId,
7265
- workspaceId,
7266
- subjectId,
7267
- fileIds: fileResources.map((resource) => resource.fileId)
7268
- });
7269
- const fileById = new Map(files.map((file) => [file.id, file]));
7270
- return fileResources.map((resource) => {
7271
- const file = fileById.get(resource.fileId);
7272
- if (!file) throw new Error(`File not found: ${resource.fileId}`);
7273
- return { resource, file };
7274
- });
7275
- }
7276
- function userMessageAttachmentsContext(attachments) {
7277
- const attachedFiles = attachments.map(
7278
- ({ resource, file }) => `- ${file.filename} (${file.contentType}, ${file.sizeBytes} bytes): ${sandboxFilePath(resource, file)}`
7279
- );
7280
- if (attachedFiles.length === 0) {
7281
- return void 0;
7282
- }
7283
- return ["Attached files are available in the sandbox:", ...attachedFiles].join("\n");
7284
- }
7285
- function sandboxFilePath(resource, file) {
7286
- return `${resourceMountPath2(resource)}/${file.safeFilename}`;
7287
- }
7288
-
7289
- // src/activities/context-compaction.ts
7290
6842
  async function maybeCompactContext(db, settings, scope, lastInputTokens, summarize = (s, m) => summarizeForCompaction(s, m, {
7291
6843
  maxOutputTokens: SUMMARY_BUFFER_TOKENS
7292
6844
  }), options = {}) {
@@ -7307,7 +6859,7 @@ async function maybeCompactContext(db, settings, scope, lastInputTokens, summari
7307
6859
  };
7308
6860
  }
7309
6861
  }
7310
- const active = await getActiveSessionHistoryItemsPaged3(db, scope.workspaceId, scope.sessionId);
6862
+ const active = await getActiveSessionHistoryItemsPaged2(db, scope.workspaceId, scope.sessionId);
7311
6863
  if (active.length === 0) {
7312
6864
  let requestConsumed = false;
7313
6865
  if (options.clearRequestedCompaction) {
@@ -7460,7 +7012,12 @@ async function compactContextRemoteV2(db, settings, scope, canonicalItems, items
7460
7012
  rewrittenToolOutputs = retry.rewrittenToolOutputs;
7461
7013
  compactionItem = await options.requestRemoteCompactionV2(settings, retry.input);
7462
7014
  }
7463
- const replacementHistory = buildRemoteV2ReplacementHistory(canonicalItems, compactionItem);
7015
+ const retainedTokens = await retentionTokenCounts(canonicalItems, projectForWire);
7016
+ const replacementHistory = buildRemoteV2ReplacementHistory(
7017
+ canonicalItems,
7018
+ compactionItem,
7019
+ (item) => retainedTokens.get(item) ?? estimateTokens([item])
7020
+ );
7464
7021
  const estimatedTokensAfter = estimateTokens(await projectForWire(replacementHistory));
7465
7022
  const replacementFingerprint = compactionReplacementFingerprint(replacementHistory);
7466
7023
  const tailItem = replacementHistory.at(-1);
@@ -7510,7 +7067,12 @@ async function compactContextPortable(db, settings, scope, canonicalItems, items
7510
7067
  const estimatedTokensBefore = estimateTokens(items);
7511
7068
  const summarized = await summarizeWithCodexOverflowTrimming(summarize, settings, items);
7512
7069
  const summaryBody = summarized.summaryBody;
7513
- const replacementHistory = buildCompactionReplacementHistory(canonicalItems, summaryBody);
7070
+ const retainedTokens = await retentionTokenCounts(canonicalItems, projectForWire);
7071
+ const replacementHistory = buildCompactionReplacementHistory(
7072
+ canonicalItems,
7073
+ summaryBody,
7074
+ (item) => retainedTokens.get(item) ?? estimateTokens([item])
7075
+ );
7514
7076
  const estimatedTokensAfter = estimateTokens(await projectForWire(replacementHistory));
7515
7077
  const replacementFingerprint = compactionReplacementFingerprint(replacementHistory);
7516
7078
  const previousReplacementFingerprint = latestCompactionReplacementFingerprint(canonicalItems);
@@ -7609,6 +7171,15 @@ function isExactContextLengthExceeded(error, seen = /* @__PURE__ */ new WeakSet(
7609
7171
  }
7610
7172
  return isExactContextLengthExceeded(record5.cause, seen) || isExactContextLengthExceeded(record5.error, seen) || isExactContextLengthExceeded(record5.diagnostics, seen);
7611
7173
  }
7174
+ async function retentionTokenCounts(items, project) {
7175
+ const counts = /* @__PURE__ */ new Map();
7176
+ for (const item of items) {
7177
+ if (item.role === "user" || item.role === "developer") {
7178
+ counts.set(item, estimateTokens(await project([item])));
7179
+ }
7180
+ }
7181
+ return counts;
7182
+ }
7612
7183
 
7613
7184
  // src/activities/open-suffix-resume.ts
7614
7185
  import {
@@ -7619,7 +7190,7 @@ import {
7619
7190
  appendSessionHistoryItems as appendSessionHistoryItems2,
7620
7191
  getActiveSessionHistoryItems,
7621
7192
  interruptedToolCallResult,
7622
- listTurnOpenSuffixToolCalls as listTurnOpenSuffixToolCalls2,
7193
+ listTurnOpenSuffixToolCalls,
7623
7194
  nextSessionHistoryPosition,
7624
7195
  recordPendingSessionToolCallResult
7625
7196
  } from "@opengeni/db";
@@ -7770,7 +7341,7 @@ async function settleOpenSuffixResumeIfNeeded(input) {
7770
7341
  if (input.trigger.type !== "user.approvalDecision" && input.trigger.type !== "user.humanInputResponse") {
7771
7342
  return { action: "continue" };
7772
7343
  }
7773
- const rows = await listTurnOpenSuffixToolCalls2(
7344
+ const rows = await listTurnOpenSuffixToolCalls(
7774
7345
  input.db,
7775
7346
  input.workspaceId,
7776
7347
  input.sessionId,
@@ -7816,7 +7387,7 @@ async function settleOpenSuffixResumeIfNeeded(input) {
7816
7387
  }
7817
7388
  if (!recorded.recorded) {
7818
7389
  const latest = resolveOpenSuffixResumeTarget(
7819
- await listTurnOpenSuffixToolCalls2(
7390
+ await listTurnOpenSuffixToolCalls(
7820
7391
  input.db,
7821
7392
  input.workspaceId,
7822
7393
  input.sessionId,
@@ -7868,7 +7439,7 @@ async function settleOpenSuffixResumeIfNeeded(input) {
7868
7439
  return { action: "cancelled" };
7869
7440
  }
7870
7441
  }
7871
- const remaining = (await listTurnOpenSuffixToolCalls2(input.db, input.workspaceId, input.sessionId, input.turnId)).filter((row) => row.resultItem == null);
7442
+ const remaining = (await listTurnOpenSuffixToolCalls(input.db, input.workspaceId, input.sessionId, input.turnId)).filter((row) => row.resultItem == null);
7872
7443
  if (remaining.length === 0) {
7873
7444
  return { action: "continue" };
7874
7445
  }
@@ -9577,7 +9148,7 @@ async function runTurnStreamAttempt(deps) {
9577
9148
  import {
9578
9149
  applySessionTurnSettlement,
9579
9150
  claimSessionWorkForAttempt,
9580
- getSessionEvent as getSessionEvent3,
9151
+ getSessionEvent as getSessionEvent2,
9581
9152
  getHumanInputResumeForEvent as getHumanInputResumeForEvent2,
9582
9153
  getInteractionInterventionResumeForEvent,
9583
9154
  installOrReadTurnExecutionPolicyForAttempt,
@@ -9934,7 +9505,7 @@ async function claimTurnAttempt(deps) {
9934
9505
  billingState.countsTowardTokenCap = billingIdentity.countsTowardTokenCap;
9935
9506
  billingState.isCodexTurn = billingIdentity.codexSubscription;
9936
9507
  billingState.isXaiTurn = billingIdentity.xaiSubscription;
9937
- const trigger = await getSessionEvent3(db, input.workspaceId, attempt.triggerEventId);
9508
+ const trigger = await getSessionEvent2(db, input.workspaceId, attempt.triggerEventId);
9938
9509
  if (!trigger) {
9939
9510
  throw new Error(`Trigger event not found: ${attempt.triggerEventId}`);
9940
9511
  }
@@ -10990,10 +10561,11 @@ async function selectCodexTurnCapacity(deps) {
10990
10561
  import {
10991
10562
  materializeRigVersionForAttempt,
10992
10563
  getWorkspaceModelPolicy,
10564
+ getFilesForSubject as getFilesForSubject2,
10993
10565
  getWorkspace as getWorkspace2,
10994
10566
  resolveCompanyBrainContextSelection,
10995
10567
  getGeneratedVideoArtifact,
10996
- listSessionSystemUpdatesForTurn as listSessionSystemUpdatesForTurn2,
10568
+ listSessionSystemUpdatesForTurn,
10997
10569
  getOrCreateCompanyProfileSnapshot,
10998
10570
  getOrCreatePreferenceRegistrySnapshot,
10999
10571
  getOrCreateWorkspaceInstructionPolicySnapshot,
@@ -11001,7 +10573,7 @@ import {
11001
10573
  resolveSessionAttemptPersonalResources
11002
10574
  } from "@opengeni/db";
11003
10575
  import {
11004
- projectHistoryForProvider as projectHistoryForProvider2,
10576
+ projectHistoryForProvider,
11005
10577
  restoreGenericDispatchHistoryItems,
11006
10578
  projectModelInputForCapabilities,
11007
10579
  hasActiveWorkspaceInstructionPolicy,
@@ -11034,7 +10606,7 @@ import {
11034
10606
  prepareImageGenerationOperation,
11035
10607
  resetImageGenerationOperationBeforeProviderDispatch
11036
10608
  } from "@opengeni/db";
11037
- import { createHash as createHash9 } from "crypto";
10609
+ import { createHash as createHash8 } from "crypto";
11038
10610
  var ImageGenerationOutcomeUnknownError = class extends Error {
11039
10611
  constructor(operationId) {
11040
10612
  super(
@@ -11247,7 +10819,7 @@ async function recoverCompletedImage(input, identity) {
11247
10819
  return retainedGeneratedImageFromArtifact(recovered).receipt;
11248
10820
  }
11249
10821
  function digest(prefix, ...values) {
11250
- const hash = createHash9("sha256").update(prefix);
10822
+ const hash = createHash8("sha256").update(prefix);
11251
10823
  for (const value of values) hash.update(value).update("\0");
11252
10824
  return hash.digest("hex");
11253
10825
  }
@@ -11358,13 +10930,11 @@ async function prepareGovernanceAndModel(deps) {
11358
10930
  };
11359
10931
  const [
11360
10932
  packRuntime,
11361
- installedSkillRuntime,
11362
10933
  rigMaterialization,
11363
10934
  [workspace, companyProfileSnapshot, instructionPolicySnapshot, preferenceSnapshot],
11364
10935
  workspaceModelPolicy
11365
10936
  ] = await Promise.all([
11366
10937
  resolveWorkspacePackRuntime(db, input.workspaceId),
11367
- resolveWorkspaceInstalledSkillRuntime(db, input.workspaceId),
11368
10938
  session.rigId && session.rigVersionId ? (async () => await materializeRigVersionForAttempt(db, {
11369
10939
  accountId: input.accountId,
11370
10940
  workspaceId: input.workspaceId,
@@ -11403,12 +10973,13 @@ async function prepareGovernanceAndModel(deps) {
11403
10973
  preferences: preferenceSnapshot
11404
10974
  },
11405
10975
  {
11406
- includeCompanyProfile: companyProfileIncluded
10976
+ includeCompanyProfile: companyProfileIncluded,
10977
+ sharedSkillReader: true
11407
10978
  }
11408
10979
  );
11409
10980
  const structuredWorkspacePolicyActive = hasActiveWorkspaceInstructionPolicy(instructionPolicySnapshot);
11410
10981
  const workspaceMemory = contextSelection.workspaceMemory;
11411
- const buildCompanyBrainContributionReceiptFor = (skillActivations) => buildCompanyBrainContributionReceipt({
10982
+ const buildCompanyBrainContributionReceiptFor = (skillCatalogText) => buildCompanyBrainContributionReceipt({
11412
10983
  contextSelectionReceiptId: contextSelection.receipt.id,
11413
10984
  attemptId: input.attemptId,
11414
10985
  turnId: turn.id,
@@ -11420,11 +10991,12 @@ async function prepareGovernanceAndModel(deps) {
11420
10991
  companyProfile: companyProfileSnapshot,
11421
10992
  companyProfileIncluded,
11422
10993
  workspaceMemory,
11423
- skillActivations
10994
+ skillActivations: [],
10995
+ skillCatalogText
11424
10996
  });
11425
10997
  try {
11426
10998
  eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
11427
- buildCompanyBrainContributionReceiptFor([])
10999
+ buildCompanyBrainContributionReceiptFor("")
11428
11000
  );
11429
11001
  } catch {
11430
11002
  }
@@ -11475,7 +11047,13 @@ async function prepareGovernanceAndModel(deps) {
11475
11047
  );
11476
11048
  if (!object) throw new Error("attachment object is missing");
11477
11049
  return object.bytes;
11478
- } : void 0
11050
+ } : void 0,
11051
+ (fileIds) => getFilesForSubject2(db, {
11052
+ accountId: input.accountId,
11053
+ workspaceId: input.workspaceId,
11054
+ subjectId: fileAuthoritySubjectId,
11055
+ fileIds
11056
+ })
11479
11057
  );
11480
11058
  const modelHistoryProjector = async (items, projectionOptions) => projectModelInputForCapabilities(
11481
11059
  await attachmentProjector(items, projectionOptions),
@@ -11486,7 +11064,7 @@ async function prepareGovernanceAndModel(deps) {
11486
11064
  return projectGeneratedImageHistoryForModel(items);
11487
11065
  };
11488
11066
  const compactionModelHistoryProjector = async (items) => await modelHistoryProjector(
11489
- projectHistoryForProvider2(
11067
+ projectHistoryForProvider(
11490
11068
  await generatedImageHistoryProjector(restoreGenericDispatchHistoryItems(items)),
11491
11069
  providerApi
11492
11070
  )
@@ -11507,7 +11085,7 @@ async function prepareGovernanceAndModel(deps) {
11507
11085
  }
11508
11086
  }
11509
11087
  }
11510
- for (const update of await listSessionSystemUpdatesForTurn2(
11088
+ for (const update of await listSessionSystemUpdatesForTurn(
11511
11089
  db,
11512
11090
  input.workspaceId,
11513
11091
  input.sessionId,
@@ -11537,7 +11115,6 @@ async function prepareGovernanceAndModel(deps) {
11537
11115
  ok: {
11538
11116
  runtimePreparationStartedAt,
11539
11117
  packRuntime,
11540
- installedSkillRuntime,
11541
11118
  rigVersion,
11542
11119
  rigName,
11543
11120
  agentHumanInputEnabled,
@@ -14710,6 +14287,8 @@ async function prepareRunCredentials(deps) {
14710
14287
  import { getWorkspaceConnectionModelRestrictions } from "@opengeni/db";
14711
14288
  import {
14712
14289
  beginConnectorActionExecution,
14290
+ getWorkspaceVideoGenerationPolicy,
14291
+ listSkillDescriptors as listSkillDescriptors2,
14713
14292
  completeConnectorActionExecution,
14714
14293
  getScheduledVariableSetExpectedGenerationForAttempt,
14715
14294
  getWorkspaceModelPolicy as getWorkspaceModelPolicy2,
@@ -14734,7 +14313,7 @@ import {
14734
14313
  } from "@opengeni/runtime";
14735
14314
 
14736
14315
  // src/activities/google-drive-publication.ts
14737
- import { createHash as createHash10 } from "crypto";
14316
+ import { createHash as createHash9 } from "crypto";
14738
14317
  import {
14739
14318
  GOOGLE_DRIVE_FILE_SCOPE,
14740
14319
  GOOGLE_DRIVE_FULL_SCOPE,
@@ -14834,7 +14413,7 @@ function googleDrivePublicationConnectorCall(target, rawRequest, approvalId) {
14834
14413
  sourceSha256: request.file.sha256
14835
14414
  },
14836
14415
  canonicalReceipt: { ...request.file },
14837
- idempotencyKeyDigest: createHash10("sha256").update(request.idempotencyKey, "utf8").digest("hex")
14416
+ idempotencyKeyDigest: createHash9("sha256").update(request.idempotencyKey, "utf8").digest("hex")
14838
14417
  }
14839
14418
  };
14840
14419
  }
@@ -15022,7 +14601,7 @@ async function executeGoogleDrivePublication(input, ports = defaultPorts) {
15022
14601
  );
15023
14602
  if (!object) throw new Error("Editable artifact export object is missing");
15024
14603
  const bytes = object.bytes;
15025
- if (bytes.byteLength !== request.file.sizeBytes || createHash10("sha256").update(bytes).digest("hex") !== request.file.sha256) {
14604
+ if (bytes.byteLength !== request.file.sizeBytes || createHash9("sha256").update(bytes).digest("hex") !== request.file.sha256) {
15026
14605
  throw new Error("Editable artifact export bytes failed verification");
15027
14606
  }
15028
14607
  const authorizedFetch = async (url, init) => {
@@ -15104,7 +14683,7 @@ function assertPublicationConnection(input, connection) {
15104
14683
  }
15105
14684
  }
15106
14685
  function publicationActorReplicaId(identity) {
15107
- const value = createHash10("sha256").update(
14686
+ const value = createHash9("sha256").update(
15108
14687
  `google-drive-publication:${identity.sessionId}:${identity.turnId}:${identity.attemptId}:${identity.executionGeneration}`,
15109
14688
  "utf8"
15110
14689
  ).digest("hex").slice(0, 16);
@@ -15149,7 +14728,7 @@ function officeFormat(modality, contentType) {
15149
14728
  return expected.format;
15150
14729
  }
15151
14730
  function deterministicUuid(seed) {
15152
- const bytes = createHash10("sha256").update(seed, "utf8").digest().subarray(0, 16);
14731
+ const bytes = createHash9("sha256").update(seed, "utf8").digest().subarray(0, 16);
15153
14732
  bytes[6] = (bytes[6] ?? 0) & 15 | 80;
15154
14733
  bytes[8] = (bytes[8] ?? 0) & 63 | 128;
15155
14734
  const hex = bytes.toString("hex");
@@ -15287,7 +14866,7 @@ function driveReceipt(input, file, replayed) {
15287
14866
  });
15288
14867
  }
15289
14868
  function publicationOperationKey(input) {
15290
- return createHash10("sha256").update(
14869
+ return createHash9("sha256").update(
15291
14870
  JSON.stringify({
15292
14871
  workspaceId: input.workspaceId,
15293
14872
  connectionId: input.connectionId,
@@ -15956,7 +15535,7 @@ function canWrite(permissions) {
15956
15535
  }
15957
15536
 
15958
15537
  // src/activities/connector-attachments.ts
15959
- import { createHash as createHash11 } from "crypto";
15538
+ import { createHash as createHash10 } from "crypto";
15960
15539
  import {
15961
15540
  CONNECTOR_ATTACHMENT_RECEIPT_VERSION,
15962
15541
  ConnectorAttachmentReceiptEnvelope
@@ -15976,7 +15555,7 @@ var ConnectorAttachmentMaterializationError = class extends Error {
15976
15555
  }
15977
15556
  };
15978
15557
  function digestParts(...parts) {
15979
- const hash = createHash11("sha256");
15558
+ const hash = createHash10("sha256");
15980
15559
  for (const part of parts) {
15981
15560
  const bytes = Buffer.from(part, "utf8");
15982
15561
  hash.update(String(bytes.byteLength));
@@ -16581,6 +16160,780 @@ function createListModelsAttemptToolDefinition(input) {
16581
16160
  };
16582
16161
  }
16583
16162
 
16163
+ // src/activities/agent-turn/skill-tools.ts
16164
+ import { createHash as createHash11 } from "crypto";
16165
+ import {
16166
+ skillReviewHumanInput
16167
+ } from "@opengeni/contracts";
16168
+ import {
16169
+ assertSkillReadAttempt,
16170
+ skillReviewResolution,
16171
+ installPortableSkill,
16172
+ replayPortableSkillInstall,
16173
+ listSkillDescriptors
16174
+ } from "@opengeni/db";
16175
+ import {
16176
+ createGitHubSkillSourceClient,
16177
+ createPublicSkillSearchClient,
16178
+ portableSkillCapabilityId,
16179
+ portableSkillPluginKey,
16180
+ readSkill,
16181
+ resolveSkillImport,
16182
+ saveSkill
16183
+ } from "@opengeni/core";
16184
+ import {
16185
+ buildPortableSkillArtifact as buildPortableSkillArtifact3,
16186
+ loadSkillLibrarySkill,
16187
+ skillLibraryRepositoryUrl
16188
+ } from "@opengeni/runtime/skill-library";
16189
+
16190
+ // src/activities/agent-turn/skill-read.ts
16191
+ import {
16192
+ assertSkillRelativePath,
16193
+ PORTABLE_SKILL_MAX_FILES,
16194
+ readSkillFiles,
16195
+ SKILL_READ_MAX_OUTPUT_BYTES,
16196
+ SKILL_READ_MAX_PATHS
16197
+ } from "@opengeni/runtime/skill-library";
16198
+ var SKILL_READ_TOOL_NAME = "skill_read";
16199
+ function createSkillReadAttemptToolDefinition(input) {
16200
+ return {
16201
+ identity: { serverId: "opengeni", toolName: SKILL_READ_TOOL_NAME },
16202
+ modelName: SKILL_READ_TOOL_NAME,
16203
+ codemodePath: ["opengeni", SKILL_READ_TOOL_NAME],
16204
+ title: "Read Skill files",
16205
+ description: "Read Skill text without starting a sandbox. Omit paths to read SKILL.md; provide relative paths to read exactly those files, never implicitly adding SKILL.md. Set listFiles:true without paths to list relative paths and available revision identity only, with no file bodies. Use an id or name from the Skill index or skill_search. Management tools are lazy; when listed, opengeni-skills explains how to use them.",
16206
+ inputSchema: {
16207
+ type: "object",
16208
+ properties: {
16209
+ skill: { type: "string", minLength: 1, maxLength: 512 },
16210
+ listFiles: { type: "boolean" },
16211
+ paths: {
16212
+ type: "array",
16213
+ minItems: 1,
16214
+ maxItems: SKILL_READ_MAX_PATHS,
16215
+ uniqueItems: true,
16216
+ items: { type: "string", minLength: 1, maxLength: 1024 }
16217
+ }
16218
+ },
16219
+ required: ["skill"],
16220
+ additionalProperties: false
16221
+ },
16222
+ annotations: {
16223
+ title: "Read Skill files",
16224
+ readOnlyHint: true,
16225
+ destructiveHint: false,
16226
+ idempotentHint: true,
16227
+ openWorldHint: false
16228
+ },
16229
+ source: "opengeni",
16230
+ approval: "none",
16231
+ execute: async (args) => {
16232
+ if (typeof args.skill !== "string" || !args.skill || args.listFiles !== void 0 && typeof args.listFiles !== "boolean" || args.paths !== void 0 && (!Array.isArray(args.paths) || args.paths.some((path) => typeof path !== "string"))) {
16233
+ throw new Error("skill_read requires a Skill identifier and optional relative paths.");
16234
+ }
16235
+ if (args.listFiles === true && args.paths !== void 0) {
16236
+ throw new Error("skill_read listFiles:true cannot be combined with paths.");
16237
+ }
16238
+ await input.authorize();
16239
+ const loaded = await input.load(args.skill);
16240
+ const metadata = "files" in loaded ? loaded : null;
16241
+ const files = metadata ? metadata.files : loaded;
16242
+ const selected = args.listFiles === true ? listSkillPaths(files) : readSkillFiles(files, args.paths);
16243
+ const output = {
16244
+ ...metadata ? {
16245
+ skillId: metadata.skillId,
16246
+ revisionId: metadata.revisionId,
16247
+ scopeVersion: metadata.scopeVersion,
16248
+ ...metadata.installationVersion !== void 0 ? { installationVersion: metadata.installationVersion } : {}
16249
+ } : {},
16250
+ ...selected
16251
+ };
16252
+ return {
16253
+ isError: false,
16254
+ content: [{ type: "text", text: JSON.stringify(output) }],
16255
+ structuredContent: output
16256
+ };
16257
+ }
16258
+ };
16259
+ }
16260
+ function listSkillPaths(files) {
16261
+ if (files.length > PORTABLE_SKILL_MAX_FILES) {
16262
+ throw new Error(`Skill inventory exceeds ${PORTABLE_SKILL_MAX_FILES} files.`);
16263
+ }
16264
+ const seen = /* @__PURE__ */ new Set();
16265
+ for (const { path } of files) {
16266
+ assertSkillRelativePath(path);
16267
+ if (seen.has(path)) throw new Error(`Duplicate stored Skill path: ${path}`);
16268
+ seen.add(path);
16269
+ }
16270
+ const result = { paths: [...seen].sort() };
16271
+ if (Buffer.byteLength(JSON.stringify(result), "utf8") > SKILL_READ_MAX_OUTPUT_BYTES) {
16272
+ throw new Error("Skill inventory exceeds the read output limit.");
16273
+ }
16274
+ return result;
16275
+ }
16276
+
16277
+ // src/activities/agent-turn/skill-search.ts
16278
+ import { PublicSkillSearchError } from "@opengeni/core";
16279
+ import { listSkillLibraryEntries } from "@opengeni/runtime/skill-library";
16280
+ function createSkillSearchAttemptToolDefinition(input) {
16281
+ return {
16282
+ identity: { serverId: "opengeni", toolName: "skill_search" },
16283
+ modelName: "skill_search",
16284
+ codemodePath: ["opengeni", "skill_search"],
16285
+ title: "Search Skills",
16286
+ description: "Find installed workspace Skills or available curated and public Skills. Returns identifiers and install sources, not file contents. Search never installs or starts a sandbox. Scope defaults to all; use installed to avoid external search.",
16287
+ inputSchema: {
16288
+ type: "object",
16289
+ properties: {
16290
+ query: { type: "string", minLength: 2, maxLength: 200 },
16291
+ scope: { type: "string", enum: ["installed", "catalog", "all"] },
16292
+ limit: { type: "integer", minimum: 1, maximum: 20 }
16293
+ },
16294
+ required: ["query"],
16295
+ additionalProperties: false
16296
+ },
16297
+ annotations: {
16298
+ title: "Search Skills",
16299
+ readOnlyHint: true,
16300
+ destructiveHint: false,
16301
+ idempotentHint: true,
16302
+ openWorldHint: true
16303
+ },
16304
+ source: "opengeni",
16305
+ approval: "none",
16306
+ execute: async (args) => {
16307
+ await input.authorize();
16308
+ const query = String(args.query).trim();
16309
+ const scope = args.scope ?? "all";
16310
+ const limit = typeof args.limit === "number" ? args.limit : 20;
16311
+ const searchText = query.toLowerCase();
16312
+ const matches = (entry) => `${entry.name}
16313
+ ${entry.description}`.toLowerCase().includes(searchText);
16314
+ const installed = scope === "catalog" ? [] : await input.listWorkspace();
16315
+ const workspaceHits = installed.filter(matches).slice(0, limit).map((entry) => ({
16316
+ ...entry,
16317
+ source: entry.source ?? "workspace",
16318
+ installed: !entry.source || entry.source === "workspace"
16319
+ }));
16320
+ const libraryHits = scope === "installed" ? [] : listSkillLibraryEntries().filter(matches).slice(0, limit).map((entry) => ({
16321
+ id: `library:${entry.id}`,
16322
+ name: entry.name,
16323
+ description: entry.description,
16324
+ source: "library",
16325
+ libraryId: entry.id
16326
+ }));
16327
+ let publicResult = null;
16328
+ let publicError = null;
16329
+ if (scope !== "installed") {
16330
+ try {
16331
+ publicResult = await input.publicSearch.search({ query, limit });
16332
+ } catch (error) {
16333
+ if (!(error instanceof PublicSkillSearchError)) throw error;
16334
+ publicError = {
16335
+ source: "skills_sh",
16336
+ code: error.code,
16337
+ retryAfterSeconds: error.retryAfterSeconds
16338
+ };
16339
+ }
16340
+ }
16341
+ const output = {
16342
+ workspace: workspaceHits,
16343
+ library: libraryHits,
16344
+ public: publicResult?.items.map((entry) => ({ ...entry })) ?? [],
16345
+ // A provider outage is not an empty search. Keep local results useful
16346
+ // and expose partial failure explicitly, without leaking network details.
16347
+ partial: publicError !== null,
16348
+ errors: publicError ? [publicError] : []
16349
+ };
16350
+ return {
16351
+ isError: false,
16352
+ content: [{ type: "text", text: JSON.stringify(output) }],
16353
+ structuredContent: output
16354
+ };
16355
+ }
16356
+ };
16357
+ }
16358
+
16359
+ // src/activities/agent-turn/skill-save.ts
16360
+ import {
16361
+ applySkillFileChanges,
16362
+ buildPortableSkillArtifact,
16363
+ PORTABLE_SKILL_MAX_FILES as PORTABLE_SKILL_MAX_FILES2
16364
+ } from "@opengeni/runtime/skill-library";
16365
+ function createSkillSaveAttemptToolDefinition(input) {
16366
+ return {
16367
+ identity: { serverId: "opengeni", toolName: "skill_save" },
16368
+ modelName: "skill_save",
16369
+ codemodePath: ["opengeni", "skill_save"],
16370
+ title: "Save Skill text",
16371
+ description: "Create or edit a workspace Skill without a sandbox. Supply only changed UTF-8 text files and explicit deletions; omitted files are preserved. Use the revision and scope version returned by Skill discovery for stale-write protection. For creation choose a new UUID, set expectedRevisionId to null and expectedScopeVersion to 1. Learning mode determines whether the change is live, pending approval, or refused. If humanInput is returned, call request_human_input verbatim, Save activates the exact reviewed revision as the answer is accepted. Do not ask for a second review or call a separate activation tool.",
16372
+ inputSchema: {
16373
+ type: "object",
16374
+ properties: {
16375
+ operationId: { type: "string", format: "uuid" },
16376
+ skillId: { type: "string", format: "uuid" },
16377
+ expectedRevisionId: { type: ["string", "null"], format: "uuid" },
16378
+ expectedScopeVersion: { type: "integer", minimum: 0 },
16379
+ files: {
16380
+ type: "array",
16381
+ maxItems: PORTABLE_SKILL_MAX_FILES2,
16382
+ items: {
16383
+ type: "object",
16384
+ properties: {
16385
+ path: { type: "string", minLength: 1, maxLength: 1024 },
16386
+ content: { type: "string" }
16387
+ },
16388
+ required: ["path", "content"],
16389
+ additionalProperties: false
16390
+ }
16391
+ },
16392
+ deletions: {
16393
+ type: "array",
16394
+ maxItems: PORTABLE_SKILL_MAX_FILES2,
16395
+ uniqueItems: true,
16396
+ items: { type: "string", minLength: 1, maxLength: 1024 }
16397
+ },
16398
+ reason: { type: "string", minLength: 1, maxLength: 2e3 }
16399
+ },
16400
+ required: [
16401
+ "operationId",
16402
+ "skillId",
16403
+ "expectedRevisionId",
16404
+ "expectedScopeVersion",
16405
+ "files",
16406
+ "reason"
16407
+ ],
16408
+ additionalProperties: false
16409
+ },
16410
+ annotations: {
16411
+ title: "Save Skill text",
16412
+ readOnlyHint: false,
16413
+ destructiveHint: false,
16414
+ idempotentHint: true,
16415
+ openWorldHint: false
16416
+ },
16417
+ source: "opengeni",
16418
+ approval: "none",
16419
+ execute: async (args) => {
16420
+ await input.authorize();
16421
+ const skillId = args.skillId;
16422
+ const expectedRevisionId = args.expectedRevisionId;
16423
+ const current = expectedRevisionId === null ? null : await input.load(skillId, expectedRevisionId);
16424
+ if (current && current.revisionId !== expectedRevisionId) {
16425
+ throw new Error("Skill edit base did not match the requested revision.");
16426
+ }
16427
+ const files = applySkillFileChanges(
16428
+ current?.files ?? [],
16429
+ args.files,
16430
+ args.deletions ?? []
16431
+ );
16432
+ const artifact = buildPortableSkillArtifact(files);
16433
+ const output = await input.save({
16434
+ operationId: args.operationId,
16435
+ skillId,
16436
+ expectedRevisionId,
16437
+ expectedScopeVersion: args.expectedScopeVersion,
16438
+ files: artifact.files,
16439
+ reason: args.reason
16440
+ });
16441
+ return {
16442
+ isError: false,
16443
+ content: [{ type: "text", text: JSON.stringify(output) }],
16444
+ structuredContent: output
16445
+ };
16446
+ }
16447
+ };
16448
+ }
16449
+
16450
+ // src/activities/agent-turn/skill-install.ts
16451
+ function createSkillInstallAttemptToolDefinition(input) {
16452
+ return {
16453
+ identity: { serverId: "opengeni", toolName: "skill_install" },
16454
+ modelName: "skill_install",
16455
+ codemodePath: ["opengeni", "skill_install"],
16456
+ title: "Install a Skill",
16457
+ description: "Install a Skill from a public skills.sh or GitHub URL, or library:<id> returned by skill_search. The server resolves and pins the source; no prior preview or invented hash is required. Learning mode controls activation. Replacing an existing installation requires its current installation version, and preserves workspace customizations.",
16458
+ inputSchema: {
16459
+ type: "object",
16460
+ properties: {
16461
+ operationId: { type: "string", format: "uuid" },
16462
+ source: { type: "string", minLength: 1, maxLength: 2048 },
16463
+ expectedInstallationVersion: { type: "integer", minimum: 0 },
16464
+ reason: { type: "string", minLength: 1, maxLength: 2e3 }
16465
+ },
16466
+ required: ["operationId", "source", "reason"],
16467
+ additionalProperties: false
16468
+ },
16469
+ annotations: {
16470
+ readOnlyHint: false,
16471
+ destructiveHint: false,
16472
+ idempotentHint: true,
16473
+ openWorldHint: true
16474
+ },
16475
+ source: "opengeni",
16476
+ approval: "none",
16477
+ execute: async (args) => {
16478
+ await input.authorize();
16479
+ const output = await input.install({
16480
+ operationId: args.operationId,
16481
+ source: args.source,
16482
+ ...args.expectedInstallationVersion !== void 0 ? { expectedInstallationVersion: args.expectedInstallationVersion } : {},
16483
+ reason: args.reason
16484
+ });
16485
+ return {
16486
+ isError: false,
16487
+ content: [{ type: "text", text: JSON.stringify(output) }],
16488
+ structuredContent: output
16489
+ };
16490
+ }
16491
+ };
16492
+ }
16493
+
16494
+ // src/activities/agent-turn/skill-transfer.ts
16495
+ import { posix } from "path";
16496
+ import {
16497
+ assertSkillRelativePath as assertSkillRelativePath2,
16498
+ buildPortableSkillArtifact as buildPortableSkillArtifact2,
16499
+ PORTABLE_SKILL_MAX_FILES as PORTABLE_SKILL_MAX_FILES3,
16500
+ PORTABLE_SKILL_MAX_FILE_BYTES,
16501
+ PORTABLE_SKILL_MAX_TOTAL_BYTES
16502
+ } from "@opengeni/runtime/skill-library";
16503
+ var maxTraversalEntries = 1024;
16504
+ function guardSkillFilesystem(fs, authority) {
16505
+ const read = (operation) => {
16506
+ authority.assertActive();
16507
+ return operation();
16508
+ };
16509
+ const write = (operation) => {
16510
+ authority.assertActive();
16511
+ return authority.runMutation(() => read(operation));
16512
+ };
16513
+ return {
16514
+ fsList: (request) => read(() => fs.fsList(request)),
16515
+ fsRead: (request) => read(() => fs.fsRead(request)),
16516
+ fsWrite: (request) => write(() => fs.fsWrite(request)),
16517
+ fsMkdir: (request) => write(() => fs.fsMkdir(request))
16518
+ };
16519
+ }
16520
+ async function checkoutSkillDirectory(fs, directory, files) {
16521
+ assertSkillRelativePath2(directory);
16522
+ const artifact = buildPortableSkillArtifact2(files);
16523
+ const parent = posix.dirname(directory);
16524
+ if (parent !== ".") await fs.fsMkdir({ path: parent, recursive: true });
16525
+ await fs.fsMkdir({ path: directory, recursive: false });
16526
+ for (const file of artifact.files) {
16527
+ const result = await fs.fsWrite({
16528
+ path: `${directory}/${file.path}`,
16529
+ content: file.content,
16530
+ encoding: "utf8",
16531
+ overwrite: false,
16532
+ createParents: true
16533
+ });
16534
+ if (result.sizeBytes !== new TextEncoder().encode(file.content).byteLength) {
16535
+ throw new Error(`Skill checkout wrote an unexpected byte count: ${file.path}`);
16536
+ }
16537
+ }
16538
+ return { directory, fileCount: artifact.files.length };
16539
+ }
16540
+ async function readSkillDirectory(fs, directory) {
16541
+ assertSkillRelativePath2(directory);
16542
+ const pending = [directory];
16543
+ const seen = new Set(pending);
16544
+ const files = [];
16545
+ let entries = 0;
16546
+ let totalBytes = 0;
16547
+ while (pending.length) {
16548
+ const current = pending.shift();
16549
+ const listing = await fs.fsList({
16550
+ path: current,
16551
+ depth: 1,
16552
+ maxEntries: maxTraversalEntries + 1,
16553
+ includeHidden: true
16554
+ });
16555
+ if (listing.root.type !== "dir" || listing.root.path !== current) {
16556
+ throw new Error(`Expected a real Skill directory: ${current}`);
16557
+ }
16558
+ if (listing.truncated || listing.root.truncated || !listing.root.children) {
16559
+ throw new Error(`Skill directory listing is incomplete: ${current}`);
16560
+ }
16561
+ for (const entry of listing.root.children) {
16562
+ assertSkillRelativePath2(entry.path);
16563
+ if (posix.dirname(entry.path) !== current || posix.basename(entry.path) !== entry.name) {
16564
+ throw new Error("Skill directory listing returned a path outside the requested directory.");
16565
+ }
16566
+ if (seen.has(entry.path)) throw new Error(`Duplicate Skill directory entry: ${entry.path}`);
16567
+ seen.add(entry.path);
16568
+ if (++entries > maxTraversalEntries) throw new Error("Skill directory has too many entries.");
16569
+ if (entry.type === "dir") {
16570
+ pending.push(entry.path);
16571
+ continue;
16572
+ }
16573
+ if (entry.type !== "file") throw new Error(`Unsupported Skill file type: ${entry.path}`);
16574
+ if (files.length >= PORTABLE_SKILL_MAX_FILES3) throw new Error("Skill has too many files.");
16575
+ if (entry.sizeBytes !== null && entry.sizeBytes > PORTABLE_SKILL_MAX_FILE_BYTES) {
16576
+ throw new Error(`Skill file exceeds the size limit: ${entry.path}`);
16577
+ }
16578
+ const read = await fs.fsRead({
16579
+ path: entry.path,
16580
+ encoding: "base64",
16581
+ maxBytes: PORTABLE_SKILL_MAX_FILE_BYTES + 1
16582
+ });
16583
+ if (read.truncated || read.sizeBytes > PORTABLE_SKILL_MAX_FILE_BYTES) {
16584
+ throw new Error(`Skill file exceeds the size limit: ${entry.path}`);
16585
+ }
16586
+ if (read.encoding !== "base64" || read.path !== entry.path) {
16587
+ throw new Error(`Invalid Skill file read response: ${entry.path}`);
16588
+ }
16589
+ const bytes = Buffer.from(read.content, "base64");
16590
+ if (bytes.byteLength !== read.sizeBytes) {
16591
+ throw new Error(`Invalid Skill file byte count: ${entry.path}`);
16592
+ }
16593
+ totalBytes += bytes.byteLength;
16594
+ if (totalBytes > PORTABLE_SKILL_MAX_TOTAL_BYTES)
16595
+ throw new Error("Skill exceeds the total size limit.");
16596
+ let content;
16597
+ try {
16598
+ content = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(bytes);
16599
+ } catch {
16600
+ throw new Error(`Skill file is not valid UTF-8 text: ${entry.path}`);
16601
+ }
16602
+ files.push({ path: entry.path.slice(directory.length + 1), content });
16603
+ }
16604
+ }
16605
+ return buildPortableSkillArtifact2(files);
16606
+ }
16607
+
16608
+ // src/activities/agent-turn/skill-checkout.ts
16609
+ function createSkillCheckoutAttemptToolDefinition(input) {
16610
+ return {
16611
+ identity: { serverId: "opengeni", toolName: "skill_checkout" },
16612
+ modelName: "skill_checkout",
16613
+ codemodePath: ["opengeni", "skill_checkout"],
16614
+ title: "Check out Skill files",
16615
+ description: "Copy a Skill to a fresh sandbox-relative directory for execution or larger edits. Starts the sandbox if needed. Never overwrites an existing directory and does not publish changes. Retain the returned revision and scope version for skill_publish. Use skill_read for ordinary reading without a sandbox.",
16616
+ inputSchema: {
16617
+ type: "object",
16618
+ properties: {
16619
+ skill: { type: "string", minLength: 1, maxLength: 512 },
16620
+ directory: { type: "string", minLength: 1, maxLength: 1024 }
16621
+ },
16622
+ required: ["skill", "directory"],
16623
+ additionalProperties: false
16624
+ },
16625
+ annotations: {
16626
+ readOnlyHint: false,
16627
+ destructiveHint: false,
16628
+ idempotentHint: false,
16629
+ openWorldHint: false
16630
+ },
16631
+ source: "opengeni",
16632
+ approval: "none",
16633
+ execute: async (args) => {
16634
+ await input.authorize();
16635
+ const skill = await input.load(args.skill);
16636
+ const copied = await checkoutSkillDirectory(
16637
+ await input.filesystem(),
16638
+ args.directory,
16639
+ skill.files
16640
+ );
16641
+ const output = {
16642
+ ...copied,
16643
+ skillId: skill.skillId,
16644
+ revisionId: skill.revisionId,
16645
+ scopeVersion: skill.scopeVersion
16646
+ };
16647
+ return {
16648
+ isError: false,
16649
+ content: [{ type: "text", text: JSON.stringify(output) }],
16650
+ structuredContent: output
16651
+ };
16652
+ }
16653
+ };
16654
+ }
16655
+ function createSkillPublishAttemptToolDefinition(input) {
16656
+ return {
16657
+ identity: { serverId: "opengeni", toolName: "skill_publish" },
16658
+ modelName: "skill_publish",
16659
+ codemodePath: ["opengeni", "skill_publish"],
16660
+ title: "Publish Skill directory",
16661
+ description: "Save a complete sandbox Skill directory through the same Learning-controlled service as skill_save. Reads UTF-8 text files directly; do not serialize the directory into arguments. Files missing from the directory are removed from the new revision. Supply the checkout revision and scope version; stale edits are refused. The result reports whether the change is live or pending approval.",
16662
+ inputSchema: {
16663
+ type: "object",
16664
+ properties: {
16665
+ operationId: { type: "string", format: "uuid" },
16666
+ skillId: { type: "string", format: "uuid" },
16667
+ expectedRevisionId: { type: ["string", "null"], format: "uuid" },
16668
+ expectedScopeVersion: { type: "integer", minimum: 0 },
16669
+ directory: { type: "string", minLength: 1, maxLength: 1024 },
16670
+ reason: { type: "string", minLength: 1, maxLength: 2e3 }
16671
+ },
16672
+ required: [
16673
+ "operationId",
16674
+ "skillId",
16675
+ "expectedRevisionId",
16676
+ "expectedScopeVersion",
16677
+ "directory",
16678
+ "reason"
16679
+ ],
16680
+ additionalProperties: false
16681
+ },
16682
+ annotations: {
16683
+ readOnlyHint: false,
16684
+ destructiveHint: false,
16685
+ idempotentHint: true,
16686
+ openWorldHint: false
16687
+ },
16688
+ source: "opengeni",
16689
+ approval: "none",
16690
+ execute: async (args) => {
16691
+ await input.authorize();
16692
+ const artifact = await readSkillDirectory(await input.filesystem(), args.directory);
16693
+ const output = await input.save({
16694
+ operationId: args.operationId,
16695
+ skillId: args.skillId,
16696
+ expectedRevisionId: args.expectedRevisionId,
16697
+ expectedScopeVersion: args.expectedScopeVersion,
16698
+ files: artifact.files,
16699
+ reason: args.reason
16700
+ });
16701
+ return {
16702
+ isError: false,
16703
+ content: [{ type: "text", text: JSON.stringify(output) }],
16704
+ structuredContent: output
16705
+ };
16706
+ }
16707
+ };
16708
+ }
16709
+
16710
+ // src/activities/agent-turn/skill-tools.ts
16711
+ function createWorkspaceSkillTools(input) {
16712
+ const context = {
16713
+ accountId: input.accountId,
16714
+ workspaceId: input.workspaceId,
16715
+ ...input.subjectId ? { subjectId: input.subjectId } : {}
16716
+ };
16717
+ const authorize = () => assertSkillReadAttempt(input.db, { ...context, actor: input.actor });
16718
+ const selected = new Map(input.selected.map((entry) => [entry.id, entry.artifact]));
16719
+ const list = async () => (await listSkillDescriptors(input.db, context)).filter(
16720
+ (entry) => entry.activationMode === "workspace_managed"
16721
+ );
16722
+ const load = async (identifier) => {
16723
+ const exact = selected.get(identifier);
16724
+ if (exact) return exact.files;
16725
+ const descriptors = await list();
16726
+ const exactWorkspace = descriptors.find((entry) => entry.id === identifier);
16727
+ const matches = exactWorkspace ? [exactWorkspace] : descriptors.filter((entry) => entry.title === identifier || entry.stableKey === identifier);
16728
+ const selectedMatches = [...selected.entries()].filter(
16729
+ ([, artifact]) => artifact.name === identifier
16730
+ );
16731
+ if (!exactWorkspace && matches.length + selectedMatches.length > 1)
16732
+ throw new Error(
16733
+ "Multiple Skills match that name. Use the Skill id from the index or search."
16734
+ );
16735
+ if (!matches.length && selectedMatches.length === 1) return selectedMatches[0][1].files;
16736
+ const match = matches[0];
16737
+ if (!match) throw new Error("Skill is not available in this session.");
16738
+ const record5 = await readSkill(input.db, context, match.id);
16739
+ if (!record5 || record5.status !== "active" || !record5.activeRevisionId || record5.revisionId !== record5.activeRevisionId)
16740
+ throw new Error("Skill is no longer active. Search again for current Skills.");
16741
+ return {
16742
+ skillId: record5.id,
16743
+ revisionId: record5.activeRevisionId,
16744
+ scopeVersion: record5.scopeVersion,
16745
+ ...match.installationVersion !== null ? { installationVersion: match.installationVersion } : {},
16746
+ files: record5.files
16747
+ };
16748
+ };
16749
+ const withConfirmation = async (receipt) => {
16750
+ const reviewResolution = receipt.skillReview ? await skillReviewResolution(input.db, context, receipt.skillReview) : void 0;
16751
+ return {
16752
+ ...receipt,
16753
+ ...reviewResolution ? { reviewResolution } : {},
16754
+ ...receipt.skillReview && reviewResolution === "pending" ? { humanInput: skillReviewHumanInput(receipt.skillReview) } : {}
16755
+ };
16756
+ };
16757
+ const save = async (request) => {
16758
+ const artifact = buildPortableSkillArtifact3(request.files);
16759
+ const base = request.expectedRevisionId ? await readSkill(input.db, context, request.skillId, request.expectedRevisionId) : null;
16760
+ return withConfirmation(
16761
+ await saveSkill(input.db, {
16762
+ ...context,
16763
+ ...request,
16764
+ actor: input.actor,
16765
+ files: [...artifact.files],
16766
+ stableKey: base?.stableKey ?? `authored-${request.skillId.replaceAll("-", "")}`
16767
+ })
16768
+ );
16769
+ };
16770
+ return [
16771
+ createSkillReadAttemptToolDefinition({ authorize, load }),
16772
+ createSkillSearchAttemptToolDefinition({
16773
+ authorize,
16774
+ listWorkspace: async () => [
16775
+ ...(await list()).map((entry) => ({
16776
+ id: entry.id,
16777
+ name: entry.title,
16778
+ description: entry.description,
16779
+ revisionId: entry.revisionId,
16780
+ scopeVersion: entry.scopeVersion,
16781
+ ...entry.installationVersion !== null ? { installationVersion: entry.installationVersion } : {}
16782
+ })),
16783
+ ...input.selected.map((entry) => ({
16784
+ id: entry.id,
16785
+ name: entry.artifact.name,
16786
+ description: entry.artifact.description || entry.artifact.name,
16787
+ source: entry.id.startsWith("builtin:") ? "builtin" : entry.id.startsWith("session:") ? "session" : "pack"
16788
+ }))
16789
+ ],
16790
+ publicSearch: createPublicSkillSearchClient(input.settings)
16791
+ }),
16792
+ createSkillSaveAttemptToolDefinition({
16793
+ authorize,
16794
+ save,
16795
+ load: async (skillId, revisionId) => {
16796
+ const record5 = await readSkill(input.db, context, skillId, revisionId);
16797
+ if (!record5?.revisionId) throw new Error("Skill edit base is unavailable.");
16798
+ return { revisionId: record5.revisionId, files: record5.files };
16799
+ }
16800
+ }),
16801
+ createSkillInstallAttemptToolDefinition({
16802
+ authorize,
16803
+ install: async (request) => {
16804
+ const requestIdentity = {
16805
+ operation: "skill_install",
16806
+ source: request.source,
16807
+ expectedInstallationVersion: request.expectedInstallationVersion ?? null,
16808
+ reason: request.reason,
16809
+ owner: "direct"
16810
+ };
16811
+ const replay = await replayPortableSkillInstall(input.db, {
16812
+ ...context,
16813
+ actor: input.actor,
16814
+ operationId: request.operationId,
16815
+ requestIdentity
16816
+ });
16817
+ if (replay) return withConfirmation(replay.skillReceipt);
16818
+ let source;
16819
+ if (request.source.startsWith("library:")) {
16820
+ const loaded = loadSkillLibrarySkill(request.source.slice("library:".length));
16821
+ source = {
16822
+ capabilityId: `skill:${loaded.entry.id}`,
16823
+ pluginKey: `skill/library/${loaded.entry.id}`,
16824
+ source: "library",
16825
+ sourceUrl: loaded.entry.sourceUrl,
16826
+ repositoryUrl: skillLibraryRepositoryUrl(loaded.entry.sourceUrl),
16827
+ version: loaded.entry.version,
16828
+ sourceCommit: loaded.entry.sourceCommit,
16829
+ sourcePath: loaded.entry.relativePath,
16830
+ name: loaded.entry.name,
16831
+ description: loaded.entry.description,
16832
+ contentSha256: loaded.entry.contentSha256,
16833
+ totalBytes: loaded.skill.files.reduce(
16834
+ (total, file) => total + Buffer.byteLength(file.content),
16835
+ 0
16836
+ ),
16837
+ files: fileMetadata(loaded.skill.files),
16838
+ provenance: "platform",
16839
+ sourceProvenance: loaded.entry.provenance,
16840
+ category: loaded.entry.category,
16841
+ tags: [...loaded.entry.tags],
16842
+ license: loaded.entry.license
16843
+ };
16844
+ } else {
16845
+ const resolved = await resolveSkillImport(
16846
+ request.source,
16847
+ createGitHubSkillSourceClient(input.settings)
16848
+ );
16849
+ source = {
16850
+ capabilityId: portableSkillCapabilityId(resolved.preview),
16851
+ pluginKey: portableSkillPluginKey(resolved.preview),
16852
+ source: resolved.preview.source,
16853
+ sourceUrl: resolved.preview.sourceUrl,
16854
+ repositoryUrl: resolved.preview.repositoryUrl,
16855
+ version: resolved.preview.sourceCommit,
16856
+ sourceCommit: resolved.preview.sourceCommit,
16857
+ sourcePath: resolved.preview.sourcePath,
16858
+ name: resolved.preview.name,
16859
+ description: resolved.preview.description,
16860
+ contentSha256: resolved.preview.contentSha256,
16861
+ totalBytes: resolved.preview.totalBytes,
16862
+ files: fileMetadata(resolved.files)
16863
+ };
16864
+ }
16865
+ const installed = await installPortableSkill(input.db, {
16866
+ ...context,
16867
+ ...source,
16868
+ subjectId: `service:skill-attempt:${input.actor.attemptId}`,
16869
+ skillActor: input.actor,
16870
+ skillOperationId: request.operationId,
16871
+ skillRequestIdentity: requestIdentity,
16872
+ ...request.expectedInstallationVersion !== void 0 ? {
16873
+ expectedInstallationVersion: request.expectedInstallationVersion
16874
+ } : {}
16875
+ });
16876
+ return withConfirmation(installed.skillReceipt);
16877
+ }
16878
+ }),
16879
+ createSkillCheckoutAttemptToolDefinition({
16880
+ authorize,
16881
+ filesystem: input.filesystem,
16882
+ load: async (skill) => {
16883
+ const content = await load(skill);
16884
+ if (!("files" in content))
16885
+ return { skillId: skill, revisionId: null, scopeVersion: null, files: content };
16886
+ return content;
16887
+ }
16888
+ }),
16889
+ createSkillPublishAttemptToolDefinition({ authorize, filesystem: input.filesystem, save })
16890
+ ];
16891
+ }
16892
+ function fileMetadata(files) {
16893
+ return files.map((file) => ({
16894
+ ...file,
16895
+ byteSize: Buffer.byteLength(file.content),
16896
+ contentSha256: createHash11("sha256").update(file.content, "utf8").digest("hex")
16897
+ }));
16898
+ }
16899
+
16900
+ // src/activities/agent-turn/skill-selection.ts
16901
+ import { loadNativeToolSkillArtifacts } from "@opengeni/runtime";
16902
+ import { loadSkillManagementSkill } from "@opengeni/runtime/skill-library";
16903
+ function configuredBundledSkillNames(context) {
16904
+ const tools = new Set(context.firstPartyTools);
16905
+ const artifacts = () => tools.has("editable_artifact_list") && tools.has("editable_artifact_get");
16906
+ const definitions = [
16907
+ { name: "opengeni-skills", include: () => true },
16908
+ { name: "opengeni-projects", include: () => true },
16909
+ { name: "opengeni-documents", include: artifacts },
16910
+ { name: "opengeni-spreadsheets", include: artifacts },
16911
+ { name: "opengeni-presentations", include: artifacts },
16912
+ {
16913
+ name: "opengeni-sites",
16914
+ include: () => tools.has("artifacts_create") && tools.has("artifacts_publish")
16915
+ },
16916
+ { name: "opengeni-video-generation", include: () => context.videoGenerationEnabled }
16917
+ ];
16918
+ return definitions.filter(
16919
+ (definition) => definition.include() && (context.bundledSkillIds === void 0 || context.bundledSkillIds.includes(`builtin:${definition.name}`))
16920
+ ).map((definition) => definition.name);
16921
+ }
16922
+ function loadConfiguredBundledSkills(context) {
16923
+ const names = new Set(configuredBundledSkillNames(context));
16924
+ const artifacts = loadNativeToolSkillArtifacts({
16925
+ projects: names.has("opengeni-projects"),
16926
+ editableArtifacts: [
16927
+ "opengeni-documents",
16928
+ "opengeni-spreadsheets",
16929
+ "opengeni-presentations"
16930
+ ].some((name) => names.has(name)),
16931
+ sites: names.has("opengeni-sites"),
16932
+ videoGeneration: names.has("opengeni-video-generation")
16933
+ });
16934
+ return [...artifacts, ...names.has("opengeni-skills") ? [loadSkillManagementSkill()] : []].filter((artifact) => names.has(artifact.name)).map((artifact) => ({ id: `builtin:${artifact.name}`, artifact }));
16935
+ }
16936
+
16584
16937
  // src/activities/agent-turn/tool-environment.ts
16585
16938
  async function prepareTurnToolPolicy(deps) {
16586
16939
  const {
@@ -16907,7 +17260,82 @@ async function prepareTurnToolRuntime(deps) {
16907
17260
  outcome
16908
17261
  })
16909
17262
  };
17263
+ const skillConfiguration = await getWorkspaceVideoGenerationPolicy(db, input.workspaceId);
17264
+ const bundledSkills = loadConfiguredBundledSkills({
17265
+ bundledSkillIds: session.bundledSkillIds,
17266
+ firstPartyTools: selectedFirstPartyMcpTools,
17267
+ videoGenerationEnabled: skillConfiguration.defaultModelId !== null && skillConfiguration.enabledModelIds.length > 0
17268
+ });
17269
+ const selectedSkills = [
17270
+ ...bundledSkills,
17271
+ ...deps.selectedSkillActivations.map((entry) => ({ id: entry.id, artifact: entry.artifact })),
17272
+ ...session.skills.map((skill) => ({
17273
+ id: `session:${session.id}:${skill.name}`,
17274
+ artifact: skill
17275
+ }))
17276
+ ];
17277
+ const sharedSkillDescriptors = await listSkillDescriptors2(db, {
17278
+ accountId: input.accountId,
17279
+ workspaceId: input.workspaceId,
17280
+ ...deps.fileAuthoritySubjectId ? { subjectId: deps.fileAuthoritySubjectId } : {}
17281
+ });
17282
+ const skillCatalog = [
17283
+ ...sharedSkillDescriptors.filter((entry) => entry.activationMode === "workspace_managed").map((entry) => ({
17284
+ id: entry.id,
17285
+ name: entry.title,
17286
+ description: entry.description
17287
+ })),
17288
+ ...selectedSkills.map((entry) => ({
17289
+ id: entry.id,
17290
+ name: entry.artifact.name,
17291
+ description: entry.artifact.description || entry.artifact.name
17292
+ }))
17293
+ ];
17294
+ const skillTools = createWorkspaceSkillTools({
17295
+ db,
17296
+ settings: runSettings,
17297
+ accountId: input.accountId,
17298
+ workspaceId: input.workspaceId,
17299
+ ...deps.fileAuthoritySubjectId ? { subjectId: deps.fileAuthoritySubjectId } : {},
17300
+ actor: {
17301
+ kind: "agent",
17302
+ sessionId: input.sessionId,
17303
+ turnId: turn.id,
17304
+ attemptId: input.attemptId,
17305
+ executionGeneration: attempt.executionGeneration
17306
+ },
17307
+ selected: selectedSkills,
17308
+ filesystem: async () => {
17309
+ throwIfWorkerShuttingDown();
17310
+ throwIfTurnCancelled();
17311
+ const access = await resolveTurnSandboxAccess(
17312
+ sandboxState,
17313
+ media.sdkOwnedSandboxSession,
17314
+ "Skill checkout/publish requires a sandbox or Connected Machine."
17315
+ );
17316
+ const machineRoot = sandboxState.machinePrimarySession?.workspaceRoot;
17317
+ const runAs = sandboxRunAs4(runSettings);
17318
+ const channel = new SandboxChannelAService3({
17319
+ session: access.session,
17320
+ workspaceRoot: machineRoot ?? "/workspace",
17321
+ ...machineRoot ? { providerPathMode: "workspace-relative" } : {},
17322
+ leaseEpoch: access.leaseEpoch,
17323
+ emit: async (events) => {
17324
+ await eventing.publish?.(events, true);
17325
+ },
17326
+ ...runAs ? { runAs } : {}
17327
+ });
17328
+ return guardSkillFilesystem(channel, {
17329
+ assertActive: () => {
17330
+ throwIfWorkerShuttingDown();
17331
+ throwIfTurnCancelled();
17332
+ },
17333
+ runMutation: async (mutation) => access.sandbox && !routingOn ? runWorkspaceMutationForSandbox(access.sandbox, "skillCheckout", mutation) : mutation()
17334
+ });
17335
+ }
17336
+ });
16910
17337
  const attemptToolDefinitions = [
17338
+ ...skillTools,
16911
17339
  createListModelsAttemptToolDefinition({
16912
17340
  currentModelId: turnExecutionPolicy.productModelId,
16913
17341
  load: async () => {
@@ -17196,7 +17624,11 @@ async function prepareTurnToolRuntime(deps) {
17196
17624
  connectorActionPolicy,
17197
17625
  generateSessionTitleInParallel: titleToolPlan.generateTitleInParallel,
17198
17626
  postToolPreparationStartedAt,
17199
- preparationIndependentToolNames: titleToolPlan.preparationIndependentToolNames
17627
+ preparationIndependentToolNames: [
17628
+ ...titleToolPlan.preparationIndependentToolNames,
17629
+ "skill_read"
17630
+ ],
17631
+ skillCatalog
17200
17632
  };
17201
17633
  }
17202
17634
 
@@ -17390,9 +17822,12 @@ import {
17390
17822
  resolveXaiProviderAccountAuthoritySnapshotForAcceptance,
17391
17823
  getXaiSessionAccountPin as getXaiSessionAccountPin2,
17392
17824
  setXaiSessionAccountPin as setXaiSessionAccountPin2,
17393
- getWorkspaceVideoGenerationPolicy,
17825
+ getWorkspaceVideoGenerationPolicy as getWorkspaceVideoGenerationPolicy2,
17394
17826
  loadWorkspaceVercelAiGatewayCredentialLease
17395
17827
  } from "@opengeni/db";
17828
+ import {
17829
+ formatSkillCatalog
17830
+ } from "@opengeni/runtime";
17396
17831
  import {
17397
17832
  serviceTierForLatencyMode as serviceTierForLatencyMode2,
17398
17833
  environmentsEncryptionKeyBytes as environmentsEncryptionKeyBytes3,
@@ -18590,8 +19025,6 @@ async function buildTurnAgent(deps) {
18590
19025
  workspaceMemory,
18591
19026
  rigVersion,
18592
19027
  rigName,
18593
- packRuntime,
18594
- installedSkillRuntime,
18595
19028
  buildCompanyBrainContributionReceiptFor,
18596
19029
  promptCacheKey,
18597
19030
  workspaceVariableSet,
@@ -18774,7 +19207,7 @@ async function buildTurnAgent(deps) {
18774
19207
  }
18775
19208
  };
18776
19209
  })();
18777
- const videoGenerationPolicy = await getWorkspaceVideoGenerationPolicy(db, input.workspaceId);
19210
+ const videoGenerationPolicy = await getWorkspaceVideoGenerationPolicy2(db, input.workspaceId);
18778
19211
  const videoGenerationEnabled = videoGenerationPolicy.defaultModelId !== null && videoGenerationPolicy.enabledModelIds.length > 0;
18779
19212
  let videoGenerationCredential = null;
18780
19213
  if (objectStorage && videoGenerationEnabled) {
@@ -18925,30 +19358,10 @@ async function buildTurnAgent(deps) {
18925
19358
  turnExecutionPolicy.latencyMode
18926
19359
  );
18927
19360
  const approvedToolCallId = approvedConnectorActionCallId(trigger);
18928
- const runtimeSkillActivations = [
18929
- ...installedSkillRuntime.activations,
18930
- ...packRuntime.skillActivations,
18931
- ...session.skills.map((skill) => ({
18932
- source: "session",
18933
- id: `session:${session.id}:${skill.name}`,
18934
- artifact: {
18935
- name: skill.name,
18936
- description: skill.description ?? null,
18937
- files: skill.files.map((file) => ({
18938
- path: file.path,
18939
- content: file.content
18940
- }))
18941
- },
18942
- reason: "attached to session"
18943
- }))
18944
- ];
18945
- const modelVisibleRuntimeSkillActivations = modelVisibleCompanyBrainSkillActivations(
18946
- eventing.modelRunSettings.sandboxBackend,
18947
- runtimeSkillActivations
18948
- );
19361
+ const modelVisibleSkillCatalogText = formatSkillCatalog(deps.skillCatalog);
18949
19362
  try {
18950
19363
  eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
18951
- buildCompanyBrainContributionReceiptFor(modelVisibleRuntimeSkillActivations)
19364
+ buildCompanyBrainContributionReceiptFor(modelVisibleSkillCatalogText)
18952
19365
  );
18953
19366
  } catch {
18954
19367
  }
@@ -19049,7 +19462,8 @@ async function buildTurnAgent(deps) {
19049
19462
  }
19050
19463
  ),
19051
19464
  onRetainableSessionImageOutput: media.retainSessionImageAtToolBoundary,
19052
- ...runtimeSkillActivations.length > 0 ? { skillActivations: runtimeSkillActivations } : {},
19465
+ skillCatalog: deps.skillCatalog,
19466
+ serverSkillReading: true,
19053
19467
  ...!structuredWorkspacePolicyActive && workspaceAgentInstructions ? { instructionsTemplate: workspaceAgentInstructions } : {},
19054
19468
  ...workspaceGovernance ? { workspaceGovernance } : {},
19055
19469
  ...workspaceMemory ? { workspaceMemory } : {},
@@ -19105,7 +19519,7 @@ async function buildTurnAgent(deps) {
19105
19519
  }
19106
19520
  return {
19107
19521
  agent,
19108
- modelVisibleRuntimeSkillActivations,
19522
+ modelVisibleSkillCatalogText,
19109
19523
  postAgentPreparationStartedAt
19110
19524
  };
19111
19525
  }
@@ -19431,7 +19845,6 @@ function createRunAgentTurnActivity(services) {
19431
19845
  const {
19432
19846
  runtimePreparationStartedAt,
19433
19847
  packRuntime,
19434
- installedSkillRuntime,
19435
19848
  rigVersion,
19436
19849
  rigName,
19437
19850
  agentHumanInputEnabled,
@@ -20002,6 +20415,7 @@ function createRunAgentTurnActivity(services) {
20002
20415
  ).values()
20003
20416
  ];
20004
20417
  const toolRuntime = await prepareTurnToolRuntime({
20418
+ selectedSkillActivations: packRuntime.skillActivations,
20005
20419
  input,
20006
20420
  catalogSourceSettings,
20007
20421
  db,
@@ -20048,6 +20462,7 @@ function createRunAgentTurnActivity(services) {
20048
20462
  preparationIndependentToolNames
20049
20463
  } = toolRuntime;
20050
20464
  const builtAgent = await buildTurnAgent({
20465
+ skillCatalog: toolRuntime.skillCatalog,
20051
20466
  input,
20052
20467
  db,
20053
20468
  runtime,
@@ -20082,8 +20497,6 @@ function createRunAgentTurnActivity(services) {
20082
20497
  workspaceMemory,
20083
20498
  rigVersion,
20084
20499
  rigName,
20085
- packRuntime,
20086
- installedSkillRuntime,
20087
20500
  buildCompanyBrainContributionReceiptFor,
20088
20501
  promptCacheKey,
20089
20502
  workspaceVariableSet,
@@ -20105,7 +20518,7 @@ function createRunAgentTurnActivity(services) {
20105
20518
  postToolPreparationStartedAt,
20106
20519
  codexContext
20107
20520
  });
20108
- const { agent, modelVisibleRuntimeSkillActivations, postAgentPreparationStartedAt } = builtAgent;
20521
+ const { agent, modelVisibleSkillCatalogText, postAgentPreparationStartedAt } = builtAgent;
20109
20522
  await bindLazySandboxProvisioner({
20110
20523
  ...sandboxRoute,
20111
20524
  input,
@@ -20159,7 +20572,7 @@ function createRunAgentTurnActivity(services) {
20159
20572
  companyBrainContributionReceiptRecorded = true;
20160
20573
  try {
20161
20574
  const companyBrainContributionReceipt = buildCompanyBrainContributionReceiptFor(
20162
- modelVisibleRuntimeSkillActivations
20575
+ modelVisibleSkillCatalogText
20163
20576
  );
20164
20577
  eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
20165
20578
  companyBrainContributionReceipt
@@ -21557,4 +21970,4 @@ export {
21557
21970
  createTurnActivities,
21558
21971
  createTurnActivitiesFromServices
21559
21972
  };
21560
- //# sourceMappingURL=activities-turn-57AOUNYN.js.map
21973
+ //# sourceMappingURL=activities-turn-V7J34ZOF.js.map