@stigmer/sdk 3.1.7 → 3.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/__tests__/errors.test.js +42 -0
  2. package/__tests__/errors.test.js.map +1 -1
  3. package/__tests__/guest-auth.test.d.ts +2 -0
  4. package/__tests__/guest-auth.test.d.ts.map +1 -0
  5. package/__tests__/guest-auth.test.js +223 -0
  6. package/__tests__/guest-auth.test.js.map +1 -0
  7. package/__tests__/sharing.test.d.ts +2 -0
  8. package/__tests__/sharing.test.d.ts.map +1 -0
  9. package/__tests__/sharing.test.js +106 -0
  10. package/__tests__/sharing.test.js.map +1 -0
  11. package/gen/agent.d.ts +20 -1
  12. package/gen/agent.d.ts.map +1 -1
  13. package/gen/agent.js +54 -1
  14. package/gen/agent.js.map +1 -1
  15. package/gen/client.d.ts +1 -1
  16. package/gen/client.d.ts.map +1 -1
  17. package/gen/environment.d.ts +2 -0
  18. package/gen/environment.d.ts.map +1 -1
  19. package/gen/environment.js +8 -0
  20. package/gen/environment.js.map +1 -1
  21. package/gen/platformclient.d.ts +2 -1
  22. package/gen/platformclient.d.ts.map +1 -1
  23. package/gen/platformclient.js +8 -0
  24. package/gen/platformclient.js.map +1 -1
  25. package/gen/session.d.ts +2 -2
  26. package/gen/session.d.ts.map +1 -1
  27. package/gen/session.js +2 -2
  28. package/gen/session.js.map +1 -1
  29. package/guest-auth.d.ts +172 -0
  30. package/guest-auth.d.ts.map +1 -0
  31. package/guest-auth.js +227 -0
  32. package/guest-auth.js.map +1 -0
  33. package/index.d.ts +2 -0
  34. package/index.d.ts.map +1 -1
  35. package/index.js +4 -0
  36. package/index.js.map +1 -1
  37. package/package.json +2 -2
  38. package/sharing.d.ts +75 -0
  39. package/sharing.d.ts.map +1 -0
  40. package/sharing.js +116 -0
  41. package/sharing.js.map +1 -0
  42. package/src/__tests__/errors.test.ts +56 -0
  43. package/src/__tests__/guest-auth.test.ts +287 -0
  44. package/src/__tests__/sharing.test.ts +159 -0
  45. package/src/gen/agent.ts +61 -2
  46. package/src/gen/client.ts +1 -1
  47. package/src/gen/environment.ts +7 -1
  48. package/src/gen/platformclient.ts +7 -1
  49. package/src/gen/session.ts +3 -3
  50. package/src/guest-auth.ts +331 -0
  51. package/src/index.ts +20 -0
  52. package/src/sharing.ts +134 -0
