@stigmer/sdk 3.15.3-dev.20260914121148 → 3.16.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/__tests__/plugin.test.d.ts +2 -0
- package/__tests__/plugin.test.d.ts.map +1 -0
- package/__tests__/plugin.test.js +74 -0
- package/__tests__/plugin.test.js.map +1 -0
- package/artifact-routing.d.ts +38 -0
- package/artifact-routing.d.ts.map +1 -0
- package/artifact-routing.js +60 -0
- package/artifact-routing.js.map +1 -0
- package/gen/authorization-config.d.ts.map +1 -1
- package/gen/authorization-config.js +1 -0
- package/gen/authorization-config.js.map +1 -1
- package/gen/client.d.ts +4 -0
- package/gen/client.d.ts.map +1 -1
- package/gen/client.js +4 -0
- package/gen/client.js.map +1 -1
- package/gen/plugin.d.ts +54 -0
- package/gen/plugin.d.ts.map +1 -0
- package/gen/plugin.js +120 -0
- package/gen/plugin.js.map +1 -0
- package/gen/resource-availability.d.ts.map +1 -1
- package/gen/resource-availability.js +1 -0
- package/gen/resource-availability.js.map +1 -1
- package/index.d.ts +2 -0
- package/index.d.ts.map +1 -1
- package/index.js +2 -0
- package/index.js.map +1 -1
- package/package.json +2 -2
- package/plugin.d.ts +25 -0
- package/plugin.d.ts.map +1 -0
- package/plugin.js +46 -0
- package/plugin.js.map +1 -0
- package/skill.d.ts +8 -32
- package/skill.d.ts.map +1 -1
- package/skill.js +24 -81
- package/skill.js.map +1 -1
- package/src/__tests__/plugin.test.ts +92 -0
- package/src/artifact-routing.ts +111 -0
- package/src/gen/authorization-config.ts +1 -0
- package/src/gen/client.ts +5 -0
- package/src/gen/plugin.ts +143 -0
- package/src/gen/resource-availability.ts +1 -0
- package/src/index.ts +2 -0
- package/src/plugin.ts +59 -0
- package/src/skill.ts +28 -94
- package/src/stigmer.ts +13 -3
- package/stigmer.d.ts +7 -0
- package/stigmer.d.ts.map +1 -1
- package/stigmer.js +13 -2
- package/stigmer.js.map +1 -1
package/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAE9B,mBAAmB;AACnB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,iBAAiB;AACjB,OAAO,EAGL,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAK7B,4EAA4E;AAC5E,OAAO,EACL,eAAe,EACf,SAAS,GAGV,MAAM,iBAAiB,CAAC;AAEzB,8DAA8D;AAC9D,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,eAAe,EACf,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,cAAc,CAAC;AAEtB,iBAAiB;AACjB,OAAO,EACL,YAAY,EAEZ,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,WAAW,EACX,eAAe,EAEf,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EAEd,cAAc,EAEd,gBAAgB,EAChB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,+CAA+C;AAC/C,OAAO,EAEL,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,8EAA8E;AAC9E,wEAAwE;AACxE,iCAAiC;AACjC,OAAO,EACL,uBAAuB,GAIxB,MAAM,8BAA8B,CAAC;AAEtC,8CAA8C;AAC9C,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,GAChB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,2CAA2C,CAAC;AAEpE,oCAAoC;AACpC,OAAO,EACL,cAAc,GAGf,MAAM,eAAe,CAAC;AAGvB,iBAAiB;AACjB,OAAO,EACL,aAAa,GAQd,MAAM,cAAc,CAAC;AAEtB,mDAAmD;AACnD,OAAO,EACL,oBAAoB,GAMrB,MAAM,sBAAsB,CAAC;AAE9B,gEAAgE;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,gBAAgB;AAChB,OAAO,EACL,YAAY,EAGZ,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,sBAAsB;AACtB,OAAO,EACL,YAAY,GAKb,MAAM,aAAa,CAAC;AAErB,oDAAoD;AACpD,OAAO,EAAE,cAAc,EAAmB,MAAM,eAAe,CAAC;AAEhE,uDAAuD;AACvD,OAAO,EACL,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,2BAA2B,EAC3B,aAAa,EACb,0BAA0B,EAC1B,0BAA0B,EAC1B,UAAU,EACV,sBAAsB,EACtB,uBAAuB,GAKxB,MAAM,qBAAqB,CAAC;AAa7B,6DAA6D;AAC7D,wEAAwE;AACxE,yEAAyE;AACzE,sDAAsD;AACtD,OAAO,EACL,WAAW,EACX,eAAe,EACf,kBAAkB,GAOnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAG1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAK5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,mBAAmB,EACnB,0BAA0B,GAE3B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GAGxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,YAAY,EACZ,mBAAmB,GAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,GAGxB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,iBAAiB,EACjB,wBAAwB,GAEzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,sBAAsB,GAEvB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,eAAe,GAGhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,4BAA4B,GAE7B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,gBAAgB,EAAwB,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EACL,sBAAsB,EACtB,6BAA6B,GAE9B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,cAAc,EACd,qBAAqB,GAEtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,sBAAsB,GAKvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GAGpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,wBAAwB,EACxB,uBAAuB,GAGxB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAE1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,oBAAoB,EACpB,2BAA2B,GAE5B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,aAAa,EACb,oBAAoB,GAErB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,qBAAqB,GAItB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,oBAAoB,GAMrB,MAAM,kBAAkB,CAAC;AAE1B,mCAAmC;AACnC,OAAO,EACL,eAAe,EACf,4BAA4B,EAC5B,mBAAmB,EACnB,eAAe,GAChB,MAAM,cAAc,CAAC;AAEtB,uFAAuF;AACvF,OAAO,EACL,QAAQ,EACR,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,GAIpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,GAC1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,GAQjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAmB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EACL,cAAc,EACd,qBAAqB,GAMtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,uBAAuB,EACvB,8BAA8B,GAE/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,sBAAsB,EACtB,6BAA6B,GAE9B,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stigmer/sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "Stigmer TypeScript SDK — typed API client for all Stigmer platform resources",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -45,6 +45,6 @@
|
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"@bufbuild/protobuf": "^2.0.0",
|
|
47
47
|
"@connectrpc/connect-node": "^2.0.0",
|
|
48
|
-
"@stigmer/protos": "3.
|
|
48
|
+
"@stigmer/protos": "3.16.0"
|
|
49
49
|
}
|
|
50
50
|
}
|
package/plugin.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Transport } from "@connectrpc/connect";
|
|
2
|
+
import type { Plugin } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/api_pb";
|
|
3
|
+
import { type PushPluginRequest } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/io_pb";
|
|
4
|
+
import { PluginClient } from "./gen/plugin.js";
|
|
5
|
+
/**
|
|
6
|
+
* Plugin client with transport-aware push routing: the plugin binding of
|
|
7
|
+
* `artifact-routing.ts`. A plugin archive travels inline when it fits the
|
|
8
|
+
* gRPC message cap and is staged over HTTP via `createArtifactUploadUrl`
|
|
9
|
+
* (the skill lane's slots, one upload surface) when it does not; `push`
|
|
10
|
+
* simply works for any valid archive size. Every other method is the
|
|
11
|
+
* generated client's, inherited unchanged.
|
|
12
|
+
*/
|
|
13
|
+
export declare class RoutedPluginClient extends PluginClient {
|
|
14
|
+
private readonly fetchImpl;
|
|
15
|
+
private readonly route;
|
|
16
|
+
/**
|
|
17
|
+
* @param fetchImpl - Custom `fetch` for the staging PUT. Must be the same
|
|
18
|
+
* implementation the transport uses where the global one is restricted
|
|
19
|
+
* (the Tauri CSP/CORS case the `Stigmer.fetch` property documents).
|
|
20
|
+
*/
|
|
21
|
+
constructor(transport: Transport, fetchImpl?: typeof globalThis.fetch);
|
|
22
|
+
/** Push a plugin archive, routing it by size (see the class comment). */
|
|
23
|
+
push(input: PushPluginRequest): Promise<Plugin>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=plugin.d.ts.map
|
package/plugin.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qDAAqD,CAAC;AAClF,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,oDAAoD,CAAC;AAG5D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2C;IAEjE;;;;OAIG;gBACS,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;IAyBrE,yEAAyE;IAChE,IAAI,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;CAGzD"}
|
package/plugin.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { create } from "@bufbuild/protobuf";
|
|
2
|
+
import { CreatePluginArtifactUploadUrlRequestSchema, PushPluginRequestSchema, } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/io_pb";
|
|
3
|
+
import { pushRoutedArtifact } from "./artifact-routing.js";
|
|
4
|
+
import { PluginClient } from "./gen/plugin.js";
|
|
5
|
+
/**
|
|
6
|
+
* Plugin client with transport-aware push routing: the plugin binding of
|
|
7
|
+
* `artifact-routing.ts`. A plugin archive travels inline when it fits the
|
|
8
|
+
* gRPC message cap and is staged over HTTP via `createArtifactUploadUrl`
|
|
9
|
+
* (the skill lane's slots, one upload surface) when it does not; `push`
|
|
10
|
+
* simply works for any valid archive size. Every other method is the
|
|
11
|
+
* generated client's, inherited unchanged.
|
|
12
|
+
*/
|
|
13
|
+
export class RoutedPluginClient extends PluginClient {
|
|
14
|
+
fetchImpl;
|
|
15
|
+
route;
|
|
16
|
+
/**
|
|
17
|
+
* @param fetchImpl - Custom `fetch` for the staging PUT. Must be the same
|
|
18
|
+
* implementation the transport uses where the global one is restricted
|
|
19
|
+
* (the Tauri CSP/CORS case the `Stigmer.fetch` property documents).
|
|
20
|
+
*/
|
|
21
|
+
constructor(transport, fetchImpl) {
|
|
22
|
+
super(transport);
|
|
23
|
+
this.fetchImpl = fetchImpl;
|
|
24
|
+
this.route = {
|
|
25
|
+
noun: "plugin",
|
|
26
|
+
artifactOf: (request) => request.artifact,
|
|
27
|
+
uploadRefOf: (request) => request.artifactUploadRef,
|
|
28
|
+
orgOf: (request) => request.org,
|
|
29
|
+
withUploadRef: (request, artifactUploadRef) => create(PushPluginRequestSchema, {
|
|
30
|
+
...request,
|
|
31
|
+
artifact: new Uint8Array(0),
|
|
32
|
+
artifactUploadRef,
|
|
33
|
+
}),
|
|
34
|
+
mintUploadUrl: (org, sizeBytes) => super.createArtifactUploadUrl(create(CreatePluginArtifactUploadUrlRequestSchema, {
|
|
35
|
+
org,
|
|
36
|
+
sizeBytes,
|
|
37
|
+
})),
|
|
38
|
+
push: (request) => super.push(request),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** Push a plugin archive, routing it by size (see the class comment). */
|
|
42
|
+
push(input) {
|
|
43
|
+
return pushRoutedArtifact(this.route, input, this.fetchImpl);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=plugin.js.map
|
package/plugin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EACL,0CAA0C,EAC1C,uBAAuB,GAExB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C;;;;;;;GAOG;AACH,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IACjC,SAAS,CAAsC;IAC/C,KAAK,CAA2C;IAEjE;;;;OAIG;IACH,YAAY,SAAoB,EAAE,SAAmC;QACnE,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ;YACzC,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB;YACnD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG;YAC/B,aAAa,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,CAC5C,MAAM,CAAC,uBAAuB,EAAE;gBAC9B,GAAG,OAAO;gBACV,QAAQ,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;gBAC3B,iBAAiB;aAClB,CAAC;YACJ,aAAa,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAChC,KAAK,CAAC,uBAAuB,CAC3B,MAAM,CAAC,0CAA0C,EAAE;gBACjD,GAAG;gBACH,SAAS;aACV,CAAC,CACH;YACH,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;SACvC,CAAC;IACJ,CAAC;IAED,yEAAyE;IAChE,IAAI,CAAC,KAAwB;QACpC,OAAO,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;CACF"}
|
package/skill.d.ts
CHANGED
|
@@ -2,50 +2,26 @@ import type { Transport } from "@connectrpc/connect";
|
|
|
2
2
|
import type { Skill } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/api_pb";
|
|
3
3
|
import { type PushSkillRequest } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/io_pb";
|
|
4
4
|
import { SkillClient } from "./gen/skill.js";
|
|
5
|
+
export { MAX_INLINE_ARTIFACT_BYTES } from "./artifact-routing.js";
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
export declare const MAX_INLINE_ARTIFACT_BYTES: number;
|
|
12
|
-
/**
|
|
13
|
-
* Skill client with transport-aware push routing (stigmer#675 / #701).
|
|
14
|
-
*
|
|
15
|
-
* The gRPC transport caps messages at 10MB while skills may be up to 100MB,
|
|
16
|
-
* so `push` routes by size: small artifacts travel inline in the request
|
|
17
|
-
* (one round trip, unchanged behavior), larger ones are staged over HTTP
|
|
18
|
-
* via `createArtifactUploadUrl` — a capability URL, so no auth header —
|
|
19
|
-
* and pushed by reference. Callers never see the mechanics: `push(req)`
|
|
20
|
-
* simply works for any valid skill size.
|
|
7
|
+
* Skill client with transport-aware push routing (stigmer#675 / #701):
|
|
8
|
+
* the skill binding of `artifact-routing.ts`, which holds the mechanism
|
|
9
|
+
* (small artifacts inline, larger ones staged over HTTP via
|
|
10
|
+
* `createArtifactUploadUrl` and pushed by reference). Callers never see
|
|
11
|
+
* the mechanics: `push(req)` simply works for any valid skill size.
|
|
21
12
|
*
|
|
22
13
|
* Every other method is the generated client's, inherited unchanged.
|
|
23
14
|
*/
|
|
24
15
|
export declare class RoutedSkillClient extends SkillClient {
|
|
25
16
|
private readonly fetchImpl;
|
|
17
|
+
private readonly route;
|
|
26
18
|
/**
|
|
27
19
|
* @param fetchImpl - Custom `fetch` for the staging PUT. Must be the same
|
|
28
20
|
* implementation the transport uses where the global one is restricted
|
|
29
21
|
* (the Tauri CSP/CORS case the `Stigmer.fetch` property documents).
|
|
30
22
|
*/
|
|
31
23
|
constructor(transport: Transport, fetchImpl?: typeof globalThis.fetch);
|
|
32
|
-
/**
|
|
33
|
-
* Push a skill, routing the artifact by size (see the class comment).
|
|
34
|
-
*
|
|
35
|
-
* A request that already carries an `artifactUploadRef` is passed through
|
|
36
|
-
* untouched — the caller has done its own staging.
|
|
37
|
-
*/
|
|
24
|
+
/** Push a skill, routing the artifact by size (see the class comment). */
|
|
38
25
|
push(input: PushSkillRequest): Promise<Skill>;
|
|
39
|
-
/**
|
|
40
|
-
* Stage the artifact over HTTP and push by reference:
|
|
41
|
-
* createArtifactUploadUrl → PUT bytes → push(artifactUploadRef).
|
|
42
|
-
*/
|
|
43
|
-
private pushViaUploadUrl;
|
|
44
|
-
/**
|
|
45
|
-
* PUT the artifact ZIP to the staging URL. The URL is the credential
|
|
46
|
-
* (capability semantics — a pre-signed R2 URL on cloud, the server's own
|
|
47
|
-
* transfer lane on OSS), so no auth header is attached.
|
|
48
|
-
*/
|
|
49
|
-
private putArtifact;
|
|
50
26
|
}
|
|
51
27
|
//# sourceMappingURL=skill.d.ts.map
|
package/skill.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAChF,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,mDAAmD,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE;;;;;;;;GAQG;AACH,qBAAa,iBAAkB,SAAQ,WAAW;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyC;IAE/D;;;;OAIG;gBACS,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK;IAsBrE,0EAA0E;IACjE,IAAI,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC;CAGvD"}
|
package/skill.js
CHANGED
|
@@ -1,29 +1,20 @@
|
|
|
1
1
|
import { create } from "@bufbuild/protobuf";
|
|
2
|
-
import { Code } from "@connectrpc/connect";
|
|
3
2
|
import { CreateSkillArtifactUploadUrlRequestSchema, PushSkillRequestSchema, } from "@stigmer/protos/ai/stigmer/agentic/skill/v1/io_pb";
|
|
4
|
-
import {
|
|
3
|
+
import { pushRoutedArtifact } from "./artifact-routing.js";
|
|
5
4
|
import { SkillClient } from "./gen/skill.js";
|
|
5
|
+
export { MAX_INLINE_ARTIFACT_BYTES } from "./artifact-routing.js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
|
|
12
|
-
export const MAX_INLINE_ARTIFACT_BYTES = 10 * 1024 * 1024 - 64 * 1024;
|
|
13
|
-
/**
|
|
14
|
-
* Skill client with transport-aware push routing (stigmer#675 / #701).
|
|
15
|
-
*
|
|
16
|
-
* The gRPC transport caps messages at 10MB while skills may be up to 100MB,
|
|
17
|
-
* so `push` routes by size: small artifacts travel inline in the request
|
|
18
|
-
* (one round trip, unchanged behavior), larger ones are staged over HTTP
|
|
19
|
-
* via `createArtifactUploadUrl` — a capability URL, so no auth header —
|
|
20
|
-
* and pushed by reference. Callers never see the mechanics: `push(req)`
|
|
21
|
-
* simply works for any valid skill size.
|
|
7
|
+
* Skill client with transport-aware push routing (stigmer#675 / #701):
|
|
8
|
+
* the skill binding of `artifact-routing.ts`, which holds the mechanism
|
|
9
|
+
* (small artifacts inline, larger ones staged over HTTP via
|
|
10
|
+
* `createArtifactUploadUrl` and pushed by reference). Callers never see
|
|
11
|
+
* the mechanics: `push(req)` simply works for any valid skill size.
|
|
22
12
|
*
|
|
23
13
|
* Every other method is the generated client's, inherited unchanged.
|
|
24
14
|
*/
|
|
25
15
|
export class RoutedSkillClient extends SkillClient {
|
|
26
16
|
fetchImpl;
|
|
17
|
+
route;
|
|
27
18
|
/**
|
|
28
19
|
* @param fetchImpl - Custom `fetch` for the staging PUT. Must be the same
|
|
29
20
|
* implementation the transport uses where the global one is restricted
|
|
@@ -32,71 +23,23 @@ export class RoutedSkillClient extends SkillClient {
|
|
|
32
23
|
constructor(transport, fetchImpl) {
|
|
33
24
|
super(transport);
|
|
34
25
|
this.fetchImpl = fetchImpl;
|
|
26
|
+
this.route = {
|
|
27
|
+
noun: "skill",
|
|
28
|
+
artifactOf: (request) => request.artifact,
|
|
29
|
+
uploadRefOf: (request) => request.artifactUploadRef,
|
|
30
|
+
orgOf: (request) => request.org,
|
|
31
|
+
withUploadRef: (request, artifactUploadRef) => create(PushSkillRequestSchema, {
|
|
32
|
+
...request,
|
|
33
|
+
artifact: new Uint8Array(0),
|
|
34
|
+
artifactUploadRef,
|
|
35
|
+
}),
|
|
36
|
+
mintUploadUrl: (org, sizeBytes) => super.createArtifactUploadUrl(create(CreateSkillArtifactUploadUrlRequestSchema, { org, sizeBytes })),
|
|
37
|
+
push: (request) => super.push(request),
|
|
38
|
+
};
|
|
35
39
|
}
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* A request that already carries an `artifactUploadRef` is passed through
|
|
40
|
-
* untouched — the caller has done its own staging.
|
|
41
|
-
*/
|
|
42
|
-
async push(input) {
|
|
43
|
-
if (input.artifactUploadRef !== "" || input.artifact.length <= MAX_INLINE_ARTIFACT_BYTES) {
|
|
44
|
-
return super.push(input);
|
|
45
|
-
}
|
|
46
|
-
return this.pushViaUploadUrl(input);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Stage the artifact over HTTP and push by reference:
|
|
50
|
-
* createArtifactUploadUrl → PUT bytes → push(artifactUploadRef).
|
|
51
|
-
*/
|
|
52
|
-
async pushViaUploadUrl(input) {
|
|
53
|
-
let minted;
|
|
54
|
-
try {
|
|
55
|
-
minted = await super.createArtifactUploadUrl(create(CreateSkillArtifactUploadUrlRequestSchema, {
|
|
56
|
-
org: input.org,
|
|
57
|
-
sizeBytes: BigInt(input.artifact.length),
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
catch (err) {
|
|
61
|
-
if (isUnimplemented(err)) {
|
|
62
|
-
// Pre-transfer-lane server: without staging, an artifact this size
|
|
63
|
-
// physically cannot travel. Say so instead of surfacing the raw
|
|
64
|
-
// transport error (the failure mode #675 reported).
|
|
65
|
-
throw new StigmerError("unknown", `skill artifact is ${input.artifact.length} bytes, above the ~10MB gRPC message cap, ` +
|
|
66
|
-
"and this server does not support the HTTP artifact transfer lane — " +
|
|
67
|
-
"upgrade stigmer-server to push skills of this size", Code.Unimplemented, { cause: err });
|
|
68
|
-
}
|
|
69
|
-
throw err;
|
|
70
|
-
}
|
|
71
|
-
await this.putArtifact(minted.url, input.artifact);
|
|
72
|
-
// Same request, artifact traveling by reference instead of by value.
|
|
73
|
-
const byRef = create(PushSkillRequestSchema, {
|
|
74
|
-
...input,
|
|
75
|
-
artifact: new Uint8Array(0),
|
|
76
|
-
artifactUploadRef: minted.artifactUploadRef,
|
|
77
|
-
});
|
|
78
|
-
return super.push(byRef);
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* PUT the artifact ZIP to the staging URL. The URL is the credential
|
|
82
|
-
* (capability semantics — a pre-signed R2 URL on cloud, the server's own
|
|
83
|
-
* transfer lane on OSS), so no auth header is attached.
|
|
84
|
-
*/
|
|
85
|
-
async putArtifact(url, artifact) {
|
|
86
|
-
const doFetch = this.fetchImpl ?? globalThis.fetch;
|
|
87
|
-
const resp = await doFetch(url, {
|
|
88
|
-
method: "PUT",
|
|
89
|
-
// Both DOM and undici accept an ArrayBufferView body at runtime; the
|
|
90
|
-
// cast bridges TS 5.7's ArrayBufferLike generic, which BodyInit's
|
|
91
|
-
// typing predates. A Blob/Buffer wrapper would copy up to 100MB for
|
|
92
|
-
// nothing, and Buffer is Node-only while this client is isomorphic.
|
|
93
|
-
body: artifact,
|
|
94
|
-
headers: { "content-type": "application/zip" },
|
|
95
|
-
});
|
|
96
|
-
if (!resp.ok) {
|
|
97
|
-
const detail = (await resp.text().catch(() => "")).slice(0, 512).trim();
|
|
98
|
-
throw new StigmerError("unknown", `skill artifact upload rejected with HTTP ${resp.status}${detail === "" ? "" : `: ${detail}`}`, Code.Unknown);
|
|
99
|
-
}
|
|
40
|
+
/** Push a skill, routing the artifact by size (see the class comment). */
|
|
41
|
+
push(input) {
|
|
42
|
+
return pushRoutedArtifact(this.route, input, this.fetchImpl);
|
|
100
43
|
}
|
|
101
44
|
}
|
|
102
45
|
//# sourceMappingURL=skill.js.map
|
package/skill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../src/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EACL,yCAAyC,EACzC,sBAAsB,GAEvB,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AAElE;;;;;;;;GAQG;AACH,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IAC/B,SAAS,CAAsC;IAC/C,KAAK,CAAyC;IAE/D;;;;OAIG;IACH,YAAY,SAAoB,EAAE,SAAmC;QACnE,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG;YACX,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ;YACzC,WAAW,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,iBAAiB;YACnD,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG;YAC/B,aAAa,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,EAAE,CAC5C,MAAM,CAAC,sBAAsB,EAAE;gBAC7B,GAAG,OAAO;gBACV,QAAQ,EAAE,IAAI,UAAU,CAAC,CAAC,CAAC;gBAC3B,iBAAiB;aAClB,CAAC;YACJ,aAAa,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAChC,KAAK,CAAC,uBAAuB,CAC3B,MAAM,CAAC,yCAAyC,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CACtE;YACH,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;SACvC,CAAC;IACJ,CAAC;IAED,0EAA0E;IACjE,IAAI,CAAC,KAAuB;QACnC,OAAO,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;CACF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Wire-shape tests for RoutedPluginClient's size-routed push: the plugin
|
|
2
|
+
// binding of the shared artifact routing. The routing mechanism itself is
|
|
3
|
+
// pinned by skill.test.ts; these arms pin that the plugin binding reads
|
|
4
|
+
// and rewrites ITS request shape (org, artifact, artifactUploadRef,
|
|
5
|
+
// visibility, message) and mints through ITS createArtifactUploadUrl.
|
|
6
|
+
import { describe, expect, it, vi } from "vitest";
|
|
7
|
+
import { createRouterTransport, type Transport } from "@connectrpc/connect";
|
|
8
|
+
import { create } from "@bufbuild/protobuf";
|
|
9
|
+
import { PluginCommandController } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/command_pb";
|
|
10
|
+
import { PluginSchema } from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/api_pb";
|
|
11
|
+
import {
|
|
12
|
+
PluginArtifactUploadUrlSchema,
|
|
13
|
+
PushPluginRequestSchema,
|
|
14
|
+
type PushPluginRequest,
|
|
15
|
+
} from "@stigmer/protos/ai/stigmer/agentic/plugin/v1/io_pb";
|
|
16
|
+
import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
|
|
17
|
+
import { RoutedPluginClient } from "../plugin.js";
|
|
18
|
+
import { MAX_INLINE_ARTIFACT_BYTES } from "../skill.js";
|
|
19
|
+
|
|
20
|
+
const STAGING_URL = "http://stage.example/v1/skill-artifacts/uploads/sau_p";
|
|
21
|
+
|
|
22
|
+
interface Captured {
|
|
23
|
+
pushes: PushPluginRequest[];
|
|
24
|
+
mints: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function fakeTransport(captured: Captured): Transport {
|
|
28
|
+
return createRouterTransport(({ service }) => {
|
|
29
|
+
service(PluginCommandController, {
|
|
30
|
+
push: (req) => {
|
|
31
|
+
captured.pushes.push(req);
|
|
32
|
+
return create(PluginSchema, {});
|
|
33
|
+
},
|
|
34
|
+
createArtifactUploadUrl: (req) => {
|
|
35
|
+
captured.mints++;
|
|
36
|
+
expect(req.org).toBe("acme");
|
|
37
|
+
expect(req.sizeBytes).toBeGreaterThan(0n);
|
|
38
|
+
return create(PluginArtifactUploadUrlSchema, {
|
|
39
|
+
url: STAGING_URL,
|
|
40
|
+
artifactUploadRef: "sau_p",
|
|
41
|
+
ttlSeconds: 900,
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
describe("RoutedPluginClient.push size routing", () => {
|
|
49
|
+
it("keeps a small archive inline", async () => {
|
|
50
|
+
const captured: Captured = { pushes: [], mints: 0 };
|
|
51
|
+
const client = new RoutedPluginClient(fakeTransport(captured));
|
|
52
|
+
await client.push(
|
|
53
|
+
create(PushPluginRequestSchema, {
|
|
54
|
+
org: "acme",
|
|
55
|
+
artifact: new Uint8Array(2048),
|
|
56
|
+
}),
|
|
57
|
+
);
|
|
58
|
+
expect(captured.mints).toBe(0);
|
|
59
|
+
expect(captured.pushes[0]?.artifact.length).toBe(2048);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("stages a large archive through the plugin's own mint and pushes by reference, keeping the envelope", async () => {
|
|
63
|
+
const captured: Captured = { pushes: [], mints: 0 };
|
|
64
|
+
const record: { url?: string; bytes?: number } = {};
|
|
65
|
+
const fetchImpl = vi.fn(async (url: unknown, init: RequestInit) => {
|
|
66
|
+
record.url = String(url);
|
|
67
|
+
record.bytes =
|
|
68
|
+
init.body instanceof Uint8Array ? init.body.byteLength : -1;
|
|
69
|
+
return new Response(null, { status: 200 });
|
|
70
|
+
}) as unknown as typeof globalThis.fetch;
|
|
71
|
+
const client = new RoutedPluginClient(fakeTransport(captured), fetchImpl);
|
|
72
|
+
const artifact = new Uint8Array(MAX_INLINE_ARTIFACT_BYTES + 1);
|
|
73
|
+
|
|
74
|
+
await client.push(
|
|
75
|
+
create(PushPluginRequestSchema, {
|
|
76
|
+
org: "acme",
|
|
77
|
+
artifact,
|
|
78
|
+
visibility: ApiResourceVisibility.visibility_public,
|
|
79
|
+
message: "big",
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
expect(captured.mints).toBe(1);
|
|
84
|
+
expect(record.url).toBe(STAGING_URL);
|
|
85
|
+
expect(record.bytes).toBe(artifact.length);
|
|
86
|
+
const pushed = captured.pushes[0]!;
|
|
87
|
+
expect(pushed.artifact.length).toBe(0);
|
|
88
|
+
expect(pushed.artifactUploadRef).toBe("sau_p");
|
|
89
|
+
expect(pushed.visibility).toBe(ApiResourceVisibility.visibility_public);
|
|
90
|
+
expect(pushed.message).toBe("big");
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Code } from "@connectrpc/connect";
|
|
2
|
+
import { isUnimplemented, StigmerError } from "./gen/errors.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Largest artifact pushed inline in the gRPC request (#675). The server's
|
|
6
|
+
* transport cap is 10MB for the WHOLE message, so the artifact leaves 64KB
|
|
7
|
+
* of headroom for the request envelope (org, tag, provenance, framing).
|
|
8
|
+
* Mirrors the Go SDK's maxInlineArtifactBytes.
|
|
9
|
+
*/
|
|
10
|
+
export const MAX_INLINE_ARTIFACT_BYTES = 10 * 1024 * 1024 - 64 * 1024;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Transport-aware push routing for archive-shaped kinds (skills, plugins;
|
|
14
|
+
* stigmer#675 / #701). The gRPC transport caps messages at 10MB while an
|
|
15
|
+
* archive may be up to 100MB, so a push routes by size: a small archive
|
|
16
|
+
* travels inline (one round trip), a larger one is staged over HTTP via
|
|
17
|
+
* the kind's `createArtifactUploadUrl` — a capability URL, so no auth
|
|
18
|
+
* header — and pushed by reference. Skills carried this alone; plugins
|
|
19
|
+
* push the same two ways, so the routing lives here once and each kind
|
|
20
|
+
* binds its request shape and its noun.
|
|
21
|
+
*/
|
|
22
|
+
export interface ArtifactRoute<Request, Response> {
|
|
23
|
+
/** The noun in error copy: "skill", "plugin". */
|
|
24
|
+
readonly noun: string;
|
|
25
|
+
artifactOf(request: Request): Uint8Array;
|
|
26
|
+
uploadRefOf(request: Request): string;
|
|
27
|
+
orgOf(request: Request): string;
|
|
28
|
+
/** The same request with the bytes replaced by a staged reference. */
|
|
29
|
+
withUploadRef(request: Request, artifactUploadRef: string): Request;
|
|
30
|
+
mintUploadUrl(
|
|
31
|
+
org: string,
|
|
32
|
+
sizeBytes: bigint,
|
|
33
|
+
): Promise<{ url: string; artifactUploadRef: string }>;
|
|
34
|
+
push(request: Request): Promise<Response>;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Push, routing the archive by size. A request that already carries an
|
|
39
|
+
* upload reference is passed through untouched — the caller has done its
|
|
40
|
+
* own staging.
|
|
41
|
+
*/
|
|
42
|
+
export async function pushRoutedArtifact<Request, Response>(
|
|
43
|
+
route: ArtifactRoute<Request, Response>,
|
|
44
|
+
input: Request,
|
|
45
|
+
fetchImpl: typeof globalThis.fetch | undefined,
|
|
46
|
+
): Promise<Response> {
|
|
47
|
+
const artifact = route.artifactOf(input);
|
|
48
|
+
if (
|
|
49
|
+
route.uploadRefOf(input) !== "" ||
|
|
50
|
+
artifact.length <= MAX_INLINE_ARTIFACT_BYTES
|
|
51
|
+
) {
|
|
52
|
+
return route.push(input);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let minted;
|
|
56
|
+
try {
|
|
57
|
+
minted = await route.mintUploadUrl(
|
|
58
|
+
route.orgOf(input),
|
|
59
|
+
BigInt(artifact.length),
|
|
60
|
+
);
|
|
61
|
+
} catch (err) {
|
|
62
|
+
if (isUnimplemented(err)) {
|
|
63
|
+
// Pre-transfer-lane server: without staging, an artifact this size
|
|
64
|
+
// physically cannot travel. Say so instead of surfacing the raw
|
|
65
|
+
// transport error (the failure mode #675 reported).
|
|
66
|
+
throw new StigmerError(
|
|
67
|
+
"unknown",
|
|
68
|
+
`${route.noun} artifact is ${artifact.length} bytes, above the ~10MB gRPC message cap, ` +
|
|
69
|
+
"and this server does not support the HTTP artifact transfer lane — " +
|
|
70
|
+
`upgrade stigmer-server to push ${route.noun}s of this size`,
|
|
71
|
+
Code.Unimplemented,
|
|
72
|
+
{ cause: err },
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
await putArtifact(route.noun, minted.url, artifact, fetchImpl);
|
|
79
|
+
return route.push(route.withUploadRef(input, minted.artifactUploadRef));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* PUT the archive to the staging URL. The URL is the credential
|
|
84
|
+
* (capability semantics — a pre-signed R2 URL on cloud, the server's own
|
|
85
|
+
* transfer lane on OSS), so no auth header is attached.
|
|
86
|
+
*/
|
|
87
|
+
async function putArtifact(
|
|
88
|
+
noun: string,
|
|
89
|
+
url: string,
|
|
90
|
+
artifact: Uint8Array,
|
|
91
|
+
fetchImpl: typeof globalThis.fetch | undefined,
|
|
92
|
+
): Promise<void> {
|
|
93
|
+
const doFetch = fetchImpl ?? globalThis.fetch;
|
|
94
|
+
const resp = await doFetch(url, {
|
|
95
|
+
method: "PUT",
|
|
96
|
+
// Both DOM and undici accept an ArrayBufferView body at runtime; the
|
|
97
|
+
// cast bridges TS 5.7's ArrayBufferLike generic, which BodyInit's
|
|
98
|
+
// typing predates. A Blob/Buffer wrapper would copy up to 100MB for
|
|
99
|
+
// nothing, and Buffer is Node-only while this client is isomorphic.
|
|
100
|
+
body: artifact as unknown as RequestInit["body"],
|
|
101
|
+
headers: { "content-type": "application/zip" },
|
|
102
|
+
});
|
|
103
|
+
if (!resp.ok) {
|
|
104
|
+
const detail = (await resp.text().catch(() => "")).slice(0, 512).trim();
|
|
105
|
+
throw new StigmerError(
|
|
106
|
+
"unknown",
|
|
107
|
+
`${noun} artifact upload rejected with HTTP ${resp.status}${detail === "" ? "" : `: ${detail}`}`,
|
|
108
|
+
Code.Unknown,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -32,5 +32,6 @@ export const GRANTABLE_ROLES: ReadonlyMap<ApiResourceKind, readonly IamRole[]> =
|
|
|
32
32
|
[ApiResourceKind.environment, [IamRole.owner, IamRole.viewer]],
|
|
33
33
|
[ApiResourceKind.artifact, [IamRole.owner, IamRole.viewer]],
|
|
34
34
|
[ApiResourceKind.schedule, [IamRole.owner, IamRole.viewer]],
|
|
35
|
+
[ApiResourceKind.plugin, [IamRole.owner, IamRole.viewer]],
|
|
35
36
|
[ApiResourceKind.project, [IamRole.owner, IamRole.viewer]],
|
|
36
37
|
]);
|
package/src/gen/client.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { MemoryClient } from "./memory.js";
|
|
|
20
20
|
import { OAuthAppClient } from "./oauthapp.js";
|
|
21
21
|
import { OrganizationClient } from "./organization.js";
|
|
22
22
|
import { PlatformClientClient } from "./platformclient.js";
|
|
23
|
+
import { PluginClient } from "./plugin.js";
|
|
23
24
|
import { ProjectClient } from "./project.js";
|
|
24
25
|
import { ScheduleClient } from "./schedule.js";
|
|
25
26
|
import { SessionClient } from "./session.js";
|
|
@@ -49,6 +50,7 @@ export class GeneratedClient {
|
|
|
49
50
|
readonly oauthapp: OAuthAppClient;
|
|
50
51
|
readonly organization: OrganizationClient;
|
|
51
52
|
readonly platformclient: PlatformClientClient;
|
|
53
|
+
readonly plugin: PluginClient;
|
|
52
54
|
readonly project: ProjectClient;
|
|
53
55
|
readonly schedule: ScheduleClient;
|
|
54
56
|
readonly session: SessionClient;
|
|
@@ -77,6 +79,7 @@ export class GeneratedClient {
|
|
|
77
79
|
this.oauthapp = new OAuthAppClient(transport);
|
|
78
80
|
this.organization = new OrganizationClient(transport);
|
|
79
81
|
this.platformclient = new PlatformClientClient(transport);
|
|
82
|
+
this.plugin = new PluginClient(transport);
|
|
80
83
|
this.project = new ProjectClient(transport);
|
|
81
84
|
this.schedule = new ScheduleClient(transport);
|
|
82
85
|
this.session = new SessionClient(transport);
|
|
@@ -126,6 +129,8 @@ export { OrganizationClient } from "./organization.js";
|
|
|
126
129
|
export { type OrganizationInput, type OrganizationPreferencesInput } from "./organization.js";
|
|
127
130
|
export { PlatformClientClient } from "./platformclient.js";
|
|
128
131
|
export { type PlatformClientInput } from "./platformclient.js";
|
|
132
|
+
export { PluginClient } from "./plugin.js";
|
|
133
|
+
export { type PluginInput, type PluginAuthorInput } from "./plugin.js";
|
|
129
134
|
export { ProjectClient } from "./project.js";
|
|
130
135
|
export { type ProjectInput } from "./project.js";
|
|
131
136
|
export { ScheduleClient } from "./schedule.js";
|