@opengeni/worker-bundle 0.27.0-canary.0 → 0.27.2-canary.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.
- package/dist/activities/agent-turn/agent-build.d.ts +3 -4
- package/dist/activities/agent-turn/governance-model.d.ts +2 -3
- package/dist/activities/agent-turn/skill-checkout.d.ts +21 -0
- package/dist/activities/agent-turn/skill-install.d.ts +12 -0
- package/dist/activities/agent-turn/skill-read.d.ts +15 -0
- package/dist/activities/agent-turn/skill-save.d.ts +26 -0
- package/dist/activities/agent-turn/skill-search.d.ts +16 -0
- package/dist/activities/agent-turn/skill-selection.d.ts +17 -0
- package/dist/activities/agent-turn/skill-tools.d.ts +20 -0
- package/dist/activities/agent-turn/skill-transfer.d.ts +26 -0
- package/dist/activities/agent-turn/tool-environment.d.ts +7 -0
- package/dist/activities/parent-wake.d.ts +12 -2
- package/dist/activities/run-input.d.ts +11 -5
- package/dist/activities/sandbox-lease.d.ts +5 -4
- package/dist/activities/types.d.ts +4 -2
- package/dist/activities/workflow-wake.d.ts +2 -4
- package/dist/{activities-control-VMA3XMHE.js → activities-control-WZRFEIJH.js} +103 -26
- package/dist/activities-control-WZRFEIJH.js.map +1 -0
- package/dist/{activities-turn-57AOUNYN.js → activities-turn-V7J34ZOF.js} +945 -532
- package/dist/activities-turn-V7J34ZOF.js.map +1 -0
- package/dist/{chunk-D4ZEFOYH.js → chunk-BARTLVBK.js} +1 -1
- package/dist/chunk-BARTLVBK.js.map +1 -0
- package/dist/{chunk-7LS42PHP.js → chunk-C54VDT6I.js} +590 -34
- package/dist/chunk-C54VDT6I.js.map +1 -0
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/model-context-contributions.d.ts +2 -0
- package/dist/observability-metrics.d.ts +1 -1
- package/dist/workflow-bundle.js +1 -1
- package/package.json +17 -17
- package/src/activities/agent-turn/agent-build.ts +8 -34
- package/src/activities/agent-turn/errors.ts +4 -0
- package/src/activities/agent-turn/governance-model.ts +15 -19
- package/src/activities/agent-turn/run.ts +4 -6
- package/src/activities/agent-turn/sandbox-provision.ts +9 -0
- package/src/activities/agent-turn/skill-checkout.ts +124 -0
- package/src/activities/agent-turn/skill-install.ts +57 -0
- package/src/activities/agent-turn/skill-read.ts +117 -0
- package/src/activities/agent-turn/skill-save.ts +124 -0
- package/src/activities/agent-turn/skill-search.ts +110 -0
- package/src/activities/agent-turn/skill-selection.ts +53 -0
- package/src/activities/agent-turn/skill-tools.ts +268 -0
- package/src/activities/agent-turn/skill-transfer.ts +137 -0
- package/src/activities/agent-turn/tool-environment.ts +93 -1
- package/src/activities/automations.ts +3 -1
- package/src/activities/context-compaction.ts +26 -2
- package/src/activities/parent-wake.ts +66 -5
- package/src/activities/run-input.ts +88 -12
- package/src/activities/sandbox-lease.ts +77 -20
- package/src/activities/scheduled-tasks.ts +2 -0
- package/src/activities/types.ts +4 -2
- package/src/activities/workflow-wake.ts +42 -5
- package/src/index.ts +3 -1
- package/src/model-context-contributions.ts +18 -2
- package/src/observability-metrics.ts +2 -0
- package/src/sandbox-routing.ts +42 -1
- package/dist/activities-control-VMA3XMHE.js.map +0 -1
- package/dist/activities-turn-57AOUNYN.js.map +0 -1
- package/dist/chunk-7LS42PHP.js.map +0 -1
- package/dist/chunk-D4ZEFOYH.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/worker-bundle",
|
|
3
|
-
"version": "0.27.
|
|
3
|
+
"version": "0.27.2-canary.0",
|
|
4
4
|
"description": "OpenGeni worker entry and reusable embedded lifecycle, shipped with a release-coherent pre-bundled Temporal workflow artifact.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -54,22 +54,22 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@llamaindex/liteparse": "2.14.2",
|
|
57
|
-
"@opengeni/agent-proto": "^0.5.1-canary.
|
|
58
|
-
"@opengeni/capabilities": "^0.3.3-canary.
|
|
59
|
-
"@opengeni/codemode": "^0.5.
|
|
60
|
-
"@opengeni/codex": "^0.2.22-canary.
|
|
61
|
-
"@opengeni/config": "^1.0.
|
|
62
|
-
"@opengeni/contracts": "^2.
|
|
63
|
-
"@opengeni/core": "^2.8.
|
|
64
|
-
"@opengeni/db": "^4.1
|
|
65
|
-
"@opengeni/documents": "^0.8.
|
|
66
|
-
"@opengeni/events": "^0.4.
|
|
67
|
-
"@opengeni/github": "^0.7.
|
|
68
|
-
"@opengeni/network": "^0.3.1-canary.
|
|
69
|
-
"@opengeni/observability": "^0.8.
|
|
70
|
-
"@opengeni/runtime": "^2.4.
|
|
71
|
-
"@opengeni/storage": "^0.2.
|
|
72
|
-
"@opengeni/xai-subscription": "^0.1.4-canary.
|
|
57
|
+
"@opengeni/agent-proto": "^0.5.1-canary.20",
|
|
58
|
+
"@opengeni/capabilities": "^0.3.3-canary.2",
|
|
59
|
+
"@opengeni/codemode": "^0.5.2-canary.0",
|
|
60
|
+
"@opengeni/codex": "^0.2.22-canary.2",
|
|
61
|
+
"@opengeni/config": "^1.0.3-canary.0",
|
|
62
|
+
"@opengeni/contracts": "^2.15.1-canary.0",
|
|
63
|
+
"@opengeni/core": "^2.8.2-canary.0",
|
|
64
|
+
"@opengeni/db": "^4.2.1-canary.0",
|
|
65
|
+
"@opengeni/documents": "^0.8.22-canary.0",
|
|
66
|
+
"@opengeni/events": "^0.4.20-canary.0",
|
|
67
|
+
"@opengeni/github": "^0.7.6-canary.0",
|
|
68
|
+
"@opengeni/network": "^0.3.1-canary.2",
|
|
69
|
+
"@opengeni/observability": "^0.8.22-canary.0",
|
|
70
|
+
"@opengeni/runtime": "^2.4.2-canary.0",
|
|
71
|
+
"@opengeni/storage": "^0.2.123-canary.0",
|
|
72
|
+
"@opengeni/xai-subscription": "^0.1.4-canary.2",
|
|
73
73
|
"@temporalio/activity": "^1.17.0",
|
|
74
74
|
"@temporalio/client": "^1.17.0",
|
|
75
75
|
"@temporalio/worker": "^1.17.0",
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
loadWorkspaceVercelAiGatewayCredentialLease,
|
|
9
9
|
} from "@opengeni/db";
|
|
10
10
|
import {
|
|
11
|
+
formatSkillCatalog,
|
|
11
12
|
type AttemptConnectorActionBinding,
|
|
12
13
|
type BuildAgentOptions,
|
|
13
14
|
type ConnectorActionPolicyHooks,
|
|
@@ -34,10 +35,7 @@ import { VideoReferenceInputError } from "../video-reference-staging";
|
|
|
34
35
|
import { rigProviderImageSourceImage } from "../packs";
|
|
35
36
|
import type { TurnActivityServices as ActivityServices, RunAgentTurnInput } from "../types";
|
|
36
37
|
import { recordTurnStartupPhase } from "../../observability-metrics";
|
|
37
|
-
import {
|
|
38
|
-
modelVisibleCompanyBrainSkillActivations,
|
|
39
|
-
summarizeCompanyBrainContributions,
|
|
40
|
-
} from "../../model-context-contributions";
|
|
38
|
+
import { summarizeCompanyBrainContributions } from "../../model-context-contributions";
|
|
41
39
|
import { createTurnCredentialLeases } from "./credential-leases";
|
|
42
40
|
import { createTurnMediaArtifacts } from "./media-artifacts";
|
|
43
41
|
import { executeGatewayImageGeneration } from "../gateway-image-generation";
|
|
@@ -75,6 +73,7 @@ import { resolveTurnSandboxAccess } from "./turn-sandbox-access";
|
|
|
75
73
|
import { resolveVideoReferenceSandboxAccess } from "./video-reference-sandbox";
|
|
76
74
|
|
|
77
75
|
export type BuildTurnAgentDeps = {
|
|
76
|
+
skillCatalog: NonNullable<BuildAgentOptions["skillCatalog"]>;
|
|
78
77
|
input: RunAgentTurnInput;
|
|
79
78
|
db: ActivityServices["db"];
|
|
80
79
|
runtime: ActivityServices["runtime"];
|
|
@@ -109,8 +108,6 @@ export type BuildTurnAgentDeps = {
|
|
|
109
108
|
workspaceMemory: GovernanceModelOk["workspaceMemory"];
|
|
110
109
|
rigVersion: GovernanceModelOk["rigVersion"];
|
|
111
110
|
rigName: GovernanceModelOk["rigName"];
|
|
112
|
-
packRuntime: GovernanceModelOk["packRuntime"];
|
|
113
|
-
installedSkillRuntime: GovernanceModelOk["installedSkillRuntime"];
|
|
114
111
|
buildCompanyBrainContributionReceiptFor: GovernanceModelOk["buildCompanyBrainContributionReceiptFor"];
|
|
115
112
|
promptCacheKey: CompactionPrepOk["promptCacheKey"];
|
|
116
113
|
workspaceVariableSet: Awaited<ReturnType<typeof loadWorkspaceEnvironmentForRunWithCredentials>>;
|
|
@@ -170,8 +167,6 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
|
|
|
170
167
|
workspaceMemory,
|
|
171
168
|
rigVersion,
|
|
172
169
|
rigName,
|
|
173
|
-
packRuntime,
|
|
174
|
-
installedSkillRuntime,
|
|
175
170
|
buildCompanyBrainContributionReceiptFor,
|
|
176
171
|
promptCacheKey,
|
|
177
172
|
workspaceVariableSet,
|
|
@@ -559,30 +554,10 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
|
|
|
559
554
|
turnExecutionPolicy.latencyMode,
|
|
560
555
|
);
|
|
561
556
|
const approvedToolCallId = approvedConnectorActionCallId(trigger);
|
|
562
|
-
const
|
|
563
|
-
...installedSkillRuntime.activations,
|
|
564
|
-
...packRuntime.skillActivations,
|
|
565
|
-
...session.skills.map((skill) => ({
|
|
566
|
-
source: "session" as const,
|
|
567
|
-
id: `session:${session.id}:${skill.name}`,
|
|
568
|
-
artifact: {
|
|
569
|
-
name: skill.name,
|
|
570
|
-
description: skill.description ?? null,
|
|
571
|
-
files: skill.files.map((file) => ({
|
|
572
|
-
path: file.path,
|
|
573
|
-
content: file.content,
|
|
574
|
-
})),
|
|
575
|
-
},
|
|
576
|
-
reason: "attached to session",
|
|
577
|
-
})),
|
|
578
|
-
];
|
|
579
|
-
const modelVisibleRuntimeSkillActivations = modelVisibleCompanyBrainSkillActivations(
|
|
580
|
-
eventing.modelRunSettings.sandboxBackend,
|
|
581
|
-
runtimeSkillActivations,
|
|
582
|
-
);
|
|
557
|
+
const modelVisibleSkillCatalogText = formatSkillCatalog(deps.skillCatalog);
|
|
583
558
|
try {
|
|
584
559
|
eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
|
|
585
|
-
buildCompanyBrainContributionReceiptFor(
|
|
560
|
+
buildCompanyBrainContributionReceiptFor(modelVisibleSkillCatalogText),
|
|
586
561
|
);
|
|
587
562
|
} catch {
|
|
588
563
|
// Contribution telemetry must never change model execution semantics.
|
|
@@ -701,9 +676,8 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
|
|
|
701
676
|
promptCacheKey: input.sessionId,
|
|
702
677
|
}),
|
|
703
678
|
onRetainableSessionImageOutput: media.retainSessionImageAtToolBoundary,
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
: {}),
|
|
679
|
+
skillCatalog: deps.skillCatalog,
|
|
680
|
+
serverSkillReading: true,
|
|
707
681
|
...(!structuredWorkspacePolicyActive && workspaceAgentInstructions
|
|
708
682
|
? { instructionsTemplate: workspaceAgentInstructions }
|
|
709
683
|
: {}),
|
|
@@ -772,7 +746,7 @@ export async function buildTurnAgent(deps: BuildTurnAgentDeps) {
|
|
|
772
746
|
}
|
|
773
747
|
return {
|
|
774
748
|
agent,
|
|
775
|
-
|
|
749
|
+
modelVisibleSkillCatalogText,
|
|
776
750
|
postAgentPreparationStartedAt,
|
|
777
751
|
};
|
|
778
752
|
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
} from "@opengeni/runtime/mcp-network";
|
|
25
25
|
import { ApplicationFailure, CancelledFailure } from "@temporalio/activity";
|
|
26
26
|
import { CODEX_USAGE_EXHAUSTED_PCT } from "../codex-rotation";
|
|
27
|
+
import { RetainedAttachmentTransportLimitError } from "../run-input";
|
|
27
28
|
import type { CodexAccountStatus } from "@opengeni/db";
|
|
28
29
|
import {
|
|
29
30
|
CodexReloginRequired,
|
|
@@ -870,6 +871,9 @@ export function agentRunFailurePayload(
|
|
|
870
871
|
historyPersistenceStage?: MandatoryHistoryPersistenceStage;
|
|
871
872
|
mcpTransportDiagnostic?: McpTransportRequestFailureDiagnostic;
|
|
872
873
|
} {
|
|
874
|
+
if (error instanceof RetainedAttachmentTransportLimitError) {
|
|
875
|
+
return { error: error.message, code: "retained_attachment_transport_limit", retryable: false };
|
|
876
|
+
}
|
|
873
877
|
if (error instanceof MandatoryHistoryPersistenceError) {
|
|
874
878
|
const underlying = isSessionEventPersistenceError(error.cause)
|
|
875
879
|
? agentRunFailurePayload(error.cause, options)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
materializeRigVersionForAttempt,
|
|
3
3
|
getWorkspaceModelPolicy,
|
|
4
|
+
getFilesForSubject,
|
|
4
5
|
getWorkspace,
|
|
5
6
|
resolveCompanyBrainContextSelection,
|
|
6
7
|
getGeneratedVideoArtifact,
|
|
@@ -22,11 +23,7 @@ import {
|
|
|
22
23
|
import { settingsWithResolvedModelContext, type Settings } from "@opengeni/config";
|
|
23
24
|
import { settingsWithSessionMcpServersForRun } from "../capabilities";
|
|
24
25
|
import { resolveRigProviderImageForRun } from "@opengeni/core";
|
|
25
|
-
import {
|
|
26
|
-
resolveWorkspacePackRuntime,
|
|
27
|
-
resolveWorkspaceInstalledSkillRuntime,
|
|
28
|
-
settingsWithPackSandboxImage,
|
|
29
|
-
} from "../packs";
|
|
26
|
+
import { resolveWorkspacePackRuntime, settingsWithPackSandboxImage } from "../packs";
|
|
30
27
|
import { createModelHistoryAttachmentProjector } from "../run-input";
|
|
31
28
|
import type {
|
|
32
29
|
TurnActivityServices as ActivityServices,
|
|
@@ -88,7 +85,6 @@ export type GovernanceModelDeps = {
|
|
|
88
85
|
export type GovernanceModelOk = {
|
|
89
86
|
runtimePreparationStartedAt: number;
|
|
90
87
|
packRuntime: Awaited<ReturnType<typeof resolveWorkspacePackRuntime>>;
|
|
91
|
-
installedSkillRuntime: Awaited<ReturnType<typeof resolveWorkspaceInstalledSkillRuntime>>;
|
|
92
88
|
rigVersion:
|
|
93
89
|
| NonNullable<Awaited<ReturnType<typeof materializeRigVersionForAttempt>>>["version"]
|
|
94
90
|
| null;
|
|
@@ -99,9 +95,7 @@ export type GovernanceModelOk = {
|
|
|
99
95
|
structuredWorkspacePolicyActive: boolean;
|
|
100
96
|
workspaceMemory: string | null | undefined;
|
|
101
97
|
buildCompanyBrainContributionReceiptFor: (
|
|
102
|
-
|
|
103
|
-
typeof buildCompanyBrainContributionReceipt
|
|
104
|
-
>[0]["skillActivations"],
|
|
98
|
+
skillCatalogText: string,
|
|
105
99
|
) => ReturnType<typeof buildCompanyBrainContributionReceipt>;
|
|
106
100
|
logicalSandboxSettings: Settings;
|
|
107
101
|
verifiedRigProviderImageId: string | undefined;
|
|
@@ -201,13 +195,11 @@ export async function prepareGovernanceAndModel(
|
|
|
201
195
|
// snapshots below so its receipt stays exact.
|
|
202
196
|
const [
|
|
203
197
|
packRuntime,
|
|
204
|
-
installedSkillRuntime,
|
|
205
198
|
rigMaterialization,
|
|
206
199
|
[workspace, companyProfileSnapshot, instructionPolicySnapshot, preferenceSnapshot],
|
|
207
200
|
workspaceModelPolicy,
|
|
208
201
|
] = await Promise.all([
|
|
209
202
|
resolveWorkspacePackRuntime(db, input.workspaceId),
|
|
210
|
-
resolveWorkspaceInstalledSkillRuntime(db, input.workspaceId),
|
|
211
203
|
session.rigId && session.rigVersionId
|
|
212
204
|
? (async () =>
|
|
213
205
|
await materializeRigVersionForAttempt(db, {
|
|
@@ -254,16 +246,13 @@ export async function prepareGovernanceAndModel(
|
|
|
254
246
|
},
|
|
255
247
|
{
|
|
256
248
|
includeCompanyProfile: companyProfileIncluded,
|
|
249
|
+
sharedSkillReader: true,
|
|
257
250
|
},
|
|
258
251
|
);
|
|
259
252
|
const structuredWorkspacePolicyActive =
|
|
260
253
|
hasActiveWorkspaceInstructionPolicy(instructionPolicySnapshot);
|
|
261
254
|
const workspaceMemory = contextSelection.workspaceMemory;
|
|
262
|
-
const buildCompanyBrainContributionReceiptFor = (
|
|
263
|
-
skillActivations: Parameters<
|
|
264
|
-
typeof buildCompanyBrainContributionReceipt
|
|
265
|
-
>[0]["skillActivations"],
|
|
266
|
-
) =>
|
|
255
|
+
const buildCompanyBrainContributionReceiptFor = (skillCatalogText: string) =>
|
|
267
256
|
buildCompanyBrainContributionReceipt({
|
|
268
257
|
contextSelectionReceiptId: contextSelection.receipt.id,
|
|
269
258
|
attemptId: input.attemptId,
|
|
@@ -276,7 +265,8 @@ export async function prepareGovernanceAndModel(
|
|
|
276
265
|
companyProfile: companyProfileSnapshot,
|
|
277
266
|
companyProfileIncluded,
|
|
278
267
|
workspaceMemory,
|
|
279
|
-
skillActivations,
|
|
268
|
+
skillActivations: [],
|
|
269
|
+
skillCatalogText,
|
|
280
270
|
});
|
|
281
271
|
try {
|
|
282
272
|
// Portable operator compaction runs before tool/skill preparation, so its
|
|
@@ -284,7 +274,7 @@ export async function prepareGovernanceAndModel(
|
|
|
284
274
|
// no runtime skill catalog. Later compaction paths replace this summary
|
|
285
275
|
// after the complete skill activation set is resolved.
|
|
286
276
|
eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
|
|
287
|
-
buildCompanyBrainContributionReceiptFor(
|
|
277
|
+
buildCompanyBrainContributionReceiptFor(""),
|
|
288
278
|
);
|
|
289
279
|
} catch {
|
|
290
280
|
// Contribution telemetry must never change model execution semantics.
|
|
@@ -367,6 +357,13 @@ export async function prepareGovernanceAndModel(
|
|
|
367
357
|
return object.bytes;
|
|
368
358
|
}
|
|
369
359
|
: undefined,
|
|
360
|
+
(fileIds) =>
|
|
361
|
+
getFilesForSubject(db, {
|
|
362
|
+
accountId: input.accountId,
|
|
363
|
+
workspaceId: input.workspaceId,
|
|
364
|
+
subjectId: fileAuthoritySubjectId,
|
|
365
|
+
fileIds,
|
|
366
|
+
}),
|
|
370
367
|
);
|
|
371
368
|
const modelHistoryProjector = async (
|
|
372
369
|
items: Array<Record<string, unknown>>,
|
|
@@ -464,7 +461,6 @@ export async function prepareGovernanceAndModel(
|
|
|
464
461
|
ok: {
|
|
465
462
|
runtimePreparationStartedAt,
|
|
466
463
|
packRuntime,
|
|
467
|
-
installedSkillRuntime,
|
|
468
464
|
rigVersion,
|
|
469
465
|
rigName,
|
|
470
466
|
agentHumanInputEnabled,
|
|
@@ -479,7 +479,6 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
479
479
|
const {
|
|
480
480
|
runtimePreparationStartedAt,
|
|
481
481
|
packRuntime,
|
|
482
|
-
installedSkillRuntime,
|
|
483
482
|
rigVersion,
|
|
484
483
|
rigName,
|
|
485
484
|
agentHumanInputEnabled,
|
|
@@ -1152,6 +1151,7 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
1152
1151
|
).values(),
|
|
1153
1152
|
];
|
|
1154
1153
|
const toolRuntime = await prepareTurnToolRuntime({
|
|
1154
|
+
selectedSkillActivations: packRuntime.skillActivations,
|
|
1155
1155
|
input,
|
|
1156
1156
|
catalogSourceSettings,
|
|
1157
1157
|
db,
|
|
@@ -1199,6 +1199,7 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
1199
1199
|
} = toolRuntime;
|
|
1200
1200
|
|
|
1201
1201
|
const builtAgent = await buildTurnAgent({
|
|
1202
|
+
skillCatalog: toolRuntime.skillCatalog,
|
|
1202
1203
|
input,
|
|
1203
1204
|
db,
|
|
1204
1205
|
runtime,
|
|
@@ -1233,8 +1234,6 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
1233
1234
|
workspaceMemory,
|
|
1234
1235
|
rigVersion,
|
|
1235
1236
|
rigName,
|
|
1236
|
-
packRuntime,
|
|
1237
|
-
installedSkillRuntime,
|
|
1238
1237
|
buildCompanyBrainContributionReceiptFor,
|
|
1239
1238
|
promptCacheKey,
|
|
1240
1239
|
workspaceVariableSet,
|
|
@@ -1256,8 +1255,7 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
1256
1255
|
postToolPreparationStartedAt,
|
|
1257
1256
|
codexContext,
|
|
1258
1257
|
});
|
|
1259
|
-
const { agent,
|
|
1260
|
-
builtAgent;
|
|
1258
|
+
const { agent, modelVisibleSkillCatalogText, postAgentPreparationStartedAt } = builtAgent;
|
|
1261
1259
|
|
|
1262
1260
|
await bindLazySandboxProvisioner({
|
|
1263
1261
|
...sandboxRoute,
|
|
@@ -1313,7 +1311,7 @@ export function createRunAgentTurnActivity(services: () => Promise<ActivityServi
|
|
|
1313
1311
|
companyBrainContributionReceiptRecorded = true;
|
|
1314
1312
|
try {
|
|
1315
1313
|
const companyBrainContributionReceipt = buildCompanyBrainContributionReceiptFor(
|
|
1316
|
-
|
|
1314
|
+
modelVisibleSkillCatalogText,
|
|
1317
1315
|
);
|
|
1318
1316
|
eventing.companyBrainContextContributions = summarizeCompanyBrainContributions(
|
|
1319
1317
|
companyBrainContributionReceipt,
|
|
@@ -361,6 +361,15 @@ export function classifySandboxLogicalProvisionFailure(
|
|
|
361
361
|
|
|
362
362
|
export function isLazySandboxProvisionRetryable(error: unknown): boolean {
|
|
363
363
|
const chain = sandboxProvisionErrorChain(error);
|
|
364
|
+
// Rotation resumes through the durable lifecycle wake. Retrying here holds
|
|
365
|
+
// a turn worker and can repeat the entire lease wait for every skill root.
|
|
366
|
+
if (
|
|
367
|
+
chain.some(
|
|
368
|
+
(value) =>
|
|
369
|
+
value instanceof SandboxLeaseTransitionError && value.reason === "rotation_in_progress",
|
|
370
|
+
)
|
|
371
|
+
)
|
|
372
|
+
return false;
|
|
364
373
|
if (
|
|
365
374
|
chain.some(
|
|
366
375
|
(value) =>
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import type { AttemptToolDefinition } from "@opengeni/codemode";
|
|
2
|
+
import type { SandboxChannelAService } from "@opengeni/runtime/sandbox";
|
|
3
|
+
import type { SkillTextFile } from "@opengeni/runtime/skill-library";
|
|
4
|
+
import { checkoutSkillDirectory, readSkillDirectory } from "./skill-transfer";
|
|
5
|
+
import type { SkillSaveReceipt, SkillSaveRequest } from "./skill-save";
|
|
6
|
+
|
|
7
|
+
type SkillFileSystem = Pick<SandboxChannelAService, "fsList" | "fsRead" | "fsWrite" | "fsMkdir">;
|
|
8
|
+
|
|
9
|
+
export function createSkillCheckoutAttemptToolDefinition(input: {
|
|
10
|
+
authorize: () => Promise<void>;
|
|
11
|
+
load: (skill: string) => Promise<{
|
|
12
|
+
skillId: string;
|
|
13
|
+
revisionId: string | null;
|
|
14
|
+
scopeVersion: number | null;
|
|
15
|
+
files: readonly SkillTextFile[];
|
|
16
|
+
}>;
|
|
17
|
+
filesystem: () => Promise<SkillFileSystem>;
|
|
18
|
+
}): AttemptToolDefinition {
|
|
19
|
+
return {
|
|
20
|
+
identity: { serverId: "opengeni", toolName: "skill_checkout" },
|
|
21
|
+
modelName: "skill_checkout",
|
|
22
|
+
codemodePath: ["opengeni", "skill_checkout"],
|
|
23
|
+
title: "Check out Skill files",
|
|
24
|
+
description:
|
|
25
|
+
"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.",
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: "object",
|
|
28
|
+
properties: {
|
|
29
|
+
skill: { type: "string", minLength: 1, maxLength: 512 },
|
|
30
|
+
directory: { type: "string", minLength: 1, maxLength: 1024 },
|
|
31
|
+
},
|
|
32
|
+
required: ["skill", "directory"],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
annotations: {
|
|
36
|
+
readOnlyHint: false,
|
|
37
|
+
destructiveHint: false,
|
|
38
|
+
idempotentHint: false,
|
|
39
|
+
openWorldHint: false,
|
|
40
|
+
},
|
|
41
|
+
source: "opengeni",
|
|
42
|
+
approval: "none",
|
|
43
|
+
execute: async (args) => {
|
|
44
|
+
await input.authorize();
|
|
45
|
+
const skill = await input.load(args.skill as string);
|
|
46
|
+
const copied = await checkoutSkillDirectory(
|
|
47
|
+
await input.filesystem(),
|
|
48
|
+
args.directory as string,
|
|
49
|
+
skill.files,
|
|
50
|
+
);
|
|
51
|
+
const output = {
|
|
52
|
+
...copied,
|
|
53
|
+
skillId: skill.skillId,
|
|
54
|
+
revisionId: skill.revisionId,
|
|
55
|
+
scopeVersion: skill.scopeVersion,
|
|
56
|
+
};
|
|
57
|
+
return {
|
|
58
|
+
isError: false,
|
|
59
|
+
content: [{ type: "text", text: JSON.stringify(output) }],
|
|
60
|
+
structuredContent: output,
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function createSkillPublishAttemptToolDefinition(input: {
|
|
67
|
+
authorize: () => Promise<void>;
|
|
68
|
+
filesystem: () => Promise<SkillFileSystem>;
|
|
69
|
+
save: (request: SkillSaveRequest) => Promise<SkillSaveReceipt>;
|
|
70
|
+
}): AttemptToolDefinition {
|
|
71
|
+
return {
|
|
72
|
+
identity: { serverId: "opengeni", toolName: "skill_publish" },
|
|
73
|
+
modelName: "skill_publish",
|
|
74
|
+
codemodePath: ["opengeni", "skill_publish"],
|
|
75
|
+
title: "Publish Skill directory",
|
|
76
|
+
description:
|
|
77
|
+
"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.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
operationId: { type: "string", format: "uuid" },
|
|
82
|
+
skillId: { type: "string", format: "uuid" },
|
|
83
|
+
expectedRevisionId: { type: ["string", "null"], format: "uuid" },
|
|
84
|
+
expectedScopeVersion: { type: "integer", minimum: 0 },
|
|
85
|
+
directory: { type: "string", minLength: 1, maxLength: 1024 },
|
|
86
|
+
reason: { type: "string", minLength: 1, maxLength: 2000 },
|
|
87
|
+
},
|
|
88
|
+
required: [
|
|
89
|
+
"operationId",
|
|
90
|
+
"skillId",
|
|
91
|
+
"expectedRevisionId",
|
|
92
|
+
"expectedScopeVersion",
|
|
93
|
+
"directory",
|
|
94
|
+
"reason",
|
|
95
|
+
],
|
|
96
|
+
additionalProperties: false,
|
|
97
|
+
},
|
|
98
|
+
annotations: {
|
|
99
|
+
readOnlyHint: false,
|
|
100
|
+
destructiveHint: false,
|
|
101
|
+
idempotentHint: true,
|
|
102
|
+
openWorldHint: false,
|
|
103
|
+
},
|
|
104
|
+
source: "opengeni",
|
|
105
|
+
approval: "none",
|
|
106
|
+
execute: async (args) => {
|
|
107
|
+
await input.authorize();
|
|
108
|
+
const artifact = await readSkillDirectory(await input.filesystem(), args.directory as string);
|
|
109
|
+
const output = await input.save({
|
|
110
|
+
operationId: args.operationId as string,
|
|
111
|
+
skillId: args.skillId as string,
|
|
112
|
+
expectedRevisionId: args.expectedRevisionId as string | null,
|
|
113
|
+
expectedScopeVersion: args.expectedScopeVersion as number,
|
|
114
|
+
files: artifact.files,
|
|
115
|
+
reason: args.reason as string,
|
|
116
|
+
});
|
|
117
|
+
return {
|
|
118
|
+
isError: false,
|
|
119
|
+
content: [{ type: "text", text: JSON.stringify(output) }],
|
|
120
|
+
structuredContent: output,
|
|
121
|
+
};
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AttemptToolDefinition } from "@opengeni/codemode";
|
|
2
|
+
import type { SkillSaveReceipt } from "./skill-save";
|
|
3
|
+
|
|
4
|
+
/** The installer resolves/pins bytes and persists them through the shared lifecycle. */
|
|
5
|
+
export function createSkillInstallAttemptToolDefinition(input: {
|
|
6
|
+
authorize: () => Promise<void>;
|
|
7
|
+
install: (request: {
|
|
8
|
+
operationId: string;
|
|
9
|
+
source: string;
|
|
10
|
+
expectedInstallationVersion?: number;
|
|
11
|
+
reason: string;
|
|
12
|
+
}) => Promise<SkillSaveReceipt>;
|
|
13
|
+
}): AttemptToolDefinition {
|
|
14
|
+
return {
|
|
15
|
+
identity: { serverId: "opengeni", toolName: "skill_install" },
|
|
16
|
+
modelName: "skill_install",
|
|
17
|
+
codemodePath: ["opengeni", "skill_install"],
|
|
18
|
+
title: "Install a Skill",
|
|
19
|
+
description:
|
|
20
|
+
"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.",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
operationId: { type: "string", format: "uuid" },
|
|
25
|
+
source: { type: "string", minLength: 1, maxLength: 2048 },
|
|
26
|
+
expectedInstallationVersion: { type: "integer", minimum: 0 },
|
|
27
|
+
reason: { type: "string", minLength: 1, maxLength: 2000 },
|
|
28
|
+
},
|
|
29
|
+
required: ["operationId", "source", "reason"],
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
},
|
|
32
|
+
annotations: {
|
|
33
|
+
readOnlyHint: false,
|
|
34
|
+
destructiveHint: false,
|
|
35
|
+
idempotentHint: true,
|
|
36
|
+
openWorldHint: true,
|
|
37
|
+
},
|
|
38
|
+
source: "opengeni",
|
|
39
|
+
approval: "none",
|
|
40
|
+
execute: async (args) => {
|
|
41
|
+
await input.authorize();
|
|
42
|
+
const output = await input.install({
|
|
43
|
+
operationId: args.operationId as string,
|
|
44
|
+
source: args.source as string,
|
|
45
|
+
...(args.expectedInstallationVersion !== undefined
|
|
46
|
+
? { expectedInstallationVersion: args.expectedInstallationVersion as number }
|
|
47
|
+
: {}),
|
|
48
|
+
reason: args.reason as string,
|
|
49
|
+
});
|
|
50
|
+
return {
|
|
51
|
+
isError: false,
|
|
52
|
+
content: [{ type: "text", text: JSON.stringify(output) }],
|
|
53
|
+
structuredContent: output,
|
|
54
|
+
};
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { AttemptToolDefinition } from "@opengeni/codemode";
|
|
2
|
+
import {
|
|
3
|
+
assertSkillRelativePath,
|
|
4
|
+
PORTABLE_SKILL_MAX_FILES,
|
|
5
|
+
readSkillFiles,
|
|
6
|
+
SKILL_READ_MAX_OUTPUT_BYTES,
|
|
7
|
+
SKILL_READ_MAX_PATHS,
|
|
8
|
+
type SkillTextFile,
|
|
9
|
+
} from "@opengeni/runtime/skill-library";
|
|
10
|
+
|
|
11
|
+
export const SKILL_READ_TOOL_NAME = "skill_read";
|
|
12
|
+
|
|
13
|
+
export type SkillReadContent = Readonly<{
|
|
14
|
+
files: readonly SkillTextFile[];
|
|
15
|
+
skillId: string;
|
|
16
|
+
revisionId: string;
|
|
17
|
+
scopeVersion: number;
|
|
18
|
+
installationVersion?: number;
|
|
19
|
+
}>;
|
|
20
|
+
|
|
21
|
+
/** A first-party gateway definition, not a sandbox capability or second backend. */
|
|
22
|
+
export function createSkillReadAttemptToolDefinition(input: {
|
|
23
|
+
authorize: () => Promise<void>;
|
|
24
|
+
load: (skill: string) => Promise<readonly SkillTextFile[] | SkillReadContent>;
|
|
25
|
+
}): AttemptToolDefinition {
|
|
26
|
+
return {
|
|
27
|
+
identity: { serverId: "opengeni", toolName: SKILL_READ_TOOL_NAME },
|
|
28
|
+
modelName: SKILL_READ_TOOL_NAME,
|
|
29
|
+
codemodePath: ["opengeni", SKILL_READ_TOOL_NAME],
|
|
30
|
+
title: "Read Skill files",
|
|
31
|
+
description:
|
|
32
|
+
"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.",
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: "object",
|
|
35
|
+
properties: {
|
|
36
|
+
skill: { type: "string", minLength: 1, maxLength: 512 },
|
|
37
|
+
listFiles: { type: "boolean" },
|
|
38
|
+
paths: {
|
|
39
|
+
type: "array",
|
|
40
|
+
minItems: 1,
|
|
41
|
+
maxItems: SKILL_READ_MAX_PATHS,
|
|
42
|
+
uniqueItems: true,
|
|
43
|
+
items: { type: "string", minLength: 1, maxLength: 1024 },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
required: ["skill"],
|
|
47
|
+
additionalProperties: false,
|
|
48
|
+
},
|
|
49
|
+
annotations: {
|
|
50
|
+
title: "Read Skill files",
|
|
51
|
+
readOnlyHint: true,
|
|
52
|
+
destructiveHint: false,
|
|
53
|
+
idempotentHint: true,
|
|
54
|
+
openWorldHint: false,
|
|
55
|
+
},
|
|
56
|
+
source: "opengeni",
|
|
57
|
+
approval: "none",
|
|
58
|
+
execute: async (args) => {
|
|
59
|
+
if (
|
|
60
|
+
typeof args.skill !== "string" ||
|
|
61
|
+
!args.skill ||
|
|
62
|
+
(args.listFiles !== undefined && typeof args.listFiles !== "boolean") ||
|
|
63
|
+
(args.paths !== undefined &&
|
|
64
|
+
(!Array.isArray(args.paths) || args.paths.some((path) => typeof path !== "string")))
|
|
65
|
+
) {
|
|
66
|
+
throw new Error("skill_read requires a Skill identifier and optional relative paths.");
|
|
67
|
+
}
|
|
68
|
+
if (args.listFiles === true && args.paths !== undefined) {
|
|
69
|
+
throw new Error("skill_read listFiles:true cannot be combined with paths.");
|
|
70
|
+
}
|
|
71
|
+
await input.authorize();
|
|
72
|
+
const loaded = await input.load(args.skill);
|
|
73
|
+
const metadata = "files" in loaded ? loaded : null;
|
|
74
|
+
const files = metadata ? metadata.files : (loaded as readonly SkillTextFile[]);
|
|
75
|
+
const selected =
|
|
76
|
+
args.listFiles === true
|
|
77
|
+
? listSkillPaths(files)
|
|
78
|
+
: readSkillFiles(files, args.paths as string[] | undefined);
|
|
79
|
+
const output = {
|
|
80
|
+
...(metadata
|
|
81
|
+
? {
|
|
82
|
+
skillId: metadata.skillId,
|
|
83
|
+
revisionId: metadata.revisionId,
|
|
84
|
+
scopeVersion: metadata.scopeVersion,
|
|
85
|
+
...(metadata.installationVersion !== undefined
|
|
86
|
+
? { installationVersion: metadata.installationVersion }
|
|
87
|
+
: {}),
|
|
88
|
+
}
|
|
89
|
+
: {}),
|
|
90
|
+
...selected,
|
|
91
|
+
};
|
|
92
|
+
return {
|
|
93
|
+
isError: false,
|
|
94
|
+
content: [{ type: "text", text: JSON.stringify(output) }],
|
|
95
|
+
structuredContent: output,
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Inventory never reads or serializes file bodies, including the entry point. */
|
|
102
|
+
function listSkillPaths(files: readonly SkillTextFile[]): { paths: string[] } {
|
|
103
|
+
if (files.length > PORTABLE_SKILL_MAX_FILES) {
|
|
104
|
+
throw new Error(`Skill inventory exceeds ${PORTABLE_SKILL_MAX_FILES} files.`);
|
|
105
|
+
}
|
|
106
|
+
const seen = new Set<string>();
|
|
107
|
+
for (const { path } of files) {
|
|
108
|
+
assertSkillRelativePath(path);
|
|
109
|
+
if (seen.has(path)) throw new Error(`Duplicate stored Skill path: ${path}`);
|
|
110
|
+
seen.add(path);
|
|
111
|
+
}
|
|
112
|
+
const result = { paths: [...seen].sort() };
|
|
113
|
+
if (Buffer.byteLength(JSON.stringify(result), "utf8") > SKILL_READ_MAX_OUTPUT_BYTES) {
|
|
114
|
+
throw new Error("Skill inventory exceeds the read output limit.");
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|