@themoltnet/node-red-contrib-core 0.3.3 → 0.4.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/nodes/src.js +328 -1
- package/dist/nodes/task-reader.js +2 -5
- package/package.json +2 -2
package/dist/nodes/src.js
CHANGED
|
@@ -2271,6 +2271,55 @@ var claimTask = (options) => (options.client ?? client).post({
|
|
|
2271
2271
|
}
|
|
2272
2272
|
});
|
|
2273
2273
|
/**
|
|
2274
|
+
* List task artifact metadata for the current team.
|
|
2275
|
+
*/
|
|
2276
|
+
var listTaskArtifacts = (options) => (options.client ?? client).get({
|
|
2277
|
+
security: [
|
|
2278
|
+
{
|
|
2279
|
+
scheme: "bearer",
|
|
2280
|
+
type: "http"
|
|
2281
|
+
},
|
|
2282
|
+
{
|
|
2283
|
+
name: "X-Moltnet-Session-Token",
|
|
2284
|
+
type: "apiKey"
|
|
2285
|
+
},
|
|
2286
|
+
{
|
|
2287
|
+
in: "cookie",
|
|
2288
|
+
name: "ory_kratos_session",
|
|
2289
|
+
type: "apiKey"
|
|
2290
|
+
}
|
|
2291
|
+
],
|
|
2292
|
+
url: "/tasks/{taskId}/artifacts",
|
|
2293
|
+
...options
|
|
2294
|
+
});
|
|
2295
|
+
/**
|
|
2296
|
+
* Upload immutable content-addressed artifact content for a task attempt.
|
|
2297
|
+
*/
|
|
2298
|
+
var uploadTaskArtifact = (options) => (options.client ?? client).put({
|
|
2299
|
+
bodySerializer: null,
|
|
2300
|
+
security: [
|
|
2301
|
+
{
|
|
2302
|
+
scheme: "bearer",
|
|
2303
|
+
type: "http"
|
|
2304
|
+
},
|
|
2305
|
+
{
|
|
2306
|
+
name: "X-Moltnet-Session-Token",
|
|
2307
|
+
type: "apiKey"
|
|
2308
|
+
},
|
|
2309
|
+
{
|
|
2310
|
+
in: "cookie",
|
|
2311
|
+
name: "ory_kratos_session",
|
|
2312
|
+
type: "apiKey"
|
|
2313
|
+
}
|
|
2314
|
+
],
|
|
2315
|
+
url: "/tasks/{taskId}/attempts/{attemptN}/artifacts",
|
|
2316
|
+
...options,
|
|
2317
|
+
headers: {
|
|
2318
|
+
"Content-Type": "application/octet-stream",
|
|
2319
|
+
...options.headers
|
|
2320
|
+
}
|
|
2321
|
+
});
|
|
2322
|
+
/**
|
|
2274
2323
|
* List teams the caller belongs to.
|
|
2275
2324
|
*/
|
|
2276
2325
|
var listTeams = (options) => (options?.client ?? client).get({
|
|
@@ -10036,6 +10085,97 @@ var VerificationRecord = _Object_({
|
|
|
10036
10085
|
$id: "VerificationRecord",
|
|
10037
10086
|
additionalProperties: false
|
|
10038
10087
|
});
|
|
10088
|
+
_Object_({
|
|
10089
|
+
artifacts: _Array_(_Object_({
|
|
10090
|
+
id: String$1({ format: "uuid" }),
|
|
10091
|
+
teamId: String$1({ format: "uuid" }),
|
|
10092
|
+
taskId: String$1({ format: "uuid" }),
|
|
10093
|
+
attemptN: Integer({ minimum: 1 }),
|
|
10094
|
+
kind: String$1({
|
|
10095
|
+
minLength: 1,
|
|
10096
|
+
maxLength: 100
|
|
10097
|
+
}),
|
|
10098
|
+
title: String$1({
|
|
10099
|
+
minLength: 1,
|
|
10100
|
+
maxLength: 255
|
|
10101
|
+
}),
|
|
10102
|
+
contentType: String$1({
|
|
10103
|
+
minLength: 1,
|
|
10104
|
+
maxLength: 200
|
|
10105
|
+
}),
|
|
10106
|
+
contentEncoding: Union([String$1({
|
|
10107
|
+
minLength: 1,
|
|
10108
|
+
maxLength: 100
|
|
10109
|
+
}), Null()]),
|
|
10110
|
+
sizeBytes: Integer({ minimum: 0 }),
|
|
10111
|
+
cid: String$1({
|
|
10112
|
+
minLength: 1,
|
|
10113
|
+
maxLength: 100
|
|
10114
|
+
}),
|
|
10115
|
+
createdByAgentId: String$1({ format: "uuid" }),
|
|
10116
|
+
expiresAt: Union([String$1({ format: "date-time" }), Null()]),
|
|
10117
|
+
createdAt: String$1({ format: "date-time" })
|
|
10118
|
+
}, { $id: "TaskArtifact" })),
|
|
10119
|
+
nextCursor: Union([String$1({ minLength: 1 }), Null()])
|
|
10120
|
+
}, { $id: "TaskArtifactList" });
|
|
10121
|
+
_Object_({
|
|
10122
|
+
limit: Optional(Integer({
|
|
10123
|
+
minimum: 1,
|
|
10124
|
+
maximum: 100
|
|
10125
|
+
})),
|
|
10126
|
+
cursor: Optional(String$1({ minLength: 1 }))
|
|
10127
|
+
}, {
|
|
10128
|
+
$id: "ListTaskArtifactsQuery",
|
|
10129
|
+
additionalProperties: false
|
|
10130
|
+
});
|
|
10131
|
+
_Object_({
|
|
10132
|
+
kind: String$1({
|
|
10133
|
+
minLength: 1,
|
|
10134
|
+
maxLength: 100
|
|
10135
|
+
}),
|
|
10136
|
+
title: String$1({
|
|
10137
|
+
minLength: 1,
|
|
10138
|
+
maxLength: 255
|
|
10139
|
+
}),
|
|
10140
|
+
contentType: Optional(String$1({
|
|
10141
|
+
minLength: 1,
|
|
10142
|
+
maxLength: 200
|
|
10143
|
+
})),
|
|
10144
|
+
contentEncoding: Optional(String$1({
|
|
10145
|
+
minLength: 1,
|
|
10146
|
+
maxLength: 100
|
|
10147
|
+
}))
|
|
10148
|
+
}, {
|
|
10149
|
+
$id: "UploadTaskArtifactQuery",
|
|
10150
|
+
additionalProperties: false
|
|
10151
|
+
});
|
|
10152
|
+
String$1({
|
|
10153
|
+
$id: "TaskArtifactContent",
|
|
10154
|
+
description: "Task artifact content stream.",
|
|
10155
|
+
format: "binary"
|
|
10156
|
+
});
|
|
10157
|
+
_Object_({ taskId: String$1({ format: "uuid" }) }, {
|
|
10158
|
+
$id: "TaskArtifactTaskParams",
|
|
10159
|
+
additionalProperties: false
|
|
10160
|
+
});
|
|
10161
|
+
_Object_({
|
|
10162
|
+
taskId: String$1({ format: "uuid" }),
|
|
10163
|
+
attemptN: Integer({ minimum: 1 })
|
|
10164
|
+
}, {
|
|
10165
|
+
$id: "TaskArtifactAttemptParams",
|
|
10166
|
+
additionalProperties: false
|
|
10167
|
+
});
|
|
10168
|
+
_Object_({
|
|
10169
|
+
taskId: String$1({ format: "uuid" }),
|
|
10170
|
+
attemptN: Integer({ minimum: 1 }),
|
|
10171
|
+
cid: String$1({
|
|
10172
|
+
minLength: 1,
|
|
10173
|
+
maxLength: 100
|
|
10174
|
+
})
|
|
10175
|
+
}, {
|
|
10176
|
+
$id: "TaskArtifactContentParams",
|
|
10177
|
+
additionalProperties: false
|
|
10178
|
+
});
|
|
10039
10179
|
new TextEncoder();
|
|
10040
10180
|
new TextDecoder();
|
|
10041
10181
|
//#endregion
|
|
@@ -10295,6 +10435,10 @@ var FreeformArtifact = _Object_({
|
|
|
10295
10435
|
description: Optional(String$1({ minLength: 1 })),
|
|
10296
10436
|
url: Optional(String$1({ minLength: 1 })),
|
|
10297
10437
|
path: Optional(String$1({ minLength: 1 })),
|
|
10438
|
+
cid: Optional(String$1({ minLength: 1 })),
|
|
10439
|
+
contentType: Optional(String$1({ minLength: 1 })),
|
|
10440
|
+
contentEncoding: Optional(String$1({ minLength: 1 })),
|
|
10441
|
+
sizeBytes: Optional(Integer({ minimum: 0 })),
|
|
10298
10442
|
body: Optional(String$1({ maxLength: 65536 }))
|
|
10299
10443
|
}, {
|
|
10300
10444
|
$id: "FreeformArtifact",
|
|
@@ -13765,7 +13909,23 @@ var TaskRef = _Object_({
|
|
|
13765
13909
|
url: Optional(String$1()),
|
|
13766
13910
|
commit_sha: Optional(String$1()),
|
|
13767
13911
|
snapshot_cid: Optional(Cid)
|
|
13768
|
-
}))
|
|
13912
|
+
})),
|
|
13913
|
+
artifact: Optional(_Object_({
|
|
13914
|
+
cid: Cid,
|
|
13915
|
+
attemptN: Integer({ minimum: 1 }),
|
|
13916
|
+
kind: Optional(String$1({
|
|
13917
|
+
minLength: 1,
|
|
13918
|
+
maxLength: 100
|
|
13919
|
+
})),
|
|
13920
|
+
title: Optional(String$1({
|
|
13921
|
+
minLength: 1,
|
|
13922
|
+
maxLength: 255
|
|
13923
|
+
})),
|
|
13924
|
+
contentType: Optional(String$1({
|
|
13925
|
+
minLength: 1,
|
|
13926
|
+
maxLength: 200
|
|
13927
|
+
}))
|
|
13928
|
+
}, { additionalProperties: false }))
|
|
13769
13929
|
}, {
|
|
13770
13930
|
$id: "TaskRef",
|
|
13771
13931
|
additionalProperties: false
|
|
@@ -14110,6 +14270,7 @@ var TaskBuilder = class {
|
|
|
14110
14270
|
message: "reference is missing required outputCid"
|
|
14111
14271
|
}]);
|
|
14112
14272
|
ref = {
|
|
14273
|
+
...s,
|
|
14113
14274
|
taskId: s.taskId ?? null,
|
|
14114
14275
|
outputCid: s.outputCid,
|
|
14115
14276
|
role
|
|
@@ -14119,6 +14280,60 @@ var TaskBuilder = class {
|
|
|
14119
14280
|
return this;
|
|
14120
14281
|
}
|
|
14121
14282
|
/**
|
|
14283
|
+
* Add a reference to a persistent task artifact while retaining the accepted
|
|
14284
|
+
* output CID as the provenance anchor.
|
|
14285
|
+
*
|
|
14286
|
+
* @param source - A result reader, raw artifact reference, or `TaskRef`.
|
|
14287
|
+
* @param role - The role the referenced artifact plays.
|
|
14288
|
+
* @returns This builder, for chaining.
|
|
14289
|
+
* @throws {TaskBuildError} when output or artifact CID is missing.
|
|
14290
|
+
*/
|
|
14291
|
+
artifactReference(source, role) {
|
|
14292
|
+
let ref;
|
|
14293
|
+
if ("artifactRef" in source && typeof source.artifactRef === "function") ref = source.artifactRef(role);
|
|
14294
|
+
else if ("artifact" in source && source.artifact?.cid) {
|
|
14295
|
+
if (typeof source.artifact.attemptN !== "number" || !Number.isInteger(source.artifact.attemptN) || source.artifact.attemptN < 1) throw new TaskBuildError([{
|
|
14296
|
+
field: "references/artifact/attemptN",
|
|
14297
|
+
message: "artifact reference is missing required attemptN"
|
|
14298
|
+
}]);
|
|
14299
|
+
ref = {
|
|
14300
|
+
...source,
|
|
14301
|
+
role
|
|
14302
|
+
};
|
|
14303
|
+
} else {
|
|
14304
|
+
const s = source;
|
|
14305
|
+
const errors = [];
|
|
14306
|
+
if (!s.outputCid) errors.push({
|
|
14307
|
+
field: "references/outputCid",
|
|
14308
|
+
message: "reference is missing required outputCid"
|
|
14309
|
+
});
|
|
14310
|
+
if (!s.artifactCid) errors.push({
|
|
14311
|
+
field: "references/artifact/cid",
|
|
14312
|
+
message: "artifact reference is missing required cid"
|
|
14313
|
+
});
|
|
14314
|
+
if (typeof s.attemptN !== "number" || !Number.isInteger(s.attemptN) || s.attemptN < 1) errors.push({
|
|
14315
|
+
field: "references/artifact/attemptN",
|
|
14316
|
+
message: "artifact reference is missing required attemptN"
|
|
14317
|
+
});
|
|
14318
|
+
if (errors.length > 0) throw new TaskBuildError(errors);
|
|
14319
|
+
const attemptN = s.attemptN;
|
|
14320
|
+
ref = {
|
|
14321
|
+
taskId: s.taskId ?? null,
|
|
14322
|
+
outputCid: s.outputCid,
|
|
14323
|
+
role,
|
|
14324
|
+
artifact: {
|
|
14325
|
+
cid: s.artifactCid,
|
|
14326
|
+
attemptN,
|
|
14327
|
+
...s.kind ? { kind: s.kind } : {},
|
|
14328
|
+
...s.title ? { title: s.title } : {},
|
|
14329
|
+
...s.contentType ? { contentType: s.contentType } : {}
|
|
14330
|
+
}
|
|
14331
|
+
};
|
|
14332
|
+
}
|
|
14333
|
+
this.refs.push(ref);
|
|
14334
|
+
return this;
|
|
14335
|
+
}
|
|
14336
|
+
/**
|
|
14122
14337
|
* Set the owning team (required by the wire schema).
|
|
14123
14338
|
*
|
|
14124
14339
|
* @param teamId - Team UUID.
|
|
@@ -14496,6 +14711,34 @@ var TaskResultReader = class {
|
|
|
14496
14711
|
role
|
|
14497
14712
|
};
|
|
14498
14713
|
}
|
|
14714
|
+
/**
|
|
14715
|
+
* Build a `TaskRef` that anchors a downstream task to this accepted output
|
|
14716
|
+
* and points at one persistent task artifact by CID.
|
|
14717
|
+
*
|
|
14718
|
+
* @param filter - Artifact object or a filter resolved against output artifacts.
|
|
14719
|
+
* @param role - The role this artifact plays in the downstream task.
|
|
14720
|
+
* @returns A `TaskRef` with `artifact.cid` populated.
|
|
14721
|
+
* @throws {TaskResultError} if no matching artifact has a CID.
|
|
14722
|
+
*/
|
|
14723
|
+
artifactRef(filter, role) {
|
|
14724
|
+
const artifact = typeof filter === "object" && "cid" in filter && "kind" in filter ? filter : this.artifact(filter);
|
|
14725
|
+
if (!artifact?.cid) throw new TaskResultError([{
|
|
14726
|
+
field: "artifacts/cid",
|
|
14727
|
+
message: "no matching artifact with a cid"
|
|
14728
|
+
}]);
|
|
14729
|
+
return {
|
|
14730
|
+
taskId: this.taskId,
|
|
14731
|
+
outputCid: this.outputCid,
|
|
14732
|
+
role,
|
|
14733
|
+
artifact: {
|
|
14734
|
+
cid: artifact.cid,
|
|
14735
|
+
attemptN: this.accepted.attemptN,
|
|
14736
|
+
kind: artifact.kind,
|
|
14737
|
+
title: artifact.title,
|
|
14738
|
+
...artifact.contentType ? { contentType: artifact.contentType } : {}
|
|
14739
|
+
}
|
|
14740
|
+
};
|
|
14741
|
+
}
|
|
14499
14742
|
};
|
|
14500
14743
|
/**
|
|
14501
14744
|
* Validate and construct a {@link TaskResultReader} from a task and its
|
|
@@ -14520,6 +14763,63 @@ function createTasksNamespace(context) {
|
|
|
14520
14763
|
auth
|
|
14521
14764
|
}));
|
|
14522
14765
|
},
|
|
14766
|
+
artifacts: {
|
|
14767
|
+
async upload(path, body, query, options) {
|
|
14768
|
+
return unwrapResult(await uploadTaskArtifact({
|
|
14769
|
+
auth,
|
|
14770
|
+
body,
|
|
14771
|
+
client,
|
|
14772
|
+
duplex: "half",
|
|
14773
|
+
headers: {
|
|
14774
|
+
...requiredTeamHeaders(options),
|
|
14775
|
+
"content-type": "application/octet-stream"
|
|
14776
|
+
},
|
|
14777
|
+
path,
|
|
14778
|
+
query
|
|
14779
|
+
}));
|
|
14780
|
+
},
|
|
14781
|
+
async list(taskId, options, query) {
|
|
14782
|
+
return unwrapResult(await listTaskArtifacts({
|
|
14783
|
+
client,
|
|
14784
|
+
auth,
|
|
14785
|
+
headers: requiredTeamHeaders(options),
|
|
14786
|
+
path: { taskId },
|
|
14787
|
+
query
|
|
14788
|
+
})).artifacts;
|
|
14789
|
+
},
|
|
14790
|
+
async listPage(taskId, query, options) {
|
|
14791
|
+
return unwrapResult(await listTaskArtifacts({
|
|
14792
|
+
client,
|
|
14793
|
+
auth,
|
|
14794
|
+
headers: requiredTeamHeaders(options),
|
|
14795
|
+
path: { taskId },
|
|
14796
|
+
query
|
|
14797
|
+
}));
|
|
14798
|
+
},
|
|
14799
|
+
async download(path, options) {
|
|
14800
|
+
const result = await client.request({
|
|
14801
|
+
auth,
|
|
14802
|
+
headers: requiredTeamHeaders(options),
|
|
14803
|
+
method: "GET",
|
|
14804
|
+
parseAs: "stream",
|
|
14805
|
+
path,
|
|
14806
|
+
security: [{
|
|
14807
|
+
scheme: "bearer",
|
|
14808
|
+
type: "http"
|
|
14809
|
+
}],
|
|
14810
|
+
url: "/tasks/{taskId}/attempts/{attemptN}/artifacts/{cid}/content"
|
|
14811
|
+
});
|
|
14812
|
+
const normalizedStream = normalizeDownloadStream(unwrapResult(result));
|
|
14813
|
+
if (normalizedStream) return {
|
|
14814
|
+
artifactId: header(result.response, "x-moltnet-task-artifact-id"),
|
|
14815
|
+
cid: header(result.response, "x-moltnet-task-artifact-cid"),
|
|
14816
|
+
contentEncoding: header(result.response, "x-moltnet-task-artifact-content-encoding"),
|
|
14817
|
+
contentType: header(result.response, "x-moltnet-task-artifact-content-type"),
|
|
14818
|
+
stream: normalizedStream
|
|
14819
|
+
};
|
|
14820
|
+
throw new MoltNetError("Unexpected task artifact download response stream", { code: "INVALID_RESPONSE" });
|
|
14821
|
+
}
|
|
14822
|
+
},
|
|
14523
14823
|
async list(query, options) {
|
|
14524
14824
|
return unwrapResult(await listTasks({
|
|
14525
14825
|
client,
|
|
@@ -14688,6 +14988,33 @@ function createTasksNamespace(context) {
|
|
|
14688
14988
|
}
|
|
14689
14989
|
};
|
|
14690
14990
|
}
|
|
14991
|
+
function header(response, name) {
|
|
14992
|
+
const value = response?.headers.get(name) ?? null;
|
|
14993
|
+
return value === "" ? null : value;
|
|
14994
|
+
}
|
|
14995
|
+
function normalizeDownloadStream(stream) {
|
|
14996
|
+
if (isAsyncIterable(stream)) return stream;
|
|
14997
|
+
if (isReadableStream(stream)) return readableStreamToAsyncIterable(stream);
|
|
14998
|
+
return null;
|
|
14999
|
+
}
|
|
15000
|
+
function isAsyncIterable(value) {
|
|
15001
|
+
return typeof value === "object" && value !== null && Symbol.asyncIterator in value && typeof value[Symbol.asyncIterator] === "function";
|
|
15002
|
+
}
|
|
15003
|
+
function isReadableStream(value) {
|
|
15004
|
+
return typeof value === "object" && value !== null && "getReader" in value && typeof value.getReader === "function";
|
|
15005
|
+
}
|
|
15006
|
+
async function* readableStreamToAsyncIterable(stream) {
|
|
15007
|
+
const reader = stream.getReader();
|
|
15008
|
+
try {
|
|
15009
|
+
while (true) {
|
|
15010
|
+
const result = await reader.read();
|
|
15011
|
+
if (result.done) return;
|
|
15012
|
+
yield result.value;
|
|
15013
|
+
}
|
|
15014
|
+
} finally {
|
|
15015
|
+
reader.releaseLock();
|
|
15016
|
+
}
|
|
15017
|
+
}
|
|
14691
15018
|
//#endregion
|
|
14692
15019
|
//#region ../sdk/src/namespaces/teams.ts
|
|
14693
15020
|
function createTeamsNamespace(context) {
|
|
@@ -19,16 +19,13 @@ var init = (RED) => {
|
|
|
19
19
|
} : def.artifactKind : void 0;
|
|
20
20
|
let artifactBody;
|
|
21
21
|
const artifact = filter ? reader.artifact(filter) : void 0;
|
|
22
|
-
if (filter && artifact && typeof artifact.body === "string")
|
|
23
|
-
artifactBody = JSON.parse(artifact.body);
|
|
24
|
-
} catch {
|
|
25
|
-
artifactBody = void 0;
|
|
26
|
-
}
|
|
22
|
+
if (filter && artifact && typeof artifact.body === "string") artifactBody = reader.artifactBody(filter);
|
|
27
23
|
const out = RED.util.cloneMessage(msg);
|
|
28
24
|
out.payload = reader.output;
|
|
29
25
|
out.result = {
|
|
30
26
|
summary: reader.summary,
|
|
31
27
|
outputRef: reader.outputRef(role),
|
|
28
|
+
artifactRef: artifact?.cid !== void 0 ? reader.artifactRef(artifact, role) : void 0,
|
|
32
29
|
artifact,
|
|
33
30
|
artifactBody,
|
|
34
31
|
accepted: reader.accepted,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/node-red-contrib-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Node-RED nodes for the MoltNet API",
|
|
6
6
|
"keywords": [
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"main": "dist/nodes/agent.js",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@themoltnet/sdk": "0.
|
|
41
|
+
"@themoltnet/sdk": "0.115.0"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@types/node": "^22.19.0",
|