@jskit-ai/assistant 0.1.11 → 0.1.13

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.
@@ -1,7 +1,7 @@
1
1
  export default Object.freeze({
2
2
  packageVersion: 1,
3
3
  packageId: "@jskit-ai/assistant",
4
- version: "0.1.11",
4
+ version: "0.1.13",
5
5
  description: "Unified assistant module with streaming chat, transcript persistence, service-aware tool execution, and workspace UI.",
6
6
  options: {
7
7
  "ai-provider": {
@@ -110,14 +110,14 @@ export default Object.freeze({
110
110
  mutations: {
111
111
  dependencies: {
112
112
  runtime: {
113
- "@jskit-ai/assistant": "0.1.11",
113
+ "@jskit-ai/assistant": "0.1.13",
114
114
  "@jskit-ai/auth-core": "0.1.8",
115
115
  "@jskit-ai/database-runtime": "0.1.8",
116
116
  "@jskit-ai/http-runtime": "0.1.8",
117
117
  "@jskit-ai/kernel": "0.1.8",
118
118
  "@jskit-ai/realtime": "0.1.8",
119
- "@jskit-ai/users-core": "0.1.11",
120
- "@jskit-ai/users-web": "0.1.11",
119
+ "@jskit-ai/users-core": "0.1.10",
120
+ "@jskit-ai/users-web": "0.1.13",
121
121
  "@tanstack/vue-query": "^5.90.5",
122
122
  "dompurify": "^3.3.3",
123
123
  "marked": "^17.0.4",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jskit-ai/assistant",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "test": "node --test"
@@ -19,8 +19,8 @@
19
19
  "@jskit-ai/kernel": "0.1.8",
20
20
  "@jskit-ai/realtime": "0.1.8",
21
21
  "@jskit-ai/shell-web": "0.1.8",
22
- "@jskit-ai/users-core": "0.1.11",
23
- "@jskit-ai/users-web": "0.1.11",
22
+ "@jskit-ai/users-core": "0.1.10",
23
+ "@jskit-ai/users-web": "0.1.13",
24
24
  "@tanstack/vue-query": "^5.90.5",
25
25
  "dompurify": "^3.3.3",
26
26
  "marked": "^17.0.4",
@@ -248,8 +248,10 @@ import { computed, nextTick, onActivated, onBeforeUnmount, onMounted, ref, shall
248
248
  import { createComponentInteractionEmitter } from "@jskit-ai/kernel/client";
249
249
  import {
250
250
  normalizeObject,
251
+ normalizeText,
251
252
  normalizeOneOf
252
253
  } from "@jskit-ai/kernel/shared/support/normalize";
254
+ import { normalizeConversationStatus as normalizeAssistantConversationStatus } from "../../shared/support/conversationStatus.js";
253
255
  import { renderMarkdownToSafeHtml } from "../lib/markdownRenderer.js";
254
256
 
255
257
  const DEFAULT_COPY = Object.freeze({
@@ -413,10 +415,6 @@ const rootClasses = computed(() => {
413
415
  return classes;
414
416
  });
415
417
 
416
- function normalizeText(value) {
417
- return String(value || "").trim();
418
- }
419
-
420
418
  function formatConversationStartedAt(value) {
421
419
  const formatter = meta?.formatConversationStartedAt;
422
420
  if (typeof formatter === "function") {
@@ -430,7 +428,9 @@ function normalizeConversationStatus(value) {
430
428
  if (typeof normalizer === "function") {
431
429
  return normalizer(value);
432
430
  }
433
- return normalizeText(value).toLowerCase() || "unknown";
431
+ return normalizeAssistantConversationStatus(value, {
432
+ fallback: "unknown"
433
+ });
434
434
  }
435
435
 
436
436
  const viewer = computed(() => {
@@ -15,6 +15,8 @@ import {
15
15
  assistantConversationsListQueryKey,
16
16
  assistantWorkspaceScopeQueryKey,
17
17
  normalizeAssistantStreamEventType,
18
+ normalizeConversationStatus as normalizeAssistantConversationStatus,
19
+ parseJsonObject,
18
20
  toPositiveInteger
19
21
  } from "../../shared/index.js";
20
22
  import { assistantHttpClient } from "../lib/assistantHttpClient.js";
@@ -98,8 +100,9 @@ function normalizeToolName(value) {
98
100
  }
99
101
 
100
102
  function normalizeConversationStatus(value) {
101
- const status = normalizeText(value).toLowerCase();
102
- return status || "unknown";
103
+ return normalizeAssistantConversationStatus(value, {
104
+ fallback: "unknown"
105
+ });
103
106
  }
104
107
 
105
108
  function formatConversationStartedAt(value) {
@@ -117,20 +120,7 @@ function formatConversationStartedAt(value) {
117
120
  }
118
121
 
119
122
  function parseToolResultPayload(value) {
120
- if (!value) {
121
- return {};
122
- }
123
-
124
- try {
125
- const parsed = typeof value === "string" ? JSON.parse(value) : value;
126
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
127
- return {};
128
- }
129
-
130
- return parsed;
131
- } catch {
132
- return {};
133
- }
123
+ return parseJsonObject(value);
134
124
  }
135
125
 
136
126
  function buildHistory(messages) {
@@ -1,5 +1,9 @@
1
1
  import { AppError } from "@jskit-ai/kernel/server/runtime/errors";
2
- import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
2
+ import {
3
+ normalizeArray,
4
+ normalizeObject,
5
+ normalizeText
6
+ } from "@jskit-ai/kernel/shared/support/normalize";
3
7
 
4
8
  const SUPPORTED_AI_PROVIDERS = Object.freeze(["openai", "deepseek", "anthropic"]);
5
9
  const SUPPORTED_AI_PROVIDER_SET = new Set(SUPPORTED_AI_PROVIDERS);
@@ -82,18 +86,6 @@ function createProviderRequestError({ status = 500, code = "assistant_provider_f
82
86
  });
83
87
  }
84
88
 
85
- function normalizeObject(value) {
86
- if (!value || typeof value !== "object" || Array.isArray(value)) {
87
- return {};
88
- }
89
-
90
- return value;
91
- }
92
-
93
- function normalizeArray(value) {
94
- return Array.isArray(value) ? value : [];
95
- }
96
-
97
89
  function normalizeContentText(content) {
98
90
  if (typeof content === "string") {
99
91
  return content;
@@ -1,5 +1,6 @@
1
1
  import { parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
2
2
  import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
3
+ import { runInTransaction } from "@jskit-ai/database-runtime/shared/repositoryOptions";
3
4
  import {
4
5
  parseJsonObject,
5
6
  stringifyJsonObject,
@@ -223,11 +224,7 @@ function createConversationsRepository(knex) {
223
224
  }
224
225
 
225
226
  async function transaction(callback) {
226
- if (typeof knex.transaction !== "function") {
227
- return callback(knex);
228
- }
229
-
230
- return knex.transaction(callback);
227
+ return runInTransaction(knex, callback);
231
228
  }
232
229
 
233
230
  return Object.freeze({
@@ -1,5 +1,6 @@
1
1
  import { parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
2
2
  import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
3
+ import { runInTransaction } from "@jskit-ai/database-runtime/shared/repositoryOptions";
3
4
  import {
4
5
  parseJsonObject,
5
6
  stringifyJsonObject,
@@ -135,11 +136,7 @@ function createMessagesRepository(knex) {
135
136
  }
136
137
 
137
138
  async function transaction(callback) {
138
- if (typeof knex.transaction !== "function") {
139
- return callback(knex);
140
- }
141
-
142
- return knex.transaction(callback);
139
+ return runInTransaction(knex, callback);
143
140
  }
144
141
 
145
142
  return Object.freeze({
@@ -1,19 +1,4 @@
1
- function parseJsonObject(value) {
2
- if (value == null) {
3
- return {};
4
- }
5
-
6
- try {
7
- const parsed = typeof value === "string" ? JSON.parse(value) : value;
8
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
9
- return {};
10
- }
11
-
12
- return parsed;
13
- } catch {
14
- return {};
15
- }
16
- }
1
+ import { parseJsonObject } from "../../shared/support/jsonObject.js";
17
2
 
18
3
  function stringifyJsonObject(value) {
19
4
  if (!value || typeof value !== "object" || Array.isArray(value)) {
@@ -1,6 +1,7 @@
1
1
  import { AppError, parsePositiveInteger } from "@jskit-ai/kernel/server/runtime";
2
2
  import { normalizeObject, normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
3
3
  import { ASSISTANT_TRANSCRIPT_CHANGED_EVENT } from "../../shared/streamEvents.js";
4
+ import { normalizeConversationStatus } from "../../shared/support/conversationStatus.js";
4
5
 
5
6
  const DEFAULT_PAGE_SIZE = 20;
6
7
  const MAX_PAGE_SIZE = 200;
@@ -98,15 +99,6 @@ function normalizeCursorPagination(query = {}, { defaultLimit = DEFAULT_PAGE_SIZ
98
99
  };
99
100
  }
100
101
 
101
- function normalizeConversationStatus(value, fallback = "active") {
102
- const normalized = normalizeText(value).toLowerCase();
103
- if (normalized === "active" || normalized === "completed" || normalized === "failed" || normalized === "aborted") {
104
- return normalized;
105
- }
106
-
107
- return fallback;
108
- }
109
-
110
102
  function deriveConversationTitleFromMessage(contentText) {
111
103
  const normalized = String(contentText == null ? "" : contentText).replace(/\s+/g, " ").trim();
112
104
  if (!normalized) {
@@ -233,7 +225,9 @@ function createTranscriptService({ conversationsRepository, messagesRepository }
233
225
  }
234
226
 
235
227
  return conversationsRepository.updateById(numericConversationId, {
236
- status: normalizeConversationStatus(source.status, "completed"),
228
+ status: normalizeConversationStatus(source.status, {
229
+ fallback: "completed"
230
+ }),
237
231
  endedAt: source.endedAt || new Date(),
238
232
  metadata: {
239
233
  ...normalizeObject(existing.metadata),
@@ -252,7 +246,9 @@ function createTranscriptService({ conversationsRepository, messagesRepository }
252
246
  maxLimit: MAX_PAGE_SIZE
253
247
  });
254
248
 
255
- const status = normalizeConversationStatus(query.status, "");
249
+ const status = normalizeConversationStatus(query.status, {
250
+ fallback: ""
251
+ });
256
252
  const filters = {
257
253
  ...(status ? { status } : {})
258
254
  };
@@ -4,6 +4,7 @@ import {
4
4
  createCursorListValidator
5
5
  } from "@jskit-ai/kernel/shared/validators";
6
6
  import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
7
+ import { normalizeConversationStatus } from "./support/conversationStatus.js";
7
8
  import { toPositiveInteger } from "./support/positiveInteger.js";
8
9
 
9
10
  const MAX_INPUT_CHARS = 8000;
@@ -16,15 +17,6 @@ function normalizePaginationValue(value, fallback, max) {
16
17
  return Math.max(1, Math.min(max, parsed));
17
18
  }
18
19
 
19
- function normalizeConversationStatus(value) {
20
- const normalized = normalizeText(value).toLowerCase();
21
- if (normalized === "active" || normalized === "completed" || normalized === "failed" || normalized === "aborted") {
22
- return normalized;
23
- }
24
-
25
- return "";
26
- }
27
-
28
20
  function normalizeChatStreamBody(payload = {}) {
29
21
  const source = normalizeObjectInput(payload);
30
22
  const normalized = {
@@ -72,7 +64,9 @@ function normalizeChatStreamBody(payload = {}) {
72
64
 
73
65
  function normalizeConversationsListQuery(payload = {}) {
74
66
  const source = normalizeObjectInput(payload);
75
- const status = normalizeConversationStatus(source.status);
67
+ const status = normalizeConversationStatus(source.status, {
68
+ fallback: ""
69
+ });
76
70
  const normalized = {};
77
71
 
78
72
  if (Object.hasOwn(source, "cursor")) {
@@ -1,5 +1,9 @@
1
1
  import { Type } from "typebox";
2
- import { normalizeObjectInput } from "@jskit-ai/kernel/shared/validators";
2
+ import {
3
+ normalizeObjectInput,
4
+ normalizeSettingsFieldInput,
5
+ normalizeSettingsFieldOutput
6
+ } from "@jskit-ai/kernel/shared/validators";
3
7
  import { normalizeText } from "@jskit-ai/kernel/shared/actions/textNormalization";
4
8
 
5
9
  const MAX_SYSTEM_PROMPT_CHARS = 12_000;
@@ -42,35 +46,14 @@ function createPromptSettingsResource({
42
46
  );
43
47
 
44
48
  function normalizeInput(payload = {}) {
45
- const source = normalizeObjectInput(payload);
46
- const normalized = {};
47
- for (const field of fields) {
48
- if (!Object.hasOwn(source, field.key)) {
49
- continue;
50
- }
51
- normalized[field.key] = field.normalizeInput(source[field.key], {
52
- payload: source
53
- });
54
- }
55
- return normalized;
49
+ return normalizeSettingsFieldInput(payload, fields);
56
50
  }
57
51
 
58
52
  function normalizeOutput(payload = {}) {
59
53
  const source = normalizeObjectInput(payload);
60
54
  const settingsSource = normalizeObjectInput(source.settings);
61
- const settings = {};
62
- for (const field of fields) {
63
- const rawValue = Object.hasOwn(settingsSource, field.key)
64
- ? settingsSource[field.key]
65
- : field.resolveDefault({
66
- settings: settingsSource
67
- });
68
- settings[field.key] = field.normalizeOutput(rawValue, {
69
- settings: settingsSource
70
- });
71
- }
72
55
  return {
73
- settings
56
+ settings: normalizeSettingsFieldOutput(settingsSource, fields)
74
57
  };
75
58
  }
76
59
 
@@ -36,4 +36,10 @@ export {
36
36
  ASSISTANT_WORKSPACE_SETTINGS_CHANGED_EVENT
37
37
  } from "./settingsEvents.js";
38
38
 
39
+ export {
40
+ ASSISTANT_CONVERSATION_STATUSES,
41
+ normalizeConversationStatus
42
+ } from "./support/conversationStatus.js";
43
+
44
+ export { parseJsonObject } from "./support/jsonObject.js";
39
45
  export { toPositiveInteger } from "./support/positiveInteger.js";
@@ -0,0 +1,18 @@
1
+ import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
2
+
3
+ const ASSISTANT_CONVERSATION_STATUSES = Object.freeze(["active", "completed", "failed", "aborted"]);
4
+ const ASSISTANT_CONVERSATION_STATUS_SET = new Set(ASSISTANT_CONVERSATION_STATUSES);
5
+
6
+ function normalizeConversationStatus(value, { fallback = "" } = {}) {
7
+ const normalized = normalizeText(value).toLowerCase();
8
+ if (ASSISTANT_CONVERSATION_STATUS_SET.has(normalized)) {
9
+ return normalized;
10
+ }
11
+
12
+ return normalizeText(fallback).toLowerCase();
13
+ }
14
+
15
+ export {
16
+ ASSISTANT_CONVERSATION_STATUSES,
17
+ normalizeConversationStatus
18
+ };
@@ -0,0 +1,18 @@
1
+ function parseJsonObject(value) {
2
+ if (value == null) {
3
+ return {};
4
+ }
5
+
6
+ try {
7
+ const parsed = typeof value === "string" ? JSON.parse(value) : value;
8
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
9
+ return {};
10
+ }
11
+
12
+ return parsed;
13
+ } catch {
14
+ return {};
15
+ }
16
+ }
17
+
18
+ export { parseJsonObject };