@jskit-ai/assistant-core 0.1.31 → 0.1.33
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 +9 -5
- package/package.json +11 -6
- package/src/server/lib/serviceToolCatalog.js +9 -2
- package/src/shared/assistantResource.js +265 -267
- package/src/shared/assistantSettingsResource.js +48 -76
- package/test/assistantResource.test.js +38 -15
- package/test/assistantSettingsResource.test.js +17 -16
- package/test/packageDescriptor.test.js +13 -0
- package/test/serviceToolCatalog.test.js +243 -262
|
@@ -1,89 +1,61 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
normalizeObjectInput,
|
|
5
|
-
nullableRecordIdSchema
|
|
6
|
-
} from "@jskit-ai/kernel/shared/validators";
|
|
1
|
+
import { createSchema } from "json-rest-schema";
|
|
2
|
+
import { RECORD_ID_PATTERN } from "@jskit-ai/kernel/shared/validators";
|
|
3
|
+
import { defineCrudResource } from "@jskit-ai/resource-crud-core/shared/crudResource";
|
|
7
4
|
|
|
8
5
|
const MAX_SYSTEM_PROMPT_CHARS = 12_000;
|
|
9
6
|
|
|
10
|
-
const assistantConfigRecordSchema =
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
{
|
|
17
|
-
systemPrompt: Type.String({ maxLength: MAX_SYSTEM_PROMPT_CHARS })
|
|
18
|
-
},
|
|
19
|
-
{ additionalProperties: false }
|
|
20
|
-
)
|
|
7
|
+
const assistantConfigRecordSchema = createSchema({
|
|
8
|
+
targetSurfaceId: {
|
|
9
|
+
type: "string",
|
|
10
|
+
required: true,
|
|
11
|
+
minLength: 1,
|
|
12
|
+
maxLength: 64
|
|
21
13
|
},
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
systemPrompt: Type.Optional(
|
|
28
|
-
Type.String({
|
|
29
|
-
maxLength: MAX_SYSTEM_PROMPT_CHARS,
|
|
30
|
-
messages: {
|
|
31
|
-
maxLength: `Assistant system prompt must be at most ${MAX_SYSTEM_PROMPT_CHARS} characters.`,
|
|
32
|
-
default: "Assistant system prompt must be valid text."
|
|
33
|
-
}
|
|
34
|
-
})
|
|
35
|
-
)
|
|
14
|
+
scopeKey: {
|
|
15
|
+
type: "string",
|
|
16
|
+
required: true,
|
|
17
|
+
minLength: 1,
|
|
18
|
+
maxLength: 160
|
|
36
19
|
},
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
20
|
+
workspaceId: {
|
|
21
|
+
type: "string",
|
|
22
|
+
required: true,
|
|
23
|
+
nullable: true,
|
|
24
|
+
minLength: 1,
|
|
25
|
+
pattern: RECORD_ID_PATTERN
|
|
26
|
+
},
|
|
27
|
+
settings: {
|
|
28
|
+
type: "object",
|
|
29
|
+
required: true,
|
|
30
|
+
schema: createSchema({
|
|
31
|
+
systemPrompt: {
|
|
32
|
+
type: "string",
|
|
33
|
+
required: true,
|
|
34
|
+
maxLength: MAX_SYSTEM_PROMPT_CHARS
|
|
35
|
+
}
|
|
36
|
+
})
|
|
46
37
|
}
|
|
38
|
+
});
|
|
47
39
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
targetSurfaceId: normalizeText(source.targetSurfaceId).toLowerCase(),
|
|
57
|
-
scopeKey: normalizeText(source.scopeKey),
|
|
58
|
-
workspaceId: normalizeRecordId(source.workspaceId, { fallback: null }),
|
|
59
|
-
settings: {
|
|
60
|
-
systemPrompt: String(settings.systemPrompt || "")
|
|
40
|
+
const assistantConfigPatchSchema = createSchema({
|
|
41
|
+
systemPrompt: {
|
|
42
|
+
type: "string",
|
|
43
|
+
required: false,
|
|
44
|
+
maxLength: MAX_SYSTEM_PROMPT_CHARS,
|
|
45
|
+
messages: {
|
|
46
|
+
maxLength: `Assistant system prompt must be at most ${MAX_SYSTEM_PROMPT_CHARS} characters.`,
|
|
47
|
+
default: "Assistant system prompt must be valid text."
|
|
61
48
|
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
64
51
|
|
|
65
|
-
const assistantConfigResource =
|
|
52
|
+
const assistantConfigResource = defineCrudResource({
|
|
66
53
|
namespace: "assistantConfig",
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
normalize: normalizeConfigRecord
|
|
73
|
-
})
|
|
74
|
-
}),
|
|
75
|
-
patch: Object.freeze({
|
|
76
|
-
method: "PATCH",
|
|
77
|
-
bodyValidator: Object.freeze({
|
|
78
|
-
schema: assistantConfigPatchSchema,
|
|
79
|
-
normalize: normalizeConfigPatch
|
|
80
|
-
}),
|
|
81
|
-
outputValidator: Object.freeze({
|
|
82
|
-
schema: assistantConfigRecordSchema,
|
|
83
|
-
normalize: normalizeConfigRecord
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
})
|
|
54
|
+
crudOperations: ["view", "patch"],
|
|
55
|
+
crud: {
|
|
56
|
+
output: assistantConfigRecordSchema,
|
|
57
|
+
patchBody: assistantConfigPatchSchema
|
|
58
|
+
}
|
|
87
59
|
});
|
|
88
60
|
|
|
89
61
|
export {
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
3
|
+
import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
|
|
4
|
+
import { resolveStructuredSchemaTransportSchema } from "@jskit-ai/kernel/shared/validators";
|
|
4
5
|
import { assistantResource } from "../src/shared/assistantResource.js";
|
|
5
6
|
|
|
6
7
|
test("assistant output schemas accept normalized paginated payloads", () => {
|
|
7
|
-
const conversationsListSchema =
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
const conversationsListSchema = resolveStructuredSchemaTransportSchema(
|
|
9
|
+
assistantResource.operations.conversationsList.output,
|
|
10
|
+
{
|
|
11
|
+
context: "assistant conversations list output",
|
|
12
|
+
defaultMode: "replace"
|
|
13
|
+
}
|
|
14
|
+
);
|
|
15
|
+
const conversationMessagesSchema = resolveStructuredSchemaTransportSchema(
|
|
16
|
+
assistantResource.operations.conversationMessagesList.output,
|
|
17
|
+
{
|
|
18
|
+
context: "assistant conversation messages output",
|
|
19
|
+
defaultMode: "replace"
|
|
20
|
+
}
|
|
21
|
+
);
|
|
14
22
|
|
|
15
23
|
const messagesPayload = {
|
|
16
24
|
conversation: {
|
|
@@ -36,14 +44,29 @@ test("assistant output schemas accept normalized paginated payloads", () => {
|
|
|
36
44
|
totalPages: 1
|
|
37
45
|
};
|
|
38
46
|
|
|
39
|
-
assert.equal(
|
|
40
|
-
assert.equal(
|
|
47
|
+
assert.equal(conversationsListSchema.type, "object");
|
|
48
|
+
assert.equal(conversationsListSchema.properties.items.type, "array");
|
|
49
|
+
assert.equal(conversationMessagesSchema.type, "object");
|
|
50
|
+
assert.equal(conversationMessagesSchema.properties.entries.type, "array");
|
|
51
|
+
assert.equal(messagesPayload.conversation.provider, "openai");
|
|
41
52
|
});
|
|
42
53
|
|
|
43
|
-
test("assistant conversation message params accept numeric path strings
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
test("assistant conversation message params accept numeric path strings", async () => {
|
|
55
|
+
const params = resolveStructuredSchemaTransportSchema(
|
|
56
|
+
assistantResource.operations.conversationMessagesList.params,
|
|
57
|
+
{
|
|
58
|
+
context: "assistant conversation message params",
|
|
59
|
+
defaultMode: "patch"
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
const parsed = await validateOperationSection({
|
|
63
|
+
operation: assistantResource.operations.conversationMessagesList,
|
|
64
|
+
section: "params",
|
|
65
|
+
value: { conversationId: "2" }
|
|
48
66
|
});
|
|
67
|
+
|
|
68
|
+
assert.equal(params.type, "object");
|
|
69
|
+
assert.equal(typeof params.properties.conversationId, "object");
|
|
70
|
+
assert.equal(parsed.ok, true);
|
|
71
|
+
assert.deepEqual(parsed.value, { conversationId: 2 });
|
|
49
72
|
});
|
|
@@ -1,29 +1,30 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import {
|
|
3
|
+
import { resolveStructuredSchemaTransportSchema } from "@jskit-ai/kernel/shared/validators";
|
|
4
4
|
import { validateOperationSection } from "@jskit-ai/http-runtime/shared/validators/operationValidation";
|
|
5
5
|
import { assistantConfigResource } from "../src/shared/assistantSettingsResource.js";
|
|
6
6
|
|
|
7
7
|
test("assistant config resource exposes valid output schema", () => {
|
|
8
|
-
const viewSchema =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
workspaceId: null,
|
|
15
|
-
settings: {
|
|
16
|
-
systemPrompt: ""
|
|
17
|
-
}
|
|
18
|
-
}),
|
|
19
|
-
true
|
|
8
|
+
const viewSchema = resolveStructuredSchemaTransportSchema(
|
|
9
|
+
assistantConfigResource.operations.view.output,
|
|
10
|
+
{
|
|
11
|
+
context: "assistant config view output",
|
|
12
|
+
defaultMode: "replace"
|
|
13
|
+
}
|
|
20
14
|
);
|
|
15
|
+
|
|
16
|
+
assert.equal(viewSchema.type, "object");
|
|
17
|
+
assert.equal(viewSchema.additionalProperties, false);
|
|
18
|
+
assert.equal(viewSchema.properties.targetSurfaceId.type, "string");
|
|
19
|
+
assert.equal(viewSchema.properties.settings["x-json-rest-schema"]?.castType, "object");
|
|
20
|
+
assert.equal(Array.isArray(viewSchema.properties.settings.allOf), true);
|
|
21
|
+
assert.match(viewSchema.properties.settings.allOf[0]?.$ref || "", /^#\/definitions\//);
|
|
21
22
|
});
|
|
22
23
|
|
|
23
|
-
test("assistant settings patch
|
|
24
|
-
const patch = validateOperationSection({
|
|
24
|
+
test("assistant settings patch validation preserves omitted fields", async () => {
|
|
25
|
+
const patch = await validateOperationSection({
|
|
25
26
|
operation: assistantConfigResource.operations.patch,
|
|
26
|
-
section: "
|
|
27
|
+
section: "body",
|
|
27
28
|
value: {}
|
|
28
29
|
});
|
|
29
30
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import descriptor from "../package.descriptor.mjs";
|
|
4
|
+
|
|
5
|
+
test("assistant-core advertises a portable json-rest-schema runtime dependency for app installs", () => {
|
|
6
|
+
const specifier = String(descriptor?.mutations?.dependencies?.runtime?.["json-rest-schema"] || "");
|
|
7
|
+
|
|
8
|
+
assert.match(
|
|
9
|
+
specifier,
|
|
10
|
+
/^(?:[~^]?\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?|\d+\.x\.x)$/,
|
|
11
|
+
"assistant-core descriptor must not write a repo-local file: dependency into app package.json"
|
|
12
|
+
);
|
|
13
|
+
});
|