@jskit-ai/assistant-core 0.1.5 → 0.1.7
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/package.descriptor.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default Object.freeze({
|
|
2
2
|
packageVersion: 1,
|
|
3
3
|
packageId: "@jskit-ai/assistant-core",
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.7",
|
|
5
5
|
kind: "runtime",
|
|
6
6
|
description: "Reusable assistant client/server/shared primitives without surface-specific routes or settings ownership.",
|
|
7
7
|
dependsOn: [
|
|
@@ -45,9 +45,9 @@ export default Object.freeze({
|
|
|
45
45
|
mutations: {
|
|
46
46
|
dependencies: {
|
|
47
47
|
runtime: {
|
|
48
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
49
|
-
"@jskit-ai/kernel": "0.1.
|
|
50
|
-
"@jskit-ai/users-core": "0.1.
|
|
48
|
+
"@jskit-ai/http-runtime": "0.1.30",
|
|
49
|
+
"@jskit-ai/kernel": "0.1.31",
|
|
50
|
+
"@jskit-ai/users-core": "0.1.41",
|
|
51
51
|
"@tanstack/vue-query": "^5.90.5",
|
|
52
52
|
"dompurify": "^3.3.3",
|
|
53
53
|
"marked": "^17.0.4",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/assistant-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "node --test"
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
"./shared": "./src/shared/index.js"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@jskit-ai/http-runtime": "0.1.
|
|
15
|
-
"@jskit-ai/kernel": "0.1.
|
|
16
|
-
"@jskit-ai/users-core": "0.1.
|
|
14
|
+
"@jskit-ai/http-runtime": "0.1.30",
|
|
15
|
+
"@jskit-ai/kernel": "0.1.31",
|
|
16
|
+
"@jskit-ai/users-core": "0.1.41",
|
|
17
17
|
"@tanstack/vue-query": "^5.90.5",
|
|
18
18
|
"dompurify": "^3.3.3",
|
|
19
19
|
"marked": "^17.0.4",
|
|
@@ -130,6 +130,30 @@ function createAssistantApi({ request, requestStream, resolveBasePath, resolveSu
|
|
|
130
130
|
appendQueryString(`${basePath}/conversations/${encodedConversationId}/messages`, params.toString()),
|
|
131
131
|
requestHeaders ? { headers: requestHeaders } : {}
|
|
132
132
|
);
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
getSettings() {
|
|
136
|
+
const basePath = resolveRequiredBasePath(resolveBasePath);
|
|
137
|
+
const requestHeaders = resolveAssistantRequestHeaders(resolveSurfaceId);
|
|
138
|
+
|
|
139
|
+
return request(
|
|
140
|
+
`${basePath}/settings`,
|
|
141
|
+
requestHeaders ? { headers: requestHeaders } : {}
|
|
142
|
+
);
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
updateSettings(payload = {}) {
|
|
146
|
+
const basePath = resolveRequiredBasePath(resolveBasePath);
|
|
147
|
+
const requestHeaders = resolveAssistantRequestHeaders(resolveSurfaceId);
|
|
148
|
+
|
|
149
|
+
return request(
|
|
150
|
+
`${basePath}/settings`,
|
|
151
|
+
{
|
|
152
|
+
method: "PATCH",
|
|
153
|
+
...(requestHeaders ? { headers: requestHeaders } : {}),
|
|
154
|
+
body: payload
|
|
155
|
+
}
|
|
156
|
+
);
|
|
133
157
|
}
|
|
134
158
|
});
|
|
135
159
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { requireAuth } from "@jskit-ai/kernel/server/runtime";
|
|
2
2
|
import { resolveActionContributors } from "@jskit-ai/kernel/server/actions";
|
|
3
3
|
import { normalizeActionDefinition } from "@jskit-ai/kernel/shared/actions";
|
|
4
|
+
import { normalizeSurfaceId } from "@jskit-ai/kernel/shared/surface/registry";
|
|
4
5
|
import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
5
6
|
import { resolveWorkspaceSlug } from "./resolveWorkspaceSlug.js";
|
|
6
7
|
|
|
@@ -209,6 +210,34 @@ function hasAutomationChannel(action = {}) {
|
|
|
209
210
|
return channels.some((channel) => normalizeText(channel).toLowerCase() === AUTOMATION_CHANNEL);
|
|
210
211
|
}
|
|
211
212
|
|
|
213
|
+
function normalizeSurfaceList(value) {
|
|
214
|
+
const source = Array.isArray(value) ? value : [value];
|
|
215
|
+
const resolved = [];
|
|
216
|
+
|
|
217
|
+
for (const entry of source) {
|
|
218
|
+
const normalized = normalizeSurfaceId(entry);
|
|
219
|
+
if (normalized) {
|
|
220
|
+
resolved.push(normalized);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return Object.freeze(resolved);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function canUseToolOnSurface(entry = {}, context = {}) {
|
|
228
|
+
const toolSurfaces = Array.isArray(entry.surfaces) ? entry.surfaces : [];
|
|
229
|
+
if (toolSurfaces.length < 1) {
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
const contextSurfaceId = normalizeSurfaceId(context?.surface);
|
|
234
|
+
if (!contextSurfaceId) {
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return toolSurfaces.includes(contextSurfaceId);
|
|
239
|
+
}
|
|
240
|
+
|
|
212
241
|
function resolveActionBackedToolEntries(scope) {
|
|
213
242
|
if (!scope || typeof scope.has !== "function" || typeof scope.make !== "function") {
|
|
214
243
|
return new Map();
|
|
@@ -261,7 +290,8 @@ function resolveActionBackedToolEntries(scope) {
|
|
|
261
290
|
description: assistantExtension.description || `Run ${actionId}.`,
|
|
262
291
|
inputSchema,
|
|
263
292
|
outputSchema,
|
|
264
|
-
permission: normalizePermissionSpec(normalizedAction.permission)
|
|
293
|
+
permission: normalizePermissionSpec(normalizedAction.permission),
|
|
294
|
+
surfaces: normalizeSurfaceList(normalizedAction.surfaces)
|
|
265
295
|
});
|
|
266
296
|
const existing = entriesByActionId.get(actionKey);
|
|
267
297
|
if (!existing || actionVersion >= Number(existing.actionVersion || 0)) {
|
|
@@ -309,7 +339,8 @@ function resolveActionToolEntries(
|
|
|
309
339
|
parameters: actionEntry.inputSchema,
|
|
310
340
|
outputSchema: actionEntry.outputSchema
|
|
311
341
|
}),
|
|
312
|
-
permission: actionEntry.permission
|
|
342
|
+
permission: actionEntry.permission,
|
|
343
|
+
surfaces: actionEntry.surfaces
|
|
313
344
|
})
|
|
314
345
|
);
|
|
315
346
|
}
|
|
@@ -346,6 +377,9 @@ function createServiceToolCatalog(
|
|
|
346
377
|
const tools = [];
|
|
347
378
|
const byName = new Map();
|
|
348
379
|
for (const entry of resolveOrCreateMethodEntries()) {
|
|
380
|
+
if (!canUseToolOnSurface(entry, context)) {
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
349
383
|
if (!canInvokeMethod(entry.permission, context)) {
|
|
350
384
|
continue;
|
|
351
385
|
}
|
|
@@ -3,30 +3,38 @@ import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
|
|
|
3
3
|
import { resolveApiBasePath } from "@jskit-ai/users-core/shared/support/usersApiPaths";
|
|
4
4
|
|
|
5
5
|
const ASSISTANT_API_RELATIVE_PATH = "/assistant";
|
|
6
|
-
const ASSISTANT_SETTINGS_API_RELATIVE_PATH = "/assistant/settings";
|
|
6
|
+
const ASSISTANT_SETTINGS_API_RELATIVE_PATH = "/assistant/:surfaceId/settings";
|
|
7
7
|
const ASSISTANT_WORKSPACE_API_BASE_PATH_TEMPLATE = "/api/w/:workspaceSlug/assistant";
|
|
8
8
|
const ASSISTANT_PUBLIC_API_BASE_PATH = "/api/assistant";
|
|
9
|
-
const ASSISTANT_WORKSPACE_SETTINGS_API_PATH_TEMPLATE = "/api/w/:workspaceSlug/assistant/settings";
|
|
10
|
-
const ASSISTANT_PUBLIC_SETTINGS_API_PATH = "/api/assistant/settings";
|
|
9
|
+
const ASSISTANT_WORKSPACE_SETTINGS_API_PATH_TEMPLATE = "/api/w/:workspaceSlug/assistant/:surfaceId/settings";
|
|
10
|
+
const ASSISTANT_PUBLIC_SETTINGS_API_PATH = "/api/assistant/:surfaceId/settings";
|
|
11
11
|
|
|
12
|
-
function materializeAssistantPath(basePath = "", workspaceSlug = "", suffix = "/") {
|
|
12
|
+
function materializeAssistantPath(basePath = "", { workspaceSlug = "", surfaceId = "", suffix = "/" } = {}) {
|
|
13
13
|
const normalizedBasePath = String(basePath || "").trim();
|
|
14
14
|
if (!normalizedBasePath) {
|
|
15
15
|
return "";
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
let materializedBasePath = normalizedBasePath;
|
|
19
19
|
if (normalizedBasePath.includes(":workspaceSlug")) {
|
|
20
20
|
const normalizedWorkspaceSlug = normalizeText(workspaceSlug).toLowerCase();
|
|
21
21
|
if (!normalizedWorkspaceSlug) {
|
|
22
22
|
return "";
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
materializedBasePath = normalizedBasePath.replace(":workspaceSlug", encodeURIComponent(normalizedWorkspaceSlug));
|
|
26
|
+
}
|
|
27
|
+
if (materializedBasePath.includes(":surfaceId")) {
|
|
28
|
+
const normalizedSurfaceId = normalizeText(surfaceId).toLowerCase();
|
|
29
|
+
if (!normalizedSurfaceId) {
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
materializedBasePath = materializedBasePath.replace(":surfaceId", encodeURIComponent(normalizedSurfaceId));
|
|
27
34
|
}
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
const normalizedSuffix = normalizePathname(suffix);
|
|
37
|
+
return normalizedSuffix === "/" ? materializedBasePath : `${materializedBasePath}${normalizedSuffix}`;
|
|
30
38
|
}
|
|
31
39
|
|
|
32
40
|
function resolveAssistantApiBasePath({ requiresWorkspace = false } = {}) {
|
|
@@ -48,18 +56,23 @@ function buildAssistantApiPath({ requiresWorkspace = false, workspaceSlug = "",
|
|
|
48
56
|
resolveAssistantApiBasePath({
|
|
49
57
|
requiresWorkspace
|
|
50
58
|
}),
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
{
|
|
60
|
+
workspaceSlug,
|
|
61
|
+
suffix
|
|
62
|
+
}
|
|
53
63
|
);
|
|
54
64
|
}
|
|
55
65
|
|
|
56
|
-
function buildAssistantSettingsApiPath({ requiresWorkspace = false, workspaceSlug = "", suffix = "/" } = {}) {
|
|
66
|
+
function buildAssistantSettingsApiPath({ requiresWorkspace = false, workspaceSlug = "", surfaceId = "", suffix = "/" } = {}) {
|
|
57
67
|
return materializeAssistantPath(
|
|
58
68
|
resolveAssistantSettingsApiPath({
|
|
59
69
|
requiresWorkspace
|
|
60
70
|
}),
|
|
61
|
-
|
|
62
|
-
|
|
71
|
+
{
|
|
72
|
+
workspaceSlug,
|
|
73
|
+
surfaceId,
|
|
74
|
+
suffix
|
|
75
|
+
}
|
|
63
76
|
);
|
|
64
77
|
}
|
|
65
78
|
|
|
@@ -11,8 +11,8 @@ test("assistant path helpers derive workspace and non-workspace API bases from s
|
|
|
11
11
|
assert.equal(resolveAssistantApiBasePath({ requiresWorkspace: false }), "/api/assistant");
|
|
12
12
|
assert.equal(resolveAssistantApiBasePath({ requiresWorkspace: true }), "/api/w/:workspaceSlug/assistant");
|
|
13
13
|
|
|
14
|
-
assert.equal(resolveAssistantSettingsApiPath({ requiresWorkspace: false }), "/api/assistant/settings");
|
|
15
|
-
assert.equal(resolveAssistantSettingsApiPath({ requiresWorkspace: true }), "/api/w/:workspaceSlug/assistant/settings");
|
|
14
|
+
assert.equal(resolveAssistantSettingsApiPath({ requiresWorkspace: false }), "/api/assistant/:surfaceId/settings");
|
|
15
|
+
assert.equal(resolveAssistantSettingsApiPath({ requiresWorkspace: true }), "/api/w/:workspaceSlug/assistant/:surfaceId/settings");
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
test("assistant path builders materialize workspace-aware and public API paths", () => {
|
|
@@ -36,16 +36,17 @@ test("assistant path builders materialize workspace-aware and public API paths",
|
|
|
36
36
|
assert.equal(
|
|
37
37
|
buildAssistantSettingsApiPath({
|
|
38
38
|
requiresWorkspace: false,
|
|
39
|
-
|
|
39
|
+
surfaceId: "admin"
|
|
40
40
|
}),
|
|
41
|
-
"/api/assistant/settings"
|
|
41
|
+
"/api/assistant/admin/settings"
|
|
42
42
|
);
|
|
43
43
|
|
|
44
44
|
assert.equal(
|
|
45
45
|
buildAssistantSettingsApiPath({
|
|
46
46
|
requiresWorkspace: true,
|
|
47
|
-
workspaceSlug: "acme"
|
|
47
|
+
workspaceSlug: "acme",
|
|
48
|
+
surfaceId: "admin"
|
|
48
49
|
}),
|
|
49
|
-
"/api/w/acme/assistant/settings"
|
|
50
|
+
"/api/w/acme/assistant/admin/settings"
|
|
50
51
|
);
|
|
51
52
|
});
|
|
@@ -1233,3 +1233,82 @@ test("service tool catalog executes action-backed tools with object payloads", a
|
|
|
1233
1233
|
}
|
|
1234
1234
|
});
|
|
1235
1235
|
});
|
|
1236
|
+
|
|
1237
|
+
test("service tool catalog hides automation actions from other surfaces", () => {
|
|
1238
|
+
const app = createApp();
|
|
1239
|
+
const actionRuntimeProvider = new ActionRuntimeServiceProvider();
|
|
1240
|
+
actionRuntimeProvider.register(app);
|
|
1241
|
+
|
|
1242
|
+
app.actions([
|
|
1243
|
+
{
|
|
1244
|
+
id: "demo.admin.list",
|
|
1245
|
+
domain: "demo",
|
|
1246
|
+
version: 1,
|
|
1247
|
+
kind: "query",
|
|
1248
|
+
channels: ["automation"],
|
|
1249
|
+
surfaces: ["admin"],
|
|
1250
|
+
permission: {
|
|
1251
|
+
require: "authenticated"
|
|
1252
|
+
},
|
|
1253
|
+
inputValidator: {
|
|
1254
|
+
schema: Type.Object({}, { additionalProperties: false })
|
|
1255
|
+
},
|
|
1256
|
+
outputValidator: {
|
|
1257
|
+
schema: Type.Array(Type.Object({}, { additionalProperties: true }))
|
|
1258
|
+
},
|
|
1259
|
+
idempotency: "none",
|
|
1260
|
+
audit: {
|
|
1261
|
+
actionName: "demo.admin.list"
|
|
1262
|
+
},
|
|
1263
|
+
observability: {},
|
|
1264
|
+
async execute() {
|
|
1265
|
+
return [];
|
|
1266
|
+
}
|
|
1267
|
+
},
|
|
1268
|
+
{
|
|
1269
|
+
id: "demo.console.list",
|
|
1270
|
+
domain: "demo",
|
|
1271
|
+
version: 1,
|
|
1272
|
+
kind: "query",
|
|
1273
|
+
channels: ["automation"],
|
|
1274
|
+
surfaces: ["console"],
|
|
1275
|
+
permission: {
|
|
1276
|
+
require: "authenticated"
|
|
1277
|
+
},
|
|
1278
|
+
inputValidator: {
|
|
1279
|
+
schema: Type.Object({}, { additionalProperties: false })
|
|
1280
|
+
},
|
|
1281
|
+
outputValidator: {
|
|
1282
|
+
schema: Type.Array(Type.Object({}, { additionalProperties: true }))
|
|
1283
|
+
},
|
|
1284
|
+
idempotency: "none",
|
|
1285
|
+
audit: {
|
|
1286
|
+
actionName: "demo.console.list"
|
|
1287
|
+
},
|
|
1288
|
+
observability: {},
|
|
1289
|
+
async execute() {
|
|
1290
|
+
return [];
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
]);
|
|
1294
|
+
|
|
1295
|
+
const catalog = createServiceToolCatalog(app, {
|
|
1296
|
+
skipActionPrefixes: []
|
|
1297
|
+
});
|
|
1298
|
+
|
|
1299
|
+
const adminToolSet = catalog.resolveToolSet({
|
|
1300
|
+
actor: { id: 1 },
|
|
1301
|
+
permissions: [],
|
|
1302
|
+
channel: "internal",
|
|
1303
|
+
surface: "admin"
|
|
1304
|
+
});
|
|
1305
|
+
const consoleToolSet = catalog.resolveToolSet({
|
|
1306
|
+
actor: { id: 1 },
|
|
1307
|
+
permissions: [],
|
|
1308
|
+
channel: "internal",
|
|
1309
|
+
surface: "console"
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
assert.deepEqual(adminToolSet.tools.map((entry) => entry.actionId), ["demo.admin.list"]);
|
|
1313
|
+
assert.deepEqual(consoleToolSet.tools.map((entry) => entry.actionId), ["demo.console.list"]);
|
|
1314
|
+
});
|