@vertesia/workflow 1.0.0-dev.20260227.112605Z → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/activities/chunkDocument.js +1 -3
- package/lib/cjs/activities/chunkDocument.js.map +1 -1
- package/lib/cjs/activities/executeInteraction.js +18 -0
- package/lib/cjs/activities/executeInteraction.js.map +1 -1
- package/lib/cjs/activities/executeRemoteActivity.js +107 -0
- package/lib/cjs/activities/executeRemoteActivity.js.map +1 -0
- package/lib/cjs/activities/getObjectFromStore.js +12 -1
- package/lib/cjs/activities/getObjectFromStore.js.map +1 -1
- package/lib/cjs/activities/index-dsl.js +5 -3
- package/lib/cjs/activities/index-dsl.js.map +1 -1
- package/lib/cjs/activities/resolveRemoteActivities.js +120 -0
- package/lib/cjs/activities/resolveRemoteActivities.js.map +1 -0
- package/lib/cjs/dsl/dsl-workflow.js +66 -6
- package/lib/cjs/dsl/dsl-workflow.js.map +1 -1
- package/lib/cjs/utils/storage.js +9 -9
- package/lib/cjs/utils/storage.js.map +1 -1
- package/lib/esm/activities/chunkDocument.js +1 -3
- package/lib/esm/activities/chunkDocument.js.map +1 -1
- package/lib/esm/activities/executeInteraction.js +18 -0
- package/lib/esm/activities/executeInteraction.js.map +1 -1
- package/lib/esm/activities/executeRemoteActivity.js +104 -0
- package/lib/esm/activities/executeRemoteActivity.js.map +1 -0
- package/lib/esm/activities/getObjectFromStore.js +12 -1
- package/lib/esm/activities/getObjectFromStore.js.map +1 -1
- package/lib/esm/activities/index-dsl.js +2 -1
- package/lib/esm/activities/index-dsl.js.map +1 -1
- package/lib/esm/activities/resolveRemoteActivities.js +117 -0
- package/lib/esm/activities/resolveRemoteActivities.js.map +1 -0
- package/lib/esm/dsl/dsl-workflow.js +66 -6
- package/lib/esm/dsl/dsl-workflow.js.map +1 -1
- package/lib/esm/utils/storage.js +9 -9
- package/lib/esm/utils/storage.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/lib/types/activities/chunkDocument.d.ts.map +1 -1
- package/lib/types/activities/executeInteraction.d.ts.map +1 -1
- package/lib/types/activities/executeRemoteActivity.d.ts +31 -0
- package/lib/types/activities/executeRemoteActivity.d.ts.map +1 -0
- package/lib/types/activities/getObjectFromStore.d.ts.map +1 -1
- package/lib/types/activities/index-dsl.d.ts +3 -1
- package/lib/types/activities/index-dsl.d.ts.map +1 -1
- package/lib/types/activities/resolveRemoteActivities.d.ts +32 -0
- package/lib/types/activities/resolveRemoteActivities.d.ts.map +1 -0
- package/lib/types/dsl/dsl-workflow.d.ts.map +1 -1
- package/lib/types/utils/storage.d.ts +2 -2
- package/lib/types/utils/storage.d.ts.map +1 -1
- package/lib/workflows-bundle.js +625 -274
- package/package.json +6 -6
- package/src/activities/chunkDocument.ts +1 -3
- package/src/activities/executeInteraction.ts +17 -0
- package/src/activities/executeRemoteActivity.test.ts +140 -0
- package/src/activities/executeRemoteActivity.ts +133 -0
- package/src/activities/getObjectFromStore.ts +11 -1
- package/src/activities/index-dsl.ts +3 -1
- package/src/activities/resolveRemoteActivities.test.ts +220 -0
- package/src/activities/resolveRemoteActivities.ts +167 -0
- package/src/dsl/dsl-workflow.ts +87 -7
- package/src/utils/storage.ts +9 -8
- package/lib/cjs/activities/copyParentArtifacts.js +0 -127
- package/lib/cjs/activities/copyParentArtifacts.js.map +0 -1
- package/lib/esm/activities/copyParentArtifacts.js +0 -124
- package/lib/esm/activities/copyParentArtifacts.js.map +0 -1
- package/lib/types/activities/copyParentArtifacts.d.ts +0 -19
- package/lib/types/activities/copyParentArtifacts.d.ts.map +0 -1
- package/src/activities/copyParentArtifacts.ts +0 -162
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { log } from "@temporalio/activity";
|
|
2
|
+
import {
|
|
3
|
+
AppInstallationWithManifest,
|
|
4
|
+
AppPackage,
|
|
5
|
+
DSLActivityExecutionPayload,
|
|
6
|
+
RemoteActivityDefinition,
|
|
7
|
+
} from "@vertesia/common";
|
|
8
|
+
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
|
9
|
+
|
|
10
|
+
/** Prefix identifying a remote activity name in DSL workflow steps */
|
|
11
|
+
const REMOTE_ACTIVITY_PREFIX = "app:";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Information about a resolved remote activity.
|
|
15
|
+
*/
|
|
16
|
+
export interface RemoteActivityInfo {
|
|
17
|
+
/** The resolved execution URL for this activity */
|
|
18
|
+
url: string;
|
|
19
|
+
/** The activity name as known by the tool server (unprefixed) */
|
|
20
|
+
activity_name: string;
|
|
21
|
+
/** The app installation ID */
|
|
22
|
+
app_install_id: string;
|
|
23
|
+
/** The app name */
|
|
24
|
+
app_name: string;
|
|
25
|
+
/** The app installation settings */
|
|
26
|
+
app_settings?: Record<string, any>;
|
|
27
|
+
/** The activity definition from the tool server */
|
|
28
|
+
definition: RemoteActivityDefinition;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Map of remote activity qualified names to their remote info.
|
|
33
|
+
* Key format: `app:<app_name>:<collection>:<activity_name>`
|
|
34
|
+
*/
|
|
35
|
+
export type RemoteActivityMap = Record<string, RemoteActivityInfo>;
|
|
36
|
+
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
|
38
|
+
export interface ResolveRemoteActivitiesParams {}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Resolves remote activities from all installed apps that have the `tools` capability.
|
|
42
|
+
* For each app with an endpoint, fetches `?scope=activities` to discover available activities.
|
|
43
|
+
* Returns a map keyed by qualified names (`app:<app_name>:<collection>:<activity_name>`).
|
|
44
|
+
*/
|
|
45
|
+
export async function resolveRemoteActivities(
|
|
46
|
+
payload: DSLActivityExecutionPayload<ResolveRemoteActivitiesParams>,
|
|
47
|
+
): Promise<RemoteActivityMap> {
|
|
48
|
+
const ctx = await setupActivity<ResolveRemoteActivitiesParams>(payload);
|
|
49
|
+
const { client } = ctx;
|
|
50
|
+
|
|
51
|
+
const map: RemoteActivityMap = {};
|
|
52
|
+
|
|
53
|
+
let installations: AppInstallationWithManifest[];
|
|
54
|
+
try {
|
|
55
|
+
installations = await client.apps.getInstalledApps("tools");
|
|
56
|
+
} catch (err: unknown) {
|
|
57
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
58
|
+
log.warn("Failed to fetch installed apps for remote activities", { error: message });
|
|
59
|
+
return map;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const install of installations) {
|
|
63
|
+
const manifest = install.manifest;
|
|
64
|
+
if (!manifest.endpoint) {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const pkg = await fetchActivitiesPackage(manifest.endpoint, payload.auth_token);
|
|
70
|
+
if (!pkg.activities || pkg.activities.length === 0) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
for (const activity of pkg.activities) {
|
|
75
|
+
const collection = activity.collection;
|
|
76
|
+
if (!collection) {
|
|
77
|
+
log.warn("Remote activity missing collection, skipping", {
|
|
78
|
+
app: manifest.name,
|
|
79
|
+
activity: activity.name,
|
|
80
|
+
});
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Build qualified name: app:<app_name>:<collection>:<activity_name>
|
|
85
|
+
const qualifiedName = `${REMOTE_ACTIVITY_PREFIX}${manifest.name}:${collection}:${activity.name}`;
|
|
86
|
+
|
|
87
|
+
if (map[qualifiedName]) {
|
|
88
|
+
log.warn("Duplicate remote activity name, skipping", {
|
|
89
|
+
qualifiedName,
|
|
90
|
+
existingApp: map[qualifiedName].app_name,
|
|
91
|
+
newApp: manifest.name,
|
|
92
|
+
});
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Resolve the activity execution URL (collection-specific endpoint)
|
|
97
|
+
const activityUrl = resolveActivityUrl(manifest.endpoint, activity, collection);
|
|
98
|
+
|
|
99
|
+
map[qualifiedName] = {
|
|
100
|
+
url: activityUrl,
|
|
101
|
+
activity_name: activity.name,
|
|
102
|
+
app_install_id: install.id,
|
|
103
|
+
app_name: manifest.name,
|
|
104
|
+
app_settings: install.settings,
|
|
105
|
+
definition: activity,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
log.info("Resolved remote activities from app", {
|
|
110
|
+
app: manifest.name,
|
|
111
|
+
count: pkg.activities.length,
|
|
112
|
+
});
|
|
113
|
+
} catch (err: unknown) {
|
|
114
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
115
|
+
log.warn("Failed to fetch activities from app, skipping", {
|
|
116
|
+
app: manifest.name,
|
|
117
|
+
endpoint: manifest.endpoint,
|
|
118
|
+
error: message,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return map;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Fetches the activities scope from a tool server package endpoint.
|
|
128
|
+
*/
|
|
129
|
+
async function fetchActivitiesPackage(endpoint: string, authToken: string): Promise<AppPackage> {
|
|
130
|
+
const url = new URL(endpoint);
|
|
131
|
+
url.searchParams.set('scope', 'activities');
|
|
132
|
+
|
|
133
|
+
const response = await fetch(url.toString(), {
|
|
134
|
+
method: 'GET',
|
|
135
|
+
headers: {
|
|
136
|
+
'Accept': 'application/json',
|
|
137
|
+
'Authorization': `Bearer ${authToken}`,
|
|
138
|
+
},
|
|
139
|
+
signal: AbortSignal.timeout(5000),
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (!response.ok) {
|
|
143
|
+
throw new Error(`HTTP ${response.status} ${response.statusText}`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return response.json() as Promise<AppPackage>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Resolves the execution URL for a remote activity.
|
|
151
|
+
* If the activity has a `url` field, resolve it relative to the endpoint base.
|
|
152
|
+
* Otherwise, use the collection-specific activities endpoint: `/api/activities/{collection}`.
|
|
153
|
+
*/
|
|
154
|
+
function resolveActivityUrl(endpoint: string, activity: RemoteActivityDefinition, collection: string): string {
|
|
155
|
+
if (activity.url) {
|
|
156
|
+
// Absolute URLs are used as-is
|
|
157
|
+
if (activity.url.startsWith('http://') || activity.url.startsWith('https://')) {
|
|
158
|
+
return activity.url;
|
|
159
|
+
}
|
|
160
|
+
// Resolve relative URLs against the endpoint's base path (not just origin)
|
|
161
|
+
return new URL(activity.url, endpoint).toString();
|
|
162
|
+
}
|
|
163
|
+
// Default: POST to the collection-specific activities endpoint
|
|
164
|
+
const base = new URL(endpoint);
|
|
165
|
+
const activitiesPath = base.pathname.replace(/\/package\/?$/, `/activities/${collection}`);
|
|
166
|
+
return new URL(activitiesPath, base.origin).toString();
|
|
167
|
+
}
|
package/src/dsl/dsl-workflow.ts
CHANGED
|
@@ -30,6 +30,22 @@ import { RateLimitParams } from "../activities/rateLimiter.js";
|
|
|
30
30
|
import { WF_NON_RETRYABLE_ERRORS, WorkflowParamNotFoundError } from "../errors.js";
|
|
31
31
|
import { Vars } from "./vars.js";
|
|
32
32
|
|
|
33
|
+
/** Prefix identifying a remote activity name in DSL workflow steps */
|
|
34
|
+
const REMOTE_ACTIVITY_PREFIX = "app:";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Minimal type for remote activity info used in the workflow.
|
|
38
|
+
* Must stay compatible with RemoteActivityInfo from resolveRemoteActivities.
|
|
39
|
+
* Defined inline to avoid importing from activity files in workflow code.
|
|
40
|
+
*/
|
|
41
|
+
interface RemoteActivityEntry {
|
|
42
|
+
url: string;
|
|
43
|
+
activity_name: string;
|
|
44
|
+
app_install_id: string;
|
|
45
|
+
app_name: string;
|
|
46
|
+
app_settings?: Record<string, any>;
|
|
47
|
+
}
|
|
48
|
+
type RemoteActivityMap = Record<string, RemoteActivityEntry>;
|
|
33
49
|
|
|
34
50
|
interface BaseActivityPayload extends WorkflowExecutionPayload {
|
|
35
51
|
workflow_name: string;
|
|
@@ -122,6 +138,25 @@ export async function dslWorkflow(payload: DSLWorkflowExecutionPayload) {
|
|
|
122
138
|
|
|
123
139
|
log.info("Executing workflow", { payload });
|
|
124
140
|
|
|
141
|
+
// Resolve remote activities from installed apps only if the workflow uses prefixed activity names
|
|
142
|
+
let remoteActivities: RemoteActivityMap = {};
|
|
143
|
+
if (patched('dsl-remote-activities') && hasRemoteActivitySteps(definition)) {
|
|
144
|
+
try {
|
|
145
|
+
const resolvePayload = dslActivityPayload(
|
|
146
|
+
basePayload, { name: 'resolveRemoteActivities' } as DSLActivitySpec, {},
|
|
147
|
+
);
|
|
148
|
+
remoteActivities = await defaultProxy.resolveRemoteActivities(resolvePayload) as RemoteActivityMap;
|
|
149
|
+
if (Object.keys(remoteActivities).length > 0) {
|
|
150
|
+
log.info("Resolved remote activities", {
|
|
151
|
+
count: Object.keys(remoteActivities).length,
|
|
152
|
+
names: Object.keys(remoteActivities),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
} catch (e: any) {
|
|
156
|
+
log.warn("Failed to resolve remote activities, continuing without them", { error: e.message });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
125
160
|
// TODO(mhuang): remove patch when all workflows are migrated to v2
|
|
126
161
|
// It avoids breaking the ongoing workflow execution running in v1 and also allows us to
|
|
127
162
|
// deploy the new error handler in production.
|
|
@@ -129,19 +164,19 @@ export async function dslWorkflow(payload: DSLWorkflowExecutionPayload) {
|
|
|
129
164
|
if (patched('dsl-workflow-error-handling')) {
|
|
130
165
|
// v2: new version with error handler
|
|
131
166
|
try {
|
|
132
|
-
await executeSteps(definition, payload, basePayload, vars, defaultProxy, defaultOptions);
|
|
167
|
+
await executeSteps(definition, payload, basePayload, vars, defaultProxy, defaultOptions, remoteActivities);
|
|
133
168
|
} catch (e) {
|
|
134
169
|
await handleError(e, basePayload, defaultOptions);
|
|
135
170
|
}
|
|
136
171
|
} else {
|
|
137
172
|
// v1: old version without error handler, deprecated since v0.52.0
|
|
138
|
-
await executeSteps(definition, payload, basePayload, vars, defaultProxy, defaultOptions);
|
|
173
|
+
await executeSteps(definition, payload, basePayload, vars, defaultProxy, defaultOptions, remoteActivities);
|
|
139
174
|
}
|
|
140
175
|
|
|
141
176
|
return vars.getValue(definition.result || 'result');
|
|
142
177
|
}
|
|
143
178
|
|
|
144
|
-
async function executeSteps(definition: DSLWorkflowSpec, payload: DSLWorkflowExecutionPayload, basePayload: BaseActivityPayload, vars: Vars, defaultProxy: ActivityInterfaceFor<UntypedActivities>, defaultOptions: ActivityOptions) {
|
|
179
|
+
async function executeSteps(definition: DSLWorkflowSpec, payload: DSLWorkflowExecutionPayload, basePayload: BaseActivityPayload, vars: Vars, defaultProxy: ActivityInterfaceFor<UntypedActivities>, defaultOptions: ActivityOptions, remoteActivities: RemoteActivityMap = {}) {
|
|
145
180
|
if (definition.steps) {
|
|
146
181
|
for (const step of definition.steps) {
|
|
147
182
|
const stepType = step.type;
|
|
@@ -153,18 +188,28 @@ async function executeSteps(definition: DSLWorkflowSpec, payload: DSLWorkflowExe
|
|
|
153
188
|
await executeChildWorkflow(childWorkflowStep, payload, vars, basePayload.debug_mode);
|
|
154
189
|
}
|
|
155
190
|
} else { // activity
|
|
156
|
-
await runActivity(step as DSLActivitySpec, basePayload, vars, defaultProxy, defaultOptions);
|
|
191
|
+
await runActivity(step as DSLActivitySpec, basePayload, vars, defaultProxy, defaultOptions, remoteActivities);
|
|
157
192
|
}
|
|
158
193
|
}
|
|
159
194
|
} else if (definition.activities) { // legacy support
|
|
160
195
|
for (const activity of definition.activities) {
|
|
161
|
-
await runActivity(activity, basePayload, vars, defaultProxy, defaultOptions);
|
|
196
|
+
await runActivity(activity, basePayload, vars, defaultProxy, defaultOptions, remoteActivities);
|
|
162
197
|
}
|
|
163
198
|
} else {
|
|
164
199
|
throw new Error("No steps or activities found in the workflow definition");
|
|
165
200
|
}
|
|
166
201
|
}
|
|
167
202
|
|
|
203
|
+
/**
|
|
204
|
+
* Check whether any activity step in the workflow definition uses a remote activity name
|
|
205
|
+
* (starts with `app:`), indicating it may reference a remote activity.
|
|
206
|
+
* Avoids resolving remote activities when not needed.
|
|
207
|
+
*/
|
|
208
|
+
function hasRemoteActivitySteps(definition: DSLWorkflowSpec): boolean {
|
|
209
|
+
const steps = definition.steps || definition.activities || [];
|
|
210
|
+
return steps.some(step => 'name' in step && step.name?.startsWith(REMOTE_ACTIVITY_PREFIX));
|
|
211
|
+
}
|
|
212
|
+
|
|
168
213
|
async function handleError(originalError: any, basePayload: BaseActivityPayload, defaultOptions: ActivityOptions) {
|
|
169
214
|
const { handleDslError } = proxyActivities<typeof activities>(defaultOptions);
|
|
170
215
|
|
|
@@ -321,7 +366,7 @@ function buildRateLimitParams(activity: DSLActivitySpec, executionPayload: DSLAc
|
|
|
321
366
|
};
|
|
322
367
|
}
|
|
323
368
|
|
|
324
|
-
async function runActivity(activity: DSLActivitySpec, basePayload: BaseActivityPayload, vars: Vars, defaultProxy: ActivityInterfaceFor<UntypedActivities>, defaultOptions: ActivityOptions) {
|
|
369
|
+
async function runActivity(activity: DSLActivitySpec, basePayload: BaseActivityPayload, vars: Vars, defaultProxy: ActivityInterfaceFor<UntypedActivities>, defaultOptions: ActivityOptions, remoteActivities: RemoteActivityMap = {}) {
|
|
325
370
|
if (basePayload.debug_mode) {
|
|
326
371
|
log.debug(`Workflow vars before executing activity ${activity.name}`, { vars: vars.resolve() });
|
|
327
372
|
}
|
|
@@ -354,6 +399,41 @@ async function runActivity(activity: DSLActivitySpec, basePayload: BaseActivityP
|
|
|
354
399
|
// https://github.com/vertesia/composableai/pull/544/files
|
|
355
400
|
}
|
|
356
401
|
|
|
402
|
+
// Check if this is a remote activity (name starts with "app:")
|
|
403
|
+
if (activity.name.startsWith(REMOTE_ACTIVITY_PREFIX)) {
|
|
404
|
+
if (!remoteActivities[activity.name]) {
|
|
405
|
+
throw new Error(
|
|
406
|
+
`Remote activity "${activity.name}" not found. ` +
|
|
407
|
+
`Available: ${Object.keys(remoteActivities).join(', ') || '(none resolved)'}`
|
|
408
|
+
);
|
|
409
|
+
}
|
|
410
|
+
const remote = remoteActivities[activity.name];
|
|
411
|
+
log.info("Executing remote activity", {
|
|
412
|
+
activityName: activity.name,
|
|
413
|
+
remoteName: remote.activity_name,
|
|
414
|
+
app: remote.app_name,
|
|
415
|
+
url: remote.url,
|
|
416
|
+
});
|
|
417
|
+
const remotePayload = dslActivityPayload(basePayload, activity, {
|
|
418
|
+
url: remote.url,
|
|
419
|
+
activity_name: remote.activity_name,
|
|
420
|
+
// Merge imported vars with static activity params, then resolve expressions
|
|
421
|
+
// (same merge pattern used by local activities — see buildRateLimitParams)
|
|
422
|
+
params: new Vars({ ...importParams, ...activity.params }).resolve(),
|
|
423
|
+
app_install_id: remote.app_install_id,
|
|
424
|
+
app_name: remote.app_name,
|
|
425
|
+
app_settings: remote.app_settings,
|
|
426
|
+
});
|
|
427
|
+
const result = await proxy.executeRemoteActivity(remotePayload);
|
|
428
|
+
if (activity.output) {
|
|
429
|
+
vars.setValue(activity.output, result);
|
|
430
|
+
}
|
|
431
|
+
if (basePayload.debug_mode) {
|
|
432
|
+
log.debug(`Workflow vars after executing remote activity ${activity.name}`, { vars: vars.resolve() });
|
|
433
|
+
}
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
357
437
|
// call rate limiter depending on the activity type
|
|
358
438
|
const rateLimitedActivities = [
|
|
359
439
|
"chunkDocument",
|
|
@@ -371,7 +451,7 @@ async function runActivity(activity: DSLActivitySpec, basePayload: BaseActivityP
|
|
|
371
451
|
|
|
372
452
|
const rateLimitPayload = dslActivityPayload(basePayload, activity, rateLimitParams);
|
|
373
453
|
let rateLimitResult = await proxy.checkRateLimit(rateLimitPayload);
|
|
374
|
-
|
|
454
|
+
|
|
375
455
|
while (rateLimitResult.delayMs > 0) {
|
|
376
456
|
log.debug(`Rate limit delay applied: ${rateLimitResult.delayMs}ms`);
|
|
377
457
|
await sleep(rateLimitResult.delayMs);
|
package/src/utils/storage.ts
CHANGED
|
@@ -25,26 +25,27 @@ export async function saveAgentArtifact(
|
|
|
25
25
|
name: string,
|
|
26
26
|
fileContent: Readable,
|
|
27
27
|
mimeType: string = "application/json",
|
|
28
|
+
storageId?: string,
|
|
28
29
|
) {
|
|
29
|
-
const
|
|
30
|
+
const id = storageId || activityInfo().workflowExecution.runId;
|
|
30
31
|
const ext = mime.getExtension(mimeType);
|
|
31
32
|
if (!name) {
|
|
32
33
|
throw ApplicationFailure.nonRetryable(`Name is required`);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
//create the file path and append extension if needed
|
|
36
|
-
const filePath = agentStoragePath(
|
|
37
|
+
const filePath = agentStoragePath(id) + "/" + name + (ext && !name.endsWith(ext) ? "." + ext : "");
|
|
37
38
|
|
|
38
39
|
try {
|
|
39
|
-
const source = new NodeStreamSource(fileContent, `${
|
|
40
|
+
const source = new NodeStreamSource(fileContent, `${id}-${basename(filePath)}`, mimeType, filePath);
|
|
40
41
|
return await client.files.uploadFile(source);
|
|
41
42
|
} catch (err: any) {
|
|
42
|
-
log.error(`Failed to save agent artifact for run ${
|
|
43
|
+
log.error(`Failed to save agent artifact for run ${id}`, {
|
|
43
44
|
err,
|
|
44
45
|
file: filePath,
|
|
45
46
|
});
|
|
46
47
|
throw ApplicationFailure.nonRetryable(
|
|
47
|
-
`Failed to save agent artifact for run ${
|
|
48
|
+
`Failed to save agent artifact for run ${id}`,
|
|
48
49
|
"SaveAgentArtifactError",
|
|
49
50
|
{
|
|
50
51
|
error: err,
|
|
@@ -53,8 +54,8 @@ export async function saveAgentArtifact(
|
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
export async function fetchAgentArtifact(client: VertesiaClient, name: string) {
|
|
57
|
-
const
|
|
58
|
-
const filePath = agentStoragePath(
|
|
57
|
+
export async function fetchAgentArtifact(client: VertesiaClient, name: string, storageId?: string) {
|
|
58
|
+
const id = storageId || activityInfo().workflowExecution.runId;
|
|
59
|
+
const filePath = agentStoragePath(id) + "/" + name;
|
|
59
60
|
return fetchBlobAsBuffer(client, filePath);
|
|
60
61
|
}
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.copyParentArtifacts = copyParentArtifacts;
|
|
4
|
-
const activity_1 = require("@temporalio/activity");
|
|
5
|
-
const node_1 = require("@vertesia/client/node");
|
|
6
|
-
const stream_1 = require("stream");
|
|
7
|
-
const ActivityContext_js_1 = require("../dsl/setup/ActivityContext.js");
|
|
8
|
-
/**
|
|
9
|
-
* Directories in the agent workspace to copy from parent to child.
|
|
10
|
-
*/
|
|
11
|
-
const WORKSPACE_DIRECTORIES = ['scripts', 'files', 'skills', 'docs', 'out'];
|
|
12
|
-
/**
|
|
13
|
-
* Files that should never be copied (child has its own).
|
|
14
|
-
*/
|
|
15
|
-
const EXCLUDED_FILES = ['conversation.json', 'tools.json'];
|
|
16
|
-
/**
|
|
17
|
-
* Copy workspace artifacts from parent workflow's agent space to current workflow's agent space.
|
|
18
|
-
*
|
|
19
|
-
* Copies: scripts/, files/, skills/, docs/, out/
|
|
20
|
-
* Excludes: conversation.json, tools.json
|
|
21
|
-
*/
|
|
22
|
-
async function copyParentArtifacts(payload) {
|
|
23
|
-
const { client, params } = await (0, ActivityContext_js_1.setupActivity)(payload);
|
|
24
|
-
const childRunId = (0, activity_1.activityInfo)().workflowExecution.runId;
|
|
25
|
-
const parentRunId = params.parent_run_id;
|
|
26
|
-
activity_1.log.info(`Copying artifacts from parent ${parentRunId} to child ${childRunId}`);
|
|
27
|
-
// List all files in parent's agent space
|
|
28
|
-
const parentFiles = await client.files.listArtifacts(parentRunId);
|
|
29
|
-
if (parentFiles.length === 0) {
|
|
30
|
-
activity_1.log.info("No artifacts in parent agent space");
|
|
31
|
-
return { copied: 0, files: [] };
|
|
32
|
-
}
|
|
33
|
-
const copiedFiles = [];
|
|
34
|
-
for (const fullPath of parentFiles) {
|
|
35
|
-
const relativePath = extractRelativePath(fullPath, parentRunId);
|
|
36
|
-
if (!relativePath)
|
|
37
|
-
continue;
|
|
38
|
-
// Only copy workspace directories
|
|
39
|
-
const dir = relativePath.split('/')[0];
|
|
40
|
-
if (!WORKSPACE_DIRECTORIES.includes(dir))
|
|
41
|
-
continue;
|
|
42
|
-
// Skip excluded files
|
|
43
|
-
const fileName = relativePath.split('/').pop() || '';
|
|
44
|
-
if (EXCLUDED_FILES.includes(fileName))
|
|
45
|
-
continue;
|
|
46
|
-
try {
|
|
47
|
-
await copyArtifact(client, parentRunId, childRunId, relativePath);
|
|
48
|
-
copiedFiles.push(relativePath);
|
|
49
|
-
}
|
|
50
|
-
catch (err) {
|
|
51
|
-
activity_1.log.warn(`Failed to copy ${relativePath}: ${err.message}`);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
activity_1.log.info(`Copied ${copiedFiles.length} artifacts from parent`);
|
|
55
|
-
return { copied: copiedFiles.length, files: copiedFiles };
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Extract relative path from full artifact storage path.
|
|
59
|
-
* Storage paths can be: "store_xxx/agents/{runId}/..." or "agents/{runId}/..."
|
|
60
|
-
*/
|
|
61
|
-
function extractRelativePath(fullPath, runId) {
|
|
62
|
-
// Look for the pattern: agents/{runId}/
|
|
63
|
-
const marker = `/agents/${runId}/`;
|
|
64
|
-
const idx = fullPath.lastIndexOf(marker);
|
|
65
|
-
if (idx >= 0) {
|
|
66
|
-
return fullPath.slice(idx + marker.length);
|
|
67
|
-
}
|
|
68
|
-
// Also try without leading slash
|
|
69
|
-
const legacyPrefix = `agents/${runId}/`;
|
|
70
|
-
if (fullPath.startsWith(legacyPrefix)) {
|
|
71
|
-
return fullPath.slice(legacyPrefix.length);
|
|
72
|
-
}
|
|
73
|
-
// If path contains the runId, try to extract after it
|
|
74
|
-
const runIdIdx = fullPath.indexOf(runId);
|
|
75
|
-
if (runIdIdx >= 0) {
|
|
76
|
-
const afterRunId = fullPath.slice(runIdIdx + runId.length);
|
|
77
|
-
if (afterRunId.startsWith('/')) {
|
|
78
|
-
return afterRunId.slice(1);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Copy a single artifact from parent to child agent space
|
|
85
|
-
*/
|
|
86
|
-
async function copyArtifact(client, parentRunId, childRunId, relativePath) {
|
|
87
|
-
// Download from parent's agent space
|
|
88
|
-
const stream = await client.files.downloadArtifact(parentRunId, relativePath);
|
|
89
|
-
// Convert web stream to node stream for upload
|
|
90
|
-
const nodeStream = stream_1.Readable.fromWeb(stream);
|
|
91
|
-
// Determine mime type from extension
|
|
92
|
-
const mimeType = getMimeType(relativePath);
|
|
93
|
-
const fileName = relativePath.split('/').pop() || relativePath;
|
|
94
|
-
// Upload to child's agent space at the same relative path
|
|
95
|
-
const source = new node_1.NodeStreamSource(nodeStream, fileName, mimeType);
|
|
96
|
-
await client.files.uploadArtifact(childRunId, relativePath, source);
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Get mime type from file extension
|
|
100
|
-
*/
|
|
101
|
-
function getMimeType(filePath) {
|
|
102
|
-
const ext = filePath.split('.').pop()?.toLowerCase();
|
|
103
|
-
const mimeTypes = {
|
|
104
|
-
'json': 'application/json',
|
|
105
|
-
'txt': 'text/plain',
|
|
106
|
-
'md': 'text/markdown',
|
|
107
|
-
'html': 'text/html',
|
|
108
|
-
'csv': 'text/csv',
|
|
109
|
-
'png': 'image/png',
|
|
110
|
-
'jpg': 'image/jpeg',
|
|
111
|
-
'jpeg': 'image/jpeg',
|
|
112
|
-
'gif': 'image/gif',
|
|
113
|
-
'svg': 'image/svg+xml',
|
|
114
|
-
'pdf': 'application/pdf',
|
|
115
|
-
'xml': 'application/xml',
|
|
116
|
-
'zip': 'application/zip',
|
|
117
|
-
'js': 'application/javascript',
|
|
118
|
-
'ts': 'application/typescript',
|
|
119
|
-
'py': 'text/x-python',
|
|
120
|
-
'sh': 'text/x-shellscript',
|
|
121
|
-
'bash': 'text/x-shellscript',
|
|
122
|
-
'yaml': 'text/yaml',
|
|
123
|
-
'yml': 'text/yaml',
|
|
124
|
-
};
|
|
125
|
-
return mimeTypes[ext || ''] || 'application/octet-stream';
|
|
126
|
-
}
|
|
127
|
-
//# sourceMappingURL=copyParentArtifacts.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copyParentArtifacts.js","sourceRoot":"","sources":["../../../src/activities/copyParentArtifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { log, activityInfo } from "@temporalio/activity";
|
|
2
|
-
import { NodeStreamSource } from "@vertesia/client/node";
|
|
3
|
-
import { Readable } from "stream";
|
|
4
|
-
import { setupActivity } from "../dsl/setup/ActivityContext.js";
|
|
5
|
-
/**
|
|
6
|
-
* Directories in the agent workspace to copy from parent to child.
|
|
7
|
-
*/
|
|
8
|
-
const WORKSPACE_DIRECTORIES = ['scripts', 'files', 'skills', 'docs', 'out'];
|
|
9
|
-
/**
|
|
10
|
-
* Files that should never be copied (child has its own).
|
|
11
|
-
*/
|
|
12
|
-
const EXCLUDED_FILES = ['conversation.json', 'tools.json'];
|
|
13
|
-
/**
|
|
14
|
-
* Copy workspace artifacts from parent workflow's agent space to current workflow's agent space.
|
|
15
|
-
*
|
|
16
|
-
* Copies: scripts/, files/, skills/, docs/, out/
|
|
17
|
-
* Excludes: conversation.json, tools.json
|
|
18
|
-
*/
|
|
19
|
-
export async function copyParentArtifacts(payload) {
|
|
20
|
-
const { client, params } = await setupActivity(payload);
|
|
21
|
-
const childRunId = activityInfo().workflowExecution.runId;
|
|
22
|
-
const parentRunId = params.parent_run_id;
|
|
23
|
-
log.info(`Copying artifacts from parent ${parentRunId} to child ${childRunId}`);
|
|
24
|
-
// List all files in parent's agent space
|
|
25
|
-
const parentFiles = await client.files.listArtifacts(parentRunId);
|
|
26
|
-
if (parentFiles.length === 0) {
|
|
27
|
-
log.info("No artifacts in parent agent space");
|
|
28
|
-
return { copied: 0, files: [] };
|
|
29
|
-
}
|
|
30
|
-
const copiedFiles = [];
|
|
31
|
-
for (const fullPath of parentFiles) {
|
|
32
|
-
const relativePath = extractRelativePath(fullPath, parentRunId);
|
|
33
|
-
if (!relativePath)
|
|
34
|
-
continue;
|
|
35
|
-
// Only copy workspace directories
|
|
36
|
-
const dir = relativePath.split('/')[0];
|
|
37
|
-
if (!WORKSPACE_DIRECTORIES.includes(dir))
|
|
38
|
-
continue;
|
|
39
|
-
// Skip excluded files
|
|
40
|
-
const fileName = relativePath.split('/').pop() || '';
|
|
41
|
-
if (EXCLUDED_FILES.includes(fileName))
|
|
42
|
-
continue;
|
|
43
|
-
try {
|
|
44
|
-
await copyArtifact(client, parentRunId, childRunId, relativePath);
|
|
45
|
-
copiedFiles.push(relativePath);
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
log.warn(`Failed to copy ${relativePath}: ${err.message}`);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
log.info(`Copied ${copiedFiles.length} artifacts from parent`);
|
|
52
|
-
return { copied: copiedFiles.length, files: copiedFiles };
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Extract relative path from full artifact storage path.
|
|
56
|
-
* Storage paths can be: "store_xxx/agents/{runId}/..." or "agents/{runId}/..."
|
|
57
|
-
*/
|
|
58
|
-
function extractRelativePath(fullPath, runId) {
|
|
59
|
-
// Look for the pattern: agents/{runId}/
|
|
60
|
-
const marker = `/agents/${runId}/`;
|
|
61
|
-
const idx = fullPath.lastIndexOf(marker);
|
|
62
|
-
if (idx >= 0) {
|
|
63
|
-
return fullPath.slice(idx + marker.length);
|
|
64
|
-
}
|
|
65
|
-
// Also try without leading slash
|
|
66
|
-
const legacyPrefix = `agents/${runId}/`;
|
|
67
|
-
if (fullPath.startsWith(legacyPrefix)) {
|
|
68
|
-
return fullPath.slice(legacyPrefix.length);
|
|
69
|
-
}
|
|
70
|
-
// If path contains the runId, try to extract after it
|
|
71
|
-
const runIdIdx = fullPath.indexOf(runId);
|
|
72
|
-
if (runIdIdx >= 0) {
|
|
73
|
-
const afterRunId = fullPath.slice(runIdIdx + runId.length);
|
|
74
|
-
if (afterRunId.startsWith('/')) {
|
|
75
|
-
return afterRunId.slice(1);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Copy a single artifact from parent to child agent space
|
|
82
|
-
*/
|
|
83
|
-
async function copyArtifact(client, parentRunId, childRunId, relativePath) {
|
|
84
|
-
// Download from parent's agent space
|
|
85
|
-
const stream = await client.files.downloadArtifact(parentRunId, relativePath);
|
|
86
|
-
// Convert web stream to node stream for upload
|
|
87
|
-
const nodeStream = Readable.fromWeb(stream);
|
|
88
|
-
// Determine mime type from extension
|
|
89
|
-
const mimeType = getMimeType(relativePath);
|
|
90
|
-
const fileName = relativePath.split('/').pop() || relativePath;
|
|
91
|
-
// Upload to child's agent space at the same relative path
|
|
92
|
-
const source = new NodeStreamSource(nodeStream, fileName, mimeType);
|
|
93
|
-
await client.files.uploadArtifact(childRunId, relativePath, source);
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Get mime type from file extension
|
|
97
|
-
*/
|
|
98
|
-
function getMimeType(filePath) {
|
|
99
|
-
const ext = filePath.split('.').pop()?.toLowerCase();
|
|
100
|
-
const mimeTypes = {
|
|
101
|
-
'json': 'application/json',
|
|
102
|
-
'txt': 'text/plain',
|
|
103
|
-
'md': 'text/markdown',
|
|
104
|
-
'html': 'text/html',
|
|
105
|
-
'csv': 'text/csv',
|
|
106
|
-
'png': 'image/png',
|
|
107
|
-
'jpg': 'image/jpeg',
|
|
108
|
-
'jpeg': 'image/jpeg',
|
|
109
|
-
'gif': 'image/gif',
|
|
110
|
-
'svg': 'image/svg+xml',
|
|
111
|
-
'pdf': 'application/pdf',
|
|
112
|
-
'xml': 'application/xml',
|
|
113
|
-
'zip': 'application/zip',
|
|
114
|
-
'js': 'application/javascript',
|
|
115
|
-
'ts': 'application/typescript',
|
|
116
|
-
'py': 'text/x-python',
|
|
117
|
-
'sh': 'text/x-shellscript',
|
|
118
|
-
'bash': 'text/x-shellscript',
|
|
119
|
-
'yaml': 'text/yaml',
|
|
120
|
-
'yml': 'text/yaml',
|
|
121
|
-
};
|
|
122
|
-
return mimeTypes[ext || ''] || 'application/octet-stream';
|
|
123
|
-
}
|
|
124
|
-
//# sourceMappingURL=copyParentArtifacts.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copyParentArtifacts.js","sourceRoot":"","sources":["../../../src/activities/copyParentArtifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { DSLActivityExecutionPayload, DSLActivitySpec } from "@vertesia/common";
|
|
2
|
-
export interface CopyParentArtifactsParams {
|
|
3
|
-
parent_run_id: string;
|
|
4
|
-
}
|
|
5
|
-
export interface CopyParentArtifacts extends DSLActivitySpec<CopyParentArtifactsParams> {
|
|
6
|
-
name: 'copyParentArtifacts';
|
|
7
|
-
projection?: never;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Copy workspace artifacts from parent workflow's agent space to current workflow's agent space.
|
|
11
|
-
*
|
|
12
|
-
* Copies: scripts/, files/, skills/, docs/, out/
|
|
13
|
-
* Excludes: conversation.json, tools.json
|
|
14
|
-
*/
|
|
15
|
-
export declare function copyParentArtifacts(payload: DSLActivityExecutionPayload<CopyParentArtifactsParams>): Promise<{
|
|
16
|
-
copied: number;
|
|
17
|
-
files: string[];
|
|
18
|
-
}>;
|
|
19
|
-
//# sourceMappingURL=copyParentArtifacts.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"copyParentArtifacts.d.ts","sourceRoot":"","sources":["../../../src/activities/copyParentArtifacts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAchF,MAAM,WAAW,yBAAyB;IACtC,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,mBAAoB,SAAQ,eAAe,CAAC,yBAAyB,CAAC;IACnF,IAAI,EAAE,qBAAqB,CAAC;IAC5B,UAAU,CAAC,EAAE,KAAK,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACrC,OAAO,EAAE,2BAA2B,CAAC,yBAAyB,CAAC,GAChE,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAuC9C"}
|