@@ -0,0 +1,287 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { create } from "@bufbuild/protobuf";
3
+ import { MintGuestTokenResponseSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/token_pb";
4
+ import { ConnectError, Code } from "@connectrpc/connect";
5
+
6
+ // Intercept the token client so no transport is exercised. The mock
7
+ // preserves the real module (create/Code/ConnectError) and only stubs
8
+ // createClient, which GuestAuth uses to build its RPC client.
9
+ const mintGuestToken = vi.fn();
10
+ vi.mock("@connectrpc/connect", async (importOriginal) => {
11
+ const actual = await importOriginal<typeof import("@connectrpc/connect")>();
12
+ return {
13
+ ...actual,
14
+ createClient: () => ({ mintGuestToken }),
15
+ };
16
+ });
17
+
18
+ import { createGuestAuth, GuestAuth, type GuestIdStorage } from "../guest-auth";
19
+
20
+ const CONFIG = {
21
+ baseUrl: "https://api.stigmer.ai",
22
+ org: "acme",
23
+ slug: "support-agent",
24
+ };
25
+
26
+ function createMemoryStorage(): GuestIdStorage & { store: Map<string, string> } {
27
+ const store = new Map<string, string>();
28
+ return {
29
+ store,
30
+ getItem: (key) => store.get(key) ?? null,
31
+ setItem: (key, value) => {
32
+ store.set(key, value);
33
+ },
34
+ };
35
+ }
36
+
37
+ function mintResponse(overrides?: {
38
+ accessToken?: string;
39
+ expiresIn?: number;
40
+ guestCookieId?: string;
41
+ }) {
42
+ return create(MintGuestTokenResponseSchema, {
43
+ accessToken: overrides?.accessToken ?? "guest-jwt-1",
44
+ tokenType: "Bearer",
45
+ expiresIn: overrides?.expiresIn ?? 900,
46
+ guestCookieId: overrides?.guestCookieId ?? "cookie-abc",
47
+ });
48
+ }
49
+
50
+ beforeEach(() => {
51
+ mintGuestToken.mockReset();
52
+ vi.useFakeTimers();
53
+ });
54
+
55
+ afterEach(() => {
56
+ vi.useRealTimers();
57
+ });
58
+
59
+ describe("createGuestAuth", () => {
60
+ it("throws when baseUrl is missing", () => {
61
+ expect(() =>
62
+ createGuestAuth({ ...CONFIG, baseUrl: "" }),
63
+ ).toThrow("baseUrl is required");
64
+ });
65
+
66
+ it("throws when org is missing", () => {
67
+ expect(() => createGuestAuth({ ...CONFIG, org: "" })).toThrow(
68
+ "org is required",
69
+ );
70
+ });
71
+
72
+ it("throws when slug is missing", () => {
73
+ expect(() => createGuestAuth({ ...CONFIG, slug: "" })).toThrow(
74
+ "slug is required",
75
+ );
76
+ });
77
+
78
+ it("returns a GuestAuth instance with valid config", () => {
79
+ expect(createGuestAuth(CONFIG)).toBeInstanceOf(GuestAuth);
80
+ });
81
+ });
82
+
83
+ describe("GuestAuth.getAccessToken", () => {
84
+ it("mints on first call and sends an empty guest id", async () => {
85
+ mintGuestToken.mockResolvedValue(mintResponse());
86
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
87
+
88
+ const token = await auth.getAccessToken();
89
+
90
+ expect(token).toBe("guest-jwt-1");
91
+ expect(mintGuestToken).toHaveBeenCalledTimes(1);
92
+ expect(mintGuestToken.mock.calls[0][0]).toMatchObject({
93
+ org: "acme",
94
+ slug: "support-agent",
95
+ guestCookieId: "",
96
+ // No embedOrigin configured (the unframed hosted page): the field
97
+ // must stay empty so the server's absence-means-exempt rule applies.
98
+ embedOrigin: "",
99
+ });
100
+ });
101
+
102
+ it("passes the configured embedOrigin through to every mint", async () => {
103
+ mintGuestToken.mockResolvedValue(mintResponse());
104
+ const auth = createGuestAuth({
105
+ ...CONFIG,
106
+ storage: createMemoryStorage(),
107
+ embedOrigin: "https://docs.example.com",
108
+ });
109
+
110
+ await auth.getAccessToken();
111
+ // Expire the cached token, forcing a re-mint — the origin must persist.
112
+ vi.advanceTimersByTime(900_000);
113
+ await auth.getAccessToken();
114
+
115
+ expect(mintGuestToken).toHaveBeenCalledTimes(2);
116
+ for (const call of mintGuestToken.mock.calls) {
117
+ expect(call[0]).toMatchObject({ embedOrigin: "https://docs.example.com" });
118
+ }
119
+ });
120
+
121
+ it("passes the configured linkToken through to every mint", async () => {
122
+ mintGuestToken.mockResolvedValue(mintResponse());
123
+ const auth = createGuestAuth({
124
+ ...CONFIG,
125
+ storage: createMemoryStorage(),
126
+ linkToken: "tok123",
127
+ });
128
+
129
+ await auth.getAccessToken();
130
+ // Expire the cached token, forcing a re-mint — the token must persist
131
+ // so a locked link keeps working across silent re-mints.
132
+ vi.advanceTimersByTime(900_000);
133
+ await auth.getAccessToken();
134
+
135
+ expect(mintGuestToken).toHaveBeenCalledTimes(2);
136
+ for (const call of mintGuestToken.mock.calls) {
137
+ expect(call[0]).toMatchObject({ linkToken: "tok123" });
138
+ }
139
+ });
140
+
141
+ it("sends an empty linkToken when none is configured (plain link)", async () => {
142
+ mintGuestToken.mockResolvedValue(mintResponse());
143
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
144
+
145
+ await auth.getAccessToken();
146
+
147
+ expect(mintGuestToken.mock.calls[0][0]).toMatchObject({ linkToken: "" });
148
+ });
149
+
150
+ it("rejects with permission-denied when the embed origin is refused", async () => {
151
+ mintGuestToken.mockRejectedValue(
152
+ new ConnectError(
153
+ "This agent can\u2019t be embedded on this site.",
154
+ Code.PermissionDenied,
155
+ ),
156
+ );
157
+ const auth = createGuestAuth({
158
+ ...CONFIG,
159
+ storage: createMemoryStorage(),
160
+ embedOrigin: "https://evil.example.com",
161
+ });
162
+
163
+ await expect(auth.getAccessToken()).rejects.toMatchObject({
164
+ code: "permission-denied",
165
+ });
166
+ });
167
+
168
+ it("persists the server-issued guest id and presents it on re-mint", async () => {
169
+ const storage = createMemoryStorage();
170
+ mintGuestToken.mockResolvedValue(mintResponse({ guestCookieId: "cookie-abc" }));
171
+ const auth = createGuestAuth({ ...CONFIG, storage });
172
+
173
+ await auth.getAccessToken();
174
+ expect(storage.store.get("stigmer:guest-id:acme")).toBe("cookie-abc");
175
+ expect(auth.guestCookieId).toBe("cookie-abc");
176
+
177
+ // Expire the cached token, forcing a second mint.
178
+ vi.advanceTimersByTime(900_000);
179
+ await auth.getAccessToken();
180
+
181
+ expect(mintGuestToken).toHaveBeenCalledTimes(2);
182
+ expect(mintGuestToken.mock.calls[1][0]).toMatchObject({
183
+ guestCookieId: "cookie-abc",
184
+ });
185
+ });
186
+
187
+ it("restores a persisted guest id from a prior visit", async () => {
188
+ const storage = createMemoryStorage();
189
+ storage.setItem("stigmer:guest-id:acme", "cookie-from-last-visit");
190
+ mintGuestToken.mockResolvedValue(mintResponse());
191
+ const auth = createGuestAuth({ ...CONFIG, storage });
192
+
193
+ await auth.getAccessToken();
194
+
195
+ expect(mintGuestToken.mock.calls[0][0]).toMatchObject({
196
+ guestCookieId: "cookie-from-last-visit",
197
+ });
198
+ });
199
+
200
+ it("returns the cached token while it is fresh", async () => {
201
+ mintGuestToken.mockResolvedValue(mintResponse());
202
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
203
+
204
+ await auth.getAccessToken();
205
+ // 13 minutes into a 15-minute token: still beyond the 60s skew.
206
+ vi.advanceTimersByTime(13 * 60_000);
207
+ const token = await auth.getAccessToken();
208
+
209
+ expect(token).toBe("guest-jwt-1");
210
+ expect(mintGuestToken).toHaveBeenCalledTimes(1);
211
+ });
212
+
213
+ it("re-mints when the cached token is within the expiry skew", async () => {
214
+ mintGuestToken
215
+ .mockResolvedValueOnce(mintResponse({ accessToken: "guest-jwt-1" }))
216
+ .mockResolvedValueOnce(mintResponse({ accessToken: "guest-jwt-2" }));
217
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
218
+
219
+ await auth.getAccessToken();
220
+ // 30 seconds of life left — inside the 60s skew window.
221
+ vi.advanceTimersByTime(900_000 - 30_000);
222
+ const token = await auth.getAccessToken();
223
+
224
+ expect(token).toBe("guest-jwt-2");
225
+ expect(mintGuestToken).toHaveBeenCalledTimes(2);
226
+ });
227
+
228
+ it("collapses concurrent callers into a single mint", async () => {
229
+ let release!: (value: ReturnType<typeof mintResponse>) => void;
230
+ mintGuestToken.mockImplementation(
231
+ () => new Promise((resolve) => { release = resolve; }),
232
+ );
233
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
234
+
235
+ const first = auth.getAccessToken();
236
+ const second = auth.getAccessToken();
237
+ release(mintResponse());
238
+
239
+ await expect(first).resolves.toBe("guest-jwt-1");
240
+ await expect(second).resolves.toBe("guest-jwt-1");
241
+ expect(mintGuestToken).toHaveBeenCalledTimes(1);
242
+ });
243
+
244
+ it("rejects with a wrapped StigmerError when sharing is revoked", async () => {
245
+ mintGuestToken.mockRejectedValue(
246
+ new ConnectError("agent not found", Code.NotFound),
247
+ );
248
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
249
+
250
+ try {
251
+ await auth.getAccessToken();
252
+ expect.fail("should have thrown");
253
+ } catch (e: unknown) {
254
+ expect(e).toHaveProperty("name", "StigmerError");
255
+ expect(e).toHaveProperty("code", "not-found");
256
+ }
257
+ });
258
+
259
+ it("recovers after a failed mint instead of caching the failure", async () => {
260
+ mintGuestToken
261
+ .mockRejectedValueOnce(new ConnectError("unavailable", Code.Unavailable))
262
+ .mockResolvedValueOnce(mintResponse());
263
+ const auth = createGuestAuth({ ...CONFIG, storage: createMemoryStorage() });
264
+
265
+ await expect(auth.getAccessToken()).rejects.toMatchObject({
266
+ code: "unavailable",
267
+ });
268
+ await expect(auth.getAccessToken()).resolves.toBe("guest-jwt-1");
269
+ expect(mintGuestToken).toHaveBeenCalledTimes(2);
270
+ });
271
+
272
+ it("still mints when storage throws", async () => {
273
+ const brokenStorage: GuestIdStorage = {
274
+ getItem: () => {
275
+ throw new Error("storage disabled");
276
+ },
277
+ setItem: () => {
278
+ throw new Error("storage disabled");
279
+ },
280
+ };
281
+ mintGuestToken.mockResolvedValue(mintResponse());
282
+ const auth = createGuestAuth({ ...CONFIG, storage: brokenStorage });
283
+
284
+ await expect(auth.getAccessToken()).resolves.toBe("guest-jwt-1");
285
+ expect(auth.guestCookieId).toBeNull();
286
+ });
287
+ });
@@ -0,0 +1,159 @@
1
+ // Unit tests for the framework-free agent-sharing helpers: origin
2
+ // validation (mirror of the proto CEL rule) and the hosted-link / embed
3
+ // snippet builders shared by the web console, desktop app, and CLI.
4
+
5
+ import { describe, expect, it } from "vitest";
6
+ import {
7
+ LINK_TOKEN_PARAM,
8
+ MAX_ALLOWED_ORIGINS,
9
+ appendLinkToken,
10
+ buildChatUrl,
11
+ buildEmbedLoaderUrl,
12
+ buildEmbedSnippet,
13
+ chatPath,
14
+ validateOrigin,
15
+ } from "../sharing";
16
+
17
+ describe("validateOrigin", () => {
18
+ it("accepts exact web origins", () => {
19
+ expect(validateOrigin("https://example.com")).toBeNull();
20
+ expect(validateOrigin("http://example.com")).toBeNull();
21
+ expect(validateOrigin("https://sub.example.com")).toBeNull();
22
+ expect(validateOrigin("https://example.com:8443")).toBeNull();
23
+ expect(validateOrigin("http://localhost:3000")).toBeNull();
24
+ });
25
+
26
+ it("trims surrounding whitespace before validating", () => {
27
+ expect(validateOrigin(" https://example.com ")).toBeNull();
28
+ });
29
+
30
+ it("rejects empty input with guidance", () => {
31
+ expect(validateOrigin("")).toMatch(/Enter an origin/);
32
+ expect(validateOrigin(" ")).toMatch(/Enter an origin/);
33
+ });
34
+
35
+ it("rejects trailing slashes, paths, queries, and fragments", () => {
36
+ for (const bad of [
37
+ "https://example.com/",
38
+ "https://example.com/path",
39
+ "https://example.com?q=1",
40
+ "https://example.com#top",
41
+ ]) {
42
+ expect(validateOrigin(bad)).toMatch(/exact web origin/);
43
+ }
44
+ });
45
+
46
+ it("rejects non-http(s) schemes and bare hosts", () => {
47
+ expect(validateOrigin("ftp://example.com")).toMatch(/exact web origin/);
48
+ expect(validateOrigin("example.com")).toMatch(/exact web origin/);
49
+ });
50
+
51
+ it("rejects hostname labels with leading/trailing hyphens", () => {
52
+ expect(validateOrigin("https://-bad.example.com")).toMatch(/exact web origin/);
53
+ expect(validateOrigin("https://bad-.example.com")).toMatch(/exact web origin/);
54
+ });
55
+
56
+ it("exposes the proto max_items bound", () => {
57
+ expect(MAX_ALLOWED_ORIGINS).toBe(32);
58
+ });
59
+ });
60
+
61
+ describe("chatPath / buildChatUrl", () => {
62
+ it("builds the canonical /chat/<org>/<slug> path", () => {
63
+ expect(chatPath("acme", "support-agent")).toBe("/chat/acme/support-agent");
64
+ });
65
+
66
+ it("builds the absolute hosted chat URL", () => {
67
+ expect(buildChatUrl("https://app.stigmer.ai", "acme", "support-agent")).toBe(
68
+ "https://app.stigmer.ai/chat/acme/support-agent",
69
+ );
70
+ });
71
+
72
+ it("tolerates a trailing slash on the origin", () => {
73
+ expect(buildChatUrl("https://app.stigmer.ai/", "acme", "support-agent")).toBe(
74
+ "https://app.stigmer.ai/chat/acme/support-agent",
75
+ );
76
+ });
77
+
78
+ it("works with localhost origins (local backend)", () => {
79
+ expect(buildChatUrl("http://localhost:8234", "stigmer", "helper")).toBe(
80
+ "http://localhost:8234/chat/stigmer/helper",
81
+ );
82
+ });
83
+
84
+ it("appends ?k= when the share link is locked with a token", () => {
85
+ expect(chatPath("acme", "support-agent", "tok123")).toBe(
86
+ "/chat/acme/support-agent?k=tok123",
87
+ );
88
+ expect(
89
+ buildChatUrl("https://app.stigmer.ai", "acme", "support-agent", "tok123"),
90
+ ).toBe("https://app.stigmer.ai/chat/acme/support-agent?k=tok123");
91
+ });
92
+
93
+ it("url-encodes the token (defense in depth; generated tokens are url-safe)", () => {
94
+ expect(chatPath("acme", "bot", "a+b/c")).toBe("/chat/acme/bot?k=a%2Bb%2Fc");
95
+ });
96
+
97
+ it("omits ?k= for an empty/undefined token (plain link)", () => {
98
+ expect(chatPath("acme", "bot", "")).toBe("/chat/acme/bot");
99
+ expect(chatPath("acme", "bot", undefined)).toBe("/chat/acme/bot");
100
+ });
101
+ });
102
+
103
+ describe("appendLinkToken", () => {
104
+ it("appends the identical ?k= shape chatPath emits", () => {
105
+ expect(appendLinkToken("https://app.stigmer.ai/chat/acme/bot", "tok123")).toBe(
106
+ buildChatUrl("https://app.stigmer.ai", "acme", "bot", "tok123"),
107
+ );
108
+ });
109
+
110
+ it("uses & when the URL already carries a query", () => {
111
+ expect(appendLinkToken("/chat/acme/bot?theme=dark", "tok123")).toBe(
112
+ `/chat/acme/bot?theme=dark&${LINK_TOKEN_PARAM}=tok123`,
113
+ );
114
+ });
115
+
116
+ it("returns the URL unchanged for a null/empty token", () => {
117
+ expect(appendLinkToken("/chat/acme/bot", null)).toBe("/chat/acme/bot");
118
+ expect(appendLinkToken("/chat/acme/bot", undefined)).toBe("/chat/acme/bot");
119
+ expect(appendLinkToken("/chat/acme/bot", "")).toBe("/chat/acme/bot");
120
+ });
121
+ });
122
+
123
+ describe("buildEmbedLoaderUrl", () => {
124
+ it("points at embed.js on the app origin root", () => {
125
+ expect(buildEmbedLoaderUrl("https://app.stigmer.ai")).toBe("https://app.stigmer.ai/embed.js");
126
+ });
127
+
128
+ it("tolerates a trailing slash on the origin", () => {
129
+ expect(buildEmbedLoaderUrl("https://app.stigmer.ai/")).toBe("https://app.stigmer.ai/embed.js");
130
+ });
131
+ });
132
+
133
+ describe("buildEmbedSnippet", () => {
134
+ it("emits exactly the two-line loader + element snippet", () => {
135
+ expect(buildEmbedSnippet("https://app.stigmer.ai", "acme", "support-agent")).toBe(
136
+ [
137
+ `<script src="https://app.stigmer.ai/embed.js" async></script>`,
138
+ `<stigmer-agent org="acme" agent="support-agent"></stigmer-agent>`,
139
+ ].join("\n"),
140
+ );
141
+ });
142
+
143
+ it("adds the token attribute when the share link is locked", () => {
144
+ expect(
145
+ buildEmbedSnippet("https://app.stigmer.ai", "acme", "support-agent", "tok123"),
146
+ ).toBe(
147
+ [
148
+ `<script src="https://app.stigmer.ai/embed.js" async></script>`,
149
+ `<stigmer-agent org="acme" agent="support-agent" token="tok123"></stigmer-agent>`,
150
+ ].join("\n"),
151
+ );
152
+ });
153
+
154
+ it("omits the token attribute for an empty token (plain link)", () => {
155
+ expect(buildEmbedSnippet("https://app.stigmer.ai", "acme", "bot", "")).toBe(
156
+ buildEmbedSnippet("https://app.stigmer.ai", "acme", "bot"),
157
+ );
158
+ });
159
+ });
package/src/gen/agent.ts CHANGED
@@ -7,9 +7,9 @@ import { create } from "@bufbuild/protobuf";
7
7
  import { createClient, type Client, type Transport } from "@connectrpc/connect";
8
8
  import { AgentSchema, type Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
9
9
  import { AgentCommandController } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/command_pb";
10
- import { AgentIdSchema, GetDefaultAgentRequestSchema, type GetDefaultAgentRequest } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/io_pb";
10
+ import { AgentIdSchema, UpdateAgentSharingInputSchema, RotateShareLinkInputSchema, GetDefaultAgentRequestSchema, GetSharedProfileRequestSchema, SharedAgentProfileSchema, type UpdateAgentSharingInput, type RotateShareLinkInput, type GetDefaultAgentRequest, type GetSharedProfileRequest, type SharedAgentProfile } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/io_pb";
11
11
  import { AgentQueryController } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/query_pb";
12
- import { AgentSpecSchema, ToolApprovalOverrideSchema, McpServerUsageSchema, McpAccessSchema, SubAgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
12
+ import { AgentSpecSchema, AgentSharingAudience, ToolApprovalOverrideSchema, McpServerUsageSchema, McpAccessSchema, SubAgentSchema, AgentSharingMessagesSchema, AgentSharingSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/spec_pb";
13
13
  import { EnvVarDeclarationSchema } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
14
14
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
15
15
  import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
@@ -55,6 +55,18 @@ export class AgentClient {
55
55
  } catch (e) { throw wrapError(e); }
56
56
  }
57
57
 
58
+ async updateSharing(input: UpdateAgentSharingInput): Promise<Agent> {
59
+ try {
60
+ return await this.command.updateSharing(input);
61
+ } catch (e) { throw wrapError(e); }
62
+ }
63
+
64
+ async rotateShareLink(input: RotateShareLinkInput): Promise<Agent> {
65
+ try {
66
+ return await this.command.rotateShareLink(input);
67
+ } catch (e) { throw wrapError(e); }
68
+ }
69
+
58
70
  async delete(id: string): Promise<Agent> {
59
71
  try {
60
72
  return await this.command.delete(create(AgentIdSchema, { value: id }));
@@ -79,6 +91,18 @@ export class AgentClient {
79
91
  } catch (e) { throw wrapError(e); }
80
92
  }
81
93
 
94
+ async getSharedProfile(input: GetSharedProfileRequest): Promise<SharedAgentProfile> {
95
+ try {
96
+ return await this.query.getSharedProfile(input);
97
+ } catch (e) { throw wrapError(e); }
98
+ }
99
+
100
+ async getSharedProfileForMember(ref: ResourceRef): Promise<SharedAgentProfile> {
101
+ try {
102
+ return await this.query.getSharedProfileForMember(create(ApiResourceReferenceSchema, { ...ref, kind: ApiResourceKind.agent }));
103
+ } catch (e) { throw wrapError(e); }
104
+ }
105
+
82
106
  async list(params: ListParams): Promise<ListResult> {
83
107
  try {
84
108
  const resp = await this.search.search(create(SearchRequestSchema, {
@@ -112,6 +136,7 @@ export interface AgentInput {
112
136
  skillRefs?: ResourceRef[];
113
137
  subAgents?: SubAgentInput[];
114
138
  env?: Record<string, EnvVarDeclarationInput>;
139
+ sharing?: AgentSharingInput;
115
140
  }
116
141
 
117
142
  /** SDK input type for McpServerUsage. */
@@ -151,6 +176,21 @@ export interface EnvVarDeclarationInput {
151
176
  optional?: boolean;
152
177
  }
153
178
 
179
+ /** SDK input type for AgentSharing. */
180
+ export interface AgentSharingInput {
181
+ enabled?: boolean;
182
+ allowedOrigins?: string[];
183
+ messages?: AgentSharingMessagesInput;
184
+ audience?: AgentSharingAudience;
185
+ }
186
+
187
+ /** SDK input type for AgentSharingMessages. */
188
+ export interface AgentSharingMessagesInput {
189
+ rateLimited?: string;
190
+ unavailable?: string;
191
+ conversationEnded?: string;
192
+ }
193
+
154
194
  function buildToolApprovalOverrideProto(input: ToolApprovalOverrideInput) {
155
195
  return Object.assign(create(ToolApprovalOverrideSchema), stripUndefined({
156
196
  toolName: input.toolName,
@@ -193,6 +233,23 @@ function buildEnvVarDeclarationProto(input: EnvVarDeclarationInput) {
193
233
  }));
194
234
  }
195
235
 
236
+ function buildAgentSharingMessagesProto(input: AgentSharingMessagesInput) {
237
+ return Object.assign(create(AgentSharingMessagesSchema), stripUndefined({
238
+ rateLimited: input.rateLimited,
239
+ unavailable: input.unavailable,
240
+ conversationEnded: input.conversationEnded,
241
+ }));
242
+ }
243
+
244
+ function buildAgentSharingProto(input: AgentSharingInput) {
245
+ const msg = create(AgentSharingSchema);
246
+ if (input.enabled !== undefined) msg.enabled = input.enabled;
247
+ if (input.allowedOrigins) msg.allowedOrigins = input.allowedOrigins;
248
+ if (input.messages) msg.messages = buildAgentSharingMessagesProto(input.messages);
249
+ if (input.audience !== undefined) msg.audience = input.audience;
250
+ return msg;
251
+ }
252
+
196
253
  export function buildAgentProto(input: AgentInput): Agent {
197
254
  const mcpServerUsages = input.mcpServerUsages?.map(buildMcpServerUsageProto);
198
255
  const skillRefs = input.skillRefs?.map(r => create(ApiResourceReferenceSchema, { ...r, kind: 43 }));
@@ -201,6 +258,7 @@ export function buildAgentProto(input: AgentInput): Agent {
201
258
  if (input.env) {
202
259
  env = Object.fromEntries(Object.entries(input.env).map(([k, v]) => [k, buildEnvVarDeclarationProto(v)]));
203
260
  }
261
+ const sharing = input.sharing ? buildAgentSharingProto(input.sharing) : undefined;
204
262
  return Object.assign(create(AgentSchema), {
205
263
  apiVersion: "agentic.stigmer.ai/v1",
206
264
  kind: "Agent",
@@ -219,6 +277,7 @@ export function buildAgentProto(input: AgentInput): Agent {
219
277
  skillRefs,
220
278
  subAgents,
221
279
  env,
280
+ sharing,
222
281
  })),
223
282
  }) as Agent;
224
283
  }
package/src/gen/client.ts CHANGED
@@ -74,7 +74,7 @@ export class GeneratedClient {
74
74
 
75
75
  // Re-export all resource client types and input types.
76
76
  export { AgentClient } from "./agent.js";
77
- export { type AgentInput, type McpServerUsageInput, type ToolApprovalOverrideInput, type SubAgentInput, type McpAccessInput, type EnvVarDeclarationInput } from "./agent.js";
77
+ export { type AgentInput, type McpServerUsageInput, type ToolApprovalOverrideInput, type SubAgentInput, type McpAccessInput, type EnvVarDeclarationInput, type AgentSharingInput, type AgentSharingMessagesInput } from "./agent.js";
78
78
  export { AgentExecutionClient } from "./agentexecution.js";
79
79
  export { type AgentExecutionInput, type ExecutionConfigInput, type ContextManagementConfigInput, type AttachmentInput } from "./agentexecution.js";
80
80
  export { AgentInstanceClient } from "./agentinstance.js";
@@ -12,7 +12,7 @@ import { EnvironmentQueryController } from "@stigmer/protos/ai/stigmer/agentic/e
12
12
  import { EnvironmentValueSchema, EnvironmentSpecSchema, type EnvironmentValue } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/spec_pb";
13
13
  import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
14
14
  import { ApiResourceVisibility } from "@stigmer/protos/ai/stigmer/commons/apiresource/enum_pb";
15
- import { ApiResourceIdSchema, ApiResourceReferenceSchema, ApiResourceDeleteInputSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
15
+ import { ApiResourceIdSchema, ApiResourceReferenceSchema, ApiResourceDeleteInputSchema, type UpdateVisibilityInput } from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
16
16
  import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
17
17
 
18
18
  /** Provides operations on environment resources. */
@@ -43,6 +43,12 @@ export class EnvironmentClient {
43
43
  } catch (e) { throw wrapError(e); }
44
44
  }
45
45
 
46
+ async updateVisibility(input: UpdateVisibilityInput): Promise<Environment> {
47
+ try {
48
+ return await this.command.updateVisibility(input);
49
+ } catch (e) { throw wrapError(e); }
50
+ }
51
+
46
52
  async delete(input: DeleteResourceInput): Promise<Environment> {
47
53
  try {
48
54
  return await this.command.delete(create(ApiResourceDeleteInputSchema, {
@@ -14,7 +14,7 @@ import { PlatformClientCommandController } from "@stigmer/protos/ai/stigmer/iam/
14
14
  import { PlatformClientCreateResponseSchema, PlatformClientIdSchema, ListPlatformClientsByOrgInputSchema, PlatformClientsSchema, type PlatformClientCreateResponse, type ListPlatformClientsByOrgInput, type PlatformClients } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/io_pb";
15
15
  import { PlatformClientQueryController } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/query_pb";
16
16
  import { PlatformClientSpecSchema } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/spec_pb";
17
- import { PlatformClientTokenController, MintUserTokenRequestSchema, MintUserTokenResponseSchema, type MintUserTokenRequest, type MintUserTokenResponse } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/token_pb";
17
+ import { PlatformClientTokenController, MintUserTokenRequestSchema, MintUserTokenResponseSchema, MintGuestTokenRequestSchema, MintGuestTokenResponseSchema, type MintUserTokenRequest, type MintUserTokenResponse, type MintGuestTokenRequest, type MintGuestTokenResponse } from "@stigmer/protos/ai/stigmer/iam/platformclient/v1/token_pb";
18
18
  import { IamRole } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
19
19
 
20
20
  /** Provides operations on platformclient resources. */
@@ -80,6 +80,12 @@ export class PlatformClientClient {
80
80
  return await this.token.mintUserToken(input);
81
81
  } catch (e) { throw wrapError(e); }
82
82
  }
83
+
84
+ async mintGuestToken(input: MintGuestTokenRequest): Promise<MintGuestTokenResponse> {
85
+ try {
86
+ return await this.token.mintGuestToken(input);
87
+ } catch (e) { throw wrapError(e); }
88
+ }
83
89
  }
84
90
 
85
91
  /** Input for creating/updating a PlatformClient. */
@@ -9,7 +9,7 @@ import { ToolApprovalOverrideSchema, McpServerUsageSchema } from "@stigmer/proto
9
9
  import { SessionSchema, type Session } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
10
10
  import { SessionCommandController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/command_pb";
11
11
  import { Harness, CursorMode, ExecutionTarget, GitWriteBackMode } from "@stigmer/protos/ai/stigmer/agentic/session/v1/enum_pb";
12
- import { SessionIdSchema, UpdateSessionSubjectRequestSchema, ListSessionsRequestSchema, SessionListSchema, ListSessionsByAgentRequestSchema, type UpdateSessionSubjectRequest, type ListSessionsRequest, type SessionList, type ListSessionsByAgentRequest } from "@stigmer/protos/ai/stigmer/agentic/session/v1/io_pb";
12
+ import { SessionIdSchema, UpdateSessionSubjectRequestSchema, ListSessionsRequestSchema, SessionListSchema, ListSessionsByAgentInstanceRequestSchema, type UpdateSessionSubjectRequest, type ListSessionsRequest, type SessionList, type ListSessionsByAgentInstanceRequest } from "@stigmer/protos/ai/stigmer/agentic/session/v1/io_pb";
13
13
  import { SessionQueryController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/query_pb";
14
14
  import { SessionSpecSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/spec_pb";
15
15
  import { GitRepoSourceSchema, LocalPathSourceSchema, WorkspaceSourceSchema, WorkspaceEntrySchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/workspace_pb";
@@ -69,9 +69,9 @@ export class SessionClient {
69
69
  } catch (e) { throw wrapError(e); }
70
70
  }
71
71
 
72
- async listByAgent(input: ListSessionsByAgentRequest): Promise<SessionList> {
72
+ async listByAgentInstance(input: ListSessionsByAgentInstanceRequest): Promise<SessionList> {
73
73
  try {
74
- return await this.query.listByAgent(input);
74
+ return await this.query.listByAgentInstance(input);
75
75
  } catch (e) { throw wrapError(e); }
76
76
  }
77
77
  